
https://hackerone.com/reports/863553
تعاني منطق التحقق من صحة عنوان URL المطبق عند معالجة /appsuite/api/oxodocumentfilter&action=addfile من ثلاثة عيوب يمكن استخدامها لتنفيذ هجوم SSRF من نوع Time of Check Time of Use (ToCToU). تسمح هذه المشكلة للمهاجمين بتنفيذ طلبات HTTP GET على خدمات الشبكة الداخلية وقد تؤدي إلى تسرب معلومات محمية.
منطق التحقق من صحة URL في طريقة URITools.getFinalURL المنفذة هنا يعاني من ثغرة ToCToU
URL u = new URL(url);
if (validator.isPresent()) {
Optional<OXException> exception = validator.get().apply(u);
if (exception.isPresent()) {
throw exception.get();
}
}
URLConnection urlConnnection = u.openConnection();
في الكود أعلاه، يتم تحليل DNS لاسم المضيف لعنوان URL المدخل خلال كل من وقت التحقق (validator.get().apply(u)) ووقت الاستخدام (u.openConnection()) عن طريق استدعاء طريقة InetAddress.getByName. لذلك إذا تمكن المهاجم من تغيير نتيجة تحليل DNS بعد وقت التحقق وقبل وقت الاستخدام، يمكنه تجاوز المدقق. هذا العيب وحده من الصعب جدًا استغلاله بسبب القيود التالية
InetAddress.getByName بتخزين نتائج تحليل DNS مؤقتًا لمدة 30 ثانية إذا نجح التحليل ولمدة 10 ثوانٍ إذا فشل.validator.get().apply(u) و u.openConnection() صغير جدًا (أقل من مللي ثانية واحدة لعناوين URL العادية). يستخدم العيب رقم 2 لتجاوز هذا القيدمدقق URL AddFileAction.validator المنفذ هنا لا يتحقق من طول عنوان URL المدخل. من خلال توفير عنوان URL بحجم كبير، يمكن للمهاجم زيادة الفاصل الزمني بين استدعاءات طريقة InetAddress.getByName في وقت التحقق ووقت الاستخدام. يسمح الفاصل الزمني الأكبر للمهاجم باستغلال العيب رقم 1 بسهولة
طريقة HostList.contains المنفذة هنا ترجع false إذا فشل تحليل DNS لاسم المضيف لعنوان URL المدخل
// Need to resolve as last resort
try {
return contains(InetAddress.getByName(toCheck), false);
} catch (UnknownHostException e) {
// Cannot be resolved
return false;
}
يقوم AddFileAction.validator باستدعاء طريقة blackImageUrlHostlist.contains للتحقق مما إذا كان اسم المضيف لعنوان URL المدخل أو عنوان IP الذي يتم حله موجودًا في القائمة السوداء. إذا تسبب المهاجم في فشل تحليل DNS لاسم المضيف، يتم تخطي فحوصات عنوان IP ويتم قبول URL.
خذ بعين الاعتبار اسم مضيف randomid.dns.pointer.pw مع خادم أسماء موثوق يسيطر عليه المهاجم. استراتيجية الهجوم هي جعل تحليل DNS لـ randomid.dns.pointer.pw يفشل في وقت التحقق (validator.get().apply(u);) وينجح في وقت الاستخدام (u.openConnection()). يسمح هذا للمهاجم بتجاوز مرشحات القائمة السوداء لعناوين IP وتنفيذ طلب HTTP GET على أي عنوان IP موجود في القائمة السوداء. قد يتبع المهاجم الخطوات التالية لتنفيذ هذا الهجوم
InetAddress.getByName على الخادم عن طريق تنفيذ إجراء addfile مع بيانات الطلب {"add_imageurl": "http://randomid.dns.pointer.pw"}. في هذا الوقت، سيتم ضبط خادم الأسماء الموثوق لفشل تحليل DNS لـ randomid.dns.pointer.pw عن طريق إرجاع حالة SERVFAIL. سيقوم InetAddress.getByName بتخزين هذه النتيجة الفاشلة مؤقتًا لمدة 10 ثوانٍ.pointer.pw بإرجاع 127.0.0.1 لطلبات DNS من النوع A لاسم المضيف randomid.dns.pointer.pw.InetAddress.getByName في الخطوة التالية بإرجاع الاستجابة المخزنة (SERVFAIL) في وقت التحقق وإرجاع 127.0.0.1 في وقت الاستخدام (url.openConnection()).add_imageurl مضبوطة على التنسيق http://u{25MB}:[email protected]/path/to/internal/resource.png. هنا u{25MB} يعني أن جزء اسم المستخدم هو سلسلة بطول 25 × 1024 × 1024 حرفًا.قم بتثبيت golang من https://golang.org/dl/
قم بتثبيت Open-Xchange و Documents في جهاز افتراضي بذاكرة وصول عشوائي لا تقل عن 4 جيجابايت باتباع الأدلة https://oxpedia.org/wiki/index.php?title=AppSuite:Open-Xchange_Installation_Guide_for_Debian_9.0 و https://oxpedia.org/wiki/index.php?title=AppSuite:Documents_Installation_Guide#Debian_GNU.2FLinux_9.0_.28valid_from_v7.10.29
قم بتنزيل واستخراج ملف poc.zip
افتح الطرفية / سطر الأوامر واجعل الدليل الحالي هو مجلد poc.zip المستخرج
قم بتشغيل الأمر
go run . -serverRoot="http://172.16.66.130" -username="testuser" -password="secret" -targetPath="appsuite/v=7.10.3-9.20200409.083030/apps/themes/logo.png" -targetPort="80" -payloadSize=25 -startSleepDuration=6600
حيث 172.16.66.130 هو عنوان IP للجهاز الظاهري