Foros del Web » Programando para Internet » PHP »

Bot IRC con PHP

Estas en el tema de Bot IRC con PHP en el foro de PHP en Foros del Web. Hola amigos. He creado un bot con php que se conecta a IRC Este bot es un script que hace una conexion por sockets y ...
  #1 (permalink)  
Antiguo 14/06/2004, 10:49
Avatar de kesthers  
Fecha de Ingreso: mayo-2004
Ubicación: Valencia
Mensajes: 358
Antigüedad: 19 años, 11 meses
Puntos: 2
Bot IRC con PHP

Hola amigos.

He creado un bot con php que se conecta a IRC

Este bot es un script que hace una conexion por sockets y esta las 24 horas activo.

El codigo no permite casi nada, simplemente hace estadisticas y las guarda en bases de datos y archivos. No acepta comandos como DDC.

Mi duda es, puede alguien a traves de este bot o script atacar mi servidor?
Se le puede hacer un exploit, ¿que pasaria?

Gracias, espero sus respuestas
  #2 (permalink)  
Antiguo 14/06/2004, 12:21
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 3 meses
Puntos: 129
mm si tu lo has diseñado .. tu sabras que problemas de seguridad tendras.

Sin ver el código (ni conocer el protocolo IRC) no sé que comandos filtras de tu socktes .. entre otras cosas y tampoco se vé como introduces esos datos a tu BD (tus INSERT.. etc) de esos datos (para evitar "SQL inyection" y problemas similares)

Un saludo,
  #3 (permalink)  
Antiguo 14/06/2004, 14:12
Avatar de Gerald  
Fecha de Ingreso: julio-2003
Mensajes: 1.356
Antigüedad: 20 años, 9 meses
Puntos: 2
consejo

Si quieres mejorar tu codigo, muestralo aqui, y como estan diseñadas tus tablas donde recoges esos datos.
Todos aqui en conjunto veremos que problemas de seguridad tiene en si.
Saludos.
__________________
Solo por Hoy: Trataré de fortalecer mi mente. Estudiaré y aprenderé algo útil
Hoteldipity
Arte Caracol
  #4 (permalink)  
Antiguo 14/06/2004, 14:35
Avatar de kesthers  
Fecha de Ingreso: mayo-2004
Ubicación: Valencia
Mensajes: 358
Antigüedad: 19 años, 11 meses
Puntos: 2
Muy bien, pues aquí lo teneis:

Código PHP:
<?
// Datos del Bot
$nickname "KesBot";
$powered "Kesthers";
$nombre "KesBot";
$version "v1.0";

$ircserver[address] = "irc.quakenet.org";
$ircserver[port] = "6667";

$red "quakenet";

$directorio[stats] = "/var/log/kesbot/quakenet/";

// Conexion a Base de Datos
mysql_connect("localhost""xxxxx""xxxxx"); mysql_select_db("xxxxx");

## Funciones de Logs & Stats ##
function WriteLogs($canal$mensaje) {
    global 
$directorio;
    
$fp = @fopen($directorio[stats].str_replace("#"""str_replace(":"""$canal)).".log""a");
    
fputs($fp$mensaje."\r\n");
    
fclose($fp);
}

