Showing posts with label Hacking. Show all posts
Showing posts with label Hacking. Show all posts

Thursday, December 8, 2011

Raw Socket: TCP Segment


Now it's time to get into the TCP header.
Obviously TCP over raw socket is very hard to use! Retrasmissions, control flow, congestion avoidance... All of that need to be implemented. However this may be interesting for learning and testing!
So let's se the tcp header structure.

File: netinet/tcp.h



struct tcphdr
{...};
tcphdr->source //[16 bit] Source Port.
tcphdr->dest //[16 bit] Destination Port.
tcphdr->seq //[32 bit] Sequence Number: received payload byte count since the first SYN. It's the segment ID.
tcphdr->ack_seq //[32 bit] Acknowledgement Number, if the segment is an ACK, this field contains the next Sequence Number that the receiver is waiting for.
tcphdr->res1 //[4 bit] Reserved.
tcphdr->fin //[Flag] After this segment, no more segment expected from sender.

tcphdr->syn //[Flag] TCP connection opening request.
tcphdr->rst //[Flag] Error or opening request denied.
tcphdr->psh //[Flag] If enabled, the data will be sent directly to the application instead of being bufferized.
tcphdr->ack //[Flag] Acknowledgement. Enables field Acknowledgement Number.
tcphdr->urg //[Flag] Notify an Urgent Data, enables field Urgen Pointer.
tcphdr->res2 //[2 bit] Reserved.
tcphdr->doff //[4 bit] Data offset, TCP Header size in 32 bit words.
tcphdr->th_flags //[8 bit] Flags.
tcphdr->window //[16 bit] Advertise Windows Size.
tcphdr->check //[16 bit] Pseudoheader + Data Checksum (see Wikipedia).
tcphdr->urg_ptr //[16 bit] If flag URG is enabled, Urgent Pointer represent the offset from the Seq. Numb.


Now we define also a structure for ip pseudoheader, in order to compute the checksum.



struct pseudoheader
{
u_int32_t sourceAddress;
u_int32_t destinationAddress;
u_int8_t zeros;
u_int8_t protocol;
u_int8_t tcpLength;
};


Ok, now let's run our TCP test and here it is our capture!






Source codes:

testTCP.c
tcp.h
tcp.c
ip.h
ip.c

Wednesday, December 7, 2011

Raw Socket: IP datagrams


IP datagrams represent data to be routed.
They store informations like IP source and destination address.
Inside <netinet/ip.h> an iphdr struct is defined, allowing us to create a custom ip header. (More detailed information about IP header here)

File: <netinet/ip.h>



struct iphdr
{...};

iphdr.ihl //[4 bit] Internet Header Length, contains the header length measured in 32 bit words.
iphdr.version //[4 bit] Datagram version. ipv4 version's 4.
iphdr.tos //[8 bit] Type of service (we won't use it).
iphdr.tot_len //[16 bit] Datagram total length in byte.
iphdr.id //[16 bit] Used on router fragmentation.
iphdr.frag_off//[3 bit] Fragmentation controls.
iphdr.ttl //[8 bit] Time to live, or max hops allowed before datagramm destruction.
iphdr.protocol //[8 bit] Payload protocol identifier  (6->TCP, 17->UDP, 1->ICMP ...).
iphdr.check //[16 bit] Header checksum (16-bit checksum RFC1071).
iphdr.saddr //[32 bit] IP source address
iphdr.daddr //[32 bit] IP destination address

Now let's define some usefull functions for future use:

int createIpv4Header(Iphdr* buffer, char * srcAddress, char * dstAddress, u_int8_t ttl);

void setPayloadInfo(Iphdr* ipheader, int payloadLength, u_int8_t protocolType);
Time for funny testing!
Editing the previous post code, we can create a function testIP(char* src, char* dest) able to send an empty datagram ip to a custom destination from a custom source.
So we initialize the buffer:

int length = createIpv4Header(ipheader, sourceAddress, destinationAddress, 100);
setPayloadInfo(ipheader, 0, 1);


Calling setPayloadInfo we are setting a ICMP protocol with 0 length (obviously that would be a malformed datagram, but now we want only to test the IP behaviour).
Now let's call the testIP function inside a main(), with parameters ("127.0.0.1", "127.0.0.1").
Compile.

Now let's open our favourite traffic analyzer (like wireshark) and enable capturing on lo (loopback interface, or 127.0.0.1). We'll be able to see our little datagram :).


