- Saved searches
- Use saved searches to filter your results more quickly
- License
- artyuum/simple-php-web-shell
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- About
- Пишем простенький веб-эмулятор терминала на PHP
- Пишем простецкий эмулятор терминала на PHP
- Основная идея реализации
- Файл shell.php
- Файл send-cmd.php
- Файл bashrc
- Файл pt.c
- Демонстрация работы
- Всё вместе
- Однострочный PHP-скрипт для получения Shell-a.
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Tiny PHP Web shell for executing unix commands from web page
License
artyuum/simple-php-web-shell
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
A really simple & tiny PHP Web shell for executing unix commands from web page.
Usage of this script as a backdoor in order to have external access to a server you do not own without prior consent is illegal. It is the end user’s responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program.
About
Tiny PHP Web shell for executing unix commands from web page
Пишем простенький веб-эмулятор терминала на PHP
Конечно же, такое решение вызывает целый набор проблем, самая незначительная из которых — это то, что ошибки на экран не попадают. Есть и намного более значительные вещи, например запуск vi просто «подвесит» выполнение команды и придется открывать новую консоль и писать killall vi . И что уж точно не получится сделать, так это выполнить команды ssh или sudo, которые требуют чтения пароля прямо с терминала. Я постараюсь показать способ, с помощью которого можно устранить большую часть описанных выше проблем.
Пишем простецкий эмулятор терминала на PHP
- PHP 5.2+ (с напильником — PHP 4.3+)
- Работающие функции system() и proc_open()
- Работающая функция flush() (flush() для nginx)
- term.js и utils.js из проекта JSLinux
- Linux, Mac OS X на стороне сервера (на *BSD не проверял, возможно, требуются доработки)
Основная идея реализации
В документации к PHP сказано, что proc_open() предназначен для двухсторонней коммуникации с процессами, поэтому мы откроем bash в интерактивном режиме с помощью этой функции и будем дальше с ним работать. К сожалению, поддержки псевдотерминалов в PHP из коробки нет, поэтому реализацию нужной нам прослойки мы напишем на Си.
Какой-либо защиты, а также проверок на ошибки и корректного завершения терминала в этом примере не предполагается(!), об этом вам придется думать самим ;).
Файл shell.php
Получение ввода пользователя
Мы должны каким-то образом получать ввод от пользователя, например через FIFO-файл:
function deleteTempFifo() < unlink($GLOBALS['temp_fifo']); >register_shutdown_function('deleteTempFifo'); $cmdfp = fopen($temp_fifo_file, 'r+'); stream_set_blocking($cmdfp, 0);
Установка переменных окружения для терминала
JSLinux работает в режиме эмуляции vt100, мы тоже будем делать также 🙂
putenv('TERM=vt100'); $cols = 80; // можно задать любые числа, в общем-то $rows = 24;
Команда для запуска bash
В принципе, мы можем просто запустить » bash -i «, и это будет работать (даже » sh -i » будет работать), но ещё лучше, если мы сможем работать через псевдотерминал, программы будут вести себя более «естественно» в таком случае. Заодно мы можем использовать свой bashrc, в котором настроим цветное приглашение :).
chdir(dirname(__FILE__)); $cmd ; // попробуем скомпилировать нашу утилиту для работы с псевдотерминалом (pt.c, будет приведена далее) // если программа не компилируется, просто не используем эту дополнительную прослойку if (!file_exists('pt')) < system('cc -D__'.strtoupper(trim(`uname`)).'__ -o pt pt.c -lutil 2>&1', $retval); if ($retval) echo('Warning: Cannot compile pseudotty helper'); > clearstatcache(); if (file_exists('pt')) $cmd = "./pt $rows $cols $cmd"; $pp = proc_open($cmd, array(array('pipe','r'), array('pipe', 'w')), $pipes); stream_set_blocking($pipes[0], 0); stream_set_blocking($pipes[1], 0); ?>
Посылка команд из javascript
Мы будем делать по одному HTTP-запросу на символ (или больше символов, если сервер «не успевает»). Да, это может быть неоправданной тратой ресурсов в данном случае и можно всё сделать через вебсокеты, но в плане реализации моя схема намного проще :).
Чтение пользовательского ввода и исполнение команд
Читаем пользовательский ввод из нашего FIFO-файла, вывод нашей команды из соответствующего пайпа, всё в неблокирующем режиме, для простоты. Также, в качестве небольшого костыля, заменяем "\n" на "\r\n", так как на самом деле, term.js обрабатывает вывод драйвера последовательного порта, а не «сырой» вывод программы ;).
\n"; flush(); while (!feof($pipes[1])) < $ln = fgets($pipes[1], 4096); if ($ln !== false) < $ln = str_replace("\n", "\r\n", $ln); echo ''; flush(); continue; > $inp_ln = fgets($cmdfp, 4096); if ($inp_ln !== false) < // ensure that command is fully written by setting blocking to 1 stream_set_blocking($pipes[0], 1); fwrite($pipes[0], $inp_ln); stream_set_blocking($pipes[0], 0); >usleep(20000); > proc_close($pp); ?>
Очищаем прием команд после выхода
После того, как процесс завершился (например человек нажал Ctrl+D или ввел «exit»), нужно перестать отправлять пользовательский ввод на сервер, ибо принимать его всё равно больше некому :).