محققای Assetnote یه آسیب پذیری از نوع XSS و شناسه CVE-2023-29489 در cPanel کشف و گزارش کردن که در این پست به بررسی گزارششون پرداختیم.
cPenel یه برنامه کنترل پنل، وب هاستینگ هستش که بطور گسترده در اینترنت مورد استفاده قرار میگیره و در زمان نگارش این گزارش حدود 1.4 میلیون نصب از این برنامه که قابل مشاهده از طریق اینترنت هست، وجود داره.
آسیب پذیری کشف شده بدون نیاز به احراز هویت و قابل مشاهده بودن پورتهای مدیریت سی پنل (یعنی پورتهای 2080, 2082, 2083, 2086 )، قابل اکسپلویت هستش . این یعنی اینکه اگه سایت شما روی پورت 80 و 443 با سی پنل مدیریت میشه، قابل اکسپلویت هستش.
اگه قابلیت بروزرسانی خودکار سی پنل رو فعال کرده باشید، در این خصوص نگرانی وجود نداره. اگه نه که باید حداقل به نسخه های زیر ارتقاء بدید :
11.109.9999.116
11.108.0.13
11.106.0.18
11.102.0.31
آشنایی با ماهیت کدهای سی پنل:
سی پنل یه برنامه ای هستش که 27 سال سن داره ،بنابراین ممکنه از مواردی استفاده کنه که فناوری جدیدی ندارن. قسمت زیادی از سی پنل با پرل نوشته شده و برای همین محققا در ابتدا روی اکسپلویت این فایلهای باینری که در دایرکتوری /cgi-sys/ قرار داشتن و از طریق درخواستهای HTTP قابل دسترس بودن، تمرکز کردن. با اینکه چندین روش اکسپلویت پیدا کردن اما با توجه به اینکه این فایلها از یسری اقدامات کاهشی استفاده میکردن، نتونستن بطور کامل اکسپلویتشون بکنن.
غیر از این باینری ها، محققا متوجه باینری cpsrvd شدن که عملکردهای اصلی سی پنل و برنامه وب رو ارائه میده. این باینری روی پورتهای زیر listening میکنه :
1 2 3 4 5 |
root@vm:~# lsof -Pi | grep cpsrvd cpsrvd 43328 root 3u IPv4 218993 0t0 TCP *:2082 (LISTEN) cpsrvd 43328 root 4u IPv4 218994 0t0 TCP *:2086 (LISTEN) cpsrvd 43328 root 5u IPv4 218995 0t0 TCP *:2083 (LISTEN) cpsrvd 43328 root 6u IPv4 218996 0t0 TCP *:2087 (LISTEN) |
سی پنل از reverse proxy های آپاچی استفاده میکنه و پیکربندی اون رو در این مسیر میتونید پیدا کنید :
1 |
/etc/apache2/conf/httpd.conf |
این فایل به دلیل اینکه نامهای اسکریپت و پروکسی های مختلف توش بوده، اطلاعات خوبی در خصوص اینکه چه مواردی رو در کد های سی پنل باید جستجو کنن، در اختیار محققین قرار داده :
1 2 3 4 5 6 7 8 9 10 11 12 13 |
ProxyPass /cpanelwebcall/ http://127.0.0.1:2082/cpanelwebcall/ max=1 retry=0 ... omitted for brevity ... ScriptAlias /.cpanel/dcv /usr/local/cpanel/cgi-priv/get_local.cgi RewriteEngine On RewriteCond %{REQUEST_URI} ^/\.well-known/acme-challenge/[0-9a-zA-Z_-]+$ [OR] RewriteCond %{REQUEST_URI} ^/\.well-known/cpanel-dcv/[0-9a-zA-Z_-]+$ [OR] RewriteCond %{REQUEST_URI} ^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Sectigo\ DCV)?$ [OR] RewriteCond %{REQUEST_URI} ^/\.well-known/pki-validation/(?:\ Ballot169)? RewriteRule ^ /.cpanel/dcv [passthrough] |
این فقط قسمتی از httpd.conf هستش. اگه میخوایید سی پنل رو ارزیابی کنید، کل موارد داخل این فایل رو بعنوان نقطه شروع در نظر بگیرید. محققا توصیه کردن که سی پنل میتونه گزینه خوبی برای ارزیابی باشه، بخصوص از دید مهندسی معکوس .
بخشی عظیمی از کدهای سی پنل بعد از نصب از مسیر /usr/local/cpanel/ قابل دسترسی هستش. البته باینری های زیادی اینجا وجود داره، اما با خوندن کتابخونه ها و کدهای پرل در این دایرکتوری، میتونید به منطق سی پنل پی ببرید.
در حالیکه تو این دایرکتوری کدهای پرل زیادی در خصوص نحوه مسیریابی قرار داره، اما فایل cpsrvd یه نسخه کامپایل شده از همه کدهای پرله.
اگرچه سورس کد موجود در /usr/local/cpanel تصویر کاملی از سی پنل رو در اختیار ما قرار نداد، اما باعث شد از طریق همین سورس کد، یه آسیب پذیری XSS پیدا کنیم.
درک ساختار Httpd.pm :
محققا در تلاش برای درک مسیریابی سی پنل با Cpanel/Server/Handlers/Httpd.pm مواجه شدن که حاوی یسری مسیرهای خاص بوده. این باعث شده تا محققین به یسری مسیر ،که امکان حمله بدون احراز هویت و درک باینری رو میده، برسن. کامنتهایی که در این فایل قرار گرفته بوده، هم تونسته به درک این قضیه بیشتر کمک کنه :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
=head1 DESCRIPTION This module implements a tiny HTTP server in cpsrvd that executes a whitelist of functionality. This is useful for contexts where no other service is running on the standard HTTP and HTTPS ports. It implements the following behaviors: =over =item * Any request whose path is under F</.well-known> is served as a static file. The path on disk that’s loaded is the same as under Apache. =item * Any other request whose C<Host> header starts with one of the following is served as appropriate: C<cpcalendars.>, C<cpcontacts.>, C<autodiscover.>, C<autoconfig.>. The latter two are only served if they are enabled in the server configuration. Note that C<cpanel.>, C<whm.>, and C<webmail.> are NOT handled here. This is largely because the relevant applications are under base cpsrvd and thus not (readily) callable from this module, so we have to handle those applications separately. |
نکات زیر از این فایل قابل استخراج بوده:
- مدیریت مسیریابی مبتنی بر subdomain/hostname به برخی سرویسها:
- cpcalendars => ‘proxy_cpcalendars_cpcontacts‘
- cpcontacts => ‘proxy_cpcalendars_cpcontacts’
- autodiscover => ‘autodiscover‘
- autoconfig => ‘autoconfig‘
- مدیریت مسیرهای استاتیک:
- /img-sys/
- /sys_cpanel/
- مدیریت ریدایرکت ها برای /cpanel, /whm, /webmail
- مدیریت درخواستهای BoxTrapper در /cgi-sys/bxd.cgi
- مدیریت عملکردهای مبتنی بر Dynamic DNS بخصوص فراخوانی /cpanelwebcall/
محققا علاوه بر Httpd.pm یه تایمی هم روی بررسی Cpanel/Server/Handlers/comet.pm گذاشتن. این فایل هم پیامهای websocket رو مدیریت میکنه. محققا براساس عملکردهایی که تو این فایل بوده، اعلام کردن که میتونه arbitrary file write داشته باشه اما نتونستن اونو اکسپلویت کنن.
پیدا کردن XSS:
داخل فایل Httpd.pm قطعه کد زیر رو مشاهده کردن :
1 2 3 4 5 6 7 8 |
elsif ( 0 == rindex( $doc_path, '/cpanelwebcall/', 0 ) ) { # First 15 chars are “/cpanelwebcall/” _serve_cpanelwebcall( $self->get_server_obj(), substr( $doc_path, 15 ), ); } |
کد بالا نشون میده که هر مسیری که با /cpanelwebcall/ شروع میشه همراه با کاراکترهای بعد از نام دایرکتوری به _serve_cpanelwebcall \ پاس داده میشن. در زیر هم کدهای تابع _serve_cpanelwebcall رو مشاهده میکنید :
1 2 3 4 5 6 7 8 |
sub _serve_cpanelwebcall ( $server_obj, $webcall_uri_piece ) { require Cpanel::Server::WebCalls; my $out = Cpanel::Server::WebCalls::handle($webcall_uri_piece); $server_obj->respond_200_ok_text($out); return; } |
این بعنوان Sink ، مارو به تابع Cpanel::Server::WebCalls::handle انتقال میده.
1 2 3 4 5 6 7 8 |
sub handle ($request) { my $id = extract_id_from_request($request); substr( $request, 0, length $id ) = q<>; Cpanel::WebCalls::ID::is_valid($id) or do { die _http_invalid_params_err("Invalid webcall ID: $id"); }; |
در این تابع هم، ما به _http_invalid_params_err میرسیم :
1 2 3 |
sub _http_invalid_params_err ($why) { return Cpanel::Exception::create_raw( 'cpsrvd::BadRequest', $why ); } |
این تابع مارو به Cpanel/Exception/cpsrvd/BadRequest.pm میرسونه. محققا با اینکه دسترسی به کدهای پرل زیادی داشتن اما کل زنجیره رو نمیشه ردیابی کرد چون فراخوانی به Httpd::ErrorPage رو از دست میدادن.
محققا متوجه شدن که سینک در Cpanel::Server::Handlers::Httpd::ErrorPage هستش که کدش در دسترسه ،اما سورس کدی که ،این کد پرل رو مقداردهی میکنه ، نداشتن. محققا حدس میزنن که کد در داخل باینری cPanel هستش و محققا نتونستن محل فراخوانیش رو پیدا کنن.
با جستجو در کدهای Httpd::ErrorPage ، محققا به یه متغییری رسیدن بنام message_html که سینک برای این آسیب پذیری هستش.
محققا با بررسی دو نسخه اصلاح شده و آسیب پذیر، متوجه شدن که دو خط زیر به Cpanel/Server/Handlers/Httpd/ErrorPage.pm اضافه شده :
1 2 3 4 5 |
++ use Cpanel::Encoder::Tiny (); ... omitted for brevity ... ++ $var{message_html} = Cpanel::Encoder::Tiny::safe_html_encode_str( $var{message_html} ); |
PoC:
اگه همه مواردی که بالا بهش اشاره شد رو کنار هم قرار بدیم ، میتونیم به یه PoC برسیم :
1 2 3 4 5 6 |
http://example.com/cpanelwebcall/<img%20src=x%20onerror="prompt(1)">aaaaaaaaaaaa http://example.com:2082/cpanelwebcall/<img%20src=x%20onerror="prompt(1)">aaaaaaaaaaaa http://example.com:2086/cpanelwebcall/<img%20src=x%20onerror="prompt(1)">aaaaaaaaaaaa http://example.com:2082/cpanelwebcall/<img%20src=x%20onerror="prompt(1)">aaaaaaaaaaaa ... potentially other ports ... |
تاثیر آسیب پذیری:
تاثیر این آسیب پذیری اینه که ما میتونیم کد جاوا سکریپت دلخواه ، قبل از احرازهویت و تقریبا در هر پورتی اجرا کنیم.
این به دلیل قوانین پروکسی هستش که این امکان به ما میده که از طریق پورت 80 و 443 هم بتونیم به دایرکتوری /cpanelwebcall/ دسترسی داشته باشیم.
بنابراین مهاجم نه تنها میتونه روی پورتهای مدیریت سی پنل حمله رو انجام بده، بلکه میتونه به برنامه هایی که روی پورت 80 و 443 در حال اجرا هستش هم حمله کنه.
با توجه به اینکه آسیب پذیری روی پورتهای مدیریت سی پنل قابل اجراست، مهاجم میتونه session کاربر قانونی سی پنل بدزده.