$ sudo ./test_ip


We will see on wireshark something like that:


We do it!


Here the code:


ip.h
ip.c
testIP.c

Raw Socket: Introduction


Sockets are APIs (application programming interface) for creating comunication flows between two endpoints. Sockets create an interface above the Transport Layer, so we can use them in order to send data on the TCP/IP Application Layer.


Raw Sockets are little different. They create a low-level comunication flow, enabling us to work directly on IP layer or better over the Data-Link Layer. Basically, we have to write the TCP/IP headers and (re)write "freehand" the comunication protocol, like 3-Ways handshake or sliding windows managment.

Only a fool would use such a thing! A fool or someone who wants to analyze/manipulate the traffic. So the creation of a Raw Socket requires root privileges.



Thankfully the OS give us structures for protocol's header (like ip, tcp, udp, icmp, arp...).

The normal execution flow is:
  • Creation of a trasmission buffer, to be filled with IP header ip and payload.
  • IP packet checksum computation.
  • Raw Socket creation.
  • Tell the operating system to avoid adding automatically IP Header.
  • Sending the trasmission buffer using sendto().
  • Wait for a reply using recivefrom(), filling the receive buffer with the answer.
  • <your code go here> :P
  • ...

Wednesday, February 2, 2011

DVWA: SQLI in BruteForce Easy

Questo post fa parte della serie DVWA.

In questo post non discuterò della vulnerabilità al brute force della pagina (nessun limite di tentativi, nessun controllo anti-bot, link costante, messaggio di errore deterministico...), ma dell'attacco SQL Injection a cui è vulnerabile.

Provando con il classico tentativo (inserendo ' nei due campi), otteniamo un errore:

[...] for the right syntax to use near '3590cb8af0bbb9e78c343b52b93773c9'' at line 1
Quella stringa di caratteri è un hash (più precisamente è il risultato di md5(') ). Da qui possiamo dedurre che le password siano salvate nel database tramite il loro hash. Dunque un attacco sqli al campo password è impossibile (qualunque stringa inserita è convertita in una stringa esadecimale da 32 caratteri). Tuttavia è possibile un attacco al campo username. Proviamo a dedurre la query:

SELECT * FROM tabella WHERE user = '$user' AND password = $password;

Non si può (come negli altri casi) inserire nel campo user il valore 1' OR '1' = '1, poichè la query risultante sarebbe:

SELECT * FROM tabella WHERE user = '1' OR '1' = '1' AND password = $password;

Se la password non è corretta, la query restituisce false.
Per aggirare questa condizione, possiamo usare il commento SQL: --, in modo da costruire questa query (gli spazi sono importanti!):

SELECT * FROM tabella WHERE user = '1' OR 1 -- AND password = $password;

Se il campo user vale "1' OR 1 -- ", otteniamo il risultato desiderato.

La query è corretta, però se proviamo ad inserire questo valore, non riusciamo a effettuare il login. Perché?

Una pratica molto comune nei casi dove il numero di risultati della query è noto, è quella di effettuare il controllo del numero di risultati.
Nel caso del login il risultato della query deve essere uno solo, poichè deve esistere una sola entry per una coppia (user, password).

A questo punto ci viene in aiuto SQL, con il comando LIMIT, che permette di selezionare indice e numero di risultati forniti dalla query. Mettendo in pratica, scrivendo 
 "1' OR 1 LIMIT 0,1 -- ", la query sarà:

SELECT * FROM tabella WHERE user = '1' OR 1 LIMIT 0, 1 -- 'AND password = $password;

Siamo riusciti ad effettuare il login!

C'è un'altra cosa interessante. In caso di succesful login, viene aggiunta alla pagina una immagine che ha come nome ciò che sembrerebbe il nome dell'utente con cui ci siamo loggati (es: admin.jpg). Perciò inserendo nel campo user 
"1' OR 1 LIMIT x,1 -- ", dove x >= 0, possiamo loggarci come ogni utente del sistema e leggerne il nome dall'immagine caricata.

Tuesday, February 1, 2011

DVWA: File Upload Medium

Questo post fa parte della serie DVWA.

Per cominciare, qual è la vulnerabilità che può comportare un file upload?
Quella più semplice risiede nella possibilità di generare un memory overflow, inserendo file giganteschi, oppure è possibile inserire programmi malevoli, script, effettuare defacing, ecc...

Il form permette di inserire una immagine nel server. Ma è veramente così? Vengono fatti dei controlli sul tipo di file inserito?

Osservando il codice html, si nota l'hidden input MAX_FILE_SIZE che accompagna sempre un file input (php implementa un controllo automatico della dimensione massima del file, basandosi su MAX_FILE_SIZE). Ovviamente questo parametro è decisamente bypassabile (modificando l'html o la request mediante un proxy).

Effettuiamo qualche prova.
Provando ad uploadare un file .php (ad esempio una shell), il form ci avverte che la nostra immagine non è stata uploadata.

Questi controlli sono solitamente fatti in determinati modi:

  • Blacklist: lo script mantiene una lista di estensioni da non accettare
  • Whitelist: lo script mantiene una lista di estensioni da accettare
  • MIME-Type: lo script controlla l'Internet Media Type del file (riportato nel campo Content-Type (eg: Image/jpeg)
  • Controllo indiretto di tipo: lo script invoca una funzione (come getimagesize() ), che fallisce se il file caricato non è una immagine.
Ovviamente il metodo più debole è quello che usa il MIME-Type, infatti, utilizzando un proxy locale, è possibile inserire un header "Content-Type: image/jpeg" nella parte relativa al file da uploadare.

Con la Blacklist, solitamente, si ricava l'estensione del file ricercando l'ultimo '.' della stringa e comparandolo con una lista. Se questa estensione compare nella blacklist, il file non viene uploadato. Ci sono vari modi di bypassare il controllo, il più immediato è quello di passare un file che ha come nome (nell'ipotesi che 'php' non sia ammessa) 'shell.php.' . Quando questo nome viene analizzato, l'estensione risulterà vuota e se non compare nella blacklist, sarà permessa. Inoltre durante la memorizzazione nel filesystem, l'ultimo punto viene ignorato dal sistema operativo, di conseguenza di avrà uploadato il file 'shell.php'.

La Whitelist ha una vulnerabilità strettamente legata al webserver e al modo in cui si comporta con le doppie estensioni. Ad esempio Apache se configurato male, può permettere di bypassare la whitelist, interpretando il file "shell.php.jpg" non come una immagine jpg, ma come un file php (molto raro che succeda).

Il controllo indiretto del tipo può essere ingannato a seconda del tipo di controllo: se è solamente limitato all'header del file, è possibile mettere nel file da uploadare le informazioni necessarie per far apparire il file ciò che in realtà non è. Ovviamene un controllo più diretto non è bypassabile.

In ogni caso, tornando a DVWA, provando ad inserire dei file non immagini si nota che questi non vengono uploadati. Provando con un proxy locale a modificare l'HTTP Request, aggiungendo al file uploadato l'header Content-Type: image/jpeg, qualunque file viene caricato.

Ma la vulnerabilità della pagina non si limita solo a questo, infatti la pagina salva tutti i file in un'unica folder, mentre le buone norme di sicurezza imporrebbero l'utilizzo di folder random-generated.

Monday, January 31, 2011

DVWA: Command Execution Easy

Questo post fa parte della serie DVWA.

SecurityLevel: Easy, entriamo in Command Execution.

È richiesto di inserire un indirizzo ip, se lo facciamo otteniamo sullo schermo l'output dell'operazione di ping.

Possiamo supporre che il codice php sia qualcosa tipo:


exec("ping ".$command);

Se siamo fortunati, non viene fatto alcun controllo sul comando inserito. Abbiamo varie soluzioni da provare (dipendono dal sistema operativo in cui è installato il webserver, nel nostro caso il nostro sistema operativo).
  1. Linux) La shell permette di separare i comandi da eseguire inserendo ";"
  2. Linux) La shell permette di eseguire due comandi concorrentemente separandoli con "&"
  3. Linux) La shell permette di eseguire due comandi sequenzialmente separandoli con "&&"
  4. Windows) cmd permette di eseguire sequenzialmente due programmi separandoli con "&"
  5. Windows) cmd permette di eseguire sequenzialmente due programmi solo se il primo esce con non-error status separandoli con "&&"
  6. Windows) cmd permette di eseguire sequenzialmente due programmi solo se il primo esce con error status separandoli con "||"
Il comando in comune che agisce sequenzialmente è && (se non si conosce il sistema operativo occorre avere l'accortezza di inserire un ip raggiungibile e pingabile in modo da non far fallire il comando ping).
Proviamo inserendo:
74.125.232.114 && echo Vuln!
Se alla fine del ping otterrete "Vuln!", significa che il codice è vulnerabile! Ora la fantasia entra in gioco! Possiamo ad esempio ottenere il codice php di qualsiasi pagina, es:

74.125.232.114 && cat path/pagina.php

Oppure, se l'OS è linux, probabilmente possiamo caricare un programma malevolo del server con wget e poi eseguirlo...



Permettere una simile vulnerabilità nel proprio sito web, è veramente da idioti.

Sunday, January 30, 2011

DVWA: SQL Injection Easy

Questo post fa parte della serie DVWA.


Impostiamo il Security Level a Easy ed entriamo in "SQL Injection".
La differenza rispetto a "SQL Injection", è che in "SQL Injection (Blind)", non viene riportato l'errore causato da una malformazione del parametro di input.

È meglio cominciare con la versione non blind, per poter osservare eventuali errori.
Cominciamo inserendo un campo intuitivamente conforme a ID (un numero piccolo), come 1.
In ouput viene visualizzato qualcosa.
Proviamo ora ad inserire dei caratteri non alfanumerici.

Provando con ', otteniamo un errore.

Abbiamo scoperto che il form è vulnerabile a SLQ Injection. Cosa possiamo farci?

Se siamo "fortunati" e anche lo script di elaborazione dei risultati è fatto male, possiamo ad esempio pensare di ottenere le informazioni su tutti gli utenti.

Possiamo intuire la struttura della query:

SELECT * FROM tabella WHERE ID = $id;
Oppure
SELECT * FROM tabella WHERE ID = '$id';

Ipotizziamo la prima e proviamo a costruire questa query:
SELECT * FROM tabella WHERE ID = 1 OR 1;

Mettiamo nel form "1 OR 1", ma non otteniamo il risultato voluto, allora probabilmente è la seconda forma. Proviamo a mettere nel form "1' OR '1' = '1", in modo da ottenere:
SELECT * FROM tabella WHERE ID = '1' OR '1' = '1';

L'output è proprio quello desiderato: la lista di tutti gli utenti del database.

Etical Hacking - Damn Vulnerable Web Application

Oggi inizio una serie di post su DVWA, una web-application utile per imparare e testare le proprie abilità di Penetration.


DVWA è una applicazione PHP/MySQL, quindi occorre installare un webserver (come apache), un modulo PHP e il database MySQL. In rete è pieno di istruzioni su come installare un web-server WAMP (Windows-Apache-MySQL-PHP) o LAMP, perciò non mi divulgherò molto.
Per i windows-users consiglio EasyPHP.


Supponiamo di aver installato il web server in ascolto su 127.0.0.1, sulla porta 80.
Ora scarichiamo DVWA, scompattiamolo e mettiamolo nella RootDirectory del nostro sito (supponiamo che la folder di DVWA sia dvwa).
A questo punto possiamo accedere, tramite il nostro browser, a:

http://127.0.0.1/dvwa


Si aprirà una pagina di login, in cui dovremo inserire le credenziali di default (admin, password).

Ora che siamo entrati nella pagina di login, a destra possiamo scegliere fra varie vulnerabilities.
Per ogni vulnerabilities esistono 3 Security Level:
  • Easy) il programmatore non ha inserito alcun sistema per prevenire attacchi.
  • Medium) il programmatore ha inserito qualche mecchanismo di protezione ma è estremamente inefficace e facilmente bucabile.
  • Hard) il programmatore ha inserito degli ottimi strumenti di protezione (serve come confronto rispetto agli altri 2).
I security level sono selezionabili nel menù a lato DVWA Security. Sempre da questo menù è possibile abilitare o meno PHPIDS (PHP-intrusion detection system), che abilità l'utilizzo di PHPIDS nel sito come layer di sicurezza (serve solo per far vedere che abilitandolo quasi tutti gli attacchi portati diventano inutili).In ogni sfida sono riportati dei link in cui è spiegato il tipo di attacco, inoltre in fondo alla pagina è presente un button "View Source", che permette di visualizzare il codice php della vulnerabilità (ovviamente da osservare dopo aver bucato il sistema ;) ).

I post che seguiranno faranno da how-to per varie sfide al livello di difficoltà easy/medium.