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.
		
		
		
		
		
			
		
			
				
					
					
						
							224 lines
						
					
					
						
							11 KiB
						
					
					
				
			
		
		
	
	
							224 lines
						
					
					
						
							11 KiB
						
					
					
				| {% extends 'base.html' %} {% block content %}
 | |
| <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>
 | |
| {% endblock %} |