किसी S3 bucket का AWS account ID कैसे पता करें
(tracebit.com)- Tracebit ने public और private S3 buckets के AWS Account ID का अनुमान लगाने की तकनीक समझाई है, और उदाहरण bucket
bucket-alphaसे123456789101को पुनर्निर्मित किया है - मुख्य संकेत S3 के Interface VPC Endpoint policy की
s3:ResourceAccountcondition और यह है कि request अपने CloudTrail logs में दिखती है या नहीं - private bucket में अंतिम response लगातार
AccessDeniedही रहे, तब भी केवल वही requests CloudTrail में दिखती हैं जो VPC Endpoint policy से पास हुई हों, इसलिए संख्या pattern के match होने का पता लगाया जा सकता है - policy propagation और CloudTrail delay के कारण साधारण खोज में लगभग
40 * 12분 = 8시간तक लग सकते हैं, लेकिनaws:useridऔरRoleSessionNameका उपयोग करने वाले 120 policy statements के parallel test से इसे 10 मिनट से कम तक घटाया जा सकता है - यह तकनीक इसलिए संभव है क्योंकि
StringLikes3:ResourceAccountपर partial match की अनुमति देता है, और कुछ गतिविधियाँ bucket owner के CloudTrail में भी दर्ज हो सकती हैं
public bucket तकनीक से शुरू हुआ विस्तार
- 2021 में Ben Bridts ने public S3 bucket का AWS Account ID कैसे पता करें प्रकाशित किया
- Tracebit का तरीका इस विचार के कई तत्वों का पुन: उपयोग करता है, लेकिन फोकस private buckets सहित S3 bucket का Account ID खोजने पर है
- उदाहरण run में
bucket-alphaके लिए CloudTrail में पास हुए session names इकट्ठा करके अंततः123456789101को पुनर्निर्मित किया गया
मौजूदा public bucket तरीका क्यों काम करता है
- Ben Bridts का तरीका तीन शर्तों के साथ काम करता है
- request पर IAM policy लागू की जा सकती है
- यह अनुमान लगाया जा सकता है कि policy ने request को allow किया या block
s3:ResourceAccountcondition key पर wildcard matching लागू की जा सकती है
- public bucket में policy request को रोक दे तो
AccessDeniedमिलता है, और policy allow करे तो request सफल होती है, इसलिए policy pass हुई या नहीं यह आसानी से अलग किया जा सकता है s3:ResourceAccountको एक-एक digit करके सीमित करने पर कुल खोज क्षेत्र खरबों से घटकर सैकड़ों तक आ जाता है
private bucket में response के बजाय CloudTrail देखा जाता है
- private bucket में कोई भी policy लागू करें, target bucket policy की वजह से अंतिम response AccessDenied ही होता है
- Tracebit का तरीका response result नहीं, बल्कि request अपने CloudTrail log में दिखती है या नहीं, इसे आधार बनाता है
- अगर request CloudTrail में दिखती है, तो VPC Endpoint policy ने allow किया और बाद में bucket policy ने deny किया
- अगर request CloudTrail में नहीं है, तो VPC Endpoint policy ने ही block किया
- S3 के लिए Interface VPC Endpoint बनाने पर request पर VPC Endpoint policy लागू की जा सकती है, और यह policy bucket policy, request principal की IAM policy आदि के साथ मिलकर evaluate होती है
- VPC Endpoint policy में भी
StringLikewildcard और resource condition keys इस्तेमाल की जा सकती हैं, इसलिए वही खोज तरीका संभव है
बुनियादी प्रक्रिया: region पहचानने से event query तक
- पहले target bucket का region पता होना चाहिए
- bucket HTTP endpoint पर
curlभेजने पर, request मना होने पर भीx-amz-bucket-regionheader लौटता है - उदाहरण में
bucket-alpha.s3.amazonaws.comresponse header सेus-east-1की पुष्टि की गई
- bucket HTTP endpoint पर
- target bucket के उसी region में VPC और S3 के लिए VPC Endpoint deploy किया जाता है
- VPC Endpoint policy लागू करने योग्य Interface type का होना चाहिए
- क्योंकि यह VPC Endpoint, VPC की S3 requests को प्रभावित करेगा, इसलिए इस उद्देश्य के लिए अलग VPC बनाना बेहतर है
- VPC के अंदर S3 request भेजने के लिए EC2 instance चलाया जाता है, और यह सुनिश्चित किया जाता है कि वह instance S3 VPC Endpoint का उपयोग कर रहा है
- VPC Endpoint policy बदलकर यह test किया जाता है कि
s3:ResourceAccountकिसी खास digit से शुरू होता है या नहीं- उदाहरण के लिए Account ID
0से शुरू होता है या नहीं देखने के लिएs3:ResourceAccountपर"0*"condition रखी जाती है
- उदाहरण के लिए Account ID
- EC2 instance से target bucket पर
GetBucketAclजैसी Management request भेजी जाती है- Management request इस्तेमाल करने पर CloudTrail configuration में अलग handling की जरूरत कम होती है
- request result अपेक्षा के अनुसार
AccessDeniedहोता है
CloudTrail से number pattern पहचानने का तरीका
- request के बाद CloudTrail में
GetBucketAclevent दिखता है या नहीं, यह query किया जाता है - event दिखे तो VPC Endpoint policy ने request allow की, यानी Account ID test किए गए pattern से match करता है
- उदाहरण:
"0*"condition में event दिखे तो Account ID0से शुरू होता है
- उदाहरण:
- event न दिखे तो VPC Endpoint policy ने request block की, यानी वह pattern match नहीं करता
- CloudTrail में event दिखने में कुछ मिनट लग सकते हैं, इसलिए event नहीं है यह मानने से पहले 10 मिनट इंतजार करने की सलाह दी जाती है
- VPC Endpoint policy change को पूरी तरह propagate होकर लागू होने में भी समय लगता है, और policy बदलने के बाद 5 मिनट इंतजार अच्छा काम करता है
automation के बाद भी बुनियादी तरीका धीमा है
- Tracebit ने इस प्रक्रिया को automate करने वाली script लिखी ताकि bucket का Account ID भरोसेमंद तरीके से खोजा जा सके
- हर digit के लिए सभी numbers को साधारण तरीके से जांचने के बजाय, हर position पर binary search के करीब तरीका अपनाकर tests की संख्या घटाई गई
- उदाहरण के लिए
s3:ResourceAccountcondition में["0*", "1*", "2*", "3*", "4*"]जैसे कई patterns डालकर range बांटी जाती है
- उदाहरण के लिए
- फिर भी policy application और CloudTrail verification का इंतजार bottleneck बना रहता है
- binary search इस्तेमाल करने पर भी लगभग
40 * 12분 = 8시간लग सकते हैं
- binary search इस्तेमाल करने पर भी लगभग
- कई घंटे चले उदाहरण में
bucket-alphaका Account ID सफलतापूर्वक123456789101निकाला गया
120 policy statements से 10 मिनट से कम तक कमी
- और तेज तरीका यह है कि VPC Endpoint policy में हर संभव position-digit combination पहले से डाल दिया जाए
- policy में कुल 120 statements होते हैं
- AWS Account ID की हर position के लिए 10 संभावित digits test किए जाते हैं
- हर statement,
s3:ResourceAccountके किसी खास position pattern के साथaws:useridcondition का उपयोग करता है
aws:useridcondition, STSAssumeRolecall में स्वतंत्र रूप से सेट किए जा सकने वालेRoleSessionNamevalue को match करने के लिए इस्तेमाल होती है- किसी खास
RoleSessionNameके साथ role assume करने पर, किसी खास position-digit test से जुड़ा policy statement चुनिंदा रूप से pass कराया जा सकता है
- किसी खास
- यह policy VPC Endpoint policy की अधिकतम character length में मुश्किल से फिट होती है
- क्योंकि सभी 120 संभावनाएँ parallel में test की जाती हैं, इसलिए हर बार policy बदलने या CloudTrail result का अलग-अलग इंतजार करने की जरूरत घट जाती है
- इस तरीके से Account ID खोजने का समय 10 मिनट से कम रह जाता है
exposure की सीमा और संभावित उपयोग
- कुछ गतिविधियाँ target bucket owner के CloudTrail logs में दिखाई दे सकती हैं
- Tracebit ने public disclosure से पहले AWS Security team से चर्चा की
- AWS Account ID संवेदनशील जानकारी है या नहीं, इस पर पहले से काफी चर्चा रही है, और उदाहरण CloudTrail event में third-party Account ID को
HIDDEN_DUE_TO_SECURITY_REASONSके रूप में छिपाया गया है - यही तकनीक bucket से जुड़े दूसरे resource condition keys पर भी लागू हो सकती है
- उदाहरण:
aws:ResourceOrgID - उदाहरण:
aws:ResourceOrgPaths - उदाहरण:
aws:ResourceTag
- उदाहरण:
- S3 के अलावा, उन अन्य services पर भी इसका उपयोग किया जा सकता है जहाँ यह तकनीक लागू हो सके
- अगर सभी regions में आपस में peered VPCs और VPC Endpoints बनाए जाएँ, तो target bucket किस region में है इससे स्वतंत्र रूप से काम करने वाला setup बनाना संभव हो सकता है
- यह तकनीक
s3:ResourceAccountcondition पर StringLike partial match इस्तेमाल कर पाने की वजह से संभव है - अगर VPC Endpoint policy द्वारा deny किए गए events भी CloudTrail में record हों, तो वह उपयोगी हो सकता है
1 टिप्पणियां
Hacker News टिप्पणियाँ
s3:ResourceAccount condition key पर wildcard matching लागू किया जा सकता है, यह वाकई अजीब है
ऐसा नहीं लगता कि account ID के आंशिक मिलान के आधार पर permissions को allow या deny करने का कोई जायज़ कारण है
StringLikeइस्तेमाल होने की वजह शायद यही हैDevOps क्षेत्र में अब side-channel attacks खोजे जाने का रुझान थोड़ा दिलचस्प है। CPU के speculative execution side-channels, जैसे Meltdown और Spectre, खोजे जाने के समय बड़ा असर लेकर आए थे, और उससे पहले power analysis, magnetic distortion detection, और constant-time cryptography जैसे क्षेत्र भी रहे हैं
https://en.m.wikipedia.org/wiki/Side-channel_attack
https://en.m.wikipedia.org/wiki/Power_analysis
हाल की एक side project में मैंने OWL से प्रेरित format में queries लिखने की सुविधा बनाई थी, जिसमें URL से host निकालना, prefix queries,
likequeries, regular expression queries वगैरह करने के लिए relational operator library हैवह मेरे side project का भी side project था, इसलिए मैंने आसान रास्ता चुना और ऐसे मामलों में भी operators हमेशा उपलब्ध रहने दिए जहाँ उनका कोई मतलब नहीं बनता। numbers पर regular expression query करने पर क्या होगा, यह भी न पता है न परवाह की। AWS के अंदर भी कुछ ऐसा हो सकता है, लेकिन अगर system के users बहुत हों और वह security-sensitive हो, तो मानदंड अलग होने चाहिए
कोई इस तरह का idea सोचकर खुद को चतुर समझ सकता है, लेकिन जिस system पर आपका 100% control नहीं है, वहाँ इसे लागू करना मूर्खता जैसा लगता है
आम तौर पर account ID को सार्वजनिक रूप से फैलाया नहीं जाएगा, लेकिन मानकर चलना चाहिए कि कभी न कभी उसका कुछ हिस्सा उजागर होगा
अधिक third-party vendors और SaaS platforms अब IAM users और access keys की जगह role delegation को पसंद करने वाले integration model की ओर बढ़ रहे हैं, और यही सही भी है। तब कम से कम integration point के रूप में इस्तेमाल होने वाले account की account ID दूसरी पार्टी को पता होगी, और वहाँ भी dependencies, vulnerabilities वगैरह होंगी
AWS account ID, IP address जैसा है। यह संवेदनशील हो सकता है, लेकिन काम करने के लिए किसी न किसी को यह जानना पड़ेगा
उदाहरण के लिए, 1–2 साल पहले एक third party के साथ anti-money-laundering प्रक्रिया के कारण integration करना था। हमने कहा कि सामान्य public SFTP port से ज्यादा सुरक्षित होगा अगर उस संगठन के साथ PrivateLink सेट कर लिया जाए, लेकिन दूसरी कंपनी ने security कारणों से account ID छिपाए रखने की बात कहकर मना कर दिया। जबकि mutual permissions के लिए PV endpoint के role ARN में इसकी ज़रूरत थी
आखिर में हमने उनके inbound port 22 के लिए इस्तेमाल हो रही public IP range को allowlist कर दिया
सबक यह है कि ID को obfuscate करके आप खुद को चतुर समझ सकते हैं, लेकिन अगर सामने वाले को वापसी का पता ही न हो, तो business चलाना मुश्किल हो जाता है
हम vendor के रूप में आम तौर पर VPC Endpoint Service से integrate करते हैं। इस तरीके में communication unidirectional होता है, और हमारी service customer VPC के अंदर load balancer endpoint के रूप में expose होती है
जिन लोगों की रुचि हो, उनके लिए code यहाँ है: https://github.com/tracebit-com/find-s3-account
यह निश्चित रूप से दिलचस्प खोज है, लेकिन सिर्फ शीर्षक देखकर लगा था कि शायद कोई अधिक सीधा तरीका होगा
अच्छा होता अगर AWS में admin account के रूप में organization के भीतर बस यह पूछा जा सकता, “X resource कहाँ है”, और जल्दी से पता चल जाता कि कोई खास S3 bucket किस account में है। दूसरे resources के लिए भी, लेकिन S3 bucket के मामले में यह खास तौर पर बड़ा मुद्दा है
सच कहूँ तो यह ज़्यादातर legacy buckets में होने वाली समस्या है, जो बेहतर practices आने से पहले बने थे, या उन buckets में जो सभी buckets को code में define करने से पहले से मौजूद थे। फिर भी अगर AWS accounts बहुत हों, तो अज्ञात accounts और regions में resources ढूँढना थकाऊ हो सकता है
तब यह पता लगाना कि resource किस account के पास है, लगभग
select accountId where arn = "x"जैसा हो जाता हैglobal namespace वाले दूसरे public AWS resources भी AWS account ID उजागर करते हैं
https://blog.plerion.com/conditional-love-for-aws-metadata-e...
थोड़ा संबंधित विषय: Cloudflare account_id और zone_id सार्वजनिक होने पर भी सुरक्षित हैं
https://github.com/cloudflare/cloudflare-docs/issues/474
https://community.cloudflare.com/t/api-zone-id/355566
लेकिन इससे जो काम किए जा सकते हैं उनमें से एक है correlation निकालना। अगर एक ही AWS account पर कई S3 sites चल रही हैं, तो लोग देख सकते हैं कि वे उसी account से host की गई हैं। यह कितना महत्वपूर्ण है, यह threat model पर निर्भर करता है
यह परफेक्ट नहीं है, लेकिन abstraction की एक और layer जोड़ देता है
संबंधित बात यह भी है कि AWS key ID में, secret key वाला हिस्सा न होने पर भी, account ID bit shift किए हुए रूप में शामिल होती है
https://medium.com/@TalBeerySec/a-short-note-on-aws-key-id-f...
यह key ID S3 pre-signed URL में शामिल होती है, इसलिए संभव है कि account ID पहले से ही सार्वजनिक हो रही हो
शायद मुझे downvote मिलेगा, लेकिन अगर आप यह पढ़ रहे हैं, तो यह इस बात का उदाहरण है कि security through obscurity अच्छी defense क्यों नहीं है। आप कुछ न कुछ मिस करेंगे, और एक persistent attacker वह मिस नहीं करेगा
obscurity पर निर्भर न करने वाली security इस बात से अलग लागू होती है कि मैंने कुछ समझा या नहीं, जब तक कि कोई attacker AES-256 को ही तोड़ देने वाला जीनियस hire न कर ले: https://www.youtube.com/watch?v=KEkrWRHCDQU
यह क्यों महत्वपूर्ण हो सकता है? एक स्पष्ट उदाहरण के तौर पर, अगर production bucket दी गई हो, तो अब उसी organization के development bucket भी ढूंढे जा सकते हैं। व्यक्तिगत रूप से, यह अपेक्षित व्यवहार नहीं लगता
ऐसे enumeration प्रयासों को रोकने के लिए bucket name में random generated prefix या suffix जोड़ना चाहिए। इसके अलावा, विकल्प के रूप में नहीं बल्कि अतिरिक्त उपाय के तौर पर, bucket objects को default hostname के बजाय किसी और नाम से serve करना भी अच्छा तरीका है ताकि bucket name खुद leak न हो
उदाहरण के लिए, घर का पता तकनीकी रूप से public information हो सकता है, लेकिन मैं कभी नहीं चाहूंगा कि परिवार की फोटो के साथ हाईवे के किनारे लगे billboard पर यह लिखा हो कि मैं कहाँ रहता हूँ। मैं इसे केवल ज़रूरतमंद लोगों को देना चाहूंगा, और आम तौर पर यह उम्मीद करूंगा कि इसे लगभग confidential रखा जाएगा या कम से कम purpose-limited होगा
अगर यह न secret है, न sensitive, न confidential, तो फिर इसे सावधानी से साझा क्यों करना चाहिए?
users इसे अलग तरह से देख सकते हैं