Avatar billede danm Nybegynder
28. februar 2010 - 22:14 Der er 14 kommentarer og
1 løsning

Hacket... Er Sessions ikke sikre nok til logind?

Har nu oplevet at blive hacket igen.. Eller nærmere er der blevet logget ind på en side, og så ændret i teksten, hvilket man kan gøre fra den her admin side jeg har lavet...

Jeg har dog samtidig lavet login siden sådan, at hver gange en logger ind, gemmes det i databasen. Det samme med fejllogins (for at undgå at trykke kode forkert mere end 3 gange).
Det er så her jeg kan se der er logget ind fra Tunesien, uden nogen forkert indtastet kode...

For at det skal se fint ud har jeg lavet admin siden sådan at index siden kører et Ajax script der tjekker koden på en PHP side. Og hvis koden er rigtig, sættes en session variabel til bruger id'et.

Hver eneste side på admin siden kører så et tjek om denne session er sat (med !isset($_SESSION["aid"]) )

Men er det en sikker nok metode?

Jeg sørger for at køre mysql_real_escape_string på alle inputs, for at undgå mysql injections...

Nogen ide til hvad der kunne være gået galt her?
Avatar billede Slettet bruger
28. februar 2010 - 22:20 #1
Hverken session hijacking eller session injection lyder sandsynligt i det her tilfælde, så det er nok en sårbarhed i dit script.
Det er næppe muligt at sige hvad det er uden noget kode.
Avatar billede superdreng Nybegynder
28. februar 2010 - 22:21 #2
Den er svær, ville umiddelbart sige at sessions er rimelig sikre, så tror problemmet ligger et andet sted på din side.
Avatar billede danm Nybegynder
28. februar 2010 - 22:27 #3
Ok, smider lige noget kode.

Først mit db_safe script tilat undgå mysql injections, som jeg engang læste mig til:

function db_safe($value) {
  if (get_magic_quotes_gpc()) {
    $value = stripslashes($value);
  }
  return mysql_real_escape_string($value);
}

Så mit login script der sætter admin session og returner til index siden om det er ok (ved at returnere "1"):

<?php session_start();
if($_GET["email"] == "" | $_GET["password"] == "") {echo "0"; exit ;}
include("db_connect.php");
$sql = mysql_query("Select count(id) from error_login where ip='".$_SERVER['REMOTE_ADDR']."' and date>'".date("Y-m-d H:i:s",time()-3600)."'");
$data = mysql_fetch_array($sql);
if($data[0] > 2) {
  echo "3";
} else {
  $sql = mysql_query("Select id from admin_users where user_name='".db_safe($_GET["email"])."' and password='".db_safe($_GET["password"])."'") ;
  if($data = mysql_fetch_array($sql)) {
    $_SESSION["admin_id"] = $data[0] ;
    mysql_query("Insert into user_logins (user_id,ip,logdate) values (".$data[0].",'".$_SERVER['REMOTE_ADDR']."',now())") ;
    echo "1";
  } else {
    mysql_query("Insert into error_login (ip,date) values ('".$_SERVER['REMOTE_ADDR']."',now())");
    echo "2";
  }
}
?>
Avatar billede danm Nybegynder
28. februar 2010 - 22:29 #4
Og hvis den returnere 3, siger index siden at der er indtaset kode forkert 3 gange. Returnerer den 2, er koden forkert. Returneres 0 sker der ingenting (Javascript skulle gerne sige at man mangler at indtaste email eller kode).
Avatar billede danm Nybegynder
28. februar 2010 - 22:54 #5
Ok, ved at kigge i logfilen fra Apache, har jeg fundet en "ny" form for mysql injection jeg slet ikke havde tænkt på (dumme mig... Men man lærer af sine fejl)..

Siderne udenfor admin kan hedde foreksempel: page.php?id=23

Og ved id har kloge jeg selvfølgelig ikke tjekket efter om det er tal eller mysql kode.. Han har så kunnet få tabel oplysninger ud samt kodeord på den måde...

Altid noget at han ikke har slettet hele databasen..
Avatar billede Slettet bruger
28. februar 2010 - 23:08 #6
Jamen, så kan vi vel godt lukke, eller skal vi kigge på mere?
Avatar billede danm Nybegynder
28. februar 2010 - 23:14 #7
Men forstår stadig ikke at man fra den bruger der er lavet til at connecte med kan få tabelnavne ud...

Jeg kan se en masse GET i form af:

