- Tracebit merangkum teknik untuk memperkirakan AWS Account ID dari bucket S3 publik maupun privat, dan memulihkan
123456789101dari bucket contohbucket-alpha - Petunjuk utamanya adalah kondisi
s3:ResourceAccountpada kebijakan Interface VPC Endpoint untuk S3, serta apakah permintaan tercatat di log CloudTrail milik sendiri - Untuk bucket privat, meskipun respons akhir tetap
AccessDenied, hanya permintaan yang lolos kebijakan VPC Endpoint yang muncul di CloudTrail, sehingga kecocokan pola angka bisa ditentukan - Karena propagasi kebijakan dan jeda CloudTrail, pencarian sederhana bisa memakan waktu hingga sekitar
40 * 12 menit = 8 jam, tetapi dapat dipangkas menjadi kurang dari 10 menit dengan pengujian paralel 120 pernyataan kebijakan menggunakanaws:useriddanRoleSessionName - Teknik ini dimungkinkan karena
StringLikemengizinkan pencocokan parsial padas3:ResourceAccount, dan sebagian aktivitas juga bisa muncul di CloudTrail milik pemilik bucket
Perluasan yang berawal dari teknik bucket publik
- Pada 2021, Ben Bridts mempublikasikan cara menemukan AWS Account ID dari bucket S3 publik
- Pendekatan Tracebit menggunakan kembali beberapa elemen dari ide ini, tetapi berfokus pada pencarian Account ID bucket S3 termasuk bucket privat
- Dalam eksekusi contoh, untuk
bucket-alpha, mereka mengumpulkan nama sesi yang lolos di CloudTrail dan akhirnya memulihkan123456789101
Mengapa metode bucket publik yang ada bisa bekerja
- Metode Ben Bridts bekerja karena tiga syarat berikut saling terkait
- Kebijakan IAM dapat diterapkan pada permintaan
- Dapat disimpulkan apakah kebijakan mengizinkan atau memblokir permintaan
- Kunci kondisi
s3:ResourceAccountdapat menggunakan pencocokan wildcard
- Pada bucket publik, jika kebijakan memblokir permintaan maka akan muncul
AccessDenied, dan jika kebijakan mengizinkan maka permintaan berhasil, sehingga mudah membedakan apakah kebijakan dilalui atau tidak - Dengan mempersempit
s3:ResourceAccountsatu digit demi satu digit, ruang pencarian total dapat dikurangi dari triliunan menjadi ratusan saja
Untuk bucket privat, lihat CloudTrail alih-alih respons
- Bucket privat akan menghasilkan AccessDenied sebagai respons akhir apa pun kebijakan yang diterapkan, karena kebijakan bucket tujuan
- Pendekatan Tracebit tidak melihat hasil respons, melainkan apakah permintaan muncul di log CloudTrail milik sendiri
- Jika permintaan muncul di CloudTrail, berarti kebijakan VPC Endpoint mengizinkannya, lalu kebijakan bucket menolaknya sesudah itu
- Jika permintaan tidak ada di CloudTrail, berarti permintaan diblokir di kebijakan VPC Endpoint
- Dengan membuat Interface VPC Endpoint untuk S3, kebijakan VPC Endpoint dapat diterapkan pada permintaan, dan kebijakan ini dievaluasi bersama kebijakan lain seperti kebijakan bucket dan kebijakan IAM dari principal peminta
- Pada kebijakan VPC Endpoint juga bisa digunakan wildcard
StringLikedan kunci kondisi resource, sehingga metode pencarian yang sama bisa diterapkan
Prosedur dasar: dari pengecekan region hingga pengambilan event
- Pertama, region bucket target harus ditemukan
- Jika
curldikirim ke endpoint HTTP bucket, meskipun permintaan ditolak, headerx-amz-bucket-regiontetap dikembalikan - Pada contoh,
us-east-1dikonfirmasi dari header responsbucket-alpha.s3.amazonaws.com
- Jika
- Deploy VPC dan VPC Endpoint untuk S3 di region yang sama dengan bucket target
- VPC Endpoint harus bertipe Interface agar kebijakan dapat diterapkan
- Karena VPC Endpoint tersebut memengaruhi permintaan S3 di VPC, sebaiknya buat VPC khusus untuk tujuan ini
- Jalankan instance EC2 di dalam VPC untuk mengirim permintaan S3, lalu pastikan instance itu menggunakan VPC Endpoint untuk S3
- Ubah kebijakan VPC Endpoint untuk menguji apakah
s3:ResourceAccountdiawali dengan angka tertentu- Misalnya, untuk memeriksa apakah Account ID dimulai dengan
0, tetapkan kondisi"0*"padas3:ResourceAccount
- Misalnya, untuk memeriksa apakah Account ID dimulai dengan
- Dari instance EC2, kirim permintaan Management seperti
GetBucketAclke bucket target- Menggunakan permintaan Management mengurangi kebutuhan penanganan tambahan di konfigurasi CloudTrail
- Hasil permintaan, seperti yang diharapkan, adalah
AccessDenied
Cara membedakan pola angka dengan CloudTrail
- Setelah permintaan dikirim, periksa di CloudTrail apakah event
GetBucketAclmuncul - Jika event muncul, berarti kebijakan VPC Endpoint mengizinkan permintaan, sehingga Account ID cocok dengan pola yang diuji
- Contoh: jika event terlihat pada kondisi
"0*", berarti Account ID dimulai dengan0
- Contoh: jika event terlihat pada kondisi
- Jika event tidak muncul, berarti kebijakan VPC Endpoint memblokir permintaan, sehingga pola tersebut tidak cocok
- Karena event bisa membutuhkan beberapa menit untuk muncul di CloudTrail, disarankan menunggu 10 menit sebelum memutuskan bahwa event tidak ada
- Perubahan kebijakan VPC Endpoint juga memerlukan waktu hingga propagasi penuh dan penerapan selesai; menunggu 5 menit setelah perubahan kebijakan bekerja dengan baik
Sudah diotomatisasi, tetapi metode dasarnya lambat
- Tracebit menulis skrip untuk mengotomatisasi proses ini sehingga Account ID bucket dapat ditemukan secara andal
- Alih-alih memeriksa semua angka satu per satu, mereka mengurangi jumlah pengujian per digit dengan pendekatan yang mendekati binary search
- Misalnya, rentang dibagi dengan memasukkan beberapa pola pada kondisi
s3:ResourceAccountseperti["0*", "1*", "2*", "3*", "4*"]
- Misalnya, rentang dibagi dengan memasukkan beberapa pola pada kondisi
- Meski begitu, waktu tunggu untuk penerapan kebijakan dan pengecekan CloudTrail tetap menjadi bottleneck
- Bahkan dengan binary search, prosesnya masih bisa memakan sekitar
40 * 12 menit = 8 jam
- Bahkan dengan binary search, prosesnya masih bisa memakan sekitar
- Dalam contoh yang dijalankan selama beberapa jam, mereka berhasil menemukan Account ID
bucket-alphasebagai123456789101
Dipangkas menjadi kurang dari 10 menit dengan 120 pernyataan kebijakan
- Cara yang lebih cepat adalah memasukkan semua kombinasi posisi-digit yang mungkin lebih dulu ke dalam kebijakan VPC Endpoint
- Kebijakan tersebut berisi total 120 pernyataan
- Menguji 10 angka yang mungkin untuk tiap posisi pada AWS Account ID
- Setiap pernyataan menggunakan pola posisi tertentu pada
s3:ResourceAccountbersama kondisiaws:userid
- Kondisi
aws:useriddigunakan untuk mencocokkan nilaiRoleSessionNameyang dapat ditentukan secara bebas pada pemanggilan STSAssumeRole- Dengan mengambil role menggunakan
RoleSessionNametertentu, hanya pernyataan kebijakan yang sesuai dengan pengujian posisi-digit tertentu yang akan diloloskan secara selektif
- Dengan mengambil role menggunakan
- Kebijakan ini nyaris pas dalam batas maksimum panjang karakter kebijakan VPC Endpoint
- Karena semua 120 kemungkinan diuji secara paralel, tidak perlu terus-menerus mengubah kebijakan atau menunggu hasil CloudTrail satu per satu
- Dengan cara ini, waktu pencarian Account ID turun menjadi kurang dari 10 menit
Cakupan paparan dan kemungkinan penerapan
- Sebagian aktivitas dapat terlihat di log CloudTrail milik pemilik bucket target
- Tracebit berdiskusi dengan tim keamanan AWS sebelum publikasi
- Sudah ada banyak diskusi tentang apakah AWS Account ID merupakan informasi sensitif, dan pada event CloudTrail contoh, Account ID pihak ketiga disamarkan sebagai
HIDDEN_DUE_TO_SECURITY_REASONS - Teknik yang sama juga bisa diterapkan pada kunci kondisi resource lain yang terkait bucket
- Contoh:
aws:ResourceOrgID - Contoh:
aws:ResourceOrgPaths - Contoh:
aws:ResourceTag
- Contoh:
- Teknik ini juga berpotensi diterapkan ke layanan selain S3
- Jika VPC dan VPC Endpoint yang saling terhubung dibuat di semua region, mungkin saja dibuat konfigurasi yang tetap bekerja terlepas dari region bucket target
- Teknik ini dimungkinkan karena kondisi
s3:ResourceAccountdapat menggunakan pencocokan parsial StringLike - Akan berguna jika event yang ditolak oleh kebijakan VPC Endpoint juga dicatat di CloudTrail
1 komentar
Pendapat di Hacker News
Sungguh aneh bahwa pencocokan wildcard bisa diterapkan pada kunci kondisi s3:ResourceAccount
Rasanya tidak ada alasan yang sah untuk mengizinkan atau menolak izin berdasarkan kecocokan sebagian ID akun
StringLikepada string ID akunAgak menarik melihat tren pihak DevOps kini menemukan serangan kanal samping. Kanal samping eksekusi spekulatif CPU seperti Meltdown dan Spectre juga menimbulkan dampak besar saat ditemukan, dan sebelumnya ada bidang seperti analisis daya, deteksi distorsi magnetik, serta kriptografi waktu konstan
https://en.m.wikipedia.org/wiki/Side-channel_attack
https://en.m.wikipedia.org/wiki/Power_analysis
Di proyek sampingan baru-baru ini, aku membuat fitur untuk menulis kueri dalam format yang terinspirasi OWL, dan ada pustaka operator relasional untuk mengambil host dari URL, kueri prefiks, kueri
like, kueri regex, dan sebagainyaKarena ini proyek sampingan dari proyek sampinganku yang lain, aku mengambil cara yang mudah, dan membiarkan operator selalu bisa digunakan meski dalam kasus yang tidak masuk akal. Aku bahkan tidak tahu dan tidak peduli apa yang terjadi jika melakukan kueri regex pada angka. Bisa saja ada hal serupa di internal AWS, tetapi untuk sistem yang punya banyak pengguna dan sensitif terhadap keamanan, standarnya seharusnya berbeda
Seseorang mungkin memikirkan ide seperti ini lalu merasa pintar, tetapi menerapkannya pada sistem yang tidak sepenuhnya dikendalikan tampak bodoh
Umumnya ID akun memang tidak akan disebarkan secara publik, tetapi harus diasumsikan bahwa suatu saat sebagian akan terekspos
Semakin banyak vendor pihak ketiga dan platform SaaS beralih ke model integrasi yang lebih memilih delegasi peran daripada pengguna IAM dan access key, dan memang seharusnya begitu. Dengan begitu, setidaknya ID akun dari akun yang dipakai sebagai titik integrasi akan diketahui pihak lain, dan pihak tersebut juga punya dependensi, kerentanan, dan sebagainya
ID akun AWS mirip dengan alamat IP. Bisa saja sensitif, tetapi agar pekerjaan berjalan, harus ada pihak yang mengetahuinya
Misalnya 1–2 tahun lalu ada pihak ketiga yang perlu kami integrasikan karena prosedur anti-pencucian uang. Karena biasanya lebih aman daripada port SFTP publik, kami mengusulkan menyiapkan PrivateLink dengan organisasi itu, tetapi perusahaan lawan menolak dengan alasan keamanan bahwa mereka harus menyembunyikan ID akun. Padahal itu diperlukan di ARN peran untuk endpoint PV demi izin timbal balik
Akhirnya kami memasukkan rentang IP publik yang mereka gunakan untuk port inbound 22 ke daftar izin
Pelajarannya: boleh saja merasa pintar dengan mengaburkan ID, tetapi sulit menjalankan bisnis jika pihak lain tidak tahu alamat untuk menghubungimu kembali
Dari sisi vendor, kami biasanya berintegrasi melalui VPC Endpoint Service. Dengan cara ini komunikasinya satu arah, dan layanan kami diekspos sebagai endpoint load balancer di dalam VPC pelanggan
Bagi yang tertarik, kodenya aku taruh di sini: https://github.com/tracebit-com/find-s3-account
Memang penemuan yang menarik, tetapi dari judulnya saja aku mengira ada metode yang lebih langsung
Akan bagus kalau di AWS, sebagai akun admin, kita bisa sekadar bertanya di dalam organisasi “resource X ada di mana” dan dengan cepat mengetahui bucket S3 tertentu berada di akun mana. Resource lain juga begitu, tetapi bucket S3 terutama terasa besar skalanya
Jujur, ini terutama masalah pada bucket legacy sebelum praktik yang lebih baik muncul, atau bucket yang sudah ada sebelum semuanya didefinisikan sebagai kode. Meski begitu, jika punya banyak akun AWS, mencari resource di akun dan region yang tidak diketahui bisa menjadi pekerjaan membosankan
Dengan begitu, mencari akun mana yang memiliki resource kira-kira bisa dilakukan dengan
select accountId where arn = "x"Resource AWS publik lain yang memiliki namespace global juga mengungkap ID akun AWS
https://blog.plerion.com/conditional-love-for-aws-metadata-e...
Sedikit terkait, Cloudflare account_id dan zone_id aman meski dipublikasikan
https://github.com/cloudflare/cloudflare-docs/issues/474
https://community.cloudflare.com/t/api-zone-id/355566
Namun salah satu hal yang bisa dilakukan dengannya adalah menemukan korelasi. Jika beberapa situs S3 dijalankan dari akun AWS yang sama, orang dapat melihat bahwa situs-situs itu di-hosting dari akun yang sama. Apakah ini penting bergantung pada model ancaman
Ini tidak sempurna, tetapi menambahkan satu lapisan abstraksi lagi
Terkait hal ini, ID kunci AWS, meskipun bukan bagian kunci rahasia, memuat ID akun di dalamnya dalam bentuk yang digeser satu bit
https://medium.com/@TalBeerySec/a-short-note-on-aws-key-id-f...
ID kunci ini disertakan dalam URL pratinjau bertanda tangan S3, jadi kemungkinan besar Anda memang sudah mengekspos ID akun
Mungkin akan di-downvote, tetapi jika tetap dibaca, ini adalah contoh mengapa security through obscurity bukan pertahanan yang baik. Kita akan melewatkan sesuatu, sementara penyerang yang gigih tidak akan melewatkannya
Keamanan yang tidak bergantung pada penyembunyian tetap berlaku terlepas dari apakah saya memahami sesuatu atau tidak, kecuali penyerang mempekerjakan seorang jenius yang, misalnya, bisa begitu saja memecahkan AES-256: https://www.youtube.com/watch?v=KEkrWRHCDQU
Mengapa ini bisa penting? Sebagai contoh yang jelas, jika diberi bucket produksi, kini orang bisa menemukan bucket pengembangan dari organisasi yang sama. Secara pribadi, ini bukan perilaku yang saya perkirakan
Untuk mencegah upaya enumerasi seperti ini, nama bucket harus diberi prefiks atau sufiks yang dibuat secara acak. Selain itu, sebagai langkah tambahan, bukan pengganti, praktik yang baik juga adalah memublikasikan objek bucket dengan nama selain hostname default agar nama bucket itu sendiri tidak bocor
Misalnya, alamat rumah secara teknis adalah informasi publik, tetapi saya tentu tidak ingin alamat tempat saya tinggal dipasang di papan reklame di pinggir jalan tol bersama foto keluarga. Saya memberikannya hanya kepada orang yang membutuhkannya, dan saya percaya serta berharap informasi itu umumnya dijaga mendekati rahasia atau dibatasi penggunaannya
Jika bukan rahasia, tidak sensitif, dan tidak bersifat rahasia, mengapa harus dibagikan dengan hati-hati?
Pengguna bisa saja melihatnya berbeda