Як я проник на сервер PayPal через баг у завантаженні файлів і отримав доступ до віддаленого виконання
Пентестер (тестувальник на проникнення) розповідає, як йому вдалося знайти баг у завантаженні файлів і проникнути на сервер платіжної системи PayPal.

Надіюсь у вас все добре. Впевнений, що заголовок вас чимало здивував, і ви кинулися сюди, щоб глянути, чи реально я зміг отримати віддалений доступ не кудись, а на сервер PayPal.
Насправді це був досить простий злом, спрямований на перевірку вразливості (так званий POC). Єдиний момент, з яким мені пощастило, — пошук та успішне визначення вразливого домену.

Почнемо з невеликої передісторії. Як ви могли раніше бачити в моєму попередньому пості, я нещодавно склав іспит на сертифікацію OSCP. Ось на це в мене справді пішло чимало днів і ночей наполегливої роботи — майже 4 місяці зосереджених занять і жодного пошуку багів, тобто, по суті, ніякого заробляння кишенькових грошей.
Нормальні люди: вихідні повні випивки, тусовок, веселощів, похмілля та іншого. Запитання на кшталт: «Ти дивився нового «Людини-павука»? Гра престолів?»
Люди на зразок мене:

Отже, одного з вихідних, переглядаючи деякі блоги та ролики на YouTube, я натрапив на матеріал по PayPal, подумав зайти на їх сторінку програми заохочення пошуку багів за допомогою Burp і виявив таке:
На скріншоті показано звичайну відповідь http://paypal.com/bugbounty/. Придивившись, можна побачити цікавий список доменів PayPal у заголовку відповіді Content Security Policy. Мене зацікавив https://*.paypalcorp.com. Цей типовий підхід, який я використовую у відлові багів. Я шукаю якнайбільше робочих піддоменів кінцевої мети, оскількисаме їх, як правило, залишають без належної уваги, і, такі як я, у результаті щось там знаходять.
Ви можете скористатися Subbrute, Knockpy, enumall або іншими схожими утилітами. Зазвичай я так і роблю, але цього вихідного ліньки взяла гору і я просканив їх у VirusTotal. Підсумковий список можна переглянути тут.
Я скопіював список піддоменів на локальну машину, запустив dig -f paypal +noall +answer, щоб отримати зручну картину того, куди насправді вказують усі субдомени.

Один із них, brandpermission.paypalcorp.com, вказував на https://www.paypal-brandcentral.com/ — сайт для реєстрації запитів до служби онлайн-підтримки вендорів, постачальників та партнерів PayPal, за допомогою якого вони вимагають дозволу на використання бренду. У системі є функція завантаження чорнових варіантів логотипів і графіки під час оформлення запиту.
Реакція будь-якого мисливця за багами, який побачив форму завантаження файлів:

Тому спочатку я створив «тикет», завантаживши просте зображення з назвою finished.jpg. На сервер воно потрапило під ім'ям finished_thumb.jpg на шляху /content/helpdesk/368/867/. Я швидко перевірив, чи завантажився файл, який ми відправляли через форму з ім'ям finished.jpg і так, на щастя (цей факт ще зіграє свою роль пізніше) він там був присутній.
Далі я трохи вивчив схему роботи програми: як вона завантажує файли, куди вони потрапляють, які шаблони імен для файлів та папок у ньому прийняті. Стало ясно, що каталог 368 був названий так за номером створеного мною тикета, а 867 - ідентифікатор папки, в якій зберігаються всі пов'язані з ним файли, тобто різні графічні матеріали, що додаються до тикету.
Я швидко повторив ті ж дії, створив ще одне звернення, з якогостало видно, що ідентифікатори тикета та папки генеруються серійно. Створив ще один тикет, але на цей раз завантажив файл з розширенням .php, що містить простий однорядковий скрипт для командного рядка:
Скрипт повернув 302 код (тобто по суті 200 ОК). Це означало, що програма не робила жодних перевірок типів файлів, контенту та іншого. Є! Моя особа в цей момент:

Побачивши 302 код, я кинувся відкривати новий тикет щоб скопіювати посилання, як це було у разі завантаження файлу зображення. Але при відправці .php побачити шлях файлу, що завантажується, було не можна. Єдине, що можна було дізнатися, — номер тікету. Що робити далі?

Але ми знаємо ім'я файлу - success.php (оскільки перевірили до того, що example.jpg опинився в тій же папці, що і example_thumb.jpg).
Отже, незважаючи на те, що при завантаженні та обробці success.php у success_thumb.php код першого був «з'їдений», success.php, проте, як і раніше, існує на сервері і до нього можна звернутися. Ми також знаємо ідентифікатор папки (867), отриманий під час завантаження простого зображення. Номер тикета для завантаження перевірочного php - 366.
Чому б просто не забрутфорсувати ідентифікатори папок, де зберігається завантажений файл?

Не можна просто взяти і забрутфорсить
Тому я швидко запустив в Intruder'і наступний перебір з ідентифікаторами 500–1000: https://www.paypal-brandcentral.com/content/_helpdesk/366/$(bruteforced 500-1000)$/success. php. У результаті 200 код було отримано на ідентифікаторі 865.



Небагато магії cat /etc/passwd щоб самому переконатися, що можливість віддаленого виконання коду дійсно є:

Хронологія обробкизвернення:
Але зачекайте! На цьому історія не закінчується. Ось ще трохи матеріалу для затравки. Про нього я розповім у своєму блозі наступних вихідних:

Я повідомив про ту ж саму вразливість у різних точках програми. Одне з повідомлень було досить очевидним, тому їх поєднали в одне звернення, а друге позначили, як дублююче.