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.
  12 4469
Heisann,

det er lenge siden jeg har skrevet en fornuftig artikkel på forumet nå - og jeg synes det nå var på tide og skrive en ny som forhåpentligvis kan være til hjelp og litt opplysende for de som måtte ha interesse i dette emnet. Artiklen er inspirert av Hacking i praksis -tråden som dukket upp på forumet for en tid tilbake - men muligens i en litt mer detaljert grad.

Temaet vi skal gå igjennom lyder noe så kult som "Session hijacking". Flere av dere har sikkert hørt om dette før, og vet dermed at det kan forekomme av blandt annet XSS (Cross site scripting) og MITM (Man in the middle attack). Anbefaler selvfølgelig å lese opp på terminologi som ikke er kjent for dere.

Hva er session hijacking?
Kort og greit oppsummert betyr det at du tar over for en session til en annen person, du lurer serveren til å tro at du er en person som har vært i kontakt med serveren og som kommer tilbake til den.

For at man skal kunne skjønne litt mer av dette og vite litt i detalj hvordan dette fungerer skal jeg forklare litt rundt hvordan dette med session fungerer. Da må vi også ta for oss litt av HTTP protokollen.

Om HTTP og session.
HTTP er protokollen som vanligvis brukes over internett mellom nettleseren og webserverene i dag. Den forekommer i klartekst og er veldig enkel og grei å forholde seg til blandt annet på grunn av nettopp dette. Det er en protokoll hvor klienten først tar kontakt med server. Server tolker det som blir sendt inn av klienten og sender tilbake et svar.

Det skal også merkes (og det er viktig å forstå dette) er at HTTP protokollen er "stateless". Dette betyr at når en klient tar kontakt med serveren så er denne kontakten totalt uavhengig av den forrige kontakten med serveren. Derfor måtte det introduseres noe som gjør at serveren kjenner igjen klienten fra en tidligere kontakt med serveren. Her er det session kommer inn i bildet.

Request-melding.
Dette er forespørselen som sendes inn til serveren og den beskriver hva det er klienten ønsker å gjøre og hvordan han vil gjøre dette. Vi har noe som heter "Request method" som indikerer hva som ønskes å gjøre. Metoden vi vil benytte oss av er GET - det er denne som sier til serveren at en fil skal leses.

Oppbygningen av en Request-melding som henter ut siden session.php på min egen webserver på domenet wilhelmsen.nu ser slik ut. Adressen er http://80.65.51.238/~kenwi/session.php

Kode

GET /~kenwi/session.php HTTP/1.1\r\n
Host: wilhelmsen.nu\r\n
\r\n
GET er request metoden, så kommer fila som skal hentes, og så protokollversjonen. \r\n er carriage return og deretter newline. Webserveren trenger også host for å vite hvilket webområde som filen skal hentes fra. Det følger dermed to \r\n for å markere slutten av requesten.

For å leke litt med dette i praksis så betyr det at vi kan dra fram putty og prøve å gjøre en slik request manuelt, og se hva svaret fra webserveren er. Du skal ikke ta med \r\n i putty når du skriver inn requesten, \r\n er en standardrepresentasjon for å markere CRLF.
http://80.65.51.238/~kenwi/art/putty.png

Session.php er et lite php-script som benytter seg av session til å spytte ut et tall. Hver gang du refresher siden så vil den slenge på +1 til en variabel og spytte denne ut.

Kode

<?php
        session_start();

        if( !isset($_SESSION['verdi']) )
        {
                $_SESSION['verdi'] = 0;
        }

        $html = '<html></body>%s</body></html>';
        echo sprintf( $html, $_SESSION['verdi']++ );
?>
Som du kan se så har jeg først skrevet inn requesten som skal inn til serveren, får deretter et svar fra serveren som sier HTTP/1.1 200 OK som betyr at den fant siden som jeg forespurte. Deretter følger det en del informasjon om tilkoblingen og helt til slutt innholdet i fila som ble forespurt.

Ikke overraskende så er svaret "<html><body>0</body></html>" i og med at dette er første forespørsel. Så hva skjer dersom jeg sender inn en lik forespørsel til serveren pånytt? Gå først i nettleseren din og refresh et par ganger, så ser du at verdien går fra 0 og oppover hver gang du refresher.

http://80.65.51.238/~kenwi/art/putty2.png

Sendt inn request? Fint. Tallet var fortsatt 0? Hvorfor skjer dette? Jo nettopp fordi det jeg snakket om tidligere. HTTP er en stateless protokoll og nåværene request er totalt uavhengig av den forrige - med mindre du kan identifisere deg til webserveren.

Leser du svaret fra webserveren vil du finne en linje som sier noe lignende

Kode

Set-Cookie: PHPSESSID=a63dfd8b2b7bd2a46bcd9f947337feef; path=/
Nå begynner det å ligne noe! Siden php-scriptet benytter seg av session, så sender webserveren inn en kommando til klienten "Hei, neste gang du skal snakke med meg så må du fortelle meg at session-iden har verdien a63dfd8b2b7bd2a46bcd9f947337feef"

Så neste gang klienten sender inn en request til serveren så ser requesten slik ut:

Kode

GET /~kenwi/session.php HTTP/1.1\r\n
Host: wilhelmsen.nu\r\n
Cookie: PHPSESSID=a63dfd8b2b7bd2a46bcd9f947337feef\r\n
\r\n
Jeg kjører denne et par ganger og tar et nytt screenshot.
http://80.65.51.238/~kenwi/art/putty3.png

WAMMO! Gratulerer, du har nettopp brukt putty som din nettleser. Dette kan du stort sett gjøre mot hvilken som helst webside som skal leses.

Men som du sikkert ser så er det kun HTML som blir spyttet ut når du besøker en webside. Dette betyr at alle bilder og elementer som ikke ligger printet inn i websiden også må hentes ut på samme måte. Jeg har lagt ut bildene i denne artiklen til følgende adresse: http://80.65.51.238/~kenwi/art/

Vi prøver å hente ut et bilde

Kode

GET /~kenwi/art/putty.png HTTP/1.1\r\n
Host: wilhelmsen.nu\r\n
\r\n
Ikke overranskende får vi massevis av merkelig informasjon opp på skjermen, dersom du hadde lastet ned bildet og åpnet det opp i notepad eller lignende så er dette nøyaktig det som du ville fått opp i notepad.

Ja, flott - men hvordan i helvete hjelper dette meg?
Grunnen til at dette er et interessant tema er fordi at innlogginger på nettsider blir veldig ofte håndtert av session. Så dersom du sitter på et nett og du sniffer trafikk med Ettercap (Jeg foretrekker i alle fall denne metoden enn XSS og lignende) så må du ikke nødvendigvis ha vært så heldig å snappe opp brukernavn og passord idet en person logger seg inn på en side. Du kan begynne sniffinga etter at han har logget inn og bare bite deg merke i session-id og gjøre en request mot webserveren med samme session-id. Dette er som sagt nettopp fordi HTTP er en stateless protokoll og må referere til session så webserveren vet hvem den snakker med! Ta for eksempel en bruker som er inne på facebook, nettby eller blink - her har du mange muligheter til å snappe opp session-ider og logge deg inn i deres session. Dermed har du utført et såkalt session hijack.

For å ha skrevet et kodeeksempel som tar for seg nøyaktig dette - slenger jeg med en C# klasse som sender inn request til webserveren, og lagrer session-id og sender inn en ny request. Så hvis du ikke vil være en script-kiddie som bruker ferdigsskrevne applikasjoner til å gjøre alt for deg, så kan du selvfølgelig omskrive hele greia til å være kompatibel med flere forskjellige sites, dra ned sesssion og sende inn en POST for å f.eks bytte passord på en bruker.

Alternativt, firefox har et plugin som heter "Tamper Data" - med denne skal du kunne sette firefox til å kjøre inn session som du selv ønsker å ha. Dermed kan du snappe opp en session-id og gjøre et hijack som brukeren aldri vil merke (du bytter ikke passord, du er bare innlogget med session hans og browser rundt med hans konto)

Jeg slenger ikke med et direkte utdrag fra verken Tamper Data eller Ettercap, dette er de to verktøyene du trenger for å få gjort noe slikt. Meget enkle verktøy som stort sett ikke trenger noen forklaring.

Kode

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text.RegularExpressions;

namespace WebClient
{
    public class Client
    {
        private string session;
        private readonly string address;
        private readonly int port;
        private TcpClient socket;

        public Client( string address, int port )
        {
            this.address = address;
            this.port = port;

            new Thread( new ThreadStart( this.Start ) ).Start();
        }

        private string ReadSite( string session )
        {
            string request = "GET /~kenwi/session.php HTTP/1.1" + Environment.NewLine +
                              "Host: wilhelmsen.nu" + Environment.NewLine;
            if( session != null )
            {
                request += string.Format( "Cookie: PHPSESSID={0}{1}", session, Environment.NewLine );
            }
            request += Environment.NewLine;

            byte[] sd = Encoding.ASCII.GetBytes( request );

            socket.Client.Send( sd );

            byte[] data = new byte[ 1024 * 10 ];
            int i = socket.Client.Receive( data, data.Length, 0 );

            return Encoding.ASCII.GetString( data, 0, i );
        }

        private void Start()
        {
            try
            {
                socket = new TcpClient( address, port );

                if( socket.Connected )
                {
                    string sData = ReadSite( null );
                    Console.Write( sData + Environment.NewLine + Environment.NewLine );

                    session = Regex.Match( sData, "(?<=PHPSESSID=)(.*)(?=;)" ).Value;
                    if( session.Equals( "" ) )
                    {
                        throw new Exception( "Could not find session id" );
                    }

                    while( true )
                    {
                        Thread.Sleep( 10 );
                        Console.Write( ReadSite( session ) + Environment.NewLine + Environment.NewLine );
                    }
                }
            }
            catch( SocketException ex )
            {
                if( ex.ErrorCode == 10053 )
                {
                    Console.WriteLine( "Connection to server has been closed, initiating new one." );
                    socket = new TcpClient( address, port );
                    ReadSite( session );
                }
            }
            catch( Exception ex )
            {
                Console.WriteLine( "Error: {0}", ex.Message );
                Console.ReadKey();
            }

        }
    }
}
Sist endret av m0b; 2. mars 2008 kl. 00:56.
Flott guide, bra skrevet Supert at du gidder og skrive slike kvalitetsposter av og til!
Sist endret av EXzlator; 6. august 2007 kl. 12:51.
Meget bra guide.

Aug 06 12:50:55 <chaninfo> KP gitt til |d13m0b av jonarnev i emnet «Hacking i praksis - Session Hijacking.»
Aug 06 12:50:55 <chaninfo> -> http://www.freakforum.nu/forum/showt...525#post964525
Aug 06 12:55:15 <chaninfo> KP gitt til |d13m0b av typisk i emnet «Hacking i praksis - Session Hijacking.»
Aug 06 12:55:15 <chaninfo> -> http://www.freakforum.nu/forum/showt...525#post964525
Aug 06 12:55:45 <chaninfo> KP gitt til |d13m0b av cos i emnet «Hacking i praksis - Session Hijacking.»
Aug 06 12:55:45 <chaninfo> -> http://www.freakforum.nu/forum/showt...525#post964525
Aug 06 12:57:41 <chaninfo> KP gitt til |d13m0b av Gjerven i emnet «Hacking i praksis - Session Hijacking.»
Aug 06 12:57:41 <chaninfo> -> http://www.freakforum.nu/forum/showt...525#post964525
Aug 06 12:58:01 <chaninfo> KP gitt til |d13m0b av DaHoIv i emnet «Hacking i praksis - Session Hijacking.»
Aug 06 12:58:01 <chaninfo> -> http://www.freakforum.nu/forum/showt...525#post964525
Vis hele sitatet...
Det hadde vært greit om session ble lagret sammen med IPen (når en logges inn), slik kan vi ihvertfall sperre ute de fleste som prøver seg på slik hijack. Fortsatt mulighet i lokalnettet, men hvem orker vel?

Det er ihvertfall slik jeg bygger opp systemene mine.
Sweet, så vet hjelp av dette jeg nettopp leste, så kan jeg klare og hacke en kammerats facebook account, bare jeg er tålmodig og leser igjennom flere ganger så jeg kjønner det ordentlig?

Veldig bra, takk
Valgfri brukertittel
Kekurikekaka's Avatar
Sitat av Restyle
Sweet, så vet hjelp av dette jeg nettopp leste, så kan jeg klare og hacke en kammerats facebook account, bare jeg er tålmodig og leser igjennom flere ganger så jeg kjønner det ordentlig?

Veldig bra, takk
Vis hele sitatet...
Faen! Skulle trykke på quote.

Men uansett. Bruker de ikke cookies på FaceBook da?
Veldig nyttig post. Deilig med litt kode også.
Sitat av PureOwnage
Men uansett. Bruker de ikke cookies på FaceBook da?
Vis hele sitatet...
Cookies er lokalt lagrede informasjonskapsler som skal kunne identifisere deg opp imot web-serveren (siden den er stateless, som nevnt i første post). Relevant cookie-informasjon sendes til web-serveren hver gang du browser sidene på domenet - og kan derfor snappes opp, på lik linje med session id. Er nok mer vrient å måtte lage en egen cookie og sende inn, enn å bare forandre en id med Tamper Data. Likevel er det veldig nært beslektet.
ah, fin guide !

Og til de som ikke skjønner hva stateless er så betyr det "tidløs" . - husker jeg hadde problemer med det, da jeg leste min første php bok på engelsk for en stund siden

Uansett, KP til deg
Sist endret av lsrr; 7. august 2007 kl. 15:27.
Stateless betyr vell på en måte ikke tidløs?

"Tallet var fortsatt 0? Hvorfor skjer dette? Jo nettopp fordi det jeg snakket om tidligere. HTTP er en stateless protokoll og nåværene request er totalt uavhengig av den forrige - med mindre du kan identifisere deg til webserveren."

Så tidløs blir vell kanskje litt feil - direkte oversatt?
Eller er jeg helt på jordet nå? xD
Trigonoceps occipita
vidarlo's Avatar
Donor
Stateless kan oversettast med tilstandsløs, mao. protokollen (HTTP) inneholder *ingen* informasjon om korleis brukeren har komt dit han er, kva som har skjedd o.l. Det må en holde orden på sjølv, t.d med cookies
Var det jeg hinta til, men fant ikke ordet.. :P

Uansett, igjen - veldig bra skrevet av tidstarter.