---
# System prepended metadata

title: Web. Практическая работа №3

---

# Web. Практическая работа №3

## Цель работы: Изучить основные атаки на WEB

По вашей просьбе выкладываю скрин прогресса на portswigger

![](https://i.imgur.com/PRs5F0V.jpg)


## Задания Практической работы:

На стенде по адресу [https://portswigger.net/web-security](https://portswigger.net/web-security) разобрать следующие задания:

## SQL-injection уязвимости:

- [https://portswigger.net/web-security/sql-injection/lab-login-bypass](https://portswigger.net/web-security/sql-injection/lab-login-bypass)
- [https://portswigger.net/web-security/sql-injection/lab-retrieve-hidden-data](https://portswigger.net/web-security/sql-injection/lab-retrieve-hidden-data)
- [https://portswigger.net/web-security/sql-injection/union-attacks/lab-retrieve-data-from-other-tables](https://portswigger.net/web-security/sql-injection/union-attacks/lab-retrieve-data-from-other-tables)
- [https://portswigger.net/web-security/sql-injection/examining-the-database/lab-querying-database-version-mysql-microsoft](https://portswigger.net/web-security/sql-injection/examining-the-database/lab-querying-database-version-mysql-microsoft)

Все решения задач по атакам на SQL базы данных сводяться к модификации запросов к БД сервера. Делается это (чаще всего) путем дописывания команд SQL в поля ввода интерфейса приложения.
Т.е. атакующий, исходя из своих предположений о том, как выглядит SQL-запрос внутри сервера, дописывает его так, чтобы можно было использовать уязвимость приложения.

Для удобства будем использовать BurpSuite хотя можно обойтись и без него.

**1. Обход аутентификации.**

Предположим, что сервер получаяя аутентификационные данные использует запрос:

`SELECT * FROM users WHERE username = 'administrator' AND password ='StrongPa$$w0rd'`

Дописывать мы можем только в поля логина/пароля (а у нас это слова administrator и StrongPa$$w0rd). Как здесь можно "отключить" проверку пароля? Да просто закомментировать его. 
Модифицируем запрос так, чтобы не нарушить синтаксис языка:

SELECT * FROM users WHERE username = 'administrator =='- -== ' AND password ='StrongPa$$w0rd'

При этом, все что идет после нашей модификации - становиться комментарием и никак не учитывается сервером БД.

Отправляем POST-запрос со страницы в входа в Репитер:

![](https://i.imgur.com/v2rT7gy.jpg)


Модифицируем запрос:

![](https://i.imgur.com/h5jNVP9.jpg)

Сайт перенаправляет нас в аккаунт. Это можно видеть в истории запросов - 302 редирект с POST-запроса на страницу аккаунта. Страница открылась с кодом 200 ОК.

![](https://i.imgur.com/JlvNoyL.jpg)

![](https://i.imgur.com/ug7MlF1.jpg)


**2. Извлечение скрытых данных**

Нам нужно извлечь скрытый список товаров. В данном случае тех, которых нет в продаже (либо есть в продаже, но для отдельных категорий граждан :)).

Зайдем в любую категорию  и посмотрим, какой отправляется запрос к серверу.

![](https://i.imgur.com/srUx5Ww.jpg)

Мы предполагаем (или уже знаем) что запрос с отображением только доступных товаров выглядит так:

`SELECT * FROM products WHERE category = 'Pets' AND released = 1`

Можно модифицировать запрос как в прошлом примере: `... Pets'-- ...`  Но тогда мы будем видеть все товары только в категории Pets. А чтобы вывести ВЕСЬ список товаров, по всем категориям, нужно модифицировать запрос так, чтобы для любого элемента таблицы WHERE всегда возвращал true
Т.е. чтобы 
`SELECT * FROM products WHERE true`

что равносильно

`SELECT * FROM products`

Делаем

SELECT * FROM products WHERE category = 'Pets ==' OR 1=1- -==' AND released = 1

Поскольку 1 всегда равен 1 , то WHERE будет возвращать либо товар из категории Pets либо true

Проверяем

![](https://i.imgur.com/zE8bQ2J.jpg)

![](https://i.imgur.com/XtgohTz.jpg)

**3.  Union-based - атака**

У нас есть ОДНА уязвимая таблица, выводом которой мы можем управлять. Каким образом можно получить доступ к другим таблицам БД используя текущую таблицу?

Нужно попробовать объединить обе таблицы в одну. В SQL 'то позволяет сделать оператор UNION

Предопложим, что приложение выполняет запрос к БД, содержащий пользовательский ввод «Gifts»:

`SELECT name, description FROM products WHERE category = 'Gifts'`

тогда злоумышленник может отправить ввод:

`' UNION SELECT username, password FROM users-- ` образуя тем самым запрос вида

SELECT name, description FROM products WHERE category ='Gifts ==' UNION SELECT username, password FROM users- -==' 

:::warning
ВАЖНО! Количество столбцов в обеих таблицах должно совпадать. 
:::

Проверяем:
![](https://i.imgur.com/xaTceMK.jpg)

Авторизуемся

![](https://i.imgur.com/97dQ9DC.jpg)

**4. Узнаем тип базы данных**

Чтобы быстрее и качественнее проникнуть в БД, нужно знать тип базы данных, какие есть в ней таблицы и прочее.

Информацию можно получить выполнив запрос 

`SELECT @@version`

А куда нам его поместить?
Нам поможет UNION оператор!

Возьмем запрос из предыдущего примера и дополним его нашей командой.

SELECT name, description FROM products WHERE category ='Gifts ==' UNION SELECT @@version, NULL- -=='

Как я писал выше, нужно чтобы количество столбцов в обоих запросах совпадало. Поэтому во втором запросе мы добавляем пустой столбец NULL, чтобы получить... Чтобы вообще хоть что-то получить. С разным количеством столбцов ответа не будет.

Пробуем, и получаем версию БД:

![](https://i.imgur.com/1vWvd9I.jpg)

## XSS уязвимости:

- [https://portswigger.net/web-security/cross-site-scripting/stored/lab-html-context-nothing-encoded](https://portswigger.net/web-security/cross-site-scripting/stored/lab-html-context-nothing-encoded)
- [https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-document-write-sink](https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-document-write-sink)
- [https://portswigger.net/web-security/cross-site-scripting/contexts/lab-javascript-string-angle-brackets-html-encoded](https://portswigger.net/web-security/cross-site-scripting/contexts/lab-javascript-string-angle-brackets-html-encoded)
- [https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-dom-xss-reflected](https://portswigger.net/web-security/cross-site-scripting/dom-based/lab-dom-xss-reflected)



**1. Хранимые XSS в HTML-коде**

Чтобы внедрить XXS нужно, как и в случае с SQL внедрить свой код в страницу таким образом, чтобы он:

1. Работал
2. Не был заметен (не поползла верстка)

В нашей задаче важно только первое.

Решение простое. 
Пробуем внедрить js-код alert("1") прямо в коммент. Можно так и написать в комментарии к посту:

```
<script>
    alert("1")
</script>
```
Но я сделаю это через Берп.

![](https://i.imgur.com/IodB37J.jpg)

Попроубем посетить страницу с комментариями снова. 
Код исполняется

![](https://i.imgur.com/7PdMzvP.jpg)


Если мы теперь заглянем в структуру страницы, то мы найдет наш код, внедренный в HTML "безшовно". 

![](https://i.imgur.com/ZPpBcCe.jpg)

:::info
Используя `alert("1")` мы рискуем попасть "на карандаш" системе безопасности целевого сайта. Чтобы снизить риски, лучше использовать теги (например <img src=x>). Так тоже можно проверить уязвимость полей ввода, но при этом не быть замеченным
:::


**2. DOM XSS в document.write**

 Приложение может быть уязвимо для DOM XSS, если есть исполняемый путь, по которому данные могут распространяться от источника к приемнику. Есть очень много приемников, которые относятся к уязвимостям на основе DOM. 
 
 Введем любой запрос на нашей странице и рассмотрим его результаты в Инспекторе браузера.
 
 Ага! Мы обнаружили приемник document.write. Мало того, он работает со скриптами. Какое счастье!
 Как видно, после выполнения скрита, наш запрос помещается в атрибут src, тега img в теле документа.
 
 ![](https://i.imgur.com/f0y8Z7c.jpg)

 Осталось только модифицировать наш поисковый запрос так, чтобы он как минимум исполнялся не вызывая синтаксических ошибок скрипта.
 
 Вывод запроса:        `<img src="/resources/images/tracker.gif?searchTerms=GIFT">`
 Модификация:          `<img src="/resources/images/tracker.gif?searchTerms=GIFT`=="\>\<svg onload=alert(1)>=="> 
 
 Я специально оставил  в конце "> чтобы показать, куда мы вставили наш пэйлоад и что эта часть исходного кода никуда не девается. Она останется в теле документа.
 
 ![](https://i.imgur.com/Mw6DXsL.jpg)

 **3. Отраженные XSS в строковых литералах**
 
 В некоторых случаях, когда контекст XSS находится внутри строкового литерала в кавычках,  можно выйти за пределы строки и выполнить JavaScript напрямую. 

для выхода из строкового литерала можн оспользовать следующий пейлоад:

`'-alert(1)-'`

Исполняем.
Запустим лабораторию и выполним любой запрос
Допишем наш пейлоад прямо в адресную строку, в появившемся запросе параметров ?search=

![](https://i.imgur.com/PetTh2L.jpg)

После того, как мы выполним запрос и уберем всплывший alert, мы увидим, что задача решена. Мы выбрались из строки.

![](https://i.imgur.com/RrHNWnH.jpg)

Теперь эту ссылку можно отправить жертве. Код будет исполняться на любой машине, с которой перейдут по этой ссылке.
Не открывайте незнакомые или подозрительные ссылки.

**4. Отраженная DOM XSS**

Уязвимость этой лабораторки возникает в случае, когда клиентский запрос получен на сервере,  обработан, результат упакован в json и отправлен обратно клиенту. Но на клиентской стороне, результат в конечном счете записывается в приемник. Но небезопасным способом. Этим мы и воспользуемся. 

Выполним любой запрос в поиске лаборатории.
В истории мы видим, что на самом деле выполняется два запроса, один из которых отправляется из пути /search-results/ в формате json.
![](https://i.imgur.com/JUHhM8T.jpg)

Также видим, что в ответе выполняется скрипт. 
`script src='resources/js/searchResults.js'`

Посмотрим скрипт поближе.
И тут мы находим небезопасную функцию eval которая может выполнить код!
Значит, нам надо выбраться из формата json, и наш код выполнится.

Сайт проглатывает (не экранирует) обратный слеш.
Поэтому, мы вводим в поисковую строку следующий пэйлоад 

`\"-alert(1)}//`

Который прочитается скриптом как `{"results":[],"searchTerm":""-alert(1)}`

Почему так? Разберем. 
Обратный слеш  сайт пропускает. Однако, видя двойные кавычки, сайт добавляет свой обратный слеш. В итоге вместо команды "экранируй кавычки" (помести их в строку) мы получаем команду "Экранируй обратный слеш, а кавычки не трогай".
Далее идет "минус" как разделитель выражений, после чего наш alert и закрываем формат json. Потом комментарий.

И это сработало.

![](https://i.imgur.com/XD9gmRp.jpg)


## CSRF:

- [https://portswigger.net/web-security/csrf/lab-no-defenses](https://portswigger.net/web-security/csrf/lab-no-defenses)
- [https://portswigger.net/web-security/csrf/lab-token-validation-depends-on-request-method](https://portswigger.net/web-security/csrf/lab-token-validation-depends-on-request-method)

**1. CSRF без защиты**

В этой лабе моделируется ситуация, когда жертва открывает ссылку, перейдя по которой, произойдет что-то нехорошее. В нашем случае это будет смена почты аккаунта жертвы. Естественно, без уведомления последней.

Как это происходит?
Атакующий пишет эксплойт и помещает его на своей контролируемой странице (для этого мы используем сервер эксплойтов).

![](https://i.imgur.com/iknK6gn.jpg)


```htmlembedded
<form method="POST" action="https://0ad9005104ef5131c0990e2d00d70040.web-security-academy.net/my-account/change-email">
    <input type="hidden" name="email" value="attack@hack.ru">
</form>
<script>
        document.forms[0].submit();
</script>
```

Затем, отправляет ссылку жертве (нажимаем отправить жертве).
При переходе по ссылке жертву перебрасывает на URL из эксплойта, происходит автозаполнение поля почты и отправка данных на сервер. 


![](https://i.imgur.com/FNg9iAd.jpg)

Возможно, жертва даже не увидит ответа сервера. Да это и не нужно. Запрос мы все равно уже отправили.

**2. CSRF, с проверкой токена**

Некоторые приложения проверяют токен лишь методе POST "забывая" про метод GET. Воспользуемся этим.
Для начала проверим нашу теорию.

Поменяем почту как обычно, по всем правилам. Затем откроем Burp и посмотрим что происходит в запросе.

![](https://i.imgur.com/TKLu6TW.jpg)

В этот раз приложение использует токен csrf для большей безопасности.
Попробуем произвольно изменить токен

![](https://i.imgur.com/iY46RG5.jpg)

Ничего не вышло. 

Тогда попробуем изменить метод запроса на GET

![](https://i.imgur.com/eFmbTWx.jpg)

Даже с неправильным токеном удалось изменить почту. 

Дальше действуем по накатанной схеме:

Создаем и отправляем эксплойт жертве. 
Жертва открывает ссылку 
Задача выполнена

В эксплойте, мы также всего лишь меняем метод

![](https://i.imgur.com/5qNYjBu.jpg)


## SSRF:

- [https://portswigger.net/web-security/ssrf/lab-basic-ssrf-against-localhost](https://portswigger.net/web-security/ssrf/lab-basic-ssrf-against-localhost)
- [https://portswigger.net/web-security/ssrf/lab-ssrf-filter-bypass-via-open-redirection](https://portswigger.net/web-security/ssrf/lab-ssrf-filter-bypass-via-open-redirection)


1. **SSRF на внутреннюю инфраструктуру**

Если мы видим, что приложение использует запросы к внутренним серверам. То можно попытаться выполнить атаку SSRF, подменив запрос на свой.

Посмотрим, что отправляет приложение серверу в POST-запросе, когда нам надо проверить остатки по товару.

![](https://i.imgur.com/FYR99Nu.jpg)

Выполняется некий запрос на внутренние сервера.

А если попробовать зайти на другие ресурсы инфраструктуры?
Изменим запрос в Репитере. Приведем его к виду 
`stockApi=http://localhost/admin`
и выполним.
![](https://i.imgur.com/OFdGhN3.jpg)

Оба-на! Админка!
Немного похулиганим и удалим аккаунт Карлоса.

Для этого еще раз изменим запрос, чтобы  выполнить удаление.

![](https://i.imgur.com/HriTGmi.jpg)

## 2. SSRF с обходом фильтра через открытое перенаправление

Приложение может проверять что мы ему подсовываем под видом запроса. Но иногда, проверка может быть неполной. 

Попробуем изменить запрос к внутреннему серверу как в прошлый раз

![](https://i.imgur.com/fdpMljK.jpg)

Ничего не выходит.
А вот внизу справа, есть кнопка "Следующий продукт". И от этой кнопки ведет ссылка, содержащая в себе открытое перенаправление.

`http: ... /product/nextProduct?currentProductId=7&path=/product?productId=8`

Более того, часть этой ссылки помещается в заголовок, при при нажатии.

`http: ... /product?productId=8`
Это как раз и есть то самое перенаправление. Вот интересно, проверяет его приложение или нет? Попробуем поместить наш адрес внутреннего ресурса в такую ссылку.

`stockApi=/product/nextProduct?path=http://192.168.0.12:8080/admin`

Нас перенаправило на внутренний сервер.

![](https://i.imgur.com/J6UFSWS.jpg)

Ура! Мы внутри. Удалим несчастного Каролоса.

![](https://i.imgur.com/ghsC8jx.jpg)

## RCE - удаленное выполение кода

Голубая мечта каждого пентестера - найти RCE. Ведь это дает, как правило, полный или значительный контроль над ресурсом.

- [https://portswigger.net/web-security/os-command-injection/lab-simple](https://portswigger.net/web-security/os-command-injection/lab-simple)


**1. Простая RCE**

Условиями задачи предполагается, что параметры запроса передаются на сервер "как есть" без проверки и выполняются скриптом. Найдем сначала передаваемые параметры

![](https://i.imgur.com/NX7lJkg.jpg)

Понятно, что скрипт будет запрашивать, скорее всего значения самих параметров. Вот их и попробуем изменять.
Кроме логического или, которое дается в решении, похожий результат выдает точка с запятой

![](https://i.imgur.com/6ZyeSvD.jpg)

Логин уже есть. Теперь можно брутфорсить пароль.


## Path traversal

- [https://portswigger.net/web-security/file-path-traversal/lab-simple](https://portswigger.net/web-security/file-path-traversal/lab-simple)
- [https://portswigger.net/web-security/file-path-traversal/lab-absolute-path-bypass](https://portswigger.net/web-security/file-path-traversal/lab-absolute-path-bypass)

Path traversal - уязвимость которая возникает на серверах nginx в случае неправильной настройки конфигурации. Я бы сказал невнимательной настройки.
Заключается в том, что используя последовательность /../ можно подняться на один уровень вверх в каталоге.

Рассмотрим на примере задачи.

**1. Простой случай Path traversal**

Включим Intercept- перехват запросов в Proxy. 
Откроем страницу с товаром, нажмем Forward и модифицируем текущий запрос так, чтобы подняться в корень сайта. 

![](https://i.imgur.com/u9Nj33D.jpg)


Наш запрос: `/image?filename=25.jpg`

Мы предполагаем, что наши картинки находяться в каталоге /var/www/image/25.jpg
До корня - 3 уровня. Поднимаемся

`/image?filename=../../../`

Теперь мы в корне. Но это еще не все.
Дальше нам надо спуститься отсюда к файлу passwd. Он находится в каталоге /etc. 
Делаем

`/image?filename=../../../etc/passwd`

Вставляем полученный пейлоад в наш запрос, выключаем перехват и смотрим на результат


![](https://i.imgur.com/YwVATyO.jpg)


Вот и список пользователей. Кстати. Еще одно подтверждение тому, что используется nginx - наличие пользователя www-data.

2. Path traversal обход с помощью абсолютного пути

Многие приложения, помещающие пользовательский ввод в пути к файлам, реализуют некоторую защиту от атак Path traversal, но и эти защиты можно обойти.

Наприме, можно попробовать использовать абсолютный путь от корня файловой системы, например filename=/etc/passwd.

Реализуем.

Порядок действий абсолютно такой же, как в предыдущем примере. 
Только вместо последовательностей `/../../..` в запросе, мы сразу пишем
`filename=/etc/passwd`

Смотрим что получилось

![](https://i.imgur.com/TXugHDB.jpg)

Задача выполнена.