PHP Tricks
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
अपने वेब ऐप्स, नेटवर्क और क्लाउड पर हैकर का दृष्टिकोण प्राप्त करें
महत्वपूर्ण, शोषण योग्य कमजोरियों को खोजें और रिपोर्ट करें जिनका वास्तविक व्यवसाय पर प्रभाव है। हमारे 20+ कस्टम टूल का उपयोग करें ताकि हमले की सतह का मानचित्रण कर सकें, सुरक्षा मुद्दों को खोज सकें जो आपको विशेषाधिकार बढ़ाने की अनुमति देते हैं, और आवश्यक सबूत इकट्ठा करने के लिए स्वचालित शोषण का उपयोग करें, जिससे आपका कठिन काम प्रभावशाली रिपोर्टों में बदल जाए।
यह phpMyAdmin कुकीज़ के लिए भी मान्य है।
कुकीज़:
स्थान:
यदि PHP में ==
का उपयोग किया जाता है, तो कुछ अप्रत्याशित मामलों में तुलना अपेक्षित रूप से व्यवहार नहीं करती है। इसका कारण यह है कि "==" केवल उन मानों की तुलना करता है जो समान प्रकार में परिवर्तित होते हैं, यदि आप यह भी तुलना करना चाहते हैं कि तुलना किए गए डेटा का प्रकार समान है, तो आपको ===
का उपयोग करना होगा।
PHP तुलना तालिकाएँ: https://www.php.net/manual/en/types.comparisons.php
"string" == 0 -> True
एक स्ट्रिंग जो संख्या से शुरू नहीं होती है, वह संख्या के बराबर होती है
"0xAAAA" == "43690" -> True
संख्याओं से बनी स्ट्रिंग्स को अन्य संख्याओं/स्ट्रिंग्स के साथ तुलना की जा सकती है, यदि संख्याएँ समान थीं (स्ट्रिंग में संख्याएँ संख्याओं के रूप में व्याख्यायित की जाती हैं)
"0e3264578" == 0 --> True
"0e" से शुरू होने वाली और किसी भी चीज़ के बाद आने वाली स्ट्रिंग 0 के बराबर होगी
"0X3264578" == 0X --> True
"0" से शुरू होने वाली और किसी भी अक्षर (X कोई भी अक्षर हो सकता है) और किसी भी चीज़ के बाद आने वाली स्ट्रिंग 0 के बराबर होगी
"0e12334" == "0" --> True
यह बहुत दिलचस्प है क्योंकि कुछ मामलों में आप "0" के स्ट्रिंग इनपुट और कुछ सामग्री को नियंत्रित कर सकते हैं जो हैश की जा रही है और इसकी तुलना की जा रही है। इसलिए, यदि आप एक ऐसा मान प्रदान कर सकते हैं जो "0e" से शुरू होने वाला हैश बनाए और बिना किसी अक्षर के, तो आप तुलना को बायपास कर सकते हैं। आप इस प्रारूप में पहले से हैश की गई स्ट्रिंग्स यहाँ पा सकते हैं: https://github.com/spaze/hashes
"X" == 0 --> True
स्ट्रिंग में कोई भी अक्षर int 0 के बराबर होता है
अधिक जानकारी के लिए https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09
टाइप जुगलिंग डिफ़ॉल्ट रूप से in_array()
फ़ंक्शन को भी प्रभावित करता है (आपको सख्त तुलना करने के लिए तीसरे तर्क को सत्य पर सेट करना होगा):
यदि इस फ़ंक्शन का उपयोग किसी भी प्रमाणीकरण जांच के लिए किया जाता है (जैसे पासवर्ड की जांच करना) और उपयोगकर्ता तुलना के एक पक्ष को नियंत्रित करता है, तो वह पासवर्ड के मान के रूप में एक स्ट्रिंग के बजाय एक खाली एरे भेज सकता है (https://example.com/login.php/?username=admin&password[]=
) और इस जांच को बायपास कर सकता है:
strcasecmp()
के साथ भी वही त्रुटि होती है
यहां तक कि यदि ===
का उपयोग किया जा रहा है तो भी ऐसी त्रुटियाँ हो सकती हैं जो तुलना को कमजोर बनाती हैं प्रकार जुगलिंग के लिए। उदाहरण के लिए, यदि तुलना तुलना करने से पहले डेटा को एक अलग प्रकार के ऑब्जेक्ट में परिवर्तित कर रही है:
preg_match()
का उपयोग उपयोगकर्ता इनपुट को मान्य करने के लिए किया जा सकता है (यह जांचता है कि क्या कोई शब्द/regex ब्लैकलिस्ट से उपयोगकर्ता इनपुट में मौजूद है और यदि नहीं है, तो कोड अपनी कार्यवाही जारी रख सकता है)।
हालांकि, जब regexppreg_match()
के प्रारंभ को सीमित किया जाता है, तो यह केवल उपयोगकर्ता इनपुट की पहली पंक्ति की जांच करता है, फिर यदि किसी तरह आप इनपुट को कई पंक्तियों में भेज सकते हैं, तो आप इस जांच को बायपास करने में सक्षम हो सकते हैं। उदाहरण:
इस जांच को बायपास करने के लिए आप नए लाइनों के साथ मान को URL-एन्कोडेड (%0A
) भेज सकते हैं या यदि आप JSON डेटा भेज सकते हैं, तो इसे कई लाइनों में भेजें:
Find an example here: https://ramadistra.dev/fbctf-2019-rceservice
(यह बायपास स्पष्ट रूप से PHP 5.2.5 पर आजमाया गया था और मैं इसे PHP 7.3.15 पर काम नहीं करवा सका)
यदि आप preg_match()
को एक मान्य बहुत बड़ा इनपुट भेज सकते हैं, तो यह इसे प्रोसेस नहीं कर पाएगा और आप चेक को बायपास कर सकेंगे। उदाहरण के लिए, यदि यह एक JSON को ब्लैकलिस्ट कर रहा है, तो आप भेज सकते हैं:
From: https://medium.com/bugbountywriteup/solving-each-and-every-fb-ctf-challenge-part-1-4bce03e2ecb0
Trick from: https://simones-organization-4.gitbook.io/hackbook-of-a-hacker/ctf-writeups/intigriti-challenges/1223 and https://mizu.re/post/pong
संक्षेप में, समस्या इस कारण होती है क्योंकि PHP में preg_*
फ़ंक्शन PCRE लाइब्रेरी पर आधारित होते हैं। PCRE में कुछ नियमित अभिव्यक्तियों को बहुत सारे पुनरावृत्त कॉल का उपयोग करके मिलाया जाता है, जो बहुत अधिक स्टैक स्पेस का उपयोग करता है। पुनरावृत्तियों की अनुमति की गई मात्रा पर एक सीमा निर्धारित करना संभव है, लेकिन PHP में यह सीमा डिफ़ॉल्ट रूप से 100.000 होती है, जो स्टैक में फिट होने से अधिक है।
यह Stackoverflow थ्रेड भी उस पोस्ट में लिंक किया गया था जहाँ इस मुद्दे के बारे में अधिक गहराई से बात की गई है। हमारा कार्य अब स्पष्ट था:
एक इनपुट भेजें जो regex को 100_000+ पुनरावृत्तियों करने के लिए मजबूर करे, जिससे SIGSEGV हो, जिससे preg_match()
फ़ंक्शन false
लौटाए और इस प्रकार एप्लिकेशन को यह सोचने पर मजबूर करे कि हमारा इनपुट दुर्भावनापूर्ण नहीं है, अंत में पे लोड में कुछ ऐसा फेंकते हुए जैसे {system(<verybadcommand>)}
SSTI --> RCE --> ध्वज :)।
खैर, regex के संदर्भ में, हम वास्तव में 100k "पुनरावृत्तियों" को नहीं कर रहे हैं, बल्कि हम "बैकट्रैकिंग स्टेप्स" की गिनती कर रहे हैं, जो जैसा कि PHP दस्तावेज़ में कहा गया है, pcre.backtrack_limit
चर में डिफ़ॉल्ट रूप से 1_000_000 (1M) होता है।
इस तक पहुँचने के लिए, 'X'*500_001
1 मिलियन बैकट्रैकिंग स्टेप्स (500k आगे और 500k पीछे) का परिणाम देगा:
यदि PHP किसी अन्य पृष्ठ पर रीडायरेक्ट कर रहा है लेकिन die
या exit
फ़ंक्शन हेडर Location
सेट करने के बाद नहीं बुलाया गया है, तो PHP निष्पादन जारी रखता है और डेटा को बॉडी में जोड़ता है:
Check:
File Inclusion/Path traversalregister_globals: In PHP < 4.1.1.1 या यदि गलत कॉन्फ़िगर किया गया हो, तो register_globals सक्रिय हो सकता है (या उनका व्यवहार अनुकरण किया जा रहा है)। इसका मतलब है कि वैश्विक चर जैसे $_GET यदि उनके पास एक मान है जैसे $_GET["param"]="1234", आप इसे $param के माध्यम से एक्सेस कर सकते हैं। इसलिए, HTTP पैरामीटर भेजकर आप उन चर को ओवरराइट कर सकते हैं जो कोड के भीतर उपयोग किए जाते हैं।
एक ही डोमेन के PHPSESSION कुकीज़ एक ही स्थान पर संग्रहीत होते हैं, इसलिए यदि एक डोमेन में विभिन्न कुकीज़ विभिन्न पथों में उपयोग की जाती हैं तो आप उस पथ को बना सकते हैं जो कुकी को पथ के रूप में एक्सेस करता है, दूसरे पथ कुकी के मान को सेट करके। इस तरह यदि दोनों पथ एक ही नाम के साथ एक चर को एक्सेस करते हैं तो आप path1 में उस चर का मान path2 पर लागू कर सकते हैं। और फिर path2 path1 के चर को मान्य के रूप में लेगा (कुकी को path2 में उसके अनुसार नाम देकर)।
जब आपके पास मशीन के उपयोगकर्ताओं के उपयोगकर्ता नाम होते हैं। पता जांचें: /~<USERNAME> यह देखने के लिए कि क्या php निर्देशिकाएँ सक्रिय हैं।
ये फ़ंक्शन आमतौर पर PHP में पासवर्ड से हैश उत्पन्न करने और यह जांचने के लिए उपयोग किए जाते हैं कि क्या एक पासवर्ड हैश के साथ सही है।
समर्थित एल्गोरिदम हैं: PASSWORD_DEFAULT
और PASSWORD_BCRYPT
(जो $2y$
से शुरू होता है)। ध्यान दें कि PASSWORD_DEFAULT अक्सर PASSWORD_BCRYPT के समान होता है। और वर्तमान में, PASSWORD_BCRYPT में 72bytes के इनपुट में आकार की सीमा है। इसलिए, जब आप इस एल्गोरिदम के साथ 72bytes से बड़ा कुछ हैश करने की कोशिश करते हैं, तो केवल पहले 72B का उपयोग किया जाएगा:
From this twitter thread आप देख सकते हैं कि 1000 से अधिक GET params या 1000 POST params या 20 फ़ाइलें भेजने पर, PHP प्रतिक्रिया में headers सेट नहीं करेगा।
उदाहरण के लिए CSP headers को बायपास करने की अनुमति देना जो कोड में सेट किए गए हैं:
यदि एक PHP पृष्ठ त्रुटियों को प्रिंट कर रहा है और उपयोगकर्ता द्वारा प्रदान की गई कुछ इनपुट को वापस इको कर रहा है, तो उपयोगकर्ता PHP सर्वर को कुछ इतना लंबा सामग्री प्रिंट करने के लिए मजबूर कर सकता है कि जब यह उत्तर में हेडर जोड़ने की कोशिश करता है, तो सर्वर एक त्रुटि फेंक देगा। निम्नलिखित परिदृश्य में हमलावर ने सर्वर को कुछ बड़े त्रुटियाँ फेंकने के लिए मजबूर किया, और जैसा कि आप स्क्रीन में देख सकते हैं, जब PHP ने हेडर जानकारी को संशोधित करने की कोशिश की, तो यह नहीं कर सका (तो उदाहरण के लिए CSP हेडर उपयोगकर्ता को नहीं भेजा गया):
पृष्ठ की जांच करें:
PHP SSRFsystem("ls"); &#xNAN;`ls`; shell_exec("ls");
अधिक उपयोगी PHP फ़ंक्शंस के लिए इसे देखें
कोड को निष्पादित करने के लिए "replace" तर्क में कम से कम एक मेल की आवश्यकता है। preg_replace का यह विकल्प PHP 5.5.0 के रूप में हटा दिया गया है।
यह फ़ंक्शन php के भीतर आपको एक स्ट्रिंग में लिखे गए कोड को निष्पादित करने की अनुमति देता है ताकि सत्य या असत्य लौटाया जा सके (और इसके आधार पर निष्पादन को बदल सके)। आमतौर पर उपयोगकर्ता चर को एक स्ट्रिंग के बीच में डाला जाएगा। उदाहरण के लिए:
assert("strpos($_GET['page']),'..') === false")
--> इस मामले में RCE प्राप्त करने के लिए आप कर सकते हैं:
आपको कोड सिंटैक्स को तोड़ना, अपना पेलोड जोड़ना, और फिर इसे फिर से ठीक करना होगा। आप लॉजिक ऑपरेशंस जैसे "and" या "%26%26" या "|" का उपयोग कर सकते हैं। ध्यान दें कि "or", "||" काम नहीं करते क्योंकि यदि पहली शर्त सही है तो हमारा पेलोड निष्पादित नहीं होगा। इसी तरह ";" काम नहीं करता क्योंकि हमारा पेलोड निष्पादित नहीं होगा।
अन्य विकल्प है कि स्ट्रिंग में कमांड का निष्पादन जोड़ें: '.highlight_file('.passwd').'
अन्य विकल्प (यदि आपके पास आंतरिक कोड है) कुछ वेरिएबल को संशोधित करना है ताकि निष्पादन को बदल सकें: $file = "hola"
यह फ़ंक्शन एक विशिष्ट फ़ंक्शन का उपयोग करके आइटम के एक एरे को क्रमबद्ध करने के लिए उपयोग किया जाता है। इस फ़ंक्शन का दुरुपयोग करने के लिए:
You can also use // to comment the rest of the code.
To discover the number of parenthesis that you need to close:
?order=id;}//
: हमें एक त्रुटि संदेश मिलता है (Parse error: syntax error, unexpected ';'
). शायद हमें एक या अधिक ब्रैकेट्स की कमी है।
?order=id);}//
: हमें एक चेतावनी मिलती है। यह सही लगता है।
?order=id));}//
: हमें एक त्रुटि संदेश मिलता है (Parse error: syntax error, unexpected ')' i
). शायद हमारे पास बहुत अधिक क्लोजिंग ब्रैकेट्स हैं।
If you can upload a .htaccess, then you can configure several things and even execute code (configuring that files with extension .htaccess can be executed).
Different .htaccess shells can be found here
If you find a vulnerability that allows you to modify env variables in PHP (and another one to upload files, although with more research maybe this can be bypassed), you could abuse this behaviour to get RCE.
LD_PRELOAD
: This env variable allows you load arbitrary libraries when executing other binaries (although in this case it might not work).
PHPRC
: PHP को इसके कॉन्फ़िगरेशन फ़ाइल का स्थान बताता है, जिसे आमतौर पर php.ini
कहा जाता है। यदि आप अपनी खुद की कॉन्फ़िगरेशन फ़ाइल अपलोड कर सकते हैं, तो PHPRC
का उपयोग करके PHP को उस पर इंगित करें। एक auto_prepend_file
प्रविष्टि जोड़ें जो एक दूसरे अपलोड किए गए फ़ाइल को निर्दिष्ट करती है। यह दूसरा फ़ाइल सामान्य PHP कोड है, जिसे फिर PHP रनटाइम द्वारा किसी अन्य कोड से पहले निष्पादित किया जाता है।
हमारे शेलकोड वाला एक PHP फ़ाइल अपलोड करें
एक दूसरा फ़ाइल अपलोड करें, जिसमें एक auto_prepend_file
निर्देश हो जो PHP प्रीप्रोसेसर को चरण 1 में अपलोड की गई फ़ाइल को निष्पादित करने के लिए कहता है
PHPRC
वेरिएबल को चरण 2 में अपलोड की गई फ़ाइल पर सेट करें।
इस श्रृंखला को निष्पादित करने के तरीके के बारे में अधिक जानकारी प्राप्त करें मूल रिपोर्ट से.
PHPRC - एक और विकल्प
यदि आप फाइलें अपलोड नहीं कर सकते, तो आप FreeBSD में "फाइल" /dev/fd/0
का उपयोग कर सकते हैं जिसमें stdin
होता है, जो stdin
पर भेजे गए अनुरोध का शरीर है:
curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary 'auto_prepend_file="/etc/passwd"'
या RCE प्राप्त करने के लिए, allow_url_include
सक्षम करें और base64 PHP कोड के साथ एक फ़ाइल को प्रीपेंड करें:
curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary $'allow_url_include=1\nauto_prepend_file="data://text/plain;base64,PD8KICAgcGhwaW5mbygpOwo/Pg=="'
तकनीक इस रिपोर्ट से.
The webserver parses HTTP requests and passes them to a PHP script executing a request such as as http://host/cgi.php?foo=bar
as php.exe cgi.php foo=bar
, which allows a parameter injection. This would allow to inject the following parameters to load the PHP code from the body:
इसके अलावा, PHP के बाद के सामान्यीकरण के कारण "-" पैरामीटर को 0xAD वर्ण का उपयोग करके इंजेक्ट करना संभव है। इस पोस्ट से शोषण उदाहरण देखें:
इस पोस्ट में बहुत कम अनुमत वर्णों के साथ एक ब्रेन फक PHP कोड उत्पन्न करने के लिए शानदार विचार मिल सकते हैं। इसके अलावा, यह कई जांचों को बायपास करने की अनुमति देने वाले कार्यों को निष्पादित करने का एक दिलचस्प तरीका भी प्रस्तावित किया गया है:
देखें कि क्या आप इन फ़ंक्शनों (से यहाँ) में कॉल में कोड डाल सकते हैं:
यदि आप एक PHP एप्लिकेशन को डिबग कर रहे हैं, तो आप display_errors = On
जोड़कर /etc/php5/apache2/php.ini
में वैश्विक रूप से त्रुटि प्रिंटिंग सक्षम कर सकते हैं और अपाचे को पुनः प्रारंभ कर सकते हैं: sudo systemctl restart apache2
आप www.unphp.net का उपयोग PHP कोड को डिओबफस्केट करने के लिए कर सकते हैं।
PHP रैपर और प्रोटोकॉल आपको एक सिस्टम में लिखने और पढ़ने की सुरक्षा को बायपास करने और इसे समझौता करने की अनुमति दे सकते हैं। अधिक जानकारी के लिए इस पृष्ठ की जांच करें।
यदि आप देखते हैं कि phpconfig()
आउटपुट में Xdebug सक्षम है, तो आपको https://github.com/nqxcode/xdebug-exploit के माध्यम से RCE प्राप्त करने का प्रयास करना चाहिए।
यदि किसी पृष्ठ में आप किसी भी मनचाही कक्षा का एक नया ऑब्जेक्ट बना सकते हैं तो आप RCE प्राप्त करने में सक्षम हो सकते हैं, जानने के लिए निम्नलिखित पृष्ठ देखें:
PHP - RCE abusing object creation: new $_GET["a"]($_GET["b"])https://securityonline.info/bypass-waf-php-webshell-without-numbers-letters/
According to this writeup यह संभव है कि इस तरीके से एक आसान शेलकोड उत्पन्न किया जा सके:
तो, अगर आप संख्याओं और अक्षरों के बिना मनमाना PHP निष्पादित कर सकते हैं तो आप उस पेलोड का दुरुपयोग करके मनमाना PHP निष्पादित करने के लिए निम्नलिखित अनुरोध भेज सकते हैं:
For a more in depth explanation check https://ctf-wiki.org/web/php/php/#preg_match
अपने वेब ऐप्स, नेटवर्क और क्लाउड पर एक हैकर का दृष्टिकोण प्राप्त करें
महत्वपूर्ण, शोषण योग्य कमजोरियों को खोजें और रिपोर्ट करें जिनका वास्तविक व्यावसायिक प्रभाव है। हमारे 20+ कस्टम टूल का उपयोग करें ताकि हमले की सतह का मानचित्रण कर सकें, उन सुरक्षा मुद्दों को खोजें जो आपको विशेषाधिकार बढ़ाने की अनुमति देते हैं, और आवश्यक सबूत इकट्ठा करने के लिए स्वचालित शोषण का उपयोग करें, जिससे आपका कठिन काम प्रभावशाली रिपोर्टों में बदल जाए।
AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE) GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)