Arroiz
  • NEW!
    NEW!  Connect Ideas Across Notes
    Save time and share insights. With Paragraph Citation, you can quote others’ work with source info built in. If someone cites your note, you’ll see a card showing where it’s used—bringing notes closer together.
    Got it
      • Create new note
      • Create a note from template
        • Sharing URL Link copied
        • /edit
        • View mode
          • Edit mode
          • View mode
          • Book mode
          • Slide mode
          Edit mode View mode Book mode Slide mode
        • Customize slides
        • Note Permission
        • Read
          • Only me
          • Signed-in users
          • Everyone
          Only me Signed-in users Everyone
        • Write
          • Only me
          • Signed-in users
          • Everyone
          Only me Signed-in users Everyone
        • Engagement control Commenting, Suggest edit, Emoji Reply
      • Invite by email
        Invitee

        This note has no invitees

      • Publish Note

        Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

        Your note will be visible on your profile and discoverable by anyone.
        Your note is now live.
        This note is visible on your profile and discoverable online.
        Everyone on the web can find and read all notes of this public team.

        Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

        Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

        Explore these features while you wait
        Complete general settings
        Bookmark and like published notes
        Write a few more notes
        Complete general settings
        Write a few more notes
        See published notes
        Unpublish note
        Please check the box to agree to the Community Guidelines.
        View profile
      • Commenting
        Permission
        Disabled Forbidden Owners Signed-in users Everyone
      • Enable
      • Permission
        • Forbidden
        • Owners
        • Signed-in users
        • Everyone
      • Suggest edit
        Permission
        Disabled Forbidden Owners Signed-in users Everyone
      • Enable
      • Permission
        • Forbidden
        • Owners
        • Signed-in users
      • Emoji Reply
      • Enable
      • Versions and GitHub Sync
      • Note settings
      • Note Insights New
      • Engagement control
      • Make a copy
      • Transfer ownership
      • Delete this note
      • Save as template
      • Insert from template
      • Import from
        • Dropbox
        • Google Drive
        • Gist
        • Clipboard
      • Export to
        • Dropbox
        • Google Drive
        • Gist
      • Download
        • Markdown
        • HTML
        • Raw HTML
    Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
    Create Create new note Create a note from template
    Menu
    Options
    Engagement control Make a copy Transfer ownership Delete this note
    Import from
    Dropbox Google Drive Gist Clipboard
    Export to
    Dropbox Google Drive Gist
    Download
    Markdown HTML Raw HTML
    Back
    Sharing URL Link copied
    /edit
    View mode
    • Edit mode
    • View mode
    • Book mode
    • Slide mode
    Edit mode View mode Book mode Slide mode
    Customize slides
    Note Permission
    Read
    Only me
    • Only me
    • Signed-in users
    • Everyone
    Only me Signed-in users Everyone
    Write
    Only me
    • Only me
    • Signed-in users
    • Everyone
    Only me Signed-in users Everyone
    Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    --- title: DT,LFI,RFI --- <div class="header__logo" >Вот они слева-направо: Directory Traversal, LFI и RFI! </div> <p> </p> <style> .header__logo { font-size: 30px; font-weight: 700; color: #270469; text-align: center; } </style> <style> .secret{ display: flex; margin-left: auto; margin-right: auto; width: 50%; } </style> <style> .secret__block{ background-color: #fff; display: block; max-width: 100%; height: auto; transition: opacity .8s linear; color: black; text-transform: uppercase; font-weight: 700; text-align: center; } </style> <style> .secret__block img{ opacity: 5; } </style> <style> .secret__block:hover { opacity: 2 ; } </style> <style> .secret__img { opacity: ; transition: transform 1.8s linear; } </style> <style> .secret__img img{ opacity: 0 ; transition: transform 1.8s linear; } </style> <style> .secret__img img: hover{ opacity: 5 ; transition: transform 1.8s linear; } </style> <style> .secret__img img { display: block; max-width: 100%; height: auto; transition: opacity 1.8s linear; } </style> <style> .secret__img:hover { opacity: 5 ; } </style> <style> .secret__inner { position: relative; background-color: #fff; } </style> <style> .secret__inner:hover .secret__img { transform: translate3d(-10px, -10px, 0); } </style> <style> .secret__inner img:hover { opacity: 0; transition: opacity 2s linear; } </style> <style> .secret__inner img { transition: opacity 2s linear; } </style> <style> .secret__inner:hover .secret__img img { opacity: 1; } </style> ![](https://i.imgur.com/xDM9RMe.png) <div class="TOC" > Содержание: <p> </p> </div> <style> .TOC { font-size: 26px; font-weight: 550; color: #270469; text-align: left; </style> > [TOC] --- # Вводная часть Приветствую вас, сегодня мы будем проходить 3 очень похожие баги, а именно: 1) Directory Traversal (порой её также называют Path Traversal). 2) Local File inclusion (LFI). 3) Remote File inclusion (RFI). Посмотрим, что они из себя представляют, чтобы вы прибавили 100 очков к интеллекту и не путали эти баги:) В качестве лаб я буду юзать [PortSwigger для Directory Traversal](https://portswigger.net/web-security/file-path-traversal), и таски ([1](https://gitlab.com/mctf/training-02.2023/-/tree/main/WEB/CTF-WIKI) и [2](https://gitlab.com/mctf/training-02.2023/-/tree/main/WEB/CTF-WIKIv2)) [@i_013K](https://t.me/i_013k), которые были на тренировке в конце февраля. --- # Из чего обычно состоит веб-приложение Как мы знаем, веб-сайты состоят в наше время из большого количества компонентов: сам HTML-документ с вёрсткой, css-файлы для задания различных стилей, возможно js-файлы, благодаря которым сайт может делать запросы и взаимодействовать с пользователям(например выводя подсказки а как правильно вводить данные в поле email), возможно элементы php(чтобы делать сайт динамичнее, взаимодействовать с БД, совершать загрузки файлов). Помимо этого есть и другие компоненты: картинки, видео и др. ![](https://i.imgur.com/dC72feJ.png) Большинство этих компонентов обрабатывается сервером и потом отправляется браузеру. И тут важный момент: все эти элементы потом включаются в HTML-документ различными способами. То есть, нам не нужно отдельно читать текст в HTML, а потом получать нужную полученную картинку, чтобы увидеть, а про что говорилось в том абзаце. Нет, мы просто получаем все файлы и видим/взаимодействуем с ними через HTML'ку. Давайте разберём а как обычно всё это добро "вкладывается" в HTML-документ --- # Как обычно включают файлы в HTML-документ ## Статичное **В качестве примера возьмём картинки.** Предположим, что некий разработчик решил сделать главную страницу своего сайта примерно такого вида: ![](https://i.imgur.com/qay1bof.png) Как мы видим, на ней есть изображения и какая-то вёрстка. Он, соответственно, сделал HTML-документ, в котором расположил все элементы как надо, сделал css-файл, с помощью которого "придал красок" сайту, и откуда-то добыл нужные изображения для сайта и положил их в директорию `/var/www/images/`. Как вы понимаете, различные картинки/файлы не находятся изначально в HTML-коде, а они загружаются извне, та же папка images. И чтобы показать HTML'ке, что потом после рендеринга должна быть картинка, или что нужно также использовать js/css из других файлов, нужно использовать теги. Например, тег img встраивает изображение в документ: ```<img width="100%" height="300" src="/home/arroiz/images/someImage.png" />``` И вот, разработчик внедрил в HTML-документ всё, что нужно, настроил сервер, поднял его, и сайт начал функционировать. Через время появился человек, который сделал HTTP-запрос на сервер с целью получить главную страницу. Сервер запрос получает и перенаправляет запрос на дальнейшую обработку к программе-обработчику — например, PHP, фреймворку Flask, Ruby или ASP.NET. Программа внимательно изучает содержимое запроса — например, понимает, в каком формате нужно отправить ответ и какие именно файлы нужны(то есть, надо вернуть html, но html в свою очередь должен содержать и картинки, так что помимо неё нужно ещё отправить определённые картинки из `/var/www/images/`). Программа собирает всё, что нужно, передаёт результат серверу, а сервер передаёт результат уже браузеру пользователя. Браузер распаковывает полученный ответ и постепенно начинает отображать полученный контент на экране пользователя. У вас может возникнуть вопрос: а зачем всё это было рассказано? Ну, в моём ответе есть 2 пункта: 1) Вы повторили основы, а это всегда полезно:) 2) Вы теперь имеете представление о том, как на сервере происходит процесс отбора нужных файлов, которые нужно отправить в ответе пользователю. Мы рассмотрели по сути как статично задать то, какие файлики нужно отправить, а что если выборка файлов будет происходить динамично? ## Динамичное Рассмотрим приложение для покупок, которое отображает изображения товаров для продажи. Изображения загружаются через HTML-тег, как показано ниже: `<img src="/loadImage?filename=218.png">` В качестве источника изображения у нас указан маршрут `/loadImage` с параметром filename. Он принимает и возвращает содержимое указанного файла. Сами файлы изображений хранятся на диске в папке `/var/www/images/`. Чтобы вернуть изображение, приложение добавляет запрошенное имя файла к этому базовому каталогу и использует API файловой системы для чтения содержимого файла. В приведенном выше случае приложение читает из следующего пути к файлу: `/var/www/images/218.png` И в этом не было ничего такого, ну обратывает приложенька пользовательский ввод(значение параметра filename, которое мы можем контролировать) и пусть обрабатывает. Однако, давайте вспомним вот такую интересную штучку: Как мы помним, чтобы вернуться в родительскую директорию в терминале(linux, windows, mac os) мы можем использовать `../`. Так вот, такой приём также можно спокойно использовать не только в терминале, но и в той же HTML'ке или в HTTP-запросе, вместо того же 218.png можно указать `../../../../../../../../../etc/passwd` и получить не картинку, а информацию об существующих пользователях на сервере, где приложенька работает. :::info **Справочка** Используя `../../../../../../../../../` в примере выше я как бы вышел из папки images, потом из www, потом из var, а потом ещё несколько "подъёмов" вверх, чтобы точно попасть в корневую папку. После я перешёл в директорию etc и попросил мне выдать файлик passwd. ![](https://i.imgur.com/hAgDYEo.png) ::: Теперь, после того как вы ознакомились с базой и поняли, что из себя представляет Directory Traversal, предлагаю наконец к ней перейти! --- # Directory Traversal :::warning **Обход каталога** — это уязвимость, которая позволяет злоумышленнику читать произвольные файлы на сервере, на котором запущено приложение. Это может включать код приложения и данные, учетные данные для серверных систем и конфиденциальные файлы операционной системы. Обычно здесь задействована комбинация из `../`, чтобы выйти из начальной папки и попасть в ту директорию, которая содержит "интересные" для нас файлы. ::: Причём, чтобы переходить на один уровень вверх в Windows можно использовать и `../` и `..\`, это следует запомнить! ```https://insecure-website.com/loadImage?filename=..\..\..\windows\win.ini``` ## Как обойти различные защиты, мешающие исполнить Directory Traversal? Естественно, в реальной жизни не всё так просто, и разработчики могут попытаться защитить своё приложение от данной уязвимости, используя различные методы, которые можно обойти, давайте ознакомимся с ними! ### Использование абсолютного пути :::info **Лабораторная**: https://portswigger.net/web-security/file-path-traversal/lab-absolute-path-bypass ::: Если приложение удаляет или блокирует последовательности обхода каталога из имени файла, предоставленного пользователем, то можно обойти защиту, используя абсолютный путь от корня файловой системы, например `filename=/etc/passwd`, для прямой ссылки на файл без использования каких-либо последовательностей обхода. **ПРИМЕР** Не катит, так как есть проверка на последовательность обхода: ![](https://i.imgur.com/PZLnkTj.png) Использования абсолютного пути без обходов: ![](https://i.imgur.com/5kLtZL5.png) ### Использование вложенных последовательностей обхода каталогов :::info **Лабораторная**: https://portswigger.net/web-security/file-path-traversal/lab-sequences-stripped-non-recursively ::: Если приложение удаляет или блокирует последовательности обхода каталога из имени файла, предоставленного пользователем, и при этом нельзя использовать абсолютный путь, то можно обойти защиту, используя вложенные последовательности обхода, такие как `....//` или `....\/`, которые вернутся к простым последовательностям обхода при удалении внутренней последовательности, проще говоря, это альтернатива для `../` **ПРИМЕР** Не катит, так как есть проверка на последовательность обхода: ![](https://i.imgur.com/x06a6Zu.png) Не катит, так как есть проверка на абсолютный путь: ![](https://i.imgur.com/yauK5AE.png) Использование вложенных последовательностей обхода: ![](https://i.imgur.com/k5cCKDw.png) ### URL-кодировка :::info **Лабораторная**: https://portswigger.net/web-security/file-path-traversal/lab-superfluous-url-decode ::: В некоторых контекстах, таких как URL-адрес или параметр filename запроса multipart/form-data, веб-серверы могут удалять любые последовательности обхода каталога перед передачей нашего ввода в приложение(то есть ни одно из перечисленных ранее методов не работает). Иногда можно обойти этот вид очистки с помощью кодирования URL-адресов или даже двойного кодирования URL-адресов, например, символов ../, что приводит к %2e%2e%2f или %252e%252e%252f соответственно. ![](https://i.imgur.com/JscYfWw.png) Можно также использовать различные нестандартные кодировки, такие как ..%c0%af или ..%ef%bc%8f. **ПРИМЕР** Вот картинки, благодаря которым можно понять, что ни один из перечисленных ранее методов больше не работает: ![](https://i.imgur.com/q6sP1tM.png) ![](https://i.imgur.com/v5MRTb8.png) ![](https://i.imgur.com/tAPSKlH.png) А вот что будет, если мы закодируем в URL нашу полезную нагрузку(2 раза закодируем): ![](https://i.imgur.com/B7NvrjZ.png) ### Обход проверки начала пути :::info **Лабораторная**: https://portswigger.net/web-security/file-path-traversal/lab-validate-start-of-path ::: Если приложение требует, чтобы имя файла, заданное пользователем, начиналось с ожидаемой базовой папки, например /var/www/images, то можно включить требуемую базовую папку, за которой следуют подходящие последовательности обхода. Например: `filename=/var/www/images/../../../etc/passwd` Тут думаю вы сами сможете решить эту лабу, она простая! ### Обход проверки расширения файла :::info **Лабораторная**: https://portswigger.net/web-security/file-path-traversal/lab-validate-file-extension-null-byte-bypass ::: Если приложение требует, чтобы введенное пользователем имя файла заканчивалось ожидаемым расширением файла, например .png, то можно использовать нулевой байт для того, чтобы опустить всё, что идёт дальше вместе с `.`(.png, .jpg ...). Например: `filename=../../../etc/passwd%00.png` :::warning Тут %00 - это и есть нулевой байт, закодированный в URL. Его можно сравнить со знаком комментария в ЯП или в SQL-запросах, то есть, всё, что идёт после него - не учитывается. Таким образом, в запросе в конце есть нужное расширение, но когда дело дойдёт до того, чтобы получить файл, исходное `filename=../../../etc/passwd%00.png` преобразуется в `filename=../../../etc/passwd`. ::: ## Как исправить данную уязвимость? Самый эффективный способ предотвратить уязвимости, связанные с обходом пути к файлу, — полностью отказаться от передачи пользовательского ввода в API файловой системы. Многие прикладные функции, которые делают это, можно переписать, чтобы обеспечить то же самое поведение более безопасным способом. То есть, мы не должны пользовательский ввод "вкладывать" в путь к файлу, чтобы не было такого: 1) Приложение получает пользовательский ввод, например ../../../../../../etc/passwd 2) Приложение получает путь к папке с картинками - /var/www/images 3) Приложение соединяет путь к папке с пользовательским вводом - /var/www/images/../../../../../../etc/passwd 4) В итоге в HTML выходит что-то типа такого: `<img src="/var/www/images/../../../../../../etc/passwd"/>`. Если же передача пользовательского ввода в API файловой системы считается неизбежной, то для предотвращения атак следует использовать вместе два уровня защиты: 1) Приложение должно проверять ввод пользователя перед его обработкой. В идеале проверка должна сравниваться с белым списком разрешенных значений. Если это невозможно для требуемой функциональности, то при проверке следует убедиться, что входные данные содержат только разрешенный контент, например чисто буквенно-цифровые символы. То есть, можно использовать различные проверки в коде, например, на наличие ../ 2) После проверки предоставленных входных данных приложение должно добавить входные данные в базовый каталог и использовать API файловой системы платформы для канонизации пути. Он должен убедиться, что канонизированный путь начинается с ожидаемого базового каталога. Ниже приведен пример простого кода Java для проверки канонического пути к файлу на основе пользовательского ввода: ``` File file = new File(BASE_DIRECTORY, userInput); if (file.getCanonicalPath().startsWith(BASE_DIRECTORY)) { // process file } ``` ## Всё? И тут можно было бы поставить жирную точку и закончить этот топик, но.. Есть один такой момент=) Directory Traversal это лишь подмножество другой баги, и эта бага уже называется совсем по-другому и умеет она не только читать файлы! --- # Что такое LFI и RFI, и почему они так похожи на Directory Traversal ![](https://i.imgur.com/htgwueT.png) На схеме выше вы можете увидеть, что Directory Traversal - это лишь часть уязвимости Local File Inclusion, а она в свою очередь принадлежит уязвимости File inclusion. Давайте разберёмся, что такое File Inclusion и на что он делится! :::warning **Для начала давайте резберёмся с Directory Traversal:** Уязвимость Path Traversal позволяет злоумышленнику получить доступ к файлу, обычно используя механизм «чтения», реализованный в целевом приложении. *С помощью этой уязвимости мы можем читать файлы!* **А теперь, что такое File Inclusion:** Уязвимость File Inclusion(включение файла) позволяет злоумышленнику "включить" файл в ответ, обычно используя механизмы «динамического включения файлов», реализованные в целевом приложении. *Если файл, который мы включаем в ответ, нельзя исполнить(так как его расширение веб-сервер не исполняет), то по сути мы просто получим его содержимое как в Directory Traversal, а вот если сервер настроен на исполнение файлов с таким расширением, то мы можем этот файл запустить, таким образом заставив, например, сервер исполнять зловредные скрипты!* ::: А теперь давайте по порядку! --- # Как использовать LFI Давайте в качестве примера возьмём таск Саши (@i_013K) с тренировки, которая была в феврале и просто запустим его, после чего зайдём на сайтик. Зайдя на страницу мы видим шапку, в которой есть разделы сайта, кликая на каждый раздел у нас меняется только основная часть сайта, а всё остальное остаётся таким же: ![](https://i.imgur.com/oH00oSj.png) ![](https://i.imgur.com/ogdBWYO.png) ![](https://i.imgur.com/QV2v8sr.png) Также стоит обратить внимание, что при смене каждого раздела меняется и URL сайта: ![](https://i.imgur.com/Y1DlVVM.png) ![](https://i.imgur.com/nR1Rpyy.png) А что это за файлы такие, которые изменяются? Давайте глянем в код: ![](https://i.imgur.com/xANI2im.png) 1) В папке с основными файлами у нас есть 5 мини HTML-файлов и один главный php-файл, который потом будет преобразован(после выполнения всего php-кода) в HTML на сервере и отдан именно HTML'кой клиенту. 2) Те самые ссылки в шапке, которые перекидывают то на ?file=1,2,3... Но это до сих пор не отвечает на вопрос, как изменяется контент сам, так как php страница тут одна, а отдельные мини html-файлы не годны для отдельного использования, так как они из себя представляют что-то такое: ![](https://i.imgur.com/ZOSrYaL.png) 3) Раз мини HTML-файлы не могут быть использованы отдельно, но мы их видим на сайте, значит они куда-то ВКЛЮЧАЮТСЯ, и вот тут как раз вступает в игру мини php-код почти в самом низу: ``` <?php if(isset($_GET['file'])) { include($_GET['file']);}?> ``` :::info **Функция Include в PHP:** На самом деле любой разрабатываемый ресурс не может поместится на одной странице, так как современный сайт состоит из десятков страниц, связанных между собой. Все файлы проекта можно сравнить с вагонами поезда. При необходимости можно убрать лишний, а при нехватке – удлинить «программный» состав еще на один. Для «сцепки» файлов используется функция **include** в PHP. Именно благодаря этой функции мы включаем контент мини HTML-файлов в наш php-файл! То есть, мы можем создать 1 шаблон, и в него внедрять другие части, как это и сделано в таске. Шапка и прочее те же, а вот основной контент меняется в зависимости от страницы. ::: :::warning **Перед тем как продолжить я хочу разъяснить вот какой момент, он связан опять с базой по вебу, но его стоит упомянуть, так как дальше он сыграет важную роль:** Как мы видим, в таске есть **1** php-файл, и сколько-то там HTML-файлов. И тут у многих может встать вопрос: - А как так получилось, что тут основная страница в php, в которую внедряются html-ки, а по факту нам приходит один единый **HTML** файл? Смотрите, я это упоминал раньше здесь "Сервер запрос получает и перенаправляет запрос на дальнейшую обработку к программе-обработчику — например, PHP, фреймворку Flask, Ruby или ASP.NET". И сейчас мы раскроем это предложение. Обычно сервер может как просто вернуть клиенту какой-то статичный файл(допустим просто обычную HTML'ку, картинку и тд), а может получить запрос на такой файл, который надо сначала **ОБРАБОТАТЬ**, и вот файл с расширением .php - один из таких файлов. Например, в таске у нас есть php-файл, который запрашивает пользователь, точнее он запрашивает не его, а главную страницу, но по факту это одно и тоже. Сервер, который настроен на исполнение .php файлов, дальше выясняет, что пользователь запросил как раз-таки этот файлик и видит, что этот файлик, грубо говоря, сырой, так как надо сначала выполнить весь php-код в нём. Для этого он передаёт данный php-файл с параметрами запроса программе-обработчику, в нашем случае это PHP. Дальше этот php, получив всё это, подставляем, если надо, что-то в этот файлик, а потом преобразует его в **HTML** и передаёт уже именно **его** веб-серверу. А веб-сервер передаёт уже готовый HTML пользователю. Что сейчас произошло, если кратко: Сервер настроен на то, чтобы **исполнять** php-файлы, и чтобы их исполнять он передаёт всё, что нужно для этого PHP'шке. После чего он результат исполнения возвращает пользователю. ::: Так, вернёмся к коду: ``` <?php if(isset($_GET['file'])) { include($_GET['file']);}?> ``` Если разорбрать, что делает тут php-код, то получится следующее: 1) Если есть в запросе параметр file с каким-то значением, то выполняется следующий пункт, в противном случае этот php-код как бы исчезает, файл конвертируется в HTML и отдаётся пользователю. 2) Если всё же есть параметр file, то нужно вернуть такой файлик, который указан в значении параметра, т.е. если значение это 2, то нужно вернуть вернуть файл с именем 2(это как раз мини html'ka, хотя по факту это что угодно может быть, оно всё равно встроится в HTML и теги внутри просто будут как теги для HTML). А под словом вернуть имеется в виду, что в **это** конкретное место в коде "внедриться" этот мини html-файл. А потом этот php-файл конвертнётся в HTML(и весь php-код из него исчезнет) и этот HTML'ка вернётся пользователю. ![](https://i.imgur.com/wAgUGwz.png) И в чём тут уязвимость, и зачем мы всё это разбирали? Да всё просто, тут есть LFI, и она тут есть, так как веб-приложение включает файл без правильной очистки ввода, что позволяет злоумышленнику манипулировать вводом и вводить символы обхода пути, а также включать другие файлы с того же веб-сервера. И по сути мы можем тут провернуть тот же Directory Traversal! ![](https://i.imgur.com/s7Kpfjg.png) Но так как тут именно LFI, мы можем не только читать файлы, но и исполнять команды, так как напоминаю о том, что было выше, веб-сервер может и порой должен исполнять некоторые файлы, и в данном случае тут исполняется php-код, а это значит мы можем сделать вредоноснгую нагрузку, связанную с php, чтобы например просмотреть путь до дериктории, в которой мы находимся: ![](https://i.imgur.com/40pdzrd.png) И в результате нам "включится" в HTML файл вывод команды pwd! Давайте ознакомимся со всеми возможностями LFI, чтобы у вас сложилось полное представление по ней: ## Чтение исполняемых файлов Если есть LFI, то можно спокойно читать те файлы, которые не исполняемые, так как при попытке прочитать исполняемые файлы веб-сервер просто исполнит файл и вернёт результат, таким образом вы например не увидите секретные креды в php-файле. Однако это ограничение можно обойти с помощью встроенного php-фильтра. ``` php://filter ``` Можно прочитать содержимое исполняемого файла закодиров его в base64, используя следующую полезную нагрузку: ``` vuln.php?page=php://filter/convert.base64-encode/resource=/etc/passwd ``` ![](https://i.imgur.com/aDeixof.png) ![](https://i.imgur.com/wG57ib3.png) А можно и без кодирования в base64: `?page=php://filter/resource=/etc/passwd` Картинок тут не будет, так как таск слегка ломается, но иногда вообщем и так можно:) Поэтому многое зависит от конфигурации!!! ## Выполнение команд ОС С помощью LFI, как я показывал ранее, можно выполнять команды в ОС. Для этого есть 2 полезные нагрузки: ``` php?page=expect://ls (модуль PHP expect не включен по умолчанию) ``` Если URL-адрес включает =on в конфигурацию php.ini, мы можем легко выполнять команды ОС и получать обратную оболочку по data://text/plain, ``` data://text/plain,<?php%20system($_GET[%27cmd%27])%20?>&cmd=whoami ``` ![](https://i.imgur.com/xnCVQGe.png) ## Обратная оболочка от LFI Вообще, такое не приветствуется на стф:) Но пару вещей скажу. Вообще есть 2 способа сделать обратную оболочку: 1) С помощью data://. Вы используете `data://text/plain, + php-код для обратного ревёрса` и netcat, чтобы включить порты для прослушивания `nc -lvp 1234`. Сначала второе делаете, а потом первое, и вот вы получили обратную оболочку! 2) Отравление логов. Тут советую ознакомиться с [ЭТИМ](https://effortlesssecurity.in/2021/08/01/lfi-rfi-from-basic-to-advance/) сайтом, тут всё подробно расписано! --- # Как использовать RFI :::warning Используя **LFI**, злоумышленник может **получить** файлы с локального сервера, а также **выполнить** файлы локального сервера. Используя **RFI**, злоумышленник может **запускать** файлы с удаленного сервера. ::: Помимо того, что исполнять файлы можно локально, это также можно сделать и удалённо. Т.е. мы можем сделать зловредный скриптик где-нибудь на гитхабе и заставить сервер его исполнить! ## Чтение файлов и команды ОС 1) Создать txt или php файл со следующим содержимым: `<?php system($_GET['cmd']) ?>` 2) Загрузить этот файл с вашего источника, исполняя команды ОС через параметр cmd: ![](https://i.imgur.com/3d4fzGj.png) ![](https://i.imgur.com/Kw3ZOjp.png) ![](https://i.imgur.com/lZAhNLI.png) ![](https://i.imgur.com/VTY5Uku.png) ## Reverse shell из-под RFI Опять-таки не буду вам тут показывать эти гадости, но быстро пройдусь по пунктам: 1) создать файл с расширением txt или php с reverse shell'ом в гит тот же 2) подтянуть этот файл как в примере выше 3) получить оболочку и огрести люлей --- # Домашка(по желанию) Ну чтож, вот топик и подошёл к концу, предлагаю вам выполнить следующую домашку, чтобы закрепить материал: 1) Прорешать [раздел Directory Traversal](https://portswigger.net/web-security/file-path-traversal) в PortSwigger'e, он там простой! 2) Сказать, что ещё можно сделать с LFI/RFI. 3) Как исправить LFI/RFI. 4) Какие есть ограничения и моменты, которые следует помнить? И на этом всё, спасибо вам, что дочитали данный топик, надеюсь вам было интересно и понятно! Если есть вопросы - пишите в тг @ArroizX ![](https://i.imgur.com/dS3tHK8.jpg)

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Google Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully