V1s3r1on

OSCP/OSWE/Penetration tester/Hobbyist/CTF speler

Coding tip 2

Vandaag ga ik wederom een stuk code beschrijven en wat er precies fout aan is.

package com.poll.repositories;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;

public class PollRepositoryImpl implements PollRepositoryCustom {

	@PersistenceContext
	private EntityManager entityManager;

	@Override
	@Transactional
	public int updatePoll(
			String id,
			String adminToken,
			String title,
			String description) {
		StringBuilder queryBuilder = new StringBuilder();
		queryBuilder
			.append("update Poll p set p.title = '").append(title)
			.append("', p.description = '").append(description)
			.append("' where p.admin_token = '").append(adminToken)
			.append("' and ").append("p.id = '").append(id).append("'");
		Query query = entityManager.createNativeQuery(queryBuilder.toString());
		return query.executeUpdate();
	}
}

Bovenstaande code bevat een fout in de code, het heeft te maken met SQL injectie.

SQL Injectie

Wat is nou precies een SQL injectie, een SQL injectie is het misbruiken van de code op zo een manier waardoor de query op de achtergrond niet doet wat het zou moeten doen.

Stel je voor je hebt de volgende query

SELECT * from users where username = 'admin' and password = $password

Bovenstaande query kan heel makkelijk worden omzeild, we hebben een inlog pagina en op deze inlog pagina voeren wij een gebruikersnaam en een wachtwoord in.

Als gebruikersnaam voeren wij het volgende in:

a' or '1'='1

Wij maken gebruik van (a’ or ‘1’=’1) omdat we nu dus zeggen van gebruiker a of 1 is gelijk aan 1. Nou er is geen gebruiker a maar 1 is altijd gelijk aan 1 dus dit resulteert in true. Hierdoor zal de query toch uitgevoerd worden, hij pakt uiteindelijk de eerste resultaat in de lijst uit de database. Wat meestal (Niet altijd) admin is.

De (limit 1 – -) die word toegevoegd zorgt ervoor dat er maar 1 resultaat word gepakt uit de database en de (- -) zoals later word uitgelegd zorgt ervoor dat de rest commentaar word en dus niet uitgevoerd zal worden.

De query ziet er dus als volgt uit nu:

SELECT * from users where username ='a' or '1'='1' and password $password

Dit ziet er veelbelovend uit maar zal nog steeds niet werken want het wachtwoord weten wij niet dus dit moeten wij zien te omzeilen. We voeren het volgende in:

a' or '1'='1' limit 1-- -

Nu ziet de query er als volgt uit:

SELECT * from users where username ='a' or '1'='1' limit 1-- -

Je ziet nu dus dat na de – – de rest word weggehaald, dit komt omdat – – als commentaar word gezien en die de rest niet zal uitvoeren. Dit is ook verschillend per database natuurlijk.

Dit is even kort beschreven hoe een sql injectie precies werkt en wat het kan doen.

De code

Even terug naar de code

package com.poll.repositories;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;

public class PollRepositoryImpl implements PollRepositoryCustom {

	@PersistenceContext
	private EntityManager entityManager;

	@Override
	@Transactional
	public int updatePoll(
			String id,
			String adminToken,
			String title,
			String description) {
		StringBuilder queryBuilder = new StringBuilder();
		queryBuilder
			.append("update Poll p set p.title = '").append(title)
			.append("', p.description = '").append(description)
			.append("' where p.admin_token = '").append(adminToken)
			.append("' and ").append("p.id = '").append(id).append("'");
		Query query = entityManager.createNativeQuery(queryBuilder.toString());
		return query.executeUpdate();
	}

Weten jullie al wat er fout is hier?

Kijk goed naar hoe de sql query precies eruit ziet en hoe jij deze kan misbruiken in dit geval. Je ziet dat de variable (title) word gebruikt om de query verder aan te vullen.

Dit betekend dat de waarde die wij meegeven in de title variable ook mee word gegeven in de query. Dit geld ook voor de overige queries want die doen precies hetzelfde in dit geval.

De code zou goed zijn als er gebruik word gemaakt van parameterized queries.

Parameterized queries

Een parameterized query of ook wel prepared statement genoemd is niks minder dan een query die word uitgevoerd maar waarbij er geen variable word meegegeven. Ieder geval niet op de manier die hierboven is gebruikt.

Een voorbeeld:

String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";

Je ziet hierboven een vraagteken in plaats van een hardcode variable naam of een waarde, dit word bedoeld met een prepared statement. Hierdoor ziet de database de vraagteken als een string en word het ook als een string uitgevoerd.

In het geval dat hierboven eerder is uitgelegd zal dus het volgende niet werken:

a' or '1'='1' limit 1-- -

Waarom werkt dit dan niet?

Nou, omdat dit nu als een gehele string word gezien en dus niet word gezien als aparte instructies die hij zal gaan uitvoeren. Hij ziet het als 1 geheel en als een string.

Dus als volgt:

"a' or '1'='1' limit 1-- -"

Dit zal natuurlijk niet werken in een sql injectie.

Tot slot

Het gedeelte wat dus fout was in de voorbeeld code aan het begin van dit artikel is dus als volgt:

Bedankt en tot volgende week!

https://media.tenor.com/images/b81897d2751c550b3e5ff7ba59cb2a18/tenor.gif
Please share and spread
5 1 stem
Artikelbeoordeling
Previous Article
Abonneer
Laat het weten als er
guest
0 Reacties
Inline feedbacks
Bekijk alle reacties
NederlandsEnglish
0
Zou graag je gedachten willen weten, s.v.p. laat een reactie achter.x
()
x