page.php?id=2+and+1=0+%20Union%20Select%20%20%20UNHEX(HEX(concat(0x5B6B65795D,schema_name,0x5B6B65795D)))%20%20+FROM+INFORMATION_SCHEMA.schemata+LIMIT%202,1

Og så den sidste hvor tabellerne bliver blottet, for derefter ser det ud til han kender tabelnavnene:

page.php?id=2+and+1=0+%20Union%20Select%20%20%20UNHEX(HEX(concat(0x5B6B65795D,column_name,0x5B6B65795D)))%20%20+FROM+INFORMATION_SCHEMA.columns+where+table_name=Concat(char(97),char(100),char(109),char(105),char(110),char(95),char(117),char(115),char(101),char(114),char(115))+LIMIT%203,1

Brugeren er ellers sat til kun at have Select, update, delete og insert privilegier.. Men det gælder måske også til at spørge til tabelnavne så?
Avatar billede Slettet bruger
28. februar 2010 - 23:44 #8
MySQL gemmer i databasen information_schema en masse informationer om alle databaser og tabeller på serveren, inklusiv navne og felter.
Kommandoen union bruges til at sætte to select-statements sammen, og da du slet ikke escaper id'et, er det let blot at hente tabelnavne i stedet for brugerdetaljer.
Dette undgås lettest ved ikke at give MySQL-brugeren adgang til databaser, som den ikke skal bruge.
Avatar billede danm Nybegynder
01. marts 2010 - 00:05 #9
Jacob, selve brugeren er oprettet til kun at havde de fire privileger på denne ene database. Der er ingen globale privilegier sat til denne bruger.

Kan man alligevel læse fra information_schema så?

Det hele er lavet gennem phpmyadmin, ved ikke om den laver noget specielt med information_schema når jeg opretter en bruger.

Ellers skal dette vel fjernes derfra for denne bruger på en eller anden måde. Eller er information_schema lavet sådan at det kun er den database som brugeren har adgang til, han kan se i dette dataset?
Avatar billede Slettet bruger
01. marts 2010 - 00:12 #10
I information_schema kan ses information om alle de databaser brugeren har rettigheder til at se. Ergo må du bare sikre dig mod SQL injections.
Avatar billede danm Nybegynder
01. marts 2010 - 00:51 #11
Ok, så når brugeren kun har adgang til denne ene database, kan jeg være lidt mere sikker på at han ikke har opsnappet andre databasers oplysninger?

Men ja, det var alligevel en tåbelig en fra min side.. Det hele bunder ud i en select sætning der henter sidens templateid for at tilføje til en include sætning (de har tal fra 1 til 10)..

Her smider han så bare en union på der henter tabel oplysninger også, og php smider så en warning med include sætningens fejl, og dermed også det hentede navn, da den skriver hvilken fil den ikke kan finde..

Den havde jeg ikke lige gennemtænkt, men utroligt at han kunne finde den side og prøve dette.. Kan se fra loggen han ikke kigger meget rundt før han går igang..

Men fejlen er ihvertfald rettet nu!

Tak for info Jacob, smider du lige et svar så jeg kan lukke
Avatar billede Slettet bruger
01. marts 2010 - 09:22 #12
Og her får vi så to fejl mere at se:
1.Slå altid error reporting fra i PHP på en produktionsserver. Brug i stedet error logging til at se hvad der er galt.
2. Brug aldrig ikke-escapet input til includes, hverken fra bruger eller database. Havde crackeren været rigtig ondsindet, havde han indsat stien til et ond script i din database, inkluderet det og slettet hele siden, eller værre.
Avatar billede danm Nybegynder
01. marts 2010 - 14:10 #13
Yes, har da lært lidt af denne hacker :-)

Error logging, er det noget PHP skriver et andet sted, eller mener at jeg selv skal smide det ind i for eksempel en database med scripts?
Avatar billede Slettet bruger
01. marts 2010 - 17:05 #14
Begge muligheder er åbne. Normalt er error logging til en fil lettest (og så bliver loggen heller ikke slettet næste gang du dummer dig :P)
PHP har en længere side om det, men det indstilles let med disse tre variabler:

ini_set('display_errors', 'Off')

ini_set('log_errors', 'On')

ini_set('error_log', '/error/logging/')

Vil du logge med MySQL er denne funktion sikkert brugbar for dig:

set_error_handler('mysql_logging_funktion')
Avatar billede danm Nybegynder
02. marts 2010 - 12:21 #15
Cool.. Jeg siger ihvertfald tak for hjælpen!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester