Sockets en PHP

08.mar 2006 Envía un trackback

Hoy he leido lo siguiente: ¿Se podría usar nmap vía web?. Aunque sería rizar el rizo, porque normalmente quien tiene acceso a web puede tener de forma sencilla y rápida acceso a una pequeña shell con nmap instalado, se podría usar pero con algún que otro matíz, fijaos en el código propuesto:
<?php
$host = "194.179.1.100";
$archivo = "./nmap.log";
$CADENA = "nmap -P0 ".$host." > $archivon";
shell_exec($CADENA);
$fd = fopen($archivo,"r");
while(!feof($fd))
{
	$scan = fgets($fd);
	echo $scan."n";
}
fclose($fd);
?>
Todavía hay gente que sigue utilizando shell_exec(), exec(), system()... aún sabiendo el riesgo de estas funciones. Pensando en un entorno seguro con servidor web enjaulado, modo seguro (safe_mode=On) y demás previsiones el código rompería por mil sitios antes de devolver un resultado coherente, (obviamente nadie tiene nmap instalado en la jaula de httpd).

De todos modos y aún pasando por alto todas las recomendaciones aconsejadas, antes de usar shell_exec() mejor entenderse con system() dejando nmap -en este caso- habilitado en un safe_mode_exec_dir. Siendo cabezones e intentando mejorar el código anterior (al menos en lo que a seguridad se refiere), opto por lo siguiente:
<?php
$host="192.179.1.100";
$init_port="80";
$end_port="631";

for ($port=$init_port; $port<=$end_port; $port++ )
{
	$fp = fsockopen( "$host", $port, &$errno, &$errstr, 4 );
	if (!$fp)
		echo "$port: Cerrado";
	else
		echo "$port: Abierto";
}
?>
Muy mejorable, no tiene opciones, ni modos invisibles ni nada del otro mundo, pero para un simple escaneo de puertos debería llegar (ninguno de los códigos está probado por el momento). Creo que es una buena alternativa a la información de nmap para usar de forma remota, vía web y sin comprometer de forma obvia la seguridad del servidor.

Tenía el mono, así que jugando un poco más con sockets he programado un minibot que se conecta a un servidor irc (irc.freenode.net en este caso) y a un canal en concreto (#lucux, hay que publicitarse). De momento no hace más, aunque tengo pensado que recoja información específica sobre el canal o logs del mismo. El código:
<?php
/* Variables */
	$CONFIG = array();
	$CONFIG['server'] = 'irc.freenode.net'; // servidor
	$CONFIG['nick'] = 'php_r0sk[bot]'; // nick
	$CONFIG['port'] = 6667; // puerto (6667)
	$CONFIG['channel'] = '#lucux'; // canal por defecto
	$CONFIG['name'] = 'php_r0sk'; // nombre del bot (whois)
	
	
/* Conectando al servidor IRC */
	$fp = fsockopen($CONFIG['server'], $CONFIG['port']);

/* Comprobamos conexión */
	if (!$fp) 
	{
		print ("No puedo conectar a: ". $CONFIG['server'] ."-". $CONFIG['port']);
	} 
	else 
	{
		print ("Conectado");
		/* Si la conexión es correcta mandamos nick y name */
		fputs($fp, "USER ". $CONFIG['nick'] ." userlinux.net userlinux.net :". $CONFIG['name']."nr");
		fputs($fp, "NICK ". $CONFIG['nick'] ." userlinux.net"."nr");
		fputs($fp, "JOIN ". $CONFIG['channel']."nr");
	}
?>
El resultado:
[08:36]            --< | php_r0sk[bot] [n=php_r0sk@r0sk.at.userlinux.net] has joined #lucux
[08:36]            >-- | php_r0sk[bot] has quit (Broken pipe)

Comentarios
Gravatar Jocker@09.03.2006, 'Re: Sockets en PHP'

Ui ui ui... me mola a mi esto de los sockets en php eh.. muuuuucho!!! si eso hazte un tutorial que me haces un favor eh xD

Gravatar GuraDXPU@09.03.2006, 'Re: Sockets en PHP'

¿Se podría usar la funcioón fsockopen no? El problema es el mismo... las disable_functions del php.ini. De todos modos, más viable la función que una llamada al sistema con exec por ejemplo. En python creo que se usa system...

Un código a ver si os sirve:

<?php
$puerto=80;
$sock=fsockopen("www.userlinux.com", $puerto, $errno, $errstr, 5);

if ($sock) {
echo "El puerto esta abierto";
} else {
echo "El puerto esta cerrado";
}
?>

A ver si me lo postea bien. Agur ;)

Gravatar GuraDXPU@09.03.2006, 'Re: Sockets en PHP'

Perdón, por alguna razón me cargó solamente parte del post, por lo que me vi obligado a complementarlo, luego me dí cuenta de la explicación. Lo siento ;)

Agur

Gravatar r0sk@09.03.2006, 'Re: Sockets en PHP'

Pues eso, la solución que yo había propuesto más o menos ;). Estamos de acuerdo en que un exec() sería una de las últimas opciones ¿no?.

Es lo que quería dejar claro, habiendo otras alternativas compensa mirar por la seguridad del sistema.

Gravatar Gura@10.03.2006, 'Re: Sockets en PHP'

Totalmente de acuerdo, a mi no me gustan un pelo. Hace tiempo quité la galería "Coppermine" de mi servidor por 3 razones:
La primera, casi no se usaba
La segunda, que necesitaba imagemagick y ese porron de dependencias con x11-libs si no recuerdo mal, y la tercera y última, llamaba a imagemagick mediante exec.
De aquella mi servidor no estaba enjaulado. Estoy pensando en migrarlo a Gentoo y el otro día se me ha ocurrido una idea, usar quickpkg para hacer binarios preocmpilados con ficheros de conf y todo (previamente configurados) y luego descomprimir en un chroot. La única pega es que si añades otros ficheros, no los mete dentro del tgz, por lo demás viable. Tu lo tienes enjaulado? Agur

Gravatar r0sk@12.03.2006, 'Re: Sockets en PHP'

Yo en un servidor tengo todo enjaulado, pero es OpenBSD y se presta para ello porque muchos de los paquetes dependientes de httpd (su fork de Apache para servir webs) vienen preparados y precompilados para trabajar en un chroot.


Escribe tu comentario
 
 
Guardar datos
Escribe tu comentario:
captcha


Intenta que tu comentario sea interesante y con información relevante al tema de la entrada. BBCodes disponibles: [url=http://direccion]texto[/url], negrita: [b]texto[/b], itálica: [i]texto[/i], subrayada: [u]texto[/u]. Para mencionar o citar a alguien (quote): [cita]texto[/cita]