Hacking 101 - Eerste stappen in hacken - SQL injectie

Door elhopo op woensdag 21 oktober 2020 16:57 - Reacties (18)
Categorieën: Hacking, OWASP, Views: 11.123

https://tweakers.net/fotoalbum/image/ERNvYKI3wiZFmU5yfSy6C1H7.png


Hallo en welkom bij deze serie waarin ik wat wil uitleggen over hacken. Hacken is een erg breed begrip, en in een serie als deze zal het niet mogelijk te zijn alle aspecten van hacken toe te lichten. Ik zal me in eerste instantie toeleggen op het hacken van websites en andere webapplicaties. Deze serie is bedoeld ter lering en vermaak, het is zeker niet de bedoeling om mensen aan te zetten tot hacken. Als je deze technieken toepast zonder toestemming zal je zeer waarschijnlijk gesnapt worden. Als dat gebeurt zal je vrijwel zeker ontslagen worden of je wordt strafrechtelijk vervolgd. Zeggen dat je security onderzoek doet werkt dan niet, want dat zeggen alle hackers.

De serie is in eerste instantie gebaseerd op de OWASP top 10. OWASP staat voor Open Web Application Security Project, dit is een organisatie die zich bezig houdt met het verbeteren van de beveiliging van software.
De OWASP Top 10 is een standaard lijst voor ontwikkelaars en webapplicatiebeveiliging. Hierin staan de meest de meest kritieke beveiligingsrisico's voor webapplicaties. Vrijwel alle berichten die je op het internet leest staan ook in deze lijst vermeld.

Zoals ik al eerder zei is hacken strafbaar. Daarom heeft de OWASP organisatie een opzettelijk slecht beveiligde applicatie gemaakt waarop je naar hartenlust kan hacken zonder dat dit gevolgen heeft. Je kan hier
https://owasp.org/www-project-juice-shop/
alles over deze applicatie vinden. Er zijn wat verschillende mogelijkheden om de applicatie te proberen, maar de makkelijkste is wel de online variant. Je kan gewoon naar
https://demo.owasp-juice.shop
gaan en daar er op los hacken.
https://tweakers.net/fotoalbum/image/FAQ79rGUR7oH8n3TCfdzBylz.jpg

In deze serie zal ik wat stap voor stap tutorials geven, uitleggen wat er gebeurt en waarom, en tot slot wat een ontwikkelaar zou kunnen doen om dit te voorkomen. Ik zal proberen alles wat laagdrempelig te houden, als het wel wat vlotter mag kwa tempo hoor ik het graag.
Op nummer 1 van de OWASP top 10 staat injectie. Daaronder valt SQL injectie, maar er zijn meer vormen van injectie. Hier zal ik SQL injectie gebruiken. SQL is een database taal. Met SQL kan je commando's aan de database geven, zoals : geef me alle users met de naam x. Stel je wil inloggen op een website met een username en een wachtwoord. Je kan dan deze SQL sturen:
select * from users where name = 'henk' and password = 'geheim'
De database geeft dan als het goed is 1 resultaat terug en je bent ingelogd. Als het fout is krijg je geen resultaat, de gebruiker bestaat niet, of het wachtwoord klopt niet. Hoe kan je dat dan in code doen? Vanuit het naam / wachtwoord scherm krijg je twee waardes. Een naam en een wachtwoord. Je kan dan deze code schrijven:
String sql = "select * from users where name = '" + naam + "' and password = '" + password + "'";
Dit werkt prima... Tot de gebruiker bijvoorbeeld Spring in 't veld heet. Dan staat in de bovenstaande code ineens een quote (') teveel. De database server geeft een rare fout en je applicatie is kaduuk. Dit kunnen we testen in de testapplicatie door op de knop account te klikken.

Laten we eens inloggen met Jan spring in 't veld. We krijgen nu een rare melding te zien. Dit komt omdat het bovenstaande SQL commando niet meer klopt. De naam van de user hoort tussen de quotes te staan, en de SQL woorden daarbuiten. Nu klopt die volgorde niet, en snapt de server het niet meer.
https://tweakers.net/fotoalbum/image/5Y1kn1dwjYXdoNSWrcTlifwE.jpg

Het is nu geworden:
select * from users where name = 'Jan spring in 't veld' and password = 'geheim'
Hoe zouden we hier nu als aanvaller gebruik van kunnen maken? We kunnen raden wat de naam van de administrator is, maar we kunnen ook gewoon de eerste gebruiker kunnen nemen die we tegen komen, grote kans dat dat de beheerder is. Hoe zou onze SQL er dan uit moeten zien? Dit zou een mooie zijn:
select * from users where name = '' OR 1=1 -- and password = 'geheim'
Wat gebeurt er nu? De database gaat op zoek naar een lege naam, kan die niet vinden, maar ziet dan : OR 1=1, wat voor alles klopt. Dan volgen twee minnetjes (--) wat in SQl taal commentaar betekent. Alles daarna wordt genegeerd, dus daar hebben we geen last van. We voeren dus bij de naam in:
' OR 1=1 --
en kijken wat er gebeurt...

