برنامه نویسی

WRITE-UP ASCIS 2023 – انجمن DEV

Summarize this content to 400 words in Persian Lang
من می خواهم مسیر خود را در مقاله وب 2 به اشتراک بگذارمهنگام دسترسی به چالش، وب سایت موارد زیر را نمایش می دهدتسوبا خواندن کد منبع، خواهید دید که چالش شامل 2 سرویس است: برگشت و جلو. انجام دهید برگشت حاوی پرچم است، بنابراین ابتدا آن را تجزیه و تحلیل خواهم کرد.خدمات برگشت نوشته شده در جاوا پس از دیکامپایل، می‌توانیم کد منبع را بخوانیم و بدانیم که برنامه از نسخه 11 جاوا، فریمورک بوت فنری برای ایجاد یک وب سرور استفاده می‌کند.تحلیل سریع: پس از خواندن کد منبع، متوجه شدم که برنامه از یک تابع برای جداسازی داده های ارسال شده از طریق تابع استفاده می کند. readObject.علاوه بر این، از آنجا که برنامه از کتابخانه قدیمی commons-collections4 نسخه 4.0 استفاده می کند => RCE را می توان با راه اندازی زنجیره های ابزار انجام داد. این زنجیره‌های گجت توسط افراد زیادی به صورت آنلاین تجزیه و تحلیل شده‌اند، فقط باید آنها را برای استفاده بیاورم (می‌توانید به ابزار ysoserial مراجعه کنید)!انجام بهره برداری: به دنبال این جهت، ما بر روی کنترلر “/ticket/{info}” تمرکز خواهیم کرد. ابتدا، برنامه داده های ارسال شده را می گیرد، base64 رمزگشایی می کند و طول را بررسی می کند، سپس gzip را از حالت فشرده خارج کرده و از حالت سریال خارج می کند. بنابراین پس از ایجاد بار آرایه بایتی، باید gzip و سپس base64 کدگذاری کنیم تا به سرور ارسال شود – پس از gzip، پس از gzip، پس از gzip، payload قبل از کدگذاری base64 با 2048 کاراکتر محدود می شود. با این حال، زمانی که آن را آزمایش کردم، پس از gzip، حجم بار بسیار کوچکتر بود، و از 2048 کاراکتر تجاوز نمی کرد، بنابراین نیازی به نگرانی در مورد دور زدن چیزی نبود (در این قسمت احساس آشنایی داشتم، به نظر می رسید که این موضوع شبیه آهنگ خطر است) سال 2022 درسته؟!).یه چیز دیگه اینکه من میخوام پیلود رو فقط یکبار اجرا کنم تا شناسایی نشه و در عین حال بدون هیچ اقدام دیگه ای پرچم به سرور ارسال بشه، چیکار کنم؟ ما می‌توانیم یک درب پشتی نصب کنیم، اما می‌توانیم آن را ساده‌تر با تنظیم یک تایمر برای وب‌سرور جاوا انجام دهیم تا پرچم را بخواند و به طور مساوی در فواصل زمانی معین ارسال کند. با استفاده از زنجیره گجت commons-collections4، می‌توانیم به راحتی کلاس جاوای خود تعریف شده را بارگیری کنیم و کد جاوا دلخواه را اجرا کنیم. این به لطف استفاده از کلاس است InvokerTransformer کتابخانه Commons-Collections4.بنابراین محموله را می توان به صورت زیر کدگذاری کردبا این حال، RCE تمام نشده است – سرویس برگشتی در یک فایل docker بدون پورت عمومی و بدون اتصال به اینترنت پیکربندی شده است! بنابراین چگونه می‌توانیم به محموله‌ها دسترسی داشته باشیم و آن‌ها را ارسال کنیم؟ ما باید به بهره برداری از این سرویس ادامه دهیم جلو.پس از خواندن کد منبع، متوجه شدم که serice تابع curl فرمان پوسته را با پارامتری که URL ارسال شده است فراخوانی می کند => 90% SSRF برای ایجاد خطاهای سرور است. برگشت. با این حال، کد منبع نیز برای جلوگیری از سوء استفاده از آن خطا فیلتر می شود!

