You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
222 lines
11 KiB
222 lines
11 KiB
<style>
|
|
code i {
|
|
color: blue;
|
|
font-style: normal;
|
|
font-weight: bold;
|
|
}
|
|
|
|
p code {
|
|
padding: 0;
|
|
margin: 2px;
|
|
}
|
|
</style>
|
|
|
|
<h1>Web App Security</h1>
|
|
|
|
<p>Welkom bij de cursus Web Application Security! Deze cursus gaan we ons richten op het hacken van websites. En met die zin
|
|
komen we meteen bij een gouden regel:</p>
|
|
|
|
<blockquote>Het hacken van websites zonder toestemming is
|
|
<strong>niet</strong> toegestaan</blockquote>
|
|
|
|
<p>Om de opdrachten te kunnen maken krijg je toestemming om de websites in de VM te mogen hacken ;). We gaan in verschillende
|
|
manieren bekijken om in te breken op een website. Aan jullie de taak om die tijdens de workshop in de praktijk te brengen</p>
|
|
|
|
<img src="/static/img/security_banner.jpg" style="width: 50%" class="center-block">
|
|
|
|
<h1>SQL injection</h1>
|
|
|
|
<p>We beginnen bij één van de meest veelvoorkomende beveiligingslekken die er bij webapplicaties voorkomen. Dagelijks nog zijn
|
|
er
|
|
<a href="https://www.google.nl/webhp?#safe=off&tbm=nws&q=sql+injection" target="_blank">nieuwsberichten</a> van websites die hun code niet goed op orde hebben en kwetsbaar zijn tegen deze aanval. Deze week gaan
|
|
we kijken hoe deze aanval werkt en hoe je er tegen kunt beveiligen.</p>
|
|
|
|
<p>In bijna alle webapplicatie projecten heb je te maken met een database waar je mee communiceert via SQL. Een typische query
|
|
die wordt uitgevoerd is bijvoorbeeld deze:</p>
|
|
|
|
<code>SELECT * FROM leden WHERE naam='<i>paul</i>' AND heeftbetaald='ja'</code>
|
|
|
|
<p>Waarbij het blauwe gedeelte invoer is uit bijvoorbeeld een GET parameter ('?naam=paul'). Er lijkt niks aan de hand, maar
|
|
als we de invoer niet zorgvuldig filteren geven de gebruiker de kans om de query op onbedoelde manier te veranderen.</p>
|
|
|
|
<h5>Commentaar</h5>
|
|
<p>Met
|
|
<code>-- </code> (streepje, streepje, spatie) is het in SQL mogelijk om commentaar te zetten in je query, hetzelfde wat je in PHP met
|
|
<code>//</code> zou doen. Met een slim gekozen invoer kunnen we de query er zo uit laten zien:</p>
|
|
|
|
<code>SELECT * FROM leden WHERE naam='<i>paul' -- </i>' AND heeftbetaald='ja'</code>
|
|
|
|
<p>De database voert de query uit, maar niet zoals de gebruiker hem heeft bedoeld: alles achter de -- wordt genegeerd als commentaar.
|
|
De query zal dus ook rijen teruggeven waar
|
|
<i>heeftbetaald</i> niet op 'ja' staat, wat afhankelijk van de code van de website kan betekenen dat we gratis dingen kunnen
|
|
kopen :)</p>
|
|
|
|
<h5>AND, OR</h5>
|
|
|
|
<p>Een andere manier om queries te veranderen is om nieuwe logica (AND, OR) te injecteren in de SQL. We kunnen bijvoorbeeld
|
|
de volgende query maken met de juiste invoer:</p>
|
|
|
|
<code>SELECT * FROM leden WHERE naam='<i>paul' OR 'bla'='</i>' AND heeftbetaald='ja'</code>
|
|
|
|
<p>Deze query maakt weer het
|
|
<i>heeftbetaald='ja'</i> gedeelte nutteloos. Als de naam al overeenkomt maakt het niet uit wat er achter de OR staat, het
|
|
resultaat is altijd true (de haakjes worden als volgt geplaatst:
|
|
<code>. OR ( . AND . )</code>).</p>
|
|
|
|
<h5>Meerdere queries</h5>
|
|
<p>Eén van de meest gevaarlijke is als het mogelijk is om compleet nieuwe queries uit te kunnen voeren op de database. Bedenk
|
|
eens wat er gebeurt als de gebruiker deze invoer geeft:</p>
|
|
|
|
<code>SELECT naam FROM leden WHERE id=<i>0; DROP TABLE leden;</i></code>
|
|
|
|
<p>Met
|
|
<code>;</code> geven we aan dat we een nieuwe query beginnen, waarna we vervolgens vrij zijn om elke query uit te voeren die we maar
|
|
willen. Let wel dat het uitvoeren van meerdere queries met bijvoorbeeld mysqli_query() iets is wat standaard uit staat.
|
|
Deze techniek is extra gevaarlijk omdat deze immuun is tegen escapen als het invoer is die niet tussen quotejes staat.</p>
|
|
|
|
<h5>UNION</h5>
|
|
|
|
<p>We kunnen met behulp van de
|
|
<a href="http://www.w3schools.com/sql/sql_union.asp" target="_blank">UNION</a> operator ook informatie halen uit andere tabellen in de database:</p>
|
|
|
|
<code>SELECT naam FROM leden WHERE id=<i>0 UNION SELECT wachtwoord FROM admins</i></code>
|
|
|
|
<p>De query haalt nu namen van leden op, samen met wachtwoorden uit de admins tabel. Belangrijk voor de UNION is dat beide queries
|
|
evenveel kolommen teruggeven.</p>
|
|
|
|
<img src="/static/img/shield.png" style="float: right">
|
|
<h4>Countermeasures</h4>
|
|
|
|
<p>Het is niet moeilijk om bovenstaande aanvallen te voorkomen. Met een paar simpele aanpassingen kan je ervoor zorgen dat je
|
|
SQL altijd wordt uitgevoerd zoals je die bedoeld hebt.</p>
|
|
|
|
<h5>Stored procedures</h5>
|
|
<p>Je slaat de SQL op als stored procedure in de database en roept deze aan vanuit je code. Omdat de SQL in de database staat
|
|
in plaats op de server is SQL injectie niet mogelijk</p>
|
|
|
|
<h5>Prepared statements</h5>
|
|
<p>Dit is de meest gebruikte en veilige manier. Met vraagtekentjes geef je aan op welke plekken de invoer moet komen en die
|
|
vul je dan later in. De SQL wordt altijd uitgevoerd zoals je hem bedoeld hebt. En ook hier is SQL injectie onmogelijk.
|
|
Lees
|
|
<a href="http://php.net/manual/en/mysqli.prepare.php" target="_blank">hier</a> verder</p>
|
|
|
|
<h5>Escaping</h5>
|
|
<p>Je kan ook alle invoer zelf escapen met functies zoals
|
|
<a href="http://php.net/manual/en/mysqli.real-escape-string.php" target="_blank">mysqli_real_escape_string()</a>. Zorg ervoor dat je dan consequent alle strings escaped met die functie en alle getallen
|
|
cast naar int's voordat je ze in je SQL plakt. Als je er ook maar eentje mist heb je al een SQL injection mogelijkheid
|
|
op je website!</p>
|
|
|
|
<p>Op
|
|
<a href="http://www.sqltutorial.nl/artikelen/sqlinjections/soorten_sql_injection.html" target="_blank">deze site</a> kan je het allemaal extra nalezen. Maar voor nu genoeg theorie, let's HACK!</p>
|
|
|
|
<img src="/static/img/sql_injectie.png" class="center-block">
|
|
|
|
<h2>Bank</h2>
|
|
<p>Bob is al jaren trouwe klant en gebruikt de site dagelijks om te kijken hoeveel geld er op zijn rekening staat. Achter op
|
|
zijn poespas pas heeft hij met een viltstift „Niet vergeten: Bob 123456” geschreven. Gebruik de site om te kijken hoeveel
|
|
geld Bob op zijn rekening heeft staan.</p>
|
|
|
|
<p>Alice is ook klant van de bank en wij willen ook graag weten hoeveel geld zij op haar rekening heeft staan. We gaan daarom
|
|
haar rekening hacken met behulp van SQL.</p>
|
|
|
|
<p>Ga nu aan de slag en hack het account van Alice! Gebruik hiervoor de bovenste link
|
|
<span class="website">"Bank"</span> op de startpagina van jouw virtuele machine.</p>
|
|
|
|
<p class="hint">
|
|
<strong>Hint 1:</strong> Kijk eerst eens wat er gebeurt als je inlogt met een enkele quote in de gebruikersnaam (').</p>
|
|
|
|
<p class="hint">
|
|
<strong>Hint 2:</strong> Met -- (twee streepjes gevolgd door een spatie) kan je commentaar achter een regel zetten in SQL.</p>
|
|
|
|
<p class="hint">
|
|
<strong>Hint 3:</strong> Bekijk de broncode achter de site:
|
|
<a href="https://git.paulwagener.nl/Paul/Security-VM/src/master/bank/index.php#L51" target="_blank">https://git.paulwagener.nl/Paul/Security-VM/src/master/bank/index.php#L51</a>
|
|
De code beschouwt een gebruiker als ingelogd als de query een rij uit de gebruikerstabel teruggeeft. Manipuleer de query
|
|
zodat deze de gegevens van Alice teruggeeft, zonder dat je het wachtwoord hoeft te weten.</p>
|
|
|
|
<img src="/static/img/poespas.png" style="width: 70%" class="center-block screenshot">
|
|
|
|
<div class="question">
|
|
<span class="question-string">Hoeveel geld heeft Alice op haar rekening staan?</span>
|
|
</div>
|
|
|
|
<p>Waarschijnlijk heb je SQL commentaar (--) gebruikt in de vorige opdracht. Voer nu een andere SQL injectie uit door alleen
|
|
het wachtwoord veld te gebruiken. Gebruik niet de SQL commentaar techniek maar verander nu de logica van de query (AND,
|
|
OR) zodat er niet meer gecontroleerd wordt op het wachtwoord.</p>
|
|
|
|
<div class="question">
|
|
<span class="question-string">Met welk 'wachtwoord' lukt het altijd om in te loggen? (gebruikersnaam moet je leeglaten)</span>
|
|
</div>
|
|
|
|
<p class="hint">
|
|
<strong>Hint:</strong> Maak er een query van die alle gebruikers teruggeeft, de site logt dan in als de eerste gebruiker.</p>
|
|
|
|
<div class="question">
|
|
<span class="question-string">Bekijk de
|
|
<a href="https://git.paulwagener.nl/Paul/Security-VM/src/master/bank/index.php#L51" target="_blank">PHP broncode</a> en los het probleem op.</span>
|
|
</div>
|
|
|
|
<p>Open de
|
|
<span class="website">"Bank (multi_query)"</span> pagina. Op deze pagina werken ook SQL Injection technieken die gebruik maken van meerdere queries
|
|
(queries gescheiden door een ; ).</p>
|
|
|
|
<div class="question">
|
|
<span class="question-string">Met welke
|
|
<i>"gebruikersnaam"</i> kan je (alleen) Bob miljonair maken? (Het saldo staat in een kolom "balans")</span>
|
|
</div>
|
|
|
|
<img src="/static/img/bank_schema.png">
|
|
|
|
<h2>Webshop</h2>
|
|
|
|
<p>Inloggen in een ander account is leuk. Maar echte hackers stelen kostbare data uit een website. Dat gaan we nu doen met de
|
|
webshop van Leaky's. Gebruik hiervoor de link
|
|
<span class="website">"Webshop"</span> op de startpagina van jouw virtuele machine.</p>
|
|
|
|
<p>Je kan de broncode vinden op:
|
|
<a href="https://git.paulwagener.nl/Paul/Security-VM/src/master/webshop/product_detail.php#L62" target="_blank">https://git.paulwagener.nl/Paul/Security-VM/src/master/webshop/product_detail.php#L62</a>
|
|
</p>
|
|
|
|
<p>Zoals je ziet hebben ze hier gebruik gemaakt van mysqli::real_escape_string(). Je kan dus geen gebruik meer maken van rare
|
|
quotejes om de query aan te passen.</p>
|
|
|
|
<p>Maar met behulp van de UNION techniek kunnen we alsnog data stelen uit de website.</p>
|
|
|
|
<p>In de database is er nog een tabel "gebruikers" waar gebruikersnamen en wachtwoorden in staan. Steel deze informatie uit
|
|
de database!</p>
|
|
|
|
<p class="hint">
|
|
<strong>Hint:</strong> Verander het cijfer in de url van de product_details.php pagina in de letter 'a' zodat je de query kan lezen.
|
|
</p>
|
|
|
|
<img src="/static/img/webshop_schema.png">
|
|
|
|
<div class="question">
|
|
<span class="question-string">Wat zijn de gebruikersnamen en wachtwoorden van de 4 gebruikers in de database? (de id's van de gebruikers zijn 1,2,3 en
|
|
4)
|
|
</span>
|
|
</div>
|
|
|
|
<div class="question">
|
|
<span class="question-string">Bekijk de
|
|
<a href="https://git.paulwagener.nl/Paul/Security-VM/src/master/webshop/product_detail.php#L62" target="_blank">broncode</a> en verbeter deze zodat je geen SQL injection meer kan gebruiken.</span>
|
|
</div>
|
|
|
|
<p>Open de pagina
|
|
<span class="website">"Webshop (replace)"</span>. De maker van deze website heeft extra maatregelen genomen en woorden als SELECT en UNION uit
|
|
de invoer gefilterd.</p>
|
|
|
|
<p class="hint">
|
|
<strong>Hint:</strong> SELSELECTECT</p>
|
|
|
|
<div class="question">
|
|
<span class="question-string">Met welke URL kan je nu het wachtwoord van Marco achterhalen?</span>
|
|
</div>
|
|
|
|
<h2>Wereldwijs</h2>
|
|
|
|
<p>Ga in de VM naar de
|
|
<span class="website">"Wereldwijs"</span> pagina. Op deze pagina kunnen studenten op spelenderwijs leren over de wereld. Maar deze site heeft
|
|
een diep donker geheim die het niet toont aan de wereld, er is een geheime pagina met id 0.</p>
|
|
|
|
<p>Geen hints en geen broncode deze keer. Aan jullie de taak om de site te hacken (meerdere manieren mogelijk).</p> |