https://tweakers.net/fotoalbum/image/dHH13rns4BBs851zsAmPPPXj.jpg

We're in!!!

Wat is er nu gebeurd? De volledige broncode is aanwezig, laten we eens kijken of onze veronderstellingen klopten:

models.sequelize.query(`SELECT * FROM Users WHERE email = '${req.body.email || ''}' AND password = '${insecurity.hash(req.body.password || '')}' AND deletedAt IS NULL`

Hmm, de SQL was net wat anders, maar dichtbij genoeg. Wat zou je nou als ontwikkelaar kunnen doen om dit te voorkomen? Nou, niet een enkele quote toestaan is natuurlijk een optie, maar dan kan je ook geen namen of wachtwoorden met een quote meer toelaten. Er zijn echter wel verschillende oplossingen. je kan alle quotes vervangen voor een ander teken. Als je dat doet bij het maken van de gebruiker en het testen van de gebruiker staat dezelfde naam uiteindelijk in de database. Een quote wordt dan bijvoorbeeld " (de html variant van een quote). Een tweede oplossing is het gebruiken van geparameteriseerde SQL. Hierbij is de SQL :
String sql = "select * from users where name = ? and password = ?";
Vervolgens geef je de losse parameters apart mee door. (iedere ? is een parameter) Parameter 1 is de user, 2 is het password.

je raad het al, de beste oplossing is beide gebruiken. Waarom? Omdat quotes nog andere nare dingen kunnen veroorzaken, daar komen we later nog op.

Je zal wel denken: Nou, dit is zo duidelijk, iedereen snapt dit toch? ja, maar helaas is dit één van de meest voorkomende aanvallen. Wel bijzonder aangezien dit ondertussen zo'n bekend probleem is...

Ik ben benieuwd of je dit interessant vond. Ik wil wel verder gaan met de serie, maar alleen als er voldoende animo voor is.

Volgende: Hacking 101 -deel 2, XSS 26-10 Hacking 101 -deel 2, XSS
Volgende: Webassembly, de toekomst van het web? 08-'18 Webassembly, de toekomst van het web?

Reacties


Door Tweakers user Creep, woensdag 21 oktober 2020 18:09

Erg leuk om op meer leken niveau te begrijpen wat er gebeurt. Ik kijk uit naar de volgende.

Door Tweakers user AW_Bos, woensdag 21 oktober 2020 23:51

"Geen wachtwoorden met een quote toelaten?"
Als je die netjes gehashed opslaat zou er geen single-quote in mogen voorkomen. Ik ken immers geen hashingalgoritme die een dergelijke quote gebruikt.

[Reactie gewijzigd op woensdag 21 oktober 2020 23:51]


Door Tweakers user elhopo, donderdag 22 oktober 2020 01:08

hallo @Creep, bedankt voor de reactie, de insteek is inderdaad om het toegankelijk te houden. Er komen nog veel lastige onderwerpen aan.

Hallo @AW_Bos, je hebt helemaal gelijk, een password moet je salted en hashed opslaan, maar voor het voorbeeld wat hier in de code staat gebeurt dat hier niet. Omdat het hier in het voorbeeld niet gebeurt heb ik het maar zo beschreven. Je kan nog verder gaan, zoals een password wat in plain text over de lijn gaat wat hier ook fout is, maar waar stopt het dan.
btw, ik heb IE van stal moeten halen om een reactie toe te voegen, in Chrome kan je gewoon niet op de Tweakers blogs reageren, zal wel iets met de cross site cookies te maken hebben.

Door Tweakers user MsG, donderdag 22 oktober 2020 12:21

Leuk en interessant hoe je hier stapsgewijs doorheen gaat. Ik zie uit naar de volgende sessie!

Door Tweakers user MsG, donderdag 22 oktober 2020 12:22

(zonder gedoe kunnen typen in Chrome trouwens)

Door Tweakers user Blokker_1999, donderdag 22 oktober 2020 15:36

MsG schreef op donderdag 22 oktober 2020 @ 12:22:
(zonder gedoe kunnen typen in Chrome trouwens)
Mjah, denk dat het probleem gezocht moet worden bij adblockers die mensen gebruiken. Het cookie staat namelijk op een ander subdomein. Firefox heeft er op zich ook geen probleem mee, al heb ik in Privacy Badger wel "tweakers.net" moeten goedkeuren.


Door Tweakers user Kraay89, vrijdag 23 oktober 2020 11:18

Wat een leuke en leerzame blog voor een nitwit (vwb hacking) zoals ik. Leuk! Ben benieuwd naar de volgende. Klein detail: de plaatjes worden aan mijn kant heel gek gecropped en de kwaliteit is dermate laag dat ik de kleinere teksten eigenlijk niet kan lezen. geen idee of dat aan jou ligt of het tweakblogsplatform though.

[Reactie gewijzigd op vrijdag 23 oktober 2020 11:19]


Door Tweakers user MdBruin, vrijdag 23 oktober 2020 12:41

Misschien handig om er een duidelijke disclaimer in te plaatsen voordat je start.
Iets in de trend van Hacken zonder toestemming is illegaal en kan zorgen voor vervolging. De gevolgen daarvan zijn voor eigen risico. Gebruik deze kennis alleen legaal en dus met toestemming, er zijn genoeg platforms (OWASP/hackthebox/tryhackme/bug bounty sites) om dit legaal te doen en/of leren.

Verder leuk dat je de kennis wilt delen, ik heb nog maar een klein stukje gelezen.

Door Tweakers user elhopo, vrijdag 23 oktober 2020 20:28

Bedankt allemaal voor de berichten! @MdBruin: ik dacht dat ik al een redelijk duidelijke disclaimer had neergezet, maar ik zal hem bij deel 2 nog wat duidelijker neerzetten.

Door Tweakers user MdBruin, zaterdag 24 oktober 2020 13:27

@elhopo, het gaat vooral om het stukje dat het voor eigen risico is en dat je dus de verantwoordelijkheid legt bij de persoon zelf.

Door Tweakers user SPee, zaterdag 24 oktober 2020 13:31

Wat zou je nou als ontwikkelaar kunnen doen om dit te voorkomen? Nou, niet een enkele quote toestaan is natuurlijk een optie, maar dan kan je ook geen namen of wachtwoorden met een quote meer toelaten. Er zijn echter wel verschillende oplossingen. je kan alle quotes vervangen voor een ander teken. Als je dat doet bij het maken van de gebruiker en het testen van de gebruiker staat dezelfde naam uiteindelijk in de database.
Je zal wel denken: Nou, dit is zo duidelijk, iedereen snapt dit toch? ja, maar helaas is dit één van de meest voorkomende aanvallen. Wel bijzonder aangezien dit ondertussen zo'n bekend probleem is...
Dit hoeft niet beperkt te zijn tot SQL of het quote teken. ;)
Ik had een nieuwe gebruiker en ww toegevoegd aan onze puppet code. (Puppet gebruiken we om onze systemen automatisch in te regelen.)
Ik had die ww netjes via een generator gemaakt en met de security key van die server ge-encrypt.
Encrypted, lang en random. Prima toch?
Kreeg ik een bericht van een boze beheerder dat het systeem fout ging omdat het ww begon met een # teken. :D :+