FILTERED_HOSTS = [“back”] FILTERED_PATHS = [“debug”, “info”, “ticket”] def is_approved(url):
“””Indicates whether the given URL is allowed to be fetched. This
prevents the server from becoming an open proxy”””
parts = urlparse(url)
host = parts.hostname
path = parts.path

if not parts.scheme in [“http”, “https”]:
return False

if host in FILTERED_HOSTS:
return False
for filter_path in FILTERED_PATHS:
if filter_path in path:
return False
return True

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

برای دور زدن این تابع بررسی، باید تفاوت بین تجزیه url تابع urlparse در پایتون و کتابخانه curl در لینوکس را پیدا کنیم.+، Bypass host: تابع urlparse با استاندارد قالب زیر مطابقت داردبا این حال، کتابخانه curl اجازه می دهد 1، 2 یا 3 اسلش بعد از کولون.(منبع https://curl.se/docs/url-syntax.html)بنابراین، اگر url دارای فرم های http:/back و http:///back باشد، تابع urlparse پس از تجزیه url، میزبان را به عنوان None در نظر می گیرد، در حالی که کتابخانه curl همچنان میزبان را به عنوان تجزیه می کند. برگشت!

#! /home/app/venv/bin/python3 test.py
parts = urlparse(“http:/back”)
host = parts.hostname
print(host)

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

$ python3 test.py
None
$ curl http:/back
<!DOCTYPE HTML>

<head>
Hello ASCIS
=”Content-Type” content=”text/html; charset=UTF-8″ />

$

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

+، مسیر Bypass: از آنجایی که curl دوباره آدرس ورودی را رمزگشایی می‌کند، فقط باید حداقل یک کاراکتر از مسیر را دو برابر کنیم و کار شما تمام شد!مشکل دیگر سرویس است برگشت اینترنت وجود ندارد، بنابراین می توانیم از خطای SSRF بالا برای دریافت از سرور استفاده کنیم برگشت فراخوانی api به سرور جلو، ارسال URL آدرس سرور ما با یک پرچم است.انجام ماینینگپرچم را بگیرید و به آن شلیک کنیدپس از اتمام مسابقه، در مورد خدمات بیشتر یاد گرفتم برگشت RCE همچنین می تواند توسط باگ SSTI در کتابخانه Thymeleaf مورد سوء استفاده قرار گیرد. به طور مشخص در بند زیر:این خطا به این دلیل است که Thymeleaf اگر بر اساس استاندارد تجزیه مشخص شده توسط کتابخانه نوشته شده باشد، eval رشته نام الگو را انجام می دهد (شما می توانید در اینجا بیشتر بخوانید).ساخت بار

byte[] data = “{\”role\”:\”__${new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(‘touch /tmp/zz’).getInputStream()).next()}__::z\”}”.getBytes();
byte[] outBase64 = Base64.getMimeEncoder().encode(data);
String payload = (new String(outBase64)).replaceAll( “\\r\\n”, “”).replaceAll( “https://dev.to/”, “_”);

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

انجام ماینینگ

$ ls -lap /tmp
total 24
drwxrwxrwt 1 root root 4096 Nov 14 17:15 ./
drwxr-xr-x 1 root root 4096 Nov 14 17:14 ../
drwxr-xr-x 2 app app 4096 Nov 14 17:14 hsperfdata_app/
-rw-r–r– 1 app app 0 Nov 14 17:15 zz
$

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خواندن پرچم و ارسال آن به سرور مشابه موارد فوق است

از اول تا آخر مسابقات فقط بلد بودم حمله کنم و مدام مورد حمله قرار بگیرم… در نهایت نتایج خیلی خوب نبود. من نمی دانم سفر CTF چقدر طولانی بوده است، اما تا به امروز هنوز برای تیم یک موفقیت است ☹.

توضیحات تصویر
من می خواهم مسیر خود را در مقاله وب 2 به اشتراک بگذارم
هنگام دسترسی به چالش، وب سایت موارد زیر را نمایش می دهد
وب 1
تسو
با خواندن کد منبع، خواهید دید که چالش شامل 2 سرویس است: برگشت و جلو. انجام دهید برگشت حاوی پرچم است، بنابراین ابتدا آن را تجزیه و تحلیل خواهم کرد.
خدمات برگشت نوشته شده در جاوا پس از دیکامپایل، می‌توانیم کد منبع را بخوانیم و بدانیم که برنامه از نسخه 11 جاوا، فریمورک بوت فنری برای ایجاد یک وب سرور استفاده می‌کند.
تحلیل سریع: پس از خواندن کد منبع، متوجه شدم که برنامه از یک تابع برای جداسازی داده های ارسال شده از طریق تابع استفاده می کند.
readObject.
توضیحات تصویر
علاوه بر این، از آنجا که برنامه از کتابخانه قدیمی commons-collections4 نسخه 4.0 استفاده می کند => RCE را می توان با راه اندازی زنجیره های ابزار انجام داد. این زنجیره‌های گجت توسط افراد زیادی به صورت آنلاین تجزیه و تحلیل شده‌اند، فقط باید آنها را برای استفاده بیاورم (می‌توانید به ابزار ysoserial مراجعه کنید)!
انجام بهره برداری: به دنبال این جهت، ما بر روی کنترلر “/ticket/{info}” تمرکز خواهیم کرد. ابتدا، برنامه داده های ارسال شده را می گیرد، base64 رمزگشایی می کند و طول را بررسی می کند، سپس gzip را از حالت فشرده خارج کرده و از حالت سریال خارج می کند. بنابراین پس از ایجاد بار آرایه بایتی، باید gzip و سپس base64 کدگذاری کنیم تا به سرور ارسال شود – پس از gzip، پس از gzip، پس از gzip، payload قبل از کدگذاری base64 با 2048 کاراکتر محدود می شود. با این حال، زمانی که آن را آزمایش کردم، پس از gzip، حجم بار بسیار کوچکتر بود، و از 2048 کاراکتر تجاوز نمی کرد، بنابراین نیازی به نگرانی در مورد دور زدن چیزی نبود (در این قسمت احساس آشنایی داشتم، به نظر می رسید که این موضوع شبیه آهنگ خطر است) سال 2022 درسته؟!).
یه چیز دیگه اینکه من میخوام پیلود رو فقط یکبار اجرا کنم تا شناسایی نشه و در عین حال بدون هیچ اقدام دیگه ای پرچم به سرور ارسال بشه، چیکار کنم؟ ما می‌توانیم یک درب پشتی نصب کنیم، اما می‌توانیم آن را ساده‌تر با تنظیم یک تایمر برای وب‌سرور جاوا انجام دهیم تا پرچم را بخواند و به طور مساوی در فواصل زمانی معین ارسال کند. با استفاده از زنجیره گجت commons-collections4، می‌توانیم به راحتی کلاس جاوای خود تعریف شده را بارگیری کنیم و کد جاوا دلخواه را اجرا کنیم. این به لطف استفاده از کلاس است InvokerTransformer کتابخانه Commons-Collections4.
بنابراین محموله را می توان به صورت زیر کدگذاری کرد
توضیحات تصویر
توضیحات تصویر
با این حال، RCE تمام نشده است – سرویس برگشتی در یک فایل docker بدون پورت عمومی و بدون اتصال به اینترنت پیکربندی شده است! بنابراین چگونه می‌توانیم به محموله‌ها دسترسی داشته باشیم و آن‌ها را ارسال کنیم؟ ما باید به بهره برداری از این سرویس ادامه دهیم جلو.
پس از خواندن کد منبع، متوجه شدم که serice تابع curl فرمان پوسته را با پارامتری که URL ارسال شده است فراخوانی می کند => 90% SSRF برای ایجاد خطاهای سرور است. برگشت. با این حال، کد منبع نیز برای جلوگیری از سوء استفاده از آن خطا فیلتر می شود!