// Conectamos
set_time_limit(0);
for(
$conn=01<=2$conn++) {
    echo
"Conectando...\n";
    
$conexion fsockopen($ircserver[address], $ircserver[port]);
    
socket_set_timeout($conexion31536000);
    if(
$conexion) {
        echo
"Esperando respuesta...\n";
        
$bucle=0$conectado=0$limit=0;
        
set_time_limit(0);
        while (
$read fgets($conexion,512)) {
            
set_time_limit(0);
            
$read str_replace("\n","",$read);
            
$read str_replace("\r","",$read);
            
$array explode(" ",$read);
            
$address explode("!",$array[0]);
            
$nick str_replace(":","",$address[0]);
            
$quit substr($readstrlen($array[0])+strlen($array[1])+3512);
            
$modo substr($readstrlen($array[0])+strlen($array[1])+strlen($array[2])+3512);
            
$mensaje substr($readstrlen($array[0])+strlen($array[1])+strlen($array[2])+4512);
            
$kick substr($readstrlen($array[0])+strlen($array[1])+strlen($array[2])+strlen($array[3])+5512);

            if (
$conectado!==0) {
                switch (
$array[1]) {
                    case 
PRIVMSG:
                    if(
$array[2]!==$nickname) {
                        if(
substr($mensaje07)=="ACTION") {
                            
$count strlen($mensaje)-9;
                            
WriteLogs($array[2], "[".date("H:i")."] * ".$nick." ".substr($mensaje8$count));
                        } else {
                            
WriteLogs($array[2], "[".date("H:i")."] <".$nick."> ".$mensaje);
                        }
                    } else {
                        
$orden explode(" "strtolower($mensaje));
                        switch (
$orden[0]) {
                            case 
"ping":
                            
fputs($conexion"NOTICE ".$nick." :PING ".$orden[1]."\n");
                            break;
                            
                            case 
"version":
                            
fputs($conexion"NOTICE ".$nick." :VERSION ".$version."\n");
                            break;
                            
                            case 
"time":
                            
fputs($conexion"NOTICE ".$nick." :TIME ".date("D M d H:i:s Y")."\n");
                            break;
                            
                            case 
"finger":
                            
fputs($conexion"NOTICE ".$nick." :FINGER ".$nombre."\n");
                            break;

                            case 
admin:
                            if(
mysql_num_rows(mysql_query("SELECT * FROM admins WHERE nick='".strtolower($nick)."'"))==1) {
                                
$accion substr($mensaje6512);
                                
fputs($conexion$accion."\n");
                                if(
$orden[1]=="nick") {
                                    
$nuevo explode(":"$orden[2]);
                                    
$nickname $nuevo[0];
                                }
                            } else {
                                
fputs($conexion"PRIVMSG ".$nick." :\002\0032No estas autorizado/da a usar este comando.\n");
                            }
                            break;

                            case 
info:
                            
fputs($conexion"PRIVMSG ".$nick." :\002\0032Bot de Logs & Stats [Creado por: ".$powered."]\n");
                            
fputs($conexion"PRIVMSG ".$nick." :\002\0032Website: http://www.kesthers.com\n");
                            
fputs($conexion"PRIVMSG ".$nick." :\002\0032E-Mail: [email][email protected][/email]\n");
                            break;

                            case 
op:
                            if(
mysql_num_rows(mysql_query("SELECT * FROM opers WHERE nick='".$orden[1]."' AND password='".$orden[2]."' AND red='".$red."' AND canal='".$orden[3]."'"))=="1") {
                                
fputs($conexion"MODE ".$orden[3]." +o ".$nick."\n");
                            } else {
                                
fputs($conexion"PRIVMSG ".$nick." :\002\0032No te puedo dar op porque los datos no son correctos\n");
                            }
                            break;
                        }
                    }
                    break;
                    
                    case 
NOTICE:
                    if(
$array[2]!==$nickname) {
                        
WriteLogs($array[2], "[".date("H:i")."] *** ".$mensaje." (".$nick.")");
                    }
                    break;
                    
                    case 
NICK:
                    
$query mysql_query("SELECT * FROM online WHERE nick='".$nick."' AND red='".$red."'");
                    while(
$sql mysql_fetch_array($query)) {
                        
WriteLogs($sql[canal], "[".date("H:i")."] *** ".$nick." is now known as ".str_replace(":"""$array[2]));
                    }
                    
mysql_query("UPDATE online SET nick='".str_replace(":"""$array[2])."' WHERE nick='".$nick."' AND red='".$red."'");
                    break;

                    case 
MODE:
                    if(
$array[2]!==$nickname) {
                        
WriteLogs($array[2], "[".date("H:i")."] *** ".$nick." sets mode: ".$modo);
                    }
                    break;

                    case 
JOIN:
                    
WriteLogs($array[2], "[".date("H:i")."] *** ".$nick." (".$address[1].") has joined ".str_replace(":"""$array[2]));
                    
mysql_query("INSERT INTO online (time, nick, canal, red) VALUES ('".time()."', '".$nick."', '".str_replace(":"""$array[2])."', '".$red."');");
                    break;

                    case 
PART:
                    
WriteLogs($array[2], "[".date("H:i")."] *** ".$nick." (".$address[1].") has left ".$array[2]);
                    
mysql_query("DELETE FROM online WHERE nick='".$nick."' AND canal='".$array[2]."' AND red='".$red."'");
                    break;

                    case 
KICK:
                    if(
$array[3]==$nickname) {
                        
fputs($conexion"JOIN ".$array[2]."\n");
                    }
                    
WriteLogs($array[2], "[".date("H:i")."] *** ".$array[3]." was kicked by ".$nick." (".$kick.")");
                    
mysql_query("DELETE FROM online WHERE nick='".$array[3]."' AND canal='".$array[2]."' AND red='".$red."'");
                    break;

                    case 
QUIT:
                    
$query mysql_query("SELECT * FROM online WHERE nick='".$nick."' AND red='".$red."'");
                    while(
$sql mysql_fetch_array($query)) {
                        
WriteLogs($sql[canal], "[".date("H:i")."] *** ".$nick." (".$address[1].") Quit (".$quit.")");
                    }
                    
mysql_query("DELETE FROM online WHERE nick='".$nick."' AND red='".$red."'");
                    break;

                    case 
TOPIC:
                    
WriteLogs($array[2], "[".date("H:i")."] *** ".$nick." changes topic to '".$mensaje."'");
                    
mysql_query("UPDATE canales SET topic='".$mensaje."' WHERE canal='".$array[2]."' AND red='".$red."'");
                    break;
                }
            }


            if (
$bucle==0) {
                
fputs($conexion"NICK $nickname\n\n");
                
fputs($conexion"USER $nickname $powered $powered :$nombre $version\n\n");
                echo
"Identificado.\n";
            }

            if (
$array[0]=="PING") {
                
fputs($conexion"PONG ".str_replace(":","",$array[1])."\n");
            }

            if (
$array[1]==251) {
                
$query mysql_query("SELECT * FROM canales WHERE red='".$red."'");
                while(
$sql mysql_fetch_array($query)) {
                    
$canales .= $sql[canal].",";
                }
                
fputs($conexion"JOIN ".$canales."\n\n");
                echo
"Entrada en canales. ($canales)\n";
                
$conectado++;
            }

            
$bucle++;
        }
    } else {
        echo
"Error al Conectar.\n";
    }
    echo
"Desconectado.\n";
}
?>
  #5 (permalink)  