Door Tweakers user Sefa, zondag 25 oktober 2020 15:24

Heel leuk! Ik kijk nu al uit naar de volgende!

Door Tweakers user Neevusicus, maandag 26 oktober 2020 09:39

Zie graag meer! Leuk geschreven

Door Tweakers user parm, dinsdag 27 oktober 2020 18:22

leuke serie, ik volg mee!

Door Tweakers user elhopo, donderdag 29 oktober 2020 08:27

Het volgende deel staat inmiddels online!

Door Tweakers user sOid, donderdag 29 oktober 2020 20:21

Leuk om te lezen. Tweede deel intussen ook gelezen!

Paar vraagjes.
- Je maakt in beide delen gebruik van bestaande invulvelden. Zijn er ook manieren om de code te injecteren zónder deze bestaande velden?
- Je schrijft in dit deel na succesvol inloggen dat de volledige broncode nu aanwezig is. Maar als ik de broncode bekijk, zie ik jouw code (models.sequelize.query(`SE......) niet staan. Wat doe ik fout?

Door Tweakers user elhopo, vrijdag 30 oktober 2020 08:57

sOid schreef op donderdag 29 oktober 2020 @ 20:21:
Paar vraagjes.
- Je maakt in beide delen gebruik van bestaande invulvelden. Zijn er ook manieren om de code te injecteren zónder deze bestaande velden?
- Je schrijft in dit deel na succesvol inloggen dat de volledige broncode nu aanwezig is. Maar als ik de broncode bekijk, zie ik jouw code (models.sequelize.query(`SE......) niet staan. Wat doe ik fout?
Hi sOid,
Code injecteren zal je altijd ergens moeten doen waar er mogelijkheden zijn om die in te voeren. Soms is dat op een invoerveld, en soms op een API service die de applicatie beschikbaar stelt.

Vrijwel alle applicaties bestaan uit een frontend, die bij jou op je browser draait en een backend die op de server draait. De API's zijn dan in de backend en die worden aangeroepen door de browser. Soms gebeurt het dat er extra velden worden meegestuurd vanaf de frontend, via zo'n API Zulke velden zou je dan ook kunnen gebruiken. Verder zijn er nog andere aanvalsmethoden die geen injectie gebruiken, zoals op zoek gaan naar log bestanden.

De code die ik bedoel staat op de Github pagina van het project. Hier staat de broncode, die je kan gebruiken om te onderzoeken wat er onder water precies gebeurt. Je kan de volledige broncode hier vinden:
https://github.com/bkimminich/juice-shop

Reageren is niet meer mogelijk