FILTERED_HOSTS = ["back"]
FILTERED_PATHS = ["debug", "info", "ticket"]
def is_approved(url):
    """Indicates whether the given URL is allowed to be fetched.  This
    prevents the server from becoming an open proxy"""
    parts = urlparse(url)
    host = parts.hostname
    path = parts.path

    if not parts.scheme in ["http", "https"]:
        return False

    if host in FILTERED_HOSTS:
        return False
    for filter_path in FILTERED_PATHS:
        if filter_path in path:
            return False
    return True
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

برای دور زدن این تابع بررسی، باید تفاوت بین تجزیه url تابع urlparse در پایتون و کتابخانه curl در لینوکس را پیدا کنیم.
+، Bypass host: تابع urlparse با استاندارد قالب زیر مطابقت دارد
توضیحات تصویر
با این حال، کتابخانه curl اجازه می دهد 1، 2 یا 3 اسلش بعد از کولون.
توضیحات تصویر
(منبع https://curl.se/docs/url-syntax.html)
بنابراین، اگر url دارای فرم های http:/back و http:///back باشد، تابع urlparse پس از تجزیه url، میزبان را به عنوان None در نظر می گیرد، در حالی که کتابخانه curl همچنان میزبان را به عنوان تجزیه می کند. برگشت!

#! /home/app/venv/bin/python3 test.py
parts = urlparse("http:/back")
host = parts.hostname
print(host)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

$ python3 test.py
None
$ curl http:/back
<!DOCTYPE HTML>

<head>
    Hello ASCIS
    ="Content-Type" content="text/html; charset=UTF-8" />



    

$
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

+، مسیر Bypass: از آنجایی که curl دوباره آدرس ورودی را رمزگشایی می‌کند، فقط باید حداقل یک کاراکتر از مسیر را دو برابر کنیم و کار شما تمام شد!
مشکل دیگر سرویس است برگشت اینترنت وجود ندارد، بنابراین می توانیم از خطای SSRF بالا برای دریافت از سرور استفاده کنیم برگشت فراخوانی api به سرور جلو، ارسال URL آدرس سرور ما با یک پرچم است.
انجام ماینینگ
توضیحات تصویر
پرچم را بگیرید و به آن شلیک کنید
توضیحات تصویر
توضیحات تصویر
پس از اتمام مسابقه، در مورد خدمات بیشتر یاد گرفتم برگشت RCE همچنین می تواند توسط باگ SSTI در کتابخانه Thymeleaf مورد سوء استفاده قرار گیرد. به طور مشخص در بند زیر:
توضیحات تصویر
این خطا به این دلیل است که Thymeleaf اگر بر اساس استاندارد تجزیه مشخص شده توسط کتابخانه نوشته شده باشد، eval رشته نام الگو را انجام می دهد (شما می توانید در اینجا بیشتر بخوانید).
ساخت بار

byte[] data = "{\"role\":\"__${new java.util.Scanner(T(java.lang.Runtime).getRuntime().exec('touch /tmp/zz').getInputStream()).next()}__::z\"}".getBytes();
byte[] outBase64 = Base64.getMimeEncoder().encode(data);
String payload = (new String(outBase64)).replaceAll( "\\r\\n", "").replaceAll( "https://dev.to/", "_");
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

انجام ماینینگ
توضیحات تصویر

$ ls -lap /tmp
total 24
drwxrwxrwt 1 root root 4096 Nov 14 17:15 ./
drwxr-xr-x 1 root root 4096 Nov 14 17:14 ../
drwxr-xr-x 2 app  app  4096 Nov 14 17:14 hsperfdata_app/
-rw-r--r-- 1 app  app     0 Nov 14 17:15 zz
$
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

خواندن پرچم و ارسال آن به سرور مشابه موارد فوق است

از اول تا آخر مسابقات فقط بلد بودم حمله کنم و مدام مورد حمله قرار بگیرم… در نهایت نتایج خیلی خوب نبود. من نمی دانم سفر CTF چقدر طولانی بوده است، اما تا به امروز هنوز برای تیم یک موفقیت است ☹.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا