Lopjunk sütit a böngészőtől

Egy .NET-es alkalmazásból a WebRequest osztály segítségével bármikor indíthatunk HTTP kéréseket egy weboldal felé. Ha a weboldal bejelentkezést igényel, akkor a webalkalmazás a szokásos módon cookie-k segítségével fogja megoldani az állapotkezelést, és a kliensre hárul a feladat, hogy a cookie-t minden kérésnél visszaküldje a szerverre. Ha a felhasználó böngészőből és a kliens alkalmazásból is eléri az alkalmazást, akkor sajnos kétszer kell bejelentkeznie, amire csak az lehet a megoldás, ha képesek vagyunk a böngésző által eltárolt sütit megszerezni.

Firefox böngésző esetén szerencsénk van, a perzisztens sütik egy cookies.sqlite fájlban tárolódnak, csak éppen a könyvtár kiderítése problémás. Az biztos, hogy a C:UsersfelhasználónévAppDataRoamingMozillaFirefoxProfiles mappa valamelyik almappájában van, az alábbi függvény visszaadja, hogy pontosan hol:

  private static string GetCookiePath()
  {
    string appDataPath = Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData );
    string profilesPath = Path.Combine( appDataPath, @"MozillaFirefoxProfiles" );

    DirectoryInfo di = new DirectoryInfo( profilesPath );
    DirectoryInfo[] dir = di.GetDirectories( "*.default" );
    if( dir.Length != 1 )
    {
        return String.Empty;
    }

    string cookiePath = Path.Combine( profilesPath, dir[ 0 ].Name + @"" + "cookies.sqlite" );

    if( !File.Exists( cookiePath ) )
    {
        return String.Empty;
    }

    return cookiePath;
  }

A cookie-kat tartalmazó fájl szerencsére strukturált, konkrétan egy SQLite adatbázisról van szó, amihez szerencsére van szabadon letölthető managed provider. Miután referenciát adtunk a System.Data.SQLite.dll szerelvényre, a szokásos connection és command osztályokon keresztül érhetjük el az adatokat. A sütik a moz_cookies táblában vannak, ami name, path, host és value oszlopokat tartalmaz. Arra kell csak figyelni, hogy a host mező “www.” előtag nélküli domain neveket tartalmaz.

A WebRequest osztálynak egy CookieContainer példányt kell átadni, az alábbi függvény kiolvassa az adatbázisból a paraméterként megadott hoszt névhez tartozó sütiket és egy CookieContainer példányba csomagolva adja vissza:

  public static CookieContainer GetCookieContainer( string url )
  {
    Uri uri = new Uri( url );
    string host = uri.Host.Replace( "www.", "" );

    CookieContainer container = new CookieContainer();

    using( SQLiteConnection conn = new SQLiteConnection( "Data Source=" + FirefoxHelper.GetCookiePath() ) )
    {
        using( SQLiteCommand cmd = conn.CreateCommand() )
        {
            cmd.CommandText = "select * from moz_cookies where host like '%" + host + "%';";
            conn.Open();
            using( SQLiteDataReader reader = cmd.ExecuteReader() )
            {
                while( reader.Read() )
                {
                    container.Add( new Cookie( reader[ "name" ].ToString(), reader[ "value" ].ToString(),
                                               reader[ "path" ].ToString(), reader[ "host" ].ToString() ) );
                }
            }
        }
    }

    return container;
  }

Persze ha csak egyetlen süti értékére vagyunk kíváncsiak, akkor a domain név és a süti nevének ismeretében azt is megtudhatjuk:

  container.GetCookies( new Uri( url ) )[ cookieName ].Value;

Internet Explorer esetén a Wininet API-n keresztül tudjuk kiolvasni a böngésző által tárolt sütiket. Az InternetGetCookie helyett célszerűbb az újabb operációs rendszert igénylő InternetGetCookieEx függvény használata, mert azzal konkrét süti értékét is megkaphatjuk, sőt a HttpOnly sütiket is engedi olvasni.

Bármily kényelmesnek is tűnik ez a programozási lehetőség, akár a felhasználó tudta nélkül vissza lehet vele élni. Hogy ez milyen biztonsági fenyegetéseket rejt magában? Megmutatom az április 29-i Ethical Hacking konferencián. Már lehet regisztrálni!

 

Technorati-címkék: ,,,

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s