Índice:
1.-Analizando un archivo
2.-Realizando comentarios
3.-Analizando una URL

Introducción

Quien no conoce Virustotal, el servicio online en el que podemos subir un archivo y nos lo escanea con hasta 42 antivirus para tener varios resultados.

Hace ya tiempo, los que se dedicaban al desarrollo de Malware usaban el KIMS (que recuerdos me trae), que era un software que se descargaba varios antivirus (creo que hasta 20) y los analizaba localmente en tu propio ordenador. Ahora con el avance de los tiempos, tenemos servicios online como este del que voy a hablar hoy, o de NoVirusThanks, el cual tuvo su auge en cuanto los desarrolladores supieron que la plataforma Virustotal distribuia lo que subian (o eso se dijo), por lo que si subian virus que estaban desarrollando, no les traia cuenta que estos ficheros fueran dados a las marcas de Antivirus para que los analizasen y detectasen posteriormente.

Una de las razones que me ha llevado a interesarme por esta API, es su increible simpleza y flexibilidad, como podremos ver a continuación en un script. Antes de nada, decir que este script, y todo lo que pondré a continuación está sacado de aquí. La razón por la cual quiera hacer un post de esto, es para dar a conocer más esta API y que todos vean lo simple que es.

Antes de dar paso al uso de la API, quisiera agradecer a Julio Canto y Emiliano Martínez (del staff de VirusTotal) por su total ayuda (incluso en un domingo =P) a través de twitter y por correo electrónico. Sin ellos no podría haber terminado este post, ya que tuve dudas importantes con el uso de la API analizando webs.

A continuación, vamos a hacer lo más simple, y es analizar un fichero y obtener el reporte de los antivirus. Para ello lo primero que tenemos que hacer, es registrarnos en Virustotal.com, y obtener la API Key, que se halla en My Account -> Inbox -> Public API.

1.-Analizando un archivo

Ahora os dejo con el código, comentado y explicado, de cómo analizar un fichero virus.exe y obtener el resultado:

<?php
 
$key = 'API_KEY';
//Api que se obtiene en el perfil
$file = 'virus.exe';
//Ruta del archivo a escanear
 
//Llamamos a la función que nos sube y escanea el archivo
virustotal_scanfile($file, $key);
 
$resource = md5_file($file); 
// Hash del archivo, usado para virustotal_scanfile()
 
$retrieve = virustotal_getreport($resource, $key);
//Obtenemos la matriz final con el resultado
//Estructura de la matriz devuelta 'retrieve'
/*
permalink: enlace del reporte en virustotal
result: 1
report: Array
--->0: fecha (-2 horas española)
--->1: Array
------>Nombre del antivirus: Resultado
------| Si no detecta nada, el resultado está vacio
------| Hay 42 antivirus
*/
 
echo "<hr>";
if($retrieve){
	foreach($retrieve['report'][1] as $clave => $valor)
	   echo $clave . ": " . $valor . "<br>";
	//Esto nos devuelve todos los antivirus, seguido del resultado que nos dan
	echo "<hr>";
}
 
function virustotal_scanfile($filepath, $key){
//Editada y comentada por lipman	
	// Author: Peter Bailey
	// Website: Bailey-Projects.com
 
	$post = array('key' => $key, 'file' => '@'.$filepath);
	//preparamos lo que vamos a pasar por POST
 
	$ch = curl_init();
        //Iniciamos CURL
 
	curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
	curl_setopt($ch, CURLOPT_URL, 'http://www.virustotal.com/api/scan_file.json');
	curl_setopt($ch, CURLOPT_POSTFIELDS, $post); 
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);   
 
	$result = curl_exec($ch);
 
	curl_close($ch);
	//Cerramos CURL
 
}
 
 
function virustotal_getreport($resource, $key){
 
	$url = 'https://www.virustotal.com/api/get_file_report.json';
	$fields = array('resource'=>$resource, 'key'=>$key);
 
	foreach($fields as $key=>$value)
	   $fields_string .= $key.'='.$value.'&';
	$fields_string = rtrim($fields_string,'&');
	//Preparamos la variable que enviaremos por el método POST
 
	$ch = curl_init();
	//Iniciamos CURL
	curl_setopt($ch,CURLOPT_URL,$url);
	curl_setopt($ch,CURLOPT_POST,count($fields));
	curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 
	$result = curl_exec($ch);
 
	curl_close($ch);
	//Cerramos CURL
 
	$result = json_decode($result, true);
	//Decodeamos usando la función de json el resultado
 
	if(isset($result['report'][0]))
		return $result; //Si todo sale bien, lo devolvemos a la función
	else
		return false;
}
 
?>

Resultado (seguro que podeis adiviniar que virus testeé):

2.-Realizando comentarios

En los reportes que se generan online tras el analizado de un fichero, se pueden realizar comentarios, incluso puntuar si estos son buenos o malos. Para realizar comentarios también disponemos de una función que he explicado en los comentarios del script:

<?
//Ejemplo de llamada a la función:
virustotal_makecomment($fileorurl, $key, "Probando la API");
//$fileorurl es lo que anteriormente vimos como el hash del fichero a analizar: el md5_file($file)
//$key es la api, y lo último es el comentario que queremos realizar
//En $fileorurl realmente se podria tambien poner la URL del reporte que queremos comentar, pero por alguna razón, no me funciona, así que lo haremos con el hash md5 del fichero.
 
function virustotal_makecomment($fileorurl, $key, $comment, $tags = ''){
 
    // Author: Kenny Lyons aka ih8censorship
	// Website: http://pasture.sourceforge.net
 
    $url = 'http://www.virustotal.com/api/make_comment.json';
 
	$fields = array('key'=>$key,'comment'=>$comment);
	 if(preg_match('/^https?:\/\/.*/',$fileorurl)){
	    $fields['url']=$fileorurl;
	 } else {
	    $fields['file']=$fileorurl;
	 }
	 //Esto detecta si lo que pasamos es la URL o el hash del archivo, pero como
	 //dije anteriormente, a mi pasando la URL no me funciona, asi que podriamos
	 //deshacer este if-else
 
    $fields_string='';
	foreach($fields as $key=>$value)
	   $fields_string .= $key.'='.$value.'&';
 
	$fields_string=rtrim($fields_string,'&');
	//Creamos lo que vamos a pasar por POST-JSON
 
        $ch = curl_init();
	//Iniciamos CURL
	curl_setopt($ch,CURLOPT_URL,$url);
	curl_setopt($ch,CURLOPT_POST,count($fields));
	curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 
	$result = curl_exec($ch);
 
	curl_close($ch);
	//Cerramos CURL
	$result = json_decode($result, true);
	//Decodeamos el resultado para saber si ha sido exitoso o no el proceso
 
	 if($result['result']=="1"){
	 	return true;
	 } else {
	 	return false;
	 }
}

Analizando una URL

Virustotal también nos permite analizar una URL. A priori, al analizar una URL, los motores de análisis tales como Google Safebrowsing y el de Firefox, nos indican la maliciosidad de la web (devuelto en un array, al igual que los resultados de cuando analizábamos un archivo). Pero además de esto, si la URL que indicábamos corresponde a un archivo, también nos devuelve un identificador que posteriormente podemos usar para ver si ese archivo es detectado o no.

Aquí el código, explicado:

$key = 'API_KEY';
//Api que se obtiene en el perfil
$file = "http://i476.photobucket.com/albums/rr125/lipmandj/asd.jpg";
//URL a analizar
 
$identificador = virustotal_scanurl($file,$key);
 
$retrieve = virustotal_geturlreport($key,$identificador);
 
 
if($retrieve){
	print_r($retrieve); // Array que contiene el reporte
}
 
function virustotal_scanurl($url, $key){
 
	// Esta función envia la URL
 
 
    // Author: Kenny Lyons aka ih8censorship
	// Website: http://pasture.sourceforge.net
    // Editado por lipman
 
    //URL a la que enviaremos los datos
    $url = 'http://www.virustotal.com/api/scan_url.json';
    //Preparamos los campos de lo que vamos a enviar
	$fields = array('url'=>$url, 'key'=>$key);
    $fields_string='';
	foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
	$fields_string=rtrim($fields_string,'&');
 
    //Procedemos a enviarlo mediante cURL
    $ch = curl_init();
 
	curl_setopt($ch,CURLOPT_URL,$url);
	curl_setopt($process, CURLOPT_HTTPHEADER, array("Content-Type: text/xml","SOAPAction: \"/soap/action/query\"", "Content-length: ".strlen($fields_string))); 
	curl_setopt($ch,CURLOPT_POST,count($fields));
	curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 
	$result = curl_exec($ch);
 
	curl_close($ch);
	//Tras enviarlo, cerramos la conexión y decodeamos el resultado devuelto
	$result = json_decode($result, true);
 
 
	if($result['result']=="1"){ //Si todo va bien, devolvemos la ID del scan
		return $result['scan_id'];
	} else {
		return false;
	}
 
}
 
function virustotal_geturlreport($key,$resource,$scan=false){
 
	// Nos devuelve el reporte
 
    // Author: Kenny Lyons aka ih8censorship
	// Website: http://pasture.sourceforge.net
    //Editado por lipman	
 
    //URL a donde enviaremos los datos
    $url = 'http://www.virustotal.com/api/get_url_report.json';
    //Preparamos los campos
	$fields = array('resource'=>$resource, 'key'=>$key,'scan'=>$scan);
    $fields_string='';
	foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
	$fields_string=rtrim($fields_string,'&');
    //Finalmente, usamos cURL para enviarlo y recoger el resultado
    $ch = curl_init();
 
	curl_setopt($ch,CURLOPT_URL,$url);
	curl_setopt($ch,CURLOPT_POST,count($fields));
	curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 
	$result = curl_exec($ch);
 
	curl_close($ch);
 
	$result = json_decode($result, true);
 
	 if($scan && $result['result']=="0"){
	 	return $result['scan_id'];
	 } else {
	 	return $result;
	 }
 
}

Saludos, lipman