Antiguo 14/06/2004, 14:36
Avatar de kesthers  
Fecha de Ingreso: mayo-2004
Ubicación: Valencia
Mensajes: 358
Antigüedad: 19 años, 11 meses
Puntos: 2
Por cierto lo pueden ver funcionar en irc.quakenet.org en el canal #kesthers

Saludos
  #6 (permalink)  
Antiguo 14/06/2004, 15:40
Avatar de Gerald  
Fecha de Ingreso: julio-2003
Mensajes: 1.356
Antigüedad: 20 años, 9 meses
Puntos: 2
Tus tablas

Faltaron tus tablas y como es que haces correr este script, lo haces con un cronjob o explicanos cual es el funcionamiento.

Como haces para que tu script quede las 24 horas conectado y como haces para que se vuelva a conectar, cuando este se cae
__________________
Solo por Hoy: Trataré de fortalecer mi mente. Estudiaré y aprenderé algo útil
Hoteldipity
Arte Caracol
  #7 (permalink)  
Antiguo 14/06/2004, 15:56
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 3 meses
Puntos: 129
Bueno .. yo poco puedo aportar sobre "seguridad" en este caso .. no conozco el protocolo del IRC ... (con respecto al filtrado de los comandos "potencialmente peligrosos que existan...)

Con respectoa a tu BD .. podrias usar mysql_escape_string() para evitar algo el tema del "SQL inyection" en las variables que usas para componer tu sentencia SQL:

Código PHP:
if(mysql_num_rows(mysql_query("SELECT * FROM admins WHERE nick='".mysql_escape_string(strtolower($nick))."'"))==1) { 
Así con todas las variables que acaben en un mysql_query(). No sea que llegue alguien con un nick que pudiera interpretarse como una sentencia SQL (mas o menos peligrosa).

Un saludo,
  #8 (permalink)  
Antiguo 14/06/2004, 16:17
Avatar de kesthers  
Fecha de Ingreso: mayo-2004
Ubicación: Valencia
Mensajes: 358
Antigüedad: 19 años, 11 meses
Puntos: 2
Aqui teneis las tablas:
Código:
-- 
-- Estructura de tabla para la tabla `admins`
-- 

CREATE TABLE `admins` (
  `nick` varchar(255) NOT NULL default '',
  `email` varchar(255) NOT NULL default ''
) TYPE=MyISAM;

-- --------------------------------------------------------

-- 
-- Estructura de tabla para la tabla `canales`
-- 

CREATE TABLE `canales` (
  `red` varchar(255) NOT NULL default '',
  `canal` varchar(255) NOT NULL default '',
  `topic` varchar(255) NOT NULL default ''
) TYPE=MyISAM;

-- --------------------------------------------------------

-- 
-- Estructura de tabla para la tabla `online`
-- 

CREATE TABLE `online` (
  `time` varchar(255) NOT NULL default '',
  `nick` varchar(255) NOT NULL default '',
  `canal` varchar(255) NOT NULL default '',
  `red` varchar(255) NOT NULL default ''
) TYPE=MyISAM;

-- --------------------------------------------------------

-- 
-- Estructura de tabla para la tabla `opers`
-- 

CREATE TABLE `opers` (
  `nick` varchar(255) NOT NULL default '',
  `password` varchar(255) NOT NULL default '',
  `red` varchar(255) NOT NULL default '',
  `canal` varchar(255) NOT NULL default ''
) TYPE=MyISAM;
El script lo ejecuto desde shell: comando: nohup php bot.php &

Al ser un for cuando se cae, vuelve a conectarse. Vease el codigo
  #9 (permalink)  
Antiguo 15/06/2004, 18:19
Avatar de Gerald  
Fecha de Ingreso: julio-2003
Mensajes: 1.356
Antigüedad: 20 años, 9 meses
Puntos: 2
Estuve probando tu bot y la verdad no logro conectarlo :S y eso que consegui una cuenta gratuita de shell aqui en cyberspace.org y no se que pasa?

sale esto appending output to `nohup.out'
__________________
Solo por Hoy: Trataré de fortalecer mi mente. Estudiaré y aprenderé algo útil
Hoteldipity
Arte Caracol
  #10 (permalink)  
Antiguo 16/06/2004, 05:14
Avatar de kesthers  
Fecha de Ingreso: mayo-2004
Ubicación: Valencia
Mensajes: 358
Antigüedad: 19 años, 11 meses
Puntos: 2
En el archivo nohup.out debera aparecer:

Código:
Conectando...
Esperando respuesta...
Identificado.
Entrada en canales. (xxxxx)
En la tabla "canales" de MySQL debes indicar los canales donde quieres que entre y la red a la que se conecta. La red debe ser la misma que tiene la variable $red
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Tema Cerrado




La zona horaria es GMT -6. Ahora son las 13:59.