SQL Injection¶
Een van de oudste truken uit het boek om programma's die een database te gebruiken te kraken is SQL Injection. Door het plakken van SQL code in tekstvelden kan je zonder de juiste rechten toch zaken aanpassen in een programma of website. Zo kan je jezelf inloggen, gegevens aanpassen, toevoegen of zelfs verwijderen. Ondertussen is veel software hiertegen beveiligd, maar toch blijft er af en toe software opduiken die voor SQL injection vatbaar zijn.
Voor dit programma gebruiken we sql-injection-tester
. Je kan het .jar-bestand hier downloaden.
PowerShell | |
---|---|
Deze versie wordt hier verder beschreven.
Inloggen zonder account (inbreuk op confidentiality)¶
Het programma toont een login. Het doel is om in te loggen zonder dat je het wachtwoord weet. Om dit te doen gebruiken we SQL injection codes. Je hebt nog geen ervaring met de SQL-programmeertaal (dat is voor het vak Databases), je moet deze dus ook nog niet begrijpen. Je vindt veel voorbeelden op het internet als je zoekt op SQL injection examples
. Je zoekt naar SQL injection codes die als volgt zijn opgesteld (let goed op de apostrof en 2 mintekens):
SQL | |
---|---|
Je kan dergelijke codes op verschillende manieren gebruiken:
-
Je weet de gebruikersnaam van de gebruiker (
Joeri
): welke code kan je ingeven in het wachtwoord-veld om in te loggen? -
Je weet zelfs de gebruikersnaam niet: welke code kan je gebruiken in het gebruikersnaam-veld? Moet je dan nog iets invullen in het wachtwoord-veld? Er zijn codes die gebruik maken van slechts 1 van de 2 of waarvoor er in beide velden iets ingevuld moet worden.
Onderaan het programma zie je de inhoud van de databank. Een echt programma of website zal deze uiteraard nooit tonen. De databank past zich automatisch aan als er iets veranderd. Om het programma terug te herstellen naar oorspronkelijke waarden sluit je het af en start je het opnieuw op.
Een account toevoegen (inbreuk op integrity)¶
Met de juiste SQL injection code kan je zelfs een account toevoegen. Zoek hiervoor SQL injection codes op die het woord INSERT
bevatten. Een tip: de databank noemt accounts
(Users
in de Windows-only versie) en bevat de kolommen username
(gebruikersnaam) en password
.
Als je de code ingeeft, krijg je de foutmelding dat er een foute gebruikersnaam en/of wachtwoord is ingegeven. Ook al heb je deze foutmelding, je merkt dat de door jou geïnjecteerde gebruikersnaam en wachtwoord nu wel zijn opgenomen in de databank. Je kan je nu met de door jou geïnjecteerde gebruikersnaam en wachtwoord inloggen.
De databank verwijderen (inbreuk op availability)¶
Je kan grote schade aanrichten met door met SQL injection code de databank te verwijderen. Eenmaal de databank verwijderd is, kan er namelijk niemand meer inloggen. Zoek hiervoor SQL injection codes op die het woord DROP
bevatten. Zie hiervoor ook de tip bij het stuk Een account toevoegen
. Bij het verwijderen van de databank zal er een foutmelding getoond woord: je drukt immers op inloggen, maar de databank is zojuist door jouw code geleegd, vandaar de foutmelding.
Hulp nodig?¶
Beide programma's hebben een hulp functie, je kan daar enkele voorbeeldcodes vinden. Natuurlijk zijn er talloze varianten op deze codes. Ook kan je nog veel meer doen met SQL injection dan hier beschreven. Zoek gerust codes op meer informatie uit de databank te sleuren.
Enkele hulpbronnen:
- https://github.com/payloadbox/sql-injection-payload-list
- https://www.openbugbounty.org/blog/ismailtsdln/sql-injection-payload-list/
- http://www.unixwiz.net/techtips/sql-injection.html
- https://www.softwaretestinghelp.com/sql-injection-how-to-test-application-for-sql-injection-attacks/
- https://pentest-tools.com/blog/sql-injection-attacks/ (geavanceerd)
Hoe werkt dit?¶
Om te begrijpen hoe dit werkt is er kennis nodig van de programmeertalen die de applicatie en de databank daarachter gebruiken. De applicatie is geschreven in Java, instructies voor de databanken worden geschreven in SQL (dit leer je bij het vak Databases).
De applicatie vraagt aan de databank of het account met een bepaalde gebruikersnaam en wachtwoord bestaat met behulp van de volgende SQL query (vraag aan de databank):
SQL | |
---|---|
De applicatie leest de waarden voor gebruikersnaam en wachtwoord in via de tekstvelden. Het plakt deze dan via de string +
operatie aan elkaar (concatenation). De fout is dat de applicatie de inhoud van de tekstvelden niet controleert. Alles wat de gebruiker typt in de tekstvelden wordt zonder controle of aanpassing in de SQL query. Indien de gebruiker SQL code typt, zal deze ook worden ingevoegd in de SQL query en kan deze zo aangepast worden.
De SQL query vraagt een lijst op van alle gebruikers waarbij de gebruikersnaam en wachtwoord overeenkomen met wat in de tekstvelden is getypt. Vergelijkbaar met if (username == 'gebruikersnaam' && password == 'password')
in Java. Door de juiste SQL code in de tekstvelden te plaatsen, kan deze query aangepast worden zodat die vereiste niet meer wordt gecontroleert maar altijd true teruggeeft. Er wordt dan dus geen controle meer gedaan op gebruikersnaam en wachtwoord.
Bijvoorbeeld, om in te loggen zonder wachtwoord:
-
Gebruikersnaam:
SQL -
Passwoord: leeg of random
De SQL query wordt dan:
SQL | |
---|---|
De SQL query zoekt nu alle accounts waar de gebruikersnaam leeg is of waarbij 1 gelijk is aan 1 (wat altijd waar is). Vergelijkbaar met if (username == '' || 1 == 1)
in Java. Dit geeft altijd true
terug en dus steeds toegang tot de databank. Alles na de --
wordt genegeerd aangezien 2 koppeltekens in SQL betekent dat de rest van de lijn overeenkomt met comments (analoog aan //
in Java). ' AND password = 'leeg of random';
wordt dus beschouwd als commentaar en genegeerd door SQL.
Valideer dus steeds telkens alle input van de gebruiker: alles wat de gebruiker kan ingeven is mogelijks een kwetsbaarheid!