SlideShare una empresa de Scribd logo
HACK X CRACK: “PORT SCANNING” -- APRENDE A ESCANEAR LA RED

                              P
                              A
                              S
                              O
P A S Oa
       a
       a
       a
       a
       a
       a
       aa
        a
        a
        a
        a
        a




                                  ANALIZANDO EQUIPOS
                                         TOS
                                     REMOTOS

   BASES DE DATOS
      DISEÑO DE
   FORMULARIOS Y
    ORGANIZACION

  PROGRAMANDO


  VARIABLES Y
     PUNTEROS
   Nº 13 -- P.V.P. 4,5 EUROS
                      00013




    8 414090 202756
P
                              A
                              S
                              O
            aa
     P A S Oaa
            aa
            a
            a
            aa
             a
             a
             a
             a
             a
             a
             aa


EDITORIAL: EDITOTRANS S.L.                      Director de la Publicación
                                                J. Sentís
C.I.F:     B43675701
PERE MARTELL Nº 20, 2º - 1ª                     E-mail contacto
43001 TARRAGONA (ESPAÑA)                        director@hackxcrack.com
Director Editorial                              Diseño gráfico:
I. SENTIS                                       J. M. Velasco
E-mail contacto
director@editotrans.com                         E-mail contacto:
Título de la publicación
Los Cuadernos de HACK X CRACK.                  grafico@hackxcrack.com
Nombre Comercial de la publicacíón
PC PASO A PASO                                  Redactores
Web: www.hackxcrack.com                         AZIMUT, ROTEADO, FASTIC, MORDEA, FAUSTO,
Dirección: PERE MARTELL Nº 20, 2º - 1ª.         ENTROPIC, MEIDOR, HASHIMUIRA, BACKBONE,
            43001 TARRAGONA (ESPAÑA)
                                                ZORTEMIUS, AK22, DORKAN, KMORK, MAILA,
                                                TITINA, SIMPSIM... ... ... ... ...
¿Quieres insertar publicidad en PC PASO A Contacto redactores
PASO? Tenemos la mejor relación precio-difusión redactores@hackxcrack.com
del mercado editorial en España. Contacta con
nosotros!!!                                     Colaboradores
                                                Mas de 130 personas: de España, de Brasil, de
Director de Marketing                           Argentina, de Francia, de Alemania, de Japón y
Sr. Miguel Mellado                              algún Estadounidense.
Tfno. directo: 652 495 607
Tfno. oficina: 877 023 356
E-mail: miguel@editotrans.com                   E-mail contacto
                                                colaboradores@hackxcrack.com
                                                Imprime
                                                I.G. PRINTONE S.A. Tel 91 808 50 15
                                                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

                                                TELÉFONO DE ATENCIÓN AL CLIENTE: 977 22 45 80
                                                Petición de Números atrasados y Suscripciones (Srta. Genoveva)

                                                HORARIO DE ATENCIÓN:                DE 9:30 A 13:30
                                                                                   (LUNES A VIERNES)
                                                © Copyright Editotrans S.L.
                                                NUMERO 13 -- PRINTED IN SPAIN
                                                PERIOCIDAD MENSUAL
                                                Deposito legal: B.26805-2002
                                                Código EAN:      8414090202756
Hxc13
EDITORIAL
      PREPARANDO EL FUTURO
Cuando uno forma parte de un proyecto, como por
ejemplo la publicación de una revista, debe preocuparse
tanto de los mil y un problemas diarios como de “el
futuro”. Hasta hace muy poco, PC PASO A PASO
(Los Cuadernos de Hack x Crack), ha sido publicada
siguiendo una filosofía tipo “vivir al día”, algo que      4 EDIT ORIAL
está muy bien en los inicios pero que no debe
                                                           5 XML:DOM
mantenerse demasiado tiempo.
                                                           14 C OLAB ORA C ON NOSO TR OS
Ahora estamos preparando toda una serie de cambios
cuyos resultados empezarán a “verse” en poco tiempo,       1 6 PR OGRAMA CION BA JO LINUX: LENGU A JE C
desde la Web hasta la revista… nuevos contenidos,
publicidad, más páginas, nuevos colaboradores y,           27 CURSO VISUAL BASIC: UN CLIENTE, UNA NECESIDAD(I).
sobre todo, mayor diversidad en las temáticas.
                                                           38 SERIE RAW (7): HTTP (I)
Hasta ahora nos hemos centrado en temas relacionados
con la Seguridad Informática orientada a Internet y        5 8 S E RV I D O R D E H XC . M O D O D E E M P L EO
hemos intentado “picar” al lector para que empiece
a programar. Ambos temas RED y CURSOS seguirán             66 C ONCURSO DE SUSE LINUX 8.2
siendo los principales pilares de PC PASO A PASO,
                                                           6 6 B A JAT E N U E S T R O S L O G O S Y M E L O D I A S
pero estamos trabajando duro para ofrecer mucho
más… tiempo al tiempo :)                                   66GANADOR DEL CONCURSO DE SUSE LINUX

Para nosotros está siendo muy difícil “madurar”, sería     66 SUSCRIPCIONES
sencillo tomar una línea tipo “análisis de productos”
y ganar de esta forma publicitantes y lectores tipo        67 NUMER OS ATRAS ADOS
“PC ACTUAL”, de hecho, hay publicaciones en el
mercado cuyas ventas ni siquiera cubren el precio de
la Imprenta pero que tienen importantes beneficios
por la publicidad. Nosotros estamos trabajando en la
cuadratura del círculo, seguiremos con nuestra temática
y la ampliaremos, seguiremos siendo educativos en
lugar de destructivos, pero empezaremos a diversificar
y, sobre todo, aumentar páginas. Esperamos poder
demostrar todo este trabajo (que hasta ahora permanece
“en la sombra”) para los primeros meses del próximo
año.

Tratar la temática Hack es tratar la Seguridad
Informática, al contrario de lo que muchos piensan
ambas cosas son exactamente lo mismo. Algunos
creyeron que era imposible hacer una revista de este
tipo sin caer en la vulgaridad y sin “empujar” al lector
a cometer todo tipo de actos ilícitos, se equivocaron…
si algo hemos hecho es enseñar y educar hasta la
saciedad.

GRACIAS POR LEERNOS
MANIPULACION DE
           DOCUMENTOS XML: EL DOM
          Primera parte: Teoria del DOM e interfaz
                        DOMDocument
                  Por Joaquim Roca Verges



          XML es una apuesta segura. El común de los mortales lo utilizamos cada día sin saberlo
          y es un estándar universal implementada en cualquier aplicación que se precie.



          Hasta ahora hemos visto lo que es el xml (nº10) y     archivo Power Designer versión 7.
           lo que son las DTD (nº 11 y 12). Recordamos que
          el XML es un lenguaje de intercambio de datos, que    Hará cosa de un año, fui a una presentación Microsoft
          hoy en día es prácticamente universal (todo el        de una herramienta BizTalk que sirve para procesar
          mundo lo entiende), y las DTD son reglas que podéis   archivos generados con SAP. Los archivos generados
          aplicar al XML. Ahora vamos a ver como procesar,      con SAP se guardaban... en formato XML.
          como recorrer, como extraer la información de los
          documentos XML.
                                                                    !               Para quien se...
          Y lo vamos a hacer con el DOM.
                                                                    Para quien se esté preguntando qué es eso del SAP, le damos otro
          Para daros ánimos e intentar inculcaros mi                par de siglas: ERP y CMR. Un ERP es, para que nos entendamos,
          entusiasmo me gustaría explicaros un par de las           un programa de gestión empresarial, pero no un "programita"
          muchas experiencias favorables y satisfactorias que       tipo "facturación/nominas", sino todo un sistema de gestión
          he tenido con este lenguaje.                              integral, para que te hagas una idea, los bancos y grandes
          Hace poco estuve diseñando una base de datos              multinacionales utilizan sistemas tipo ERP para gestionar desde
          bastante grande conjuntamente con otra empresa            los datacenters (centros de datos que pueden llegar a ocupar varias
          que llamaremos XXX. Nos reuníamos semanalmente            plantas de un edificio e incluso varios edificios) hasta la sucursal
          con los usuarios y fruto de las conversaciones con        de un pequeño pueblo o un simple punto de venta. Alguno estará
          ellos íbamos diseñando la base de datos. El diseño        pensando como es posible "instalar" un ERP (algo tan
          se hacia con Power Designer (podéis bajároslo de          aparentemente "grande") en un punto de venta (por ejemplo en
          http://crm.sybase.com/sybase/www/eBD/my_03/               un pequeño McDonals), pues bien, es posible porque un sistema
          pd952_dwnld_eval.jsp una vez os hayáis registrado),       ERP contiene infinidad de pequeños módulos especialmente
          una herramienta de modelado de base de datos de           adaptados para cada una de las áreas que puede tener una empresa.
          la casa Sybase. La empresa XXX utilizaba Power            Pero un ERP es mucho más, porque permite a las empresas
          Designer 7, y mi empresa disponía de Power Designer       ampliar, personalizar e incluso crear módulos completamente
          8 y 9.                                                    nuevos que se adapten perfectamente a cualquier tarea. Pero lo
                                                                    verdaderamente importante no es ni su capacidad ni su
          Si la empresa XXX hacia modificaciones y nos las          modularidad, lo realmente importante es que un ERP permite un
          mandaba a mi empresa ningún problema ya que               análisis global y en tiempo real de cualquier aspecto de una
          las versiones 8 y 9 entendían a la perfección la          empresa, desde una visión financiera de alto nivel (activos/pasivos
          versión 7, sin embargo si nosotros hacíamos               globales de toda una multinacional) hasta las ventas en la última
          modificaciones ellos no podían abrir nuestros             hora de una diminuta sucursal de un pequeño pueblo de Murcia.
          documentos.
                                                                    Pues bien, SAP es uno de los ERP más difundidos. Microsoft,
          Lo solucionamos guardando nuestras modificaciones         como no podía ser menos, compró una empresa especializada en
          como archivo XML, y entonces sí, entonces el colega       la creación de Software tipo ERP y comercializa su producto ERP
          de la empresa XXX cogía el XML y lo convertía a un        bajo el nombre de AXAPTA-NAVISION. Y nos queda el CMR,


PC PASO A PASO Nº 13                                                                                                        Página 5
XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM




                                                                         <DOCUMENTO>
                                                                                  <!-- solo se mostrará a partir de la una del mediodía -->
    que para no extendernos más diremos que es un importante
                                                                                  <BIENVENIDA hora="13:00"> Hola, buenas tardes </BIENVENIDA>
    módulo del Sistema ERP que se encarga de "los contactos",
                                                                         </DOCUMENTO>
    vamos, como el Outlook pero a lo grande ;p (espero que se capte
    la ironía, comparar Outlook con un CMR es de tan mal gusto
                                                                         este comentario también formaría parte del DOM.
    como comparar el vinagre con un buen vino :)

                                                                         Y (atención!!) el texto "Hola, buenas tardes" también es parte del
    No creo que en esta revista se trate nunca en profundidad los
                                                                         DOM
    sistemas ERP, de hecho, la temática que rodea al mundo de los
    ERPs es tan basta que daría para hacer una revista solo dedicada
                                                                         El DOM es el conjunto de todos los componentes (elementos,
    a ello. Lo malo es que, como todo lo bueno, apenas vendería un
                                                                         atributos, comentarios, entidades, texto...) que conforman el
    millar de ejemplares… aunque la cosa quizá está cambiando…
                                                                         documento XML.
    hasta hace poco únicamente las grandes corporaciones podían
    acceder a un sistema de este calibre (no solo por el precio, sino
                                                                         Todos estos componentes se denominan objetos.
    por lo complejo de su puesta en marcha, implantación, gestión,
    mantenimiento…); pero actualmente las empresas que crean este
                                                                         Por ejemplo, si nuestro PC fuera un documento XML, el DOM estaría
    tipo de productos están haciendo un guiño a las medianas e incluso
                                                                         formado por el disco duro, la memoria, el procesador, la pantalla,
    pequeñas empresas sacando al mercado "mini-ERPs" diseñados
                                                                         la frecuencia de la pantalla....
    específicamente para determinados sectores empresariales.

                                                                         El DOM es independiente del lenguaje de programación con el que
    Con esta nota, simplemente pretendemos abrir un poco tus
                                                                         estemos trabajando. Podemos acceder al DOM XML tanto con Java,
    horizontes. Los usuarios de informática muchas veces creemos
                                                                         como con Visual Basic, C, JavaScript...
    conocer los programas más importantes/difundidos, pero seguro
    que muy pocos lectores habrán instalado alguna vez un ERP en
                                                                         Está basado en lo que se denomina interfaz de nodos = un
    su ordenador. Si tenemos en cuenta que los ERP dominan el
                                                                         conjunto de métodos (funciones) y propiedades para los objetos
    mundo y que son los programas utilizados por las grandes
                                                                         (elementos, comentarios, atributos, entidades... del documento
    empresas/instituciones… ¿cómo es posible que la inmensa mayoría
                                                                         XML) DOM.
    de los usuarios no tengan/tengamos ni idea del tema?... Desde
    aquí te invitamos a que investigues sobre ello ;)
                                                                         El DOM es una vista estructurada de un documento XML. Podemos
                                                                         verlo como un árbol, y sus hojas:
                                                                          Una estructura de tipo árbol y las hojas se llaman nodos.
¿QUE ES EL DOM?
                                                                         Recordemos el XML de ordenes de compra:
DOM = Document Object Model, es decir modelo de objetos
del documento xml.                                                       <?xml versión="1.0" standalone="yes"?>
                                                                         <ORDEN_DE_COMPRA>
Hemos visto que un XML puede ser lo siguiente:                                    <CLIENTE>


<DOCUMENTO>                                                              <NUMERO_DE_CUENTA>12345678</NUMERO_DE_CUENTA>
      <BIENVENIDA> Hola, buenas tardes </BIENVENIDA>                                   <NOMBRE_COMPLETO>
</DOCUMENTO>                                                                                 <NOMBRE>Sam</NOMBRE>
                                                                                             <APELLIDO1>Bass</APELLIDO1>
Pues el modelo de objetos de este documento estaría formado por                              <APELLIDO2></APELLIDO2>
TODOS los elementos que lo componen, o sea por el elemento                             </NOMBRE_COMPLETO>
DOCUMENTO, y por el elemento BIENVENIDA y si por ejemplo el                     </CLIENTE>
elemento BIENVENIDA tuviera un atributo que se llamara "hora":           </ORDEN_DE_COMPRA>


<DOCUMENTO>                                                              Los elementos, comentarios, atributos, entidades, texto
         <BIENVENIDA hora="13:00"> Hola, buenas tardes </BIENVENIDA>     etc. que contiene el documento xml , se denominan todos
</DOCUMENTO>                                                             como NODOS, así tenemos que <NOMBRE> es un NODO y
                                                                         "Sam" es otro NODO.
también sería parte del DOM, y si hubiéramos escrito un comentario:      Y el conjunto de NODOS con sus funciones (lo que podemos


 Página 6                                                                                                        PC PASO A PASO Nº 13
XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM




hacer sobre los nodos) y propiedades se denomina
INTERFAZ DE NODOS.

Y ve á m o s l o r e p r e s e n t a d o c o m o u n c o n j u n t o d e n o d o s
que dibujaremos con elipses, y su contenido(el texto)
q u e re p r e s e n t a r e m o s c o n n o d o s re c t á n g u l o s ( e s u s u a l
 dibujarlo todo en rectángulos, pero he preferido
hacer esta primera aproximación de esta manera):




Si esto fuese un objeto Visual Basic, nos gustaría ser capaces de
manipular estos nodos, y leer y manipular sus valores. El objeto
Visual Basic que contiene el documento xml se llama
DocumentObject y los nodos son una matriz de objetos de tipo
NODE.

Con lo que la instrucción DocumentObject.Node (index).value nos
proporciona el valor de un nodo en particular. Y esto es básicamente
lo que el DOM (Document Object Model) XML hace: carga en
memoria el documento (con todos sus nodos) y accede, modifica,
añade, elimina…

Pero no nos adelantemos.

TIPOS DE NODOS QUE PUEDE CONTENER UN
DOCUMENTO XML

Todos los nodos comparten propiedades y métodos comunes, pero
dependiendo del tipo de nodo que sea, tiene unas propiedades
y métodos particulares.


  PC PASO A PASO Nº 13                                                                    Página 7
XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM




           Cuando estemos programando el DOM, podremos            Los elementos y el Texto, se tratan con las tres primeras interfaces
           hacer referencia al nodo indicando el tipo de nodo     (DOMDocument, XMLDOMNode y XMLDOMNodeList)
           (NODE_ ATTRIBUTE por ejemplo) o a su valor             Los atributos, no son hijos de ningún otro elemento, sino que
           númerico (2 para el NODE_ ATTRIBUTE)                   forman parte de un elemento. Como caracterizan a un elemento,
                                                                  es decir describen características de un elemento, son diferentes
           Siguiendo el ejemplo anterior:                         a los otros nodos, no están considerados como hijos de ningún
                                                                  padre y se tratan con la interfaz XMLDOMNamedNodeMap
           Serían NODE_ELEMENT:
                                                                  INTERFAZ DOMDocument
           <ORDEN_DE_COMPRA>;<CLIENTE>;<NUMERO
           _DE_CUENTA>;<NOMBRE_COMPLETO>;<NOMB                    Es la interfaz del objeto documento (nodo documento), que
           RE>; <APELLIDO1> y <APELLIDO2>                         incorpora propiedades y métodos para trabajar con el nodo raíz
                                                                  del DOM.
           Serían NODE_TEXT: "Sam" Y "Bass"                       El nodo raíz del DOM representa TODO el documento XML y no
                                                                  lo debemos confundirlo con el elemento raíz del documento.
                                                                  Si miráis el diagrama de nodos que hemos dibujado antes, podéis
           ¿CÓMO MANIPULAMOS EL ARCHIVO                           observar el nodo raíz del DOM arriba del todo, con la leyenda XML.
           XML CON EL DOM?                                        Seguidamente y colgando de el podéis ver el elemento raíz del
                                                                  documento que seria el nodo ORDEN_DE_COMPRA.
           Para manipular un documento XML, lo primero que
           tenemos que hacer es cargarlo en la memoria de         Vamos a irlo viendo todo con un ejemplo.
           nuestro ordenador con un parser XML. Nosotros          Cread en la raíz de vuestro sistema de archivos una carpeta que
           utilizaremos el parser de Microsoft: el Msxml, tal     se llame xmlDom ("C:xmlDom")
           como ya hicimos en el ejemplo de la primera entrega
           (nº 10).                                               Primero crearemos un DTD, contra el cual se validará nuestro xml.
           Una vez el documento está en memoria, ya lo            Abrid un editor de texto y escribid:
           podemos manipular utilizando el DOM
                                                                  <!ELEMENT ORDEN_DE_COMPRA (CLIENTE)>
                                                                           <!ELEMENT CLIENTE (NUMERO_DE_CUENTA,NOMBRE_COMPLETO)>
           El DOM, trata el documento XML como un árbol. El
           DocumentElement es el elemento superior o raíz                  <!ELEMENT NUMERO_DE_CUENTA ( #PCDATA)>
                                                                           <!ELEMENT NOMBRE_COMPLETO ( NOMBRE, APELLIDO1, APELLIDO2) >
           del árbol. Este elemento raíz puede tener uno o
                                                                           <!ELEMENT NOMBRE (#PCDATA)>
           mas nodos (nodes) hijos (child) que representarían
                                                                           <!ELEMENT APELLIDO1 (#PCDATA)>
           las hojas del árbol.
                                                                           <!ELEMENT APELLIDO2 (#PCDATA)>

           Una interfaz, como hemos avanzado antes es un
                                                                  Guardad el archivo como ordenCompra.dtd dentro de la carpeta
           conjunto de métodos (funciones) y propiedades
                                                                  xmlDom
           para los objetos (elementos, comentarios, atributos,
           entidades... del documento XML) DOM.
                                                                  Abrid de nuevo el editor de texto y escribid

           Para acceder a los objetos del dom (los nodos del
                                                                  <?xml version "1.0" standalone="no" ?>
           DOM) disponemos de cuatro interfaces principales,
                                                                  "ordenCompra.dtd">
            que trataremos una a una a continuación:
                                                                  <ORDEN_DE_COMPRA>
                                                                           <CLIENTE>
           1.       DOMDocument                                                      <NUMERO_DE_CUENTA>12345678</NUMERO_DE_CUENTA>
           2.       XMLDOMNode                                                  <NOMBRE_COMPLETO>
           3.       XMLDOMNodeList                                                    <NOMBRE>Sam</NOMBRE>
           4.       XMLDOMNamedNodeMap                                                <APELLIDO1>Bass</APELLIDO1>
                                                                                      <APELLIDO2></APELLIDO2>
           Para la mayoría de documentos XML, los tipos de                      </NOMBRE_COMPLETO>
           nodos más comunes son:                                        </CLIENTE>
           •        Elementos                                     </ORDEN_DE_COMPRA>
           •        Atributos
           •        Texto                                         y guardad el archivo como Compra.xml

Página 8                                                                                                      PC PASO A PASO Nº 13
Hxc13
XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM




            Abrid el Visual Basic y cread un proyecto nuevo tal    '**************Escribid********************
            y como indicamos en el nº 10 (asumimos que tenéis      Dim xmlDocument As DOMDocument
            conocimientos básicos de visual basic): esto es        Dim xmlString as String
            •         Abrid el Visual Basic                        Dim blnValido As Boolean
            •         Seleccionar un Standard exe                  Set xmlDocument = New DOMDocument
            •         Añadid una referencia al DOM. Para ello      '****************************************
                      seleccionar del menú PROYECTO la opción
                      REFERENCIAS.                                 •       Cargar el documento xml en memoria, en el objeto de
            •         Buscad una que pone Microsoft XML, v3.0      tipo DOMDocument (método load()), asignarle algunas propiedades
                      y seleccionarla, haciendo click en el        y comprobar que está bien formado.
                      cuadradito que hay a la izquierda de modo
                      que quede marcado. Y dadle al botón de       '**************Escribid********************
                      Aceptar (yo lo tengo en inglés podéis ver    'Antes de cargarlo en memoria, damos valor a alguna de sus propiedades:
                      que en la pantalla se puede leer OK.)        'primero le indicamos que se ejecute de manera síncrona, esto es que se ejecute
                                                                   'inmediatamente, que se cargue inmediatamente
                                                                   xmlDocument.async = False
                                                                   'le indicamos que se valide contra el DTD
                                                                   xmlDocument.validateOnParse = True
                                                                   'y si hay referencias externas, que las resuelva. Por ejemplo, controlar que el DTD que
                                                                   'referenciamos existe donde le indicamos, en el path que le indicamos.
                                                                   xmlDocument.resolveExternals = True
                                                                   'si el documento es valido, el método Load que es el carga el documento
                                                                   devolverá un valor true, en caso contrario un valor false
                                                                   blnValido= xmlDocument.Load ("C:XmlDomCompra.xml")
                                                                   if blnValido then
                                                                              MsgBox "El documento es válido"
                                                                   Else
                                                                              MsgBox "El documento no cumple con el DTD"
                                                                              Exit sub
                                                                   End If
                                                                   '****************************************************



            Fijaros que el nombre de la referencia es a la dll            !                    Nota aclaratoria
            msxml3.
                                                                          Cuando asignamos un valor a una variable:
            A. DOMDocument CARGAR DEL DOCUMENTO,                          Dim i as integer
            CREAR UN NUEVO DOCUMENTO XML                                  I= 8
                                                                          Lo que estamos diciéndole al ordenador es:
            Colocad un botón en el formulario, id a las                   Dim i as integer => Resérvame un espacio en memoria para un tipo integer
                               propiedades y poner:                       I= 8 => En el espacio que me has reservado, colócame un 8
                               • name = cmdCargar
                               • caption = &Cargar                        En el ejemplo, cuando escribimos
                                                                          Dim xmlDocument As DOMDocument
                               documento xml
                                                                          Set xmlDocument = New DOMDocument
                                                                          xmlDocument.Load ("C:XmlDomCompra.xml")
                                   Codificad el evento click del          Lo que estamos diciendo al ordenador es:
                                   botón:                                 Dim xmlDocument As DOMDocument
                                                                          Set xmlDocument = New DOMDocument =>resérvame un
                                   •   Estas líneas de código             espacio en memoria para un tipo DomDocument
                                   lo que hacen es crear un               xmlDocument.Load ("C:XmlDomCompra.xml") => ponme en
                                   objeto        de     tipo              el espacio reservado el archivo Compra.xml
                                   DOMDocument:



Página 10                                                                                                                     PC PASO A PASO Nº 13
XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM




•         Pedimos que nos muestre el texto del xml en un mensaje:          B.   DOMDocument ACCEDER AL
                                                                           ARBOL DESDE EL ELEMENTO RAIZ,
'**************Escribid********************
                                                                           CONTENIDO DE UN NODO EN
MsgBox xmlDocument.Text
'****************************************                                  PARTICULAR

Si todo va bien, os mostrará el siguiente                                  Podemos acceder al árbol del DOM, empezando por
message box, con todo el texto del                                         la raíz y navegando hacia abajo del árbol (de el
documento:                                                                 nodo mas externo al mas interno) o bien podemos
                                                                           hacer una consulta de un nodo en particular.
•       Vamos a Crear el documento                                         Navegaremos desde el elemento raíz utilizando la
xml Compras2.xml de manera dinámica,                                       propiedad del domdocument documentElement ,
con el método LoadXML                                                      que nos devuelve el elemento raíz, convertido en un
                                                                           objeto de tipo XMLDOMNode (un objeto de la
'**************Escribid***********                                         interfaz XMLDOMNode).
'Ponemos todo el texto del xml en una variable de tipo String
'Fijaros en que he sustituido las dobles comillas de
‘version, de standalone y de la ubicación del dtd por ‘comillas simples         !             Al igual que...

xmlString = "<?xml version='1.0' standalone='no' ?>" & _                        al igual que una propiedad nos puede devolver un valor de
" <!DOCTYPE ORDEN_DE_COMPRA SYSTEM 'C:XmlDomordenCompra.dtd'>      "&_
                                                                                tipo booleano, también nos puede devolver un valor de
" <ORDEN_DE_COMPRA> " & _
                                                                                tipo objeto de una clase. En este caso nos devuelve un
" <CLIENTE> " & _
"    <NUMERO_DE_CUENTA>87654321</NUMERO_DE_CUENTA> " & _
                                                                                objeto de la interfaz documentElement. Por eso hemos
"    <NOMBRE_COMPLETO> " & _                                                    tenido que declarar una variable de este tipo. Veréis este
"      <NOMBRE>Pat</NOMBRE> " & _                                               tipo de asignaciones muy frecuentemente cuando trabajéis
"      <APELLIDO1>Garret</APELLIDO1> " & _                                      con el Dom.
"      <APELLIDO2></APELLIDO2> " & _
"    </NOMBRE_COMPLETO> " & _
" </CLIENTE> " & _                                                         Necesitaremos pues, referenciar de alguna manera
" </ORDEN_DE_COMPRA>"                                                      la interfaz IXMLDOMElement (el DOM tiene mas
                                                                           interfaces que las cuatro principales; esta se utiliza
'el método loadXML carga en memoria, en el dom, la cadena que le pasamos   para nodos de tipo elemento. Es una ampliación de
                                                                           de XMLDomNode) y la interfaz XMLDOMNode. Lo
xmlDocument.loadXML xmlString                                              haremos con dos variables de estos tipos. (Mirad
MsgBox xmlDocument.Text
                                                                           el ejemplo)

'****************************************************
                                                                           Para navegar por el documento, vamos a crear un
                     El texto del segundo mensaje será distinto,
                     ahora os saldrá.                                      nuevo DTD y un nuevo XML muy parecidos a los
                                                                           que hemos estado utilizando hasta ahora.
                             • Finalmente, Guardamos el archivo            Vamos a cambiar solamente el nodo raíz, vamos a
                             xml generado, con un nombre distinto,         hacer que ORDEN_DE_COMPRA cuelgue de un nuevo
                             con el método save                            elemento que llamaremos PEDIDOS. Y ampliaremos
                                                                           la información que puede tener ORDEN_DE_COMPRA
                                                                           añadiéndole el elemento PRODUCTO.
'**************Escribid********************************
'el método save guarda el documento generado o modificado.                 Finalmente vamos a indicar a ORDEN_DE_COMPRA
xmlDocument.save ("C:XmlDomCompra2.xml")
                                                                           que tiene puede tener mas de un orden de compra
'liberamos memoria
                                                                           con el signo +.
On Error Resume Next
Set xmlDocument = Nothing
'****************************************************                      Abrid un editor de texto y escribid:



    PC PASO A PASO Nº 13                                                                                                            Página 11
XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM




<!ELEMENT PEDIDOS (ORDEN_DE_COMPRA+)>                                  Codificad el evento click del botón:
         <!ELEMENT ORDEN_DE_COMPRA (CLIENTE, PRODUCTO)>
         <!ELEMENT CLIENTE (NUMERO_DE_CUENTA,NOMBRE_COMPLETO)>         Private Sub cmdArbolDoc_Click()
         <!ELEMENT PRODUCTO (#PCDATA)>                                 Dim xmlDocument As DOMDocument
         <!ELEMENT NUMERO_DE_CUENTA ( #PCDATA)>                        Dim raizDocumento As IXMLDOMElement
         <!ELEMENT NOMBRE_COMPLETO ( NOMBRE, APELLIDO1, APELLIDO2) >   Dim nodohijo As IXMLDOMNode
         <!ELEMENT NOMBRE (#PCDATA)>                                   Dim xmlString As String
         <!ELEMENT APELLIDO1 (#PCDATA)>                                Set xmlDocument = New DOMDocument
         <!ELEMENT APELLIDO2 (#PCDATA)>                                'síncrono, externas y DTD
                                                                       xmlDocument.async = False
Guardad el archivo como pedidos.dtd                                    'le indicamos que se valide contra el DTD
Abrid de nuevo el editor de texto y escribid:                          xmlDocument.validateOnParse = True
                                                                       'y si hay referencias externas, que las resuelva.
<?xml version="1.0" standalone="no" ?>                                 xmlDocument.resolveExternals = True
<!DOCTYPE PEDIDOS SYSTEM                                               If xmlDocument.Load("C:xmlDompedidos.xml") Then
         "pedidos.dtd">                                                   MsgBox "El documento es válido"
<PEDIDOS>                                                              Else
         <ORDEN_DE_COMPRA>                                                MsgBox "El documento no cumple con el DTD"
         <CLIENTE>                                                        Exit Sub
                                                                       End If
<NUMERO_DE_CUENTA>12345678</NUMERO_DE_CUENTA>                          'le decimos que raizDocumento = PEDIDOS
             <NOMBRE_COMPLETO>                                         Set raizDocumento = xmlDocument.documentElement
                   <NOMBRE>Sam</NOMBRE>                                'Navegamos por los nodos hijos del elemento raíz
                   <APELLIDO1>Bass</APELLIDO1>                         For Each nodohijo In raizDocumento.childNodes
                   <APELLIDO2></APELLIDO2>                                MsgBox nodohijo.Text
             </NOMBRE_COMPLETO>                                        Next
      </CLIENTE>                                                       'liberamos la memoria
      <PRODUCTO>LIBRO</PRODUCTO>                                       On Error Resume Next
      </ORDEN_DE_COMPRA>                                               Set nodohijo = Nothing
      <ORDEN_DE_COMPRA>                                                Set raizDocumento = Nothing
      <CLIENTE>                                                        Set xmlDocument = Nothing

<NUMERO_DE_CUENTA>987654321</NUMERO_DE_CUENTA>                         End Sub
              <NOMBRE_COMPLETO>
                    <NOMBRE>Jesse</NOMBRE>                             Fijaros en los dos mensajes que os han salido por
                    <APELLIDO1>James</APELLIDO1>                       pantalla:
                    <APELLIDO2></APELLIDO2>
              </NOMBRE_COMPLETO>
       </CLIENTE>                                                                            Seguido de
       <PRODUCTO>DISCO DE VINILO</PRODUCTO>
       </ORDEN_DE_COMPRA>
</PEDIDOS>
                                                                       Vamos a interpretarlo.
Volved al Visual Basic
Colocad un botón en el formulario, id a las propiedades y poner:       El DOM, ha leído el primer nodo que contenía el
•        name = cmdArbol                                               nodo raíz. El nodo raíz es PEDIDOS, y el texto que
•        caption = &árbol del documento xml                            ha leído el DOM es el texto que tenia su primer nodo
                                                                       hijo ORDEN_DE_COMPRA, y el texto que tenia su
                                                                       primer nodo hijo era TODO el texto que contenía
                                                                       ORDEN_DE_COMPRA.

                                                                       ¿Y cual es todo el texto que tiene el primer nodo
                                                                       ORDEN_DE_COMPRA?, pues nada más y nada menos


  Página 12                                                                                                   PC PASO A PASO Nº 13
XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM




          que el texto que tienen todos sus nodos hijos:         Si lo entendéis, si os ha entrado bien en la cabeza,
          •       12345678                                       lo tenéis muy pero que muy bien.
          •       Sam                                            Para consultar un nodo en particular, podemos
          •       Bass                                           utilizar el método getElementsByTagName que
          •       LIBRO                                          devuelve todos los nodos elemento de un tag en
                                                                 concreto. Devuelve un array que contiene todos los
          Y para el segundo nodo ORDEN_DE_COMPRA lo              elementos del documento que tienen ese nombre.
          mismo, todo el texto que tienen todos sus nodos        Recordad que un tag es otra manera de llamar a un
          hijos:                                                 elemento: Al elemento <ORDEN_DE_COMPRA>
          •        987654321                                     también podéis llámalo tag <ORDEN_DE_COMPRA>
          •        Jesse
          •        James                                         Volved al Visual Basic
          •        DISCO DE VINILO                               Colocad un botón en el formulario, id a las propiedades
                                                                 y poner:
          Para verlo mas claro, pensemos en el explorador        •        name = cmdUnElemento
          de windows.                                            •        caption = &Un elemento concreto del
                                                                          árbol
          Supongamos esta estructura de directorios:




                                                                 Codificad el evento click del botón:

                                                                 Private Sub cmdUnElemento_Click()
                                                                 Dim ListaDeNodos As IXMLDOMNodeList
                                                                 Dim xmlDocument As New DOMDocument
                                                                 Dim i As Integer
                                                                 xmlDocument.async = False
                                                                 xmlDocument.validateOnParse = True
                                                                 xmlDocument.resolveExternals = True
                                                                 If xmlDocument.Load("C:xmlDompedidos.xml") Then
                                                                      MsgBox "El documento es válido"
                                                                 Else
                                                                     MsgBox "El documento no cumple con el DTD"
                                                                     Exit Sub
                                                                 End If
          Supongamos que ordenCompra tiene un archivo            MsgBox xmlDocument.xml
          que se llama 12345678.txt                              Set ListaDeNodos = xmlDocument.getElementsByTagName("NOMBRE")

          Supongamos que Apellido1 tiene un archivo que se       For i = 0 To (ListaDeNodos.length - 1)
          llama Sam.txt                                            MsgBox ListaDeNodos.Item(i).xml
          Supongamos que Apellido2 tiene un archivo que se         MsgBox ListaDeNodos.Item(i).Text
          llama Bass.txt                                         Next
          Supongamos que Producto tiene un archivo que se        On Error Resume Next
          llama LIBRO.txt                                        Set ListaDeNodos = Nothing
                                                                 Set xmlDocument = Nothing
          Y pedimos al Sistema Operativo que nos liste todos     End Sub
          los archivos que contiene la carpeta Pedidos....
          Efectivamente nos devolverá lo mismo que nos ha        Utilizamos la interfaz IXMLDOMNodeList, interfaz
          devuelto el DOM de XML.                                que nos permite trabajar con la lista de nodos del
          Pararos un segundo en pensar y analizar este código.   DOM, tal como su nombre indica.


PC PASO A PASO Nº 13                                                                                                             Página 13
XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM




            Fijaros en que el atributo xmlDocument.xml os           a true, preserva los espacios en blanco del documento
            devuelve el contenido de todo el xml, y el atributo     •       ReadyState = nos indica el estado en que
            del ListaDeNodos.Item(i).xml nos devuelve también       se encuentra el documento en este momento. Por
            el contenido de todo el xml que contiene ese nodo,      ejemplo el documento puede hallarse en estado
            y así como el atributo xmlDocument.text nos             LOADING (cargando) o en estado COMPLETE (carga
            devuelve el contenido de texto de todo el documento     completa y el DOM disponible)
            xml, el atributo de la interfaz ixmldomnodelist
            ListaDeNodos.Item(i).text también nos devuelve el
                                                                    •        url = devuelve una cadena (string) que
                                                                    nos informa de la url de Internet donde se halla
            texto del nodo que hemos seleccionado.
                                                                    nuestro xml
            Con ello os quiero demostrar que aunque son
            interfaces diferentes, el comportamiento es el mismo,   Los métodos mas importantes de la interfaz
            si encontráis en alguna otra interfaz las propiedades   DomDocument, son los que hemos visto (load,
            xml, o text, sin hacer ninguna prueba ya podéis         loadXML, getElementsbyTagName y Save) y
            saber lo que devuelve.                                  los de creación de fragmento de xml.
                                                                    Supongamos que queremos añadir otro
            C.   DOMDocument CREAR UN                               ORDEN_DE_COMPRA a nuestro xml: el modo de
            FRAGMENTO DE XML                                        hacerlo es creando un nuevo nodo
                                                                    ORDEN_DE_COMPRA de acuerdo con el DTD(con
            Hemos visto hasta ahora las principales propiedades     todos sus nodos hijos tal como se especifica en el
            de la interfaz DomDocument, pero no todas. Las          DTD) y una vez creado lo insertaremos en el
            otras propiedades son informativas del documento:       documento xml.
                                                                    El tiempo en que este nuevo nodo esta desvinculado
            •        Doctype= devuelve el tipo de documento
                                                                    de nuestro documento XML, tiempo en el que le
            asociado al xml, en nuestro ejemplo nos devolvería
                                                                    estamos añadiendo sus nodos hijos es el tiempo de
            el dtd.
                                                                    creación de un fragmento xml, que es un trozo
            •        PreserveWhiteSpace = que si ponemos            de xml a anexar al xml principal.


            ¿QUIERES COLABORAR CON PC PASO A PASO?
            PC PASO A PASO busca personas que posean conocimientos de
            informática y deseen publicar sus trabajos.
            SABEMOS que muchas personas (quizás tu eres una de ellas) han creado
            textos y cursos para “consumo propio” o “de unos pocos”.

            SABEMOS que muchas personas tienen inquietudes periodísticas pero
            nunca se han atrevido a presentar sus trabajos a una editorial.
            SABEMOS que hay verdaderas “obras de arte” creadas por personas
            como tu o yo y que nunca verán la luz.

            PC PASO A PASO desea contactar contigo!

            NOSOTROS PODEMOS PUBLICAR TU OBRA!!!
            SI DESEAS MÁS INFORMACIÓN, envíanos un mail a
            empleo@editotrans.com y te responderemos concretando nuestra oferta.


Página 14                                                                                                   PC PASO A PASO Nº 13
XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM




       Todo nuevo nodo se construye con los métodos de   con los métodos
       la interfaz DOMdocument que comienzan con la
       palabra create+tipodenodo. Por ejemplo para       •        InsertBefore
       crear un nodo de tipo elemento haremos
       createElement, y para crear un atributo haremos
                                                         •        RemoveChild
       createAttribute etc.                              •        ReplaceChild
                                                         Veremos un ejemplo de cómo crear un nuevo nodo,
       Listado de métodos create que se utilizan         en el próximo capítulo, cuando tratemos la interfaz
       para crear un fragmento xml:                      XMLDOMNode ya que es necesaria para
                                                         "enganchar" un nodo hijo a su padre, por ejemplo
                                                         <NOMBRE_COMPLETO> a <CLIENTE>, o para borrar
       •       CreateAttribute
                                                         un nodo hijo, necesitaremos de muchas de las
       •       CreateCDATASection                        propiedades y métodos que tiene esta interfaz
       •       CreateComment
       •       CreateDocumentFragment                    Tenéis la lista completa de propiedades y métodos
                                                         de DOMDocument en la dirección:
       •       CreateElement
       •       CreateEntityReference                     http://msdn.microsoft.com/library/default.asp?url
       •       CreateNode                                =/library/en-us/xmlsdk30/htm/
       •       CreateProcessingInstruction               xmobjxmldomdocument.asp

       •       CreateTextNode
                                                         ¡Saludos compañeros!

       también podemos, sustituir, insertar los nodos
Programacion en GNU/LiNUX
              Desarrollo de aplicaciones en
               entornos UNiX e iniciaciaon al
                      lenguaje C (II)
                el_chaman.                     Luis U. Rodriguez Paniagua




            Este mes, en nuestra entrega habitual de LINUX entraremos en el temido mundo de los
            punteros en C (entre otras cosas). Coged aire y ADELANTE!!!




            1. Introducción.                                         2.1. Arrays o vectores

                                                                     A casi todos nos sonará el término vector de haberlo visto en
            En el artículo anterior vimos como a la hora de
                                                                     matemáticas. Allí considerábamos un vector o arreglo como una
            realizar un proyecto en un entorno UNiX se suele
                                                                     colección de bloques de datos. En la programación sucederá algo
            emplear una modularización del mismo para mejorar
                                                                     similar: Un array o vector será una colección de datos del mismo
            la productividad. Así mismo comenzamos una breve
                                                                     tipo.
            introducción al lenguaje C que enlazaba con las
                                                                     Además de esta definición, surgen dos términos asociados al
            estructuras de control de dicho lenguaje vistas en
                                                                     término vector: la dimensión y el índice
            el primer artículo de esta serie.
                                                                     Para entender qué es un vector y cómo funcionan estos dos nuevos
                                                                     conceptos, vamos a imaginarnos lo siguiente:
            Este artículo, tal vez por la necesidad de la
            temática, está orientado a la práctica. Se propondrán
                                                                     Tal como vimos en el anterior número podemos definir las variables
            algunos ejercicios y búsqueda de información, que
                                                                     como cajas en las que meter datos. Así mismo vimos que los tipos
            espero hagan de su lectura y estudio un tema
                                                                     de dichas variables nos decían de qué tamaño eran dichas cajas.
            ameno.

                                                                     Dicho esto podremos definir un vector como un conjunto de cajas
            Continuando con lo visto, hoy seguiremos viendo
                                                                     del mismo tamaño colocadas en fila. El índice será la posición de
            algunos de los tipos disponibles en C. En el número
                                                                     una determinada caja dentro de estas cajas y la dimensión será
            anterior se quedaron en el tintero los tipos derivados
                                                                     cómo podemos colocar en el espacio las distintas filas, columnas,
            debido a que he considerado que el tema de los
                                                                     etc... que formarán la geometría de este conjunto de cajas.
            punteros, vectores y matrices, merece un tratamiento
            más profundo que el de los tipos básicos.
            Y sin entretenernos más pasemos ya a los tipos               /* Ejemplo de declaración de varios tipos de vectores o arrays */
            derivados.                                                   /* Vector unidimensional de números enteros */
                                                                         int un_vector[5];
            2. Tipos Derivados.
                                                                         /* Vector bidimensional o matriz de números reales */
            Los tipos derivados serán aquellos que se generen            float una_matriz[5][5];
            a partir de los tipos fundamentales o de otros tipos         /* Vector tridimensional de caracteres */
            derivados. Nosotros veremos los arrays o vectores,
                                                                         char un_cubo[5][5][5];
            punteros, estructuras, uniones y campos de bits.


Página 16                                                                                                     PC PASO A PASO Nº 13
Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II)-




           Como podemos observar en el ejemplo, la declaración    Así por ejemplo, para introducir datos en una casilla
           de un vector corresponde al siguiente esquema:         teclearemos algo como:

           tipo_array nombre_array[dim1][dim2]..[dimN]            un_vector[0] = 34;
           Donde tipo_array será el tipo de datos que contiene    un_vector[1] = 2 + 3;
           el array (es decir el tamaño de cada una de las        una_matriz[2][3] = 3.1416 * 34;
           cajas que lo componen), nombre_array será el           un_cubo[0][2][1] = 'a';
           nombre que demos al array y [dimX] será el tamaño
           tope de cada una de las dimensiones, o dicho de        Para acceder al contenido se hará de manera similar:
           otro modo: el número máximo de cajas que se                  int suma;
           admite en una dimensión.                                    char respuesta;
                                                                       ...
           Para entender mejor el concepto de dimensión,               suma = un_vector[0] + un_vector[1];
           representemos gráficamente el código arriba visto:          printf("%f", una_matriz[2][3]);
                                                                       ...
                                                                       printf(" Teclee una letra: ");
                                                                       scanf("%c", &respuesta);
                                                                       if( un_cubo[0][2][1]==respuesta)
                                                                       printf("Ha pulsado una a");



                                                                       !                  No se intente...

                                                                       No se intente buscar sentido alguno a los dos últimos
                                                                       ejemplos: Están hechos con la intención de mostrar el
                                                                       acceso a los componentes de un array. Fíjense en cómo se
                                                                       acceden a los datos, no en lo que se hace con ellos. Este
                                                                       será un tema que trataremos a lo largo del curso.
                                                                       En el primer ejemplo mostramos como introducir datos en
                                                                       casillas concretas de los distintos arrays dependiendo del
                                                                       tipo de estos, y en el segundo caso mostramos como sacar
                                                                       datos de dichos arrays.


                                                                   A continuación vamos a hacer un programa que
                                                                   cree una matriz de dimensión 3x4 (tres filas y cuatro
           Observando el gráfico arriba expuesto, accederemos     columnas) y la llene de con sus coordenadas de la
           al contenido de cada casilla mediante sus              siguiente manera: El número almacenado en cada
           coordenadas. Obsérvese algo muy importante: En         casilla mostrará en su parte entera el número de
           C, siempre los índices empiezan a contar desde 0.      fila, y en su parte decimal en número de columna.
           Esto quiere decir que si declaramos un vector con      Así las segunda casilla de la primera fila contendrá
           cinco casillas, a la hora de poner su dimensión        un 0.1 (Recordemos que las coordenadas empiezan
           pondremos int un_vector[5] pero a la hora de           a contar en C siempre desde 0).
           acceder a todas sus casillas pondremos un_vector[0],
                                                                  /*
           un_vector[1], un_vector[2], un_vector[3] y
                                                                  * Programa: ej00.c
           un_vector[4] siendo el número total de casillas
                                                                  *
           cinco, pero siendo el valor máximo del índice una
                                                                  * Descripción: Crea una matriz de dimensión 3x4, llena cada casilla
           unidad menor que la dimensión total del vector.
                                                                  * con sus coordenadas de la siguiente manera:


 PC PASO A PASO Nº 13                                                                                                                   Página 17
Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II)




            * _____ _____ _____ _____                                                     representar las coordenadas de la casilla en un único
            * |_0.0_|_0.1_|_0.2_|_0.3_|                                                   número. Puesto de otra forma:
            * |_1.0_|_1.1_|_1.2_|_1.3_|
                                                                                             matriz[num_fila][num_col]= num_fila + (num_col * 0.1);
            * |_2.0_|_2.1_|_2.2_|_2.3_|
            *                                                                             Así para la casilla matriz[0][2] tendremos que su
            * e imprime el contenido de la matriz por pantalla.                           contenido será 0 + ( 0.2 ) = 0.2.
            *
            * Compilación:                                                                Hasta ahí todos de acuerdo. Ahora bien: ¿ Qué
            *      gcc ej00.c -o ej00                                                     significa eso de poner (float) delante de las variables
                                                                                          contadoras i y j?.
            */
            #include <stdio.h>                                                            A esto se le denomina casting y consiste en
            main()                                                                        transformar el tipo del resultado que nos devuelve
            {                                                                             una operación cuyos operadores son den tipo distinto
                   /* Declaración de la matriz de tres filas por cuatro columnas */       a quien va a recibir el dato. Dicho de otra manera:
                   /* Tiene que ser de números reales */                                  Sirve para cambiar el tipo de un dato en tiempo de
                   float matriz[3][4];                                                    ejecución.
                   /* Declaración de variables auxiliares contadoras */
                                                                                          Si prestamos atención a la línea de la que estamos
                   int i,j;
                                                                                          hablando, veremos que los operadores son de tipo
                   /* Llenamos la matriz con datos */
                                                                                          entero, pero no así el resultado que esperamos
                   /* i contará filas */
                                                                                          conseguir tras la operación. Es por ello que ese
                   for(i=0;i<3;i++)                                                       resultado lo tenemos que convertir a real. En próximos
                   {                                                                      ejemplos veremos más usos del casting.
                         /* j contará columnas dentro de cada fila */
                         for(j=0;j<4;j++)                                                 2.1.1. Ejercicio 0.0
                         {
                                                                                          Se desea hacer un juego del tres en raya para dos
                                matriz[i][j]= (float)(i + (j * 0.1));
                                                                                          jugadores humanos muy sencillo. Las posibles
                         }
                                                                                          pantallas a mostrar a lo largo del juego pueden ser
                   }
                                                                                          las siguientes:
                   /* Imprimimos la matriz */
                   for(i=0;i<3;i++)                                                              ___|___|___       _X_|___|___
                   {
                         for(j=0;j<4;j++)                                                        ___|___|___       ___|_O_|___

                         {
                                                                                                 ___|___|___       ___|___|_O_
                                printf(" %1.1f ",matriz[i][j]);
                         }                                                                Se pide además que el estado del tablero actual se
                         /* Después de imprimir una fila, debemos de saltar una línea*/   conserve en una matriz de dimensión 3x3 de números
                         printf("n");                                                    enteros.
                   }                                                                      Entrada y Salida
            }
                                                                                          La entrada y la salida en C se realizan habitualmente
            En este programa de ejemplo, debemos de abundar                               sobre los dispositivos de entrada estándar ( stdin )
            en una línea un tanto extraña:                                                y salida estándar ( stdout). Tradicionalmente se
                                                                                          asocia la entrada estándar al teclado y la salida
                 matriz[i][j]= (float)(i + (j * 0.1));                                    estándar a la pantalla de la consola, pero esto no
                                                                                          tiene porqué ser así siempre. Ya trataremos con
            En un principio puede parecer que efectivamente                               ficheros y veremos que stdin y stdout no son más
            estamos empleando la fórmula adecuada para                                    que dos de los muchos flujos de datos que podremos

Página 18                                                                                                                            PC PASO A PASO Nº 13
Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II)




           emplear en un programa.                                                        que estamos tratando :

           A efectos prácticos nosotros consideraremos por                                Tabla 1. Formatos de tipos de dato
           ahora que la entrada estándar (stdin)
           es el teclado y tiene una función de
           lectura asociada llamada scanf y que la
           salida estándar (stdout) es la consola
           del ordenador y tiene asociada la función
           printf.

           En conclusión: La lectura de datos del
           teclado se hará mediante scanf y la
           impresión de datos en la pantalla de la
           consola se hará mediante printf.

           Un ejemplo de lectura de datos puede
           ser:
                   int coor_x, coor_y;
                   ...
                   printf("n Deme la coordenada X: ")
                   scanf("%i",&coor_x);
                   printf("n Deme la coordenada Y: ");
                   scanf("%i",&coor_y);
                   ...
                                                                                          Para estos formatos podemos también especificar el
           Observese el & que ponemos delante de la variable                              ancho de caracteres reservados para expresar un
           donde queremos depositar el dato leído por teclado.                            número. Asi %5i reservaría 5 caracteres para imprimir
           Al término del artículo de hoy seremos capaces de                              un número entero, independientemente de la longitud
           comprender qué significa ese & y por qué lo ponemos                            de este. %5.2f reservaría 5 caracteres para imprimir
           ahí. Por ahora baste decir que estamos depositando                             la parte entera y dos para la parte decimal, etc...
           el dato leído en la posición de memoria donde se
                                                                                          Obsérvese también, que debemos de poner la cadena
           encuentra la variable donde queremos que se guarde
                                                                                          de formato en el lugar exacto donde queremos que
           dicho dato.
                                                                                          se imprima el dato, y, posteriormente una lista de
           Un ejemplo de impresión de datos puede ser:                                    variables que irán en el mismo orden el que queremos
                                                                                          que aparezca el dato.
           int var_entera=3;
           float var_real=3.14;                                                           Dadas las siguientes variables:
           char cadena[8]="Hola0";                                                             int varA=3;
           char var_char='a';                                                                    float varB=4;
           printf("Valores: %i, %f, %s, %c. ", var_entera, var_real, cadena, var_char);
                                                                                               char varC[6]="Hola0";
           A la hora de imprimir el contenido de una variable,                                 char varD='e';
           (o de leerlo, observar el ejemplo anterior de scanf,
                                                                                          Serán ejemplos correctos:
           tenemos que decir de alguna manera a las funciones
                                                                                               printf(" %3i ", varA);
           de lectura o escritura de datos por entrada y salida
           estándar respectivamente ( scanf y printf ) qué es                                 scanf("%f",&varB);
           lo que van a leer o escribir. Para ello se emplean                                 printf("Una cadena: %s y un real: %3.6f ",varC, varB);
                                                                                              printf("Una letra %c y un número: %i", varD, varA);
           las cadenas de formato. Las cadenas de formato
                                                                                              printf("Una letra %c y otra letra %c", varD, varC[1]);
           son esas letras que comienzan por % y que en
                                                                                              printf("Decimal: %i, Octal: %o, Hexadecimal: %x ", varA, varA, varA);
           función de su valor, indican el tipo de dato con el

 PC PASO A PASO Nº 13                                                                                                                                                 Página 19
Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II)




            E incorrectos:                                                Prescindiendo de esa oscura mitología y de historias
               printf(" %i ", varC);                                      espeluznantes que se cuentan relacionadas con los
               scanf("%f",&varA);                                         mismos, trataremos de presentar los punteros de
               printf("Una cadena: %s y un real: %f ",varD, varA);        una manera clara y asequible, de manera que les
               printf("Una letra %c y un número: %i", varA, varD);        perdamos el miedo pero nunca el respeto, dado que
               printf("Una letra %c y otra letra %c", varD, varC);        son una de las herramientas más potentes que nos
               printf("Decimal: %i, Octal: %o, Hexadecimal: %x ", varA)   suministra el lenguaje C.

            Además de las cadenas de formato, printf admite               2.2.1. ¿Qué son los punteros?:
            una serie de caracteres no imprimibles o secuencias           Desmitificando al monstruo
            de estape como son:
                                                                          Un puntero no es más que una variable que cuyo
            Tabla 2. Secuencias de escape para printf                     contenido, en vez de datos, son direcciones de
                                                                          memoria.

                                                                          Dicho de otra forma: Hasta ahora utilizábamos las
                                                                          variables para guardar cantidades numéricas,
                                                                          caracteres o cadenas de texto. Ahora utilizaremos
                                                                          un tipo especial de variable que será capaz de guardar
                                                                          una dirección de memoria.

                                                                          Contemplemos el siguiente esquema que nos resultará
                                                                          familiar del anterior artículo (PC PASO A PASO 12):




            El programa debe se capaz de verificar cuando se
            ha hecho tres en línea y cuándo ha habido tablas.
            Así mismo debe de verificar que las coordenadas
            están dentro del rango permitido y el turno de cada
            jugador.

            2.2. Punteros

            Los punteros suelen ser el caballo de batalla al que
            se enfrentan los programadores que se adentran
            por primera vez en lenguajes como C o Pascal.


Página 20                                                                                                          PC PASO A PASO Nº 13
Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II)




             En la primera línea resaltada char *var_puntero;,          Otros ejemplos de declaración de punteros serán:
             lo que hacemos es declarar una variable
             de tipo puntero que es capaz de apuntar a                    int *p_entero;

             direcciones de memoria (es decir, es capaz
                                                                          float *p_real;
             de guardar direcciones de memoria), que
             contengan un dato char. Esto puede causar                    char *p_caracter;
             confusión dado que si sabemos que los
             punteros contienen direcciones de memoria, ¿qué
              necesidad hay de asociarlos un tipo? Esta pregunta,           !                Existe un tipo de...
             que en principio puede parecer compleja, queda
             explicada cuando más adelante veamos que como
             el resto de las variables podemos realizar operaciones         Existe un tipo de puntero denominado void que virtualmente
             aritméticas con el contenido de las mismas, como
                                                                            en conjunción con el casting es capaz de apuntar a cualquier
             por ejemplo el incremento. Claro que no es lo mismo
                                                                            tipo de variable o dirección de memoria. Recomiendo que
             incrementar una dirección que apunta a caracteres
                                                                            el lector investigue por su cuenta este tipo de punteros pues
             la cual se incrementará (siempre según la figura)
                                                                            muy pronto los veremos. Ya sabes: www.google.com ;)
             de un byte en un byte, que incrementar la dirección
             que apunta a un número real, que aumentará de
             cuatro en cuatro bytes. Es decir, el puntero "debe
             conocer a qué apunta".                                     2.2.2. Operadores sobre punteros

                                                                        Dos son los principales operadores que se utilizan en relación con
   !             Aunque esta...                                         los punteros:

   Aunque esta explicación no sea muy formal, creo que sirva            & (ampersand)
   para comprender alguno de los comportamientos particulares
   de los punteros.                                                     El operador & nos devuelve la dirección de memoria donde se
                                                                        encuentra una determinada variable.
   No es la primera vez que en esta serie de artículos se
   prescinde del rigor informático en favor de la claridad de           Algunos ejemplos de este operador son:
   la exposición del tema. Por poner un ejemplo, en el esquema
                                                                                var_puntero=&caracter;
   de arriba (ya presente en el anterior artículo) existe un
   gazapo muy sutil. Está relacionado en la manera en como
                                                                                /* El ejemplo visto arriba. A var puntero le asignamos la dirección
   se guardan los números reales en la memoria de un
                                                                                de memoria donde reside caracter. En la figura la variable
   ordenador. Dejo al lector la tarea de encontrar este gazapo.
   En esta búsqueda, espero, aprenderá y comprenderá mucho                      caracter se encuentra en la posición 00, luego var_puntero
   sobre las representaciones de datos en la memoria de una                     contendrá dicha dirección (apuntará a dicha dirección) */
   computadora.                                                                 int cosa1, cosa2;
                                                                                int *pent;
                                                                                pent=&cosa1;
             Tras examinar esta línea llegamos a la conclusión
             de que un puntero se declara siempre según el                      printf("La dirección de cosa1 es %m", &cosa1);
             siguiente esquema:                                                 pent=&cosa2;
                                                                                printf("La dirección de cosa2 es %m y el puntero apunta a %m",&cosa2,pent);
                tipo_dato *nombre_variable_puntero;                             printf("El puntero pent que está en %m apunta a %m", &pent, pent);

             Como vemos es el asterisco precediendo al nombre           * (asterisco)
             de la variable el que convierte a esta en un puntero:
             El asterisco, en el caso de la declaración de variables,   Este operador nada tiene que ver con lo explicado arriba sobre
             es quien dice si la variable es un puntero y no una        como se declara una variable puntero.
             variable normal.

 PC PASO A PASO Nº 13                                                                                                                     Página 21
Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II)




            Este operador que precede siempre a una variable                              char *pchar1, *pchar2;
            puntero, nos devuelve el contenido de la dirección                            /* Inicializamos las variables */
            almacenada por el puntero. Ojo: El contenido de la                            vchar1='a';
            dirección almacenada por el puntero. Por poner un                             vchar2='b';
            ejemplo, imaginemos que el código de la figura lo                             /* Inicializamos los punteros */
            cambiamos a:
                                                                                          pchar1=&vchar1;
                      #include <stdio.h>                                                  pchar2=&vchar2;
                         main()                                                           /* Imprimimos información */
                          {                                                               printf("n Tras ejecutar las siguientes instrucciones:nn");
                              char caracter;                                              printf("t033[31;1m vchar1='a';n");
                              char *var_puntero;
                                                                                          printf("t vchar2='b';nn");
                              /* código ignorado por carecer de importancia */
                                                                                          printf("t pchar1=&vchar1;n");
                              caracter=10;
                              var_puntero=&caracter;                                      printf("t pchar2=&vchar2;033[0;0mnn");
                              printf("%c", *var_puntero);                                 printf(" El contenido de las variables y los punterosn");
                          }                                                               printf(" es el siguiente:n");
                                                                                         printf("n 033[34;1m Dir Variable tt ContenidottContenido de lo apuntado 033[0;0m");
            En este programa imprimiremos lo que hay
            almacenado en la dirección que contiene la variable                           printf("n &vchar1 = %x,t vchar1 = %c", &vchar1, vchar1);
            puntero; es decir, en la dirección donde apunta el                            printf("n &vchar2 = %x,t vchar2 = %c", &vchar2, vchar2);
            puntero. Como hemos hecho que el puntero contenga                            printf("n &pchar1 = %x,t pchar1 = %x,t *pchar1 = %c", &pchar1, pchar1, *pchar1);
            la dirección (apunte) de la variable caracter (la
                                                                                         printf("n &pchar2 = %x,t pchar2 = %x,t *pchar2 = %c", &pchar2, pchar2, *pchar2);
            dirección 00 en el diagrama) en la instrucción
                                                                                          printf("n");
            var_puntero=&caracter, el contenido de lo apuntado
            por el puntero será el contenido de la variable a la
                                                                                   }
            que apunta el puntero: el caracter correspondiente
            al decimal 10 (salto de línea).                                        Tras su ejecución, obtendremos una salida similar a esta:

            A este acceso al contenido de una variable mediante                    luis@nostromo:~/hxc/articulo6_el_chaman$ ./ej01
            un puntero se le denomina indirección.
                                                                                   Tras ejecutar las siguientes instrucciones:
            A continuación muestro un pequeño programa que                                vchar1='a';
            puede llegar a facilitar la comprensión de los                                 vchar2='b';
            operadores & y *
                                                                                           pchar1=&vchar1;
            /*
                                                                                           pchar2=&vchar2;
            * Programa: ej01.c
            *                                                                      El contenido de las variables y los punteros es el siguiente:
            * Descripción:
            *    Este programa muestra el comportamiento básico de los punteros.       Dir Variable                   Contenido              Contenido de lo apuntado
            *
            * Compilación:                                                         &vchar1 = bffff9f7,               vchar1 = a
            *      gcc ej01.c -o ej01
            */                                                                     &vchar2 = bffff9f6,                vchar2 = b
            #include <stdio.h>
            main()                                                                 &pchar1 = bffff9f0,                pchar1 = bffff9f7,              *pchar1 = a
            {
                   char vchar1, vchar2;                                            &pchar2 = bffff9ec,                pchar2 = bffff9f6,                  *pchar2 = b



Página 22                                                                                                                                   PC PASO A PASO Nº 13
Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II)




   !                 Ejercicio 0.1
                                                                              *
  Ejercicio 0.1                                                               * Compilación:
                                                                              * gcc ej02.c -o ej02
  Teniendo el siguiente código:                                               *
                                                                              */
        /*                                                                   #include <stdio.h>
             * Programa: ej02.c                                              main()
              *
             * Descripción: Segundo ejercicio del artículo 6                 {
              *                                                                       int a,b, *pInt;
             * Compilación:
             * gcc ej02.c -o ej02
              *                                                                           pInt=&a;
              */                                                                          *pInt=3;
             #include <stdio.h>
                                                                                          pInt=&b;
             main()                                                                       *pInt=5;
             {
               int a, b, *pInt;                                                           printf("n a = %i, b = %i n",a,b);
                                                                             }
                 ........
                 ........
                 ........
                 ........
                                                                    2.2.3. Operando con punteros
                 printf("n a = %i, b = %i n", a, b);
             }                                                      Anteriormente hemos mencionado que los punteros
                                                                    se pueden incrementar y decrementar. Cuando
  Sustituir las líneas punteadas por las instrucciones necesarias   hagamos esto tendremos que tener presente que lo
  para que el resultado sea:                                        que se incrementa o decrementa es el contenido del
                                                                    puntero, o dicho de otra forma: una dirección de
                                                                    memoria.
  luis@nostromo:~/hxc/articulo6_el_chaman$ ./ej02
                                                                    Prestemos atención a este código:
   a = 3, b = 5
                                                                    /*
  ¡Ah! Se me olvidaba. Para este ejercicio están prohibidas             * Programa: ej03a.c
  las siguientes instrucciones:                                         *
         a = 3;                                                         * Descripción:
                                                                    *        Muestra el uso de los operadores incremento y decremento
         b = 5;
                                                                        *     con un puntero.
                                                                        *
                                                                        * Compilación:
   !                 Solución del ejercicio                             *     gcc ej03a.c -o ej03a
                                                                        *
   Solución del ejercicio                                               */
                                                                    include <stdio.h>
    /*
                                                                    main()
    * Programa: ej02.c
                                                                    {
    *
                                                                              /* Declaramos las variables necesarias */
     * Descripción: Segundo ejercicio del artículo 6
                                                                              int vector[5];


 PC PASO A PASO Nº 13                                                                                                                   Página 23
Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II)




                     int i, *pEntero;                                              * Compilación:
                     /* Llenamos el vector con los números 1, 2, 3, 4 y 5 */       *    gcc ej03b.c -o ej03b
                     for(i=0;i<5;i++)                                              *
                     {                                                             */
                          vector[i]=i+1;                                       #include <stdio.h>
                     }                                                         main()
                     /* Hacemos que el puntero apunte al array */              {
                     pEntero = vector;                                                  /* Declaramos las variables necesarias */
                     printf(" %i n", *pEntero);                                        int vectorE[5];
                     pEntero++; /* Equivale a pEntero = pEntero +1 */                   int i, *pEntero;
                     printf(" %i n", *pEntero);                                        char vectorC[5], *pCaracter;
                     pEntero++;                                                         float vectorR[5], *pReal;
                     printf(" %i n", *pEntero);                                        /* Llenamos los vectores con datos */
                     pEntero++;                                                         for(i=0;i<5;i++)
                     printf(" %i n", *pEntero);                                        {
                     pEntero++;                                                              vectorE[i]=i+1;
                     printf(" %i n", *pEntero);                                             vectorC[i]=i+40;
            }                                                                                vectorR[i]=(float)i*0.1;
                                                                                        }
            En este código lo primero que nos debería de llamar
                                                                                        /* Hacemos que el puntero apunte al array */
            la atención es la instrucción pEntero = vector;. Es
                                                                                        pEntero = vectorE;
            fácil pensar que la instrucción adecuada sería pEntero
                                                                                        pCaracter = vectorC;
            = &vector;. Pero no olvidemos que pEntero es un
                                                                                        pReal    = vectorR;
            puntero que apunta a una variable de tipo entero
            mientras que vector representa un conjunto de                               printf("n Los puntero se incrementarán es:");
            variables de tipo entero que sólo puede accederse                           printf("n pEntero: %i bytes", sizeof(int));
            a ellas a través de los índices.                                            printf("n pCaracter: %i bytes", sizeof(char));
                                                                                        printf("n pReal:      %i bytes", sizeof(float));
            Para rizar más el rizo, el programa sería igual de                          printf("n Cada vez que pongamos "puntero++"n");
            válido si en vez de escribir pEntero = vector;,                             printf(" %i, %c, %f n", *pEntero, *pCaracter, *pReal);
            hubiésemos escrito pEntero = &vector[0];.
                                                                                        pEntero++;      /* Equivale a pEntero = pEntero +1 */

            Y esto es porque los vectores y los arrays en general,                      pCaracter++;     /* Equivale a pCaracter = pCaracter +1 */

            a efectos prácticos, son punteros... Y viceversa...                         pReal++;       /* Equivale a pReal     = pReal +1       */
                                                                                        printf(" %i, %c, %f n", *pEntero, *pCaracter, *pReal);
            Al ir aumentando de uno en uno el puntero, podría                           pEntero++;
            parecer que estamos incrementando en un byte la                             pCaracter++;
            dirección de memoria, pero el siguiente código nos                          pReal++;
            va a sacar de dudas:
                                                                                        printf(" %i, %c, %f n", *pEntero, *pCaracter, *pReal);

                /*                                                                      pEntero++;
                * Programa: ej03b.c                                                     pCaracter++;
                *                                                                       pReal++;
                * Descripción:                                                          printf(" %i, %c, %f n", *pEntero, *pCaracter, *pReal);

                * Muestra el uso de los operadores incremento y decremento              pEntero++;
                * con un puntero, así como las peculiaridades de cada tipo              pCaracter++;
                *    de puntero.                                                        pReal++;
                *                                                                       printf(" %i, %c, %f n", *pEntero, *pCaracter, *pReal);
                                                                               }

Página 24                                                                                                                          PC PASO A PASO Nº 13
Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II)




           ¿Por qué sabe cada puntero sabe en cuántas casillas                    Obsérvese que en el segundo bucle for, pEntero se
           debe incrementarse cuando nosotros tan sólo le                         comporta como si de un array se tratase, accediendo
           incrementamos en una posición? Pues porque
                                                                                  al contenido de las distintas posiciones de memoria
           nosotros hemos dicho a cada puntero a qué familia
                                                                                  mediante pEntero[i] donde i es el índice. Observando
           de punteros pertenece al declararlos (int, float,
           char...., de manera que automáticamente los punteros                   el tercer bucle for podemos llegar a la conclusión de
           se incrementarán tantos bytes como ocupen en                           que pEntero[i] es una manera abreviada de escribir
           memoria sus tipos base.                                                *(pEntero + i).... Y no estaremos en absoluto
                                                                                  equivocados.
           Otra particularidad de poder incrementar el contenido
           de un puntero, es la utilización de éste como si de
           un vector se tratase. Veámoslo, porque es cuando
                                                                                  3. Cierre
           menos curioso:                                                         Y con esto termina el artículo de hoy. Ya sólo nos
            /*                                                                    quedan un par de cosillas del lenguaje C (estructuras,
             * Programa: ej03c.c                                                  uniones, campos de bits, funciones, etc.... ) y pronto
             *                                                                    podremos meternos en el C puro y duro.
             * Descripción:
               *    Muestra el comportamiento de un puntero como vector           Puede parecer que en este artículo hemos dejado
             *                                                                    en la cuneta la parte de la programación modular.
             *                                                                    Considero que no ha sido así pues en este artículo
             * Compilación:                                                       ya se manda realizar alguna práctica con lo que
             * gcc ej03c.c -o ej03c                                               espero que os vayáis familiarizando con el compilador
             *                                                                    de GNU.
             */
           #include <stdio.h>                                                     En el número que viene, explicaremos el tema de
           main()                                                                 las funciones con un pequeño proyecto que ya usará
           {                                                                      Makefiles, archivos de cabecera y, como no, funciones,
                /* Declaramos las variables necesarias */                         estructuras de datos, punteros, muchos punteros y
                int vector[5];                                                    alguna que otra macro.
                int i, *pEntero;
                                                                                  Obviamente, antes de enfrentarnos a todo esto,
                   /* Llenamos el vector con los números 1, 2, 3, 4 y 5 */
                                                                                  debemos de tener muy claro que lo que vamos
                    for(i=0;i<5;i++)
                                                                                  viendo lo debemos de manejar con cierta soltura.
                    {
                                                                                  Espero que este artículo os ayude a ello. Nos vemos
                         vector[i]=i+1;
                                                                                  en el foro. Saludos y gracias por vuestra atención.
                    }
                   /* Hacemos que el puntero apunte al array */
                    pEntero = vector;
                                                                                  Bibliografía
                   /* Comportamiento de un puntero como un array "normal" */
                                                                                  man printf; man scanf, Varios.
                   for(i=0;i<5;i++)
                   {                                                              UNiX Programación Avanzada, Fco. Manuel Márquez,
                        printf(" %i ", pEntero[i]);                               Editado por Ra-Ma, ISBN: 84-7897-239-0.
                   }
                   printf("n");                                                  Slackware Linux Unleashed, Bao Ha y Tina Nguyen,
                   /* Comportamiento de un puntero como "base + indirección" */   Editado por Pearson Education, ISBN: 0-672-31768-
                   for(i=0;i<5;i++)                                               0.
                   {
                        printf(" %i ", *(pEntero + i));                           Advanced Linux Programming, Mark Mitchel, Jeffrey
                   }                                                              Oldham, y Alex Samuel, Editado por New Riders,
           }                                                                      ISBN: 0-7357-1043-0.



 PC PASO A PASO Nº 13                                                                                                                      Página 25
Hxc13
Curso de VISUAL BASIC
       UN CLIENTE, UNA NECESIDAD, TENEMOS
              UN PROYECTO (PARTE I)



          VISUAL BASIC es la forma más rápida de crear un programa. Vamos a aplicar los
          conocimientos acumulados y a crear un ” proyecto real”.


          Aquí estamos de nuevo con nuestro particular curso     medianamente decente, que les gestione
          de Visual Basic. Después de varios meses escribiendo   el stock de helados. Nosotros, como proveedores,
          para vosotros he decido que la temática ha             damos una respuesta comercial, y le indicamos
          llegado a su fin, con esto quiero decir que            q u e s o b ra d a m e n t e p o d e m o s a b a r c a r e l
          esta será la última entrega del curso de               proyecto. Ellos nos comentan que necesitan
          aprendizaje de Visual Basic y constará de dos o tres   un software de gestión que catalogue los
          partes.                                                helados por su nombre, y si fuera necesario,
                                                                 su sabor. También cree necesario que se
          Os quiero recordar que la finalidad de esta serie de   controlen las entradas de productos y, como
          artículos era despertaros el gusanillo de la           no, las ventas de estos. La base de datos
          programación y animaros a crear vuestros               debe estar en un servidor central, mientras
          propios programas. Ciertamente, no hemos               que las terminales deben poder interactuar
          dedicado mucho tiempo a ningún tema                    con él. El programa se instalará en diferentes
          relacionado con la seguridad, y creo que ha            puntos de venta, así como en el almacén,
          sido lo correcto, ya que la revista dedica             desde donde se controlarán las entradas.
          gran parte de su contenido a esta temática,            Por último, nos piden que elaboremos un
          y si dejamos a parte la programación como              módulo capaz de crear estadísticas sobre
          tal, estaríamos montando una mesa con tres             las ventas.
          patas.
                                                                 Parece difícil, ¿no?, pues veréis que realmente, así
          Por eso, en este curso, hemos aprendido                es, difícil como lo parece, sobre todo porque el cliente
          Visual Basic desde cero 0, y hemos ido                 nunca queda satisfecho.
          subiendo el nivel progresivamente. Estoy
          seguro que vosotros habéis dedicado horas              Empecemos pues. Lo primero que voy a hacer es
          de vuestro tiempo libre para realizar los              introduciros en un nuevo concepto de organización
          ejercicios y ampliarlos a vuestro gusto,               de formularios, el menú conocido como
          eso me enorgullece. Así que, para acabar y             MDI.
          despedirnos, plantearemos un ejercicio
          con acceso a base de datos, diseño de formularios,     El MDI no es más que un "padre de formularios", es
          organización, etc, etc...                              decir, un formulario gigante que abarca todos los
                                                                 demás. Cuando creamos un formulario MDI, es lógico
          Y es que nos vamos a imaginar a un cliente que         hacerlo padre de los demás formularios que creemos
          tiene una necesidad, y nosotros, como proveedores      posteriormente. Abramos un nuevo proyecto. Lo
          vamos a darle una solución a un altísimo coste,        primero que vamos a hacer es agregar el formulario
          claro... ;)                                            de tipo MDI en el explorador de proyectos. Lo
                                                                 haremos picando con el botón derecho sobre él y
          Nuestro cliente podría ser Micosoft (conocida          eligiendo la opción "Formulario MDI" del menú
          marca de helados), y necesitan un software,            "agregar".


PC PASO A PASO Nº 13                                                                                                            Página 27
Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad




                                                                                                Vamos ahora al cuadro
                                                                                                de propiedades del
                                                                                                formulario MDI.
                                                                                                Indiquémosle que se
                                                                                                abra, por defecto, a
                                                                                                pantalla completa.
                                                                                                Para hacer esto
                                                                                                tenemos que cambiar
                                                                                                la     propiedad
                                                                                                "WindowsState" a
                                                                                                "Maximized".
                                                                                                Ejecutamos y vemos
                                                                                                que aparece una
                                                                                                pantalla que ocupa
                                                                                                todo nuestro área de
                                                                                                trabajo, exceptuando
                                                                                                claro está, la barra de
                                                                                                tareas.

                                                                                                 Cabe decir que
                                                                                                 estamos empezando la
            Apreciaremos que se nos ha agregado al proyecto      casa por el tejado, pero quería dejar claro el concepto
            un formulario más oscuro de lo normal. Tenemos       de formulario MDI antes de empezar a diseñar
            que decirle al proyecto que este será nuestro        nuestra base de datos.
            formulario principal, y que los demás son hijos de
            él.                                                  Para vuestra sorpresa, dejaremos el Access y nos
                                                                 introduciremos en el maravilloso mundo de MySql,
                                                                 que aunque parezca increíble, también se pueden
  !            Posteriormente...                                 gestionar desde Visual Basic. Voy a intentar hacer
                                                                 un resumen de cómo instalarse una base de datos
                                                                 MySql en local. Seré breve, ya que existen cientos
  Posteriormente veremos como hacer que los formularios
                                                                 de manuales que lo explican detalladamente, y
  sean hijos (child) de un MDI.
                                                                 porque si lo explicase todo con pelos y señales, nos
                                                                 ocuparía prácticamente toda esta entrega.

            Para indicar al proyecto que debe iniciarse por      Bien, existen varias formas de tener y gestionar
                                           uno u otro            MySql en tu PC. Una es instalando directamente el
                                           formulario, vamos     gestor que podemos encontrar en
                                           al       menú         http://www.mysql.org (el "database server") y usar
                                           "Proyecto",           el "Control Center" que podemos encontrar en la
                                           "Propiedades" y       misma página. Otra opción es descargar el servidor
                                           en el combo           web Apache, instalarlo y descargar también el
                                           "Objeto inicial"      conocido "PHPMyAdmin", conjunto al script necesario
                                           seleccionamos el      para hacer funcionar PHP en Apache web Server.
                                           nombre         de     Por supuesto esta opción es mucho más complicada,
                                           n u e s t r o         pero lo dejo a vuestra elección. Lo que si debemos
                                           formulario MDI (al    descargar obligatoriamente en los dos casos es el
                                           cual yo he            "Database Server" y el "Conector/ODBC", que nos
                                           l l a m a d o         va a ayudar a crear la conexión con la base de datos.


Página 28                                                                                                 PC PASO A PASO Nº 13
Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad




                                                                                      Una vez creada la base de
                                                                                      datos, vamos a crear una tabla,
                                                                                      para poder hacer pruebas. Esta
                                                                                      tabla será la encargada de
                                                                                      gestionar el stock de helados,
                                                                                      por lo tanto, llamémosla
                                                                                      "stock". Los campos serán
                                                                                      Nombre, Sabor y Cantidad,
                                                                                      siendo Sabor un campo que
                                                                                      aceptará valores nulos.

            Una vez descargados, debemos instalar el servidor
            de base de datos, el driver de ODBC y el "Control
            Center", en este orden a ser posible. Una vez
            instalado todo, y si lo hemos hecho correctamente,
            deberíamos tener en la barra de tareas el icono de
            un semáforo, con la luz verde encendida, que viene
            a indicar que está arrancado el servicio de MySql.



  !            En el curso de apache...
                                                                 Introduzcamos algunos registros para poder hacer
  En el curso de APACHE, publicado en los anteriores
                                                                 una prueba primero de acceso a la base de datos,
  números de la revista, ya instalamos el MySQL paso a
                                                                 por ejemplo, con un par de ellos, tenemos de sobra.
  paso. De todas maneras, si tienes problemas durante la
  instalación, recuerda que en el foro de la revista
  (www.hackxcrack.com) puedes contactar con muchos de
  nuestros lectores y hacer las consultas que quieras, seguro
  que recibes la ayuda que necesitas :)


            Ejecutamos entonces el "Control Center" y
            deberíamos ver un listado de todas las bases de
            datos de prueba que MySql nos ha creado.
            Vamos a crear nuestra base de datos. Con el botón
            derecho en el explorador de bases de datos,          Muy bien. Ahora intentemos un acceso fugaz a la
            seleccionamos "New Database" y la llamamos           tabla. Volvamos al proyecto de Visual Basic y
            micosoft.                                            agreguemos las referencias de acceso a


PC PASO A PASO Nº 13                                                                                                    Página 29
Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad




datos (Microsoft Active Data Objects) y el ADO
DataControl. También vamos a agregar el "Microsoft
 Windows Common Controls 6.0".
Vamos a ayudarnos con el ADO Data Control para
generar una cadena de conexión que utilizaremos
temporalmente para esta prueba. Creo que ya
expliqué los pasos a seguir para generar una cadena
de conexión, pero los volveré a explicar. Añadimos
el Data Control. Vamos a la propiedad
"ConnectionString" y picamos en el botón con puntos
que aparece. Nos debería aparecer un pequeño
formulario con una opción para generar la cadena
de conexión, seleccionamos esa.

Nos volverá a aparecer otro formulario con diferentes
proveedores OLE DB, ignorémoslos. Vamos a la
segunda pestaña y volvemos picar en "Usar cadena
de conexión", "Generar". En la siguiente ventana
elegimos la segunda pestaña y picamos en "Nuevo".
Elegimos la segunda opción, "Orígenes de datos del
sistema", para que todo el que se conecte al equipo                         !            La dirección IP...
lo pueda utilizar. En la siguiente ventana, elegimos
el driver correspondiente a MySql, que seguramente                         La dirección IP que se aparece en la imagen es una dirección
estará de los últimos, y le ponemos un nombre al                           de red interna. Para no tener problemas de acceso, yo
origen de datos.                                                           introduciré el literal "LocalHost".



                                                         Aceptamos varias veces, hasta llegar al punto en que tenemos una preciosa cadena
                                                         de conexión a la base de datos. Agregamos un módulo a nuestro proyecto, un
                                                         módulo que contendrá, por ahora, una variable global con la cadena de conexión,
                                                         una variable de tipo Connection y otra Recordset, además de una función para
                                                         inicializarlos.

                                                         Option Explicit
                                                         Global Cadena As String
                                                         Global Conn As ADODB.Connection
                                                         Global Rs As ADODB.Recordset

                                                         Public Function Conectar() As Long
                                                         On Error GoTo Errores
                                                           Cadena = "DSN=micosoft;DESC=MySQL ODBC 3.51 Driver
                                                           DSN;DATABASE=micosoft;SERVER=localhost;UID=;PASSWORD=;PORT=3306;
                                                           OPTION=3;STMT=;"
                                                           Set Conn = New ADODB.Connection
                                                           Conn.ConnectionString = Cadena
También podríamos introducir la dirección IP en vez
                                                           Conn.Open
del literal "LocalHost" en el cuadro de configuración,
                                                           Exit Function
y testear la conexión inmediatamente después (no         Errores:
os olvidéis de poner el nombre de vuestra BD, no           Conextar = Err.Number
dejéis puesta la que viene por defecto, "test").         End Function


  Página 30                                                                                                    PC PASO A PASO Nº 13
Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad




                                                                     También agregaremos algunos Labels y botones, para poder realizar
  !            La función...                                         mantenimientos del stock. Este es uno de los posibles aspectos
                                                                     del formulario.
 La función "On Error goto Errores" es la manera que tiene           Volvemos un segundo al MDI. La función principal, como ya he
 el Visual Basic de controlar los errores. Esta función está         dicho, del MDI es actuar como menú principal del proyecto. Ya
                                                                     que esta es su función, debemos agregar los módulos necesarios
 indicando que, en caso de que se produzca un error en la
                                                                     para poder abrir los formularios según el usuario final lo necesite.
 conexión a la base de datos, el código haga un salto de
                                                                     Para hacer este acceso más atractivo, nosotros vamos a agregar
 línea hasta la etiqueta "Errores", donde podemos ver que
                                                                     una "ToolBar". La podemos añadir simplemente haciendo doble
 inmediatamente después hace que el valor de la función
                                                                     click sobre ella en el cuadro de herramientas, ya que se posicionará
 sea el número de error que se ha producido, ya que el objeto        automáticamente en su lugar. Vamos ahora a su cuadro de
 "Err" nos puede indicar tanto el número como la descripción.        propiedades y picamos sobre "personalizado". En la primera pestaña
 Un ejemplo para entender mejor esto sería provocar un               tenemos una gran cantidad de opciones que, principalmente,
 error voluntariamente (cambiando caracteres de la cadena            cambian el diseño de la "ToolBar". A nosotros nos interesa la
 de conexión, por ejemplo) y poniendo un "MsgBox                     segunda pestaña, "Botones". Vamos agregando botones a la barra,
 Err.Descripción", recibiendo así un mensaje con la                  usando el botón "Insertar Botón", pudiendo a su vez
 descripción del error.                                              incluir iconos para dar un aspecto más atractivo a la
                                                                     "ToolBar".

            Para ver que no hay errores, llamaremos a la función
            abrir desde el "Form_Load" del MDI.                          !             Para agregar...

                                                                         Para agregar iconos o imágenes a la ToolBar es necesario
            Option Explicit                                              antes añadir al formulario un objeto del tipo "ImageList"
            Dim Error As Integer                                         y agregar aquí las imágenes. Posteriormente podemos
                                                                         indicar a la ToolBar que va a utilizar esta ImageList en la
            Private Sub MDIForm_Load()                                   primera pestaña, e indicar también que imagen corresponde
              Error = Conectar                                           a que botón en la pestaña "Botones", propiedad "Image"
            End Sub

                                          ¿Va bien?, perfecto.
                                          Va m o s a d i s e ñ a r   Una vez acabada la barra de herramientas con los menús, vamos
                                          nuestro primer             a indicarle que, al pulsar stock, se abra el formulario que estamos
                                          formulario, que será       diseñando. Vamos entonces a codificar el evento "Click" de la
                                           en parte nuestro          ToolBar. La cosa quedaría así.
                                           formulario de prueba.
                                           Este nos mostrará         Private Sub Toolbar1_ButtonClick(ByVal Button As MSComctlLib.Button)
                                           el Stock de productos,      Select Case Button.Caption
                                           además de permitir             Case "Stock"
                                           dar de alta, modificar            Stock.Show
                                           y borrar estos.             End Select
                                           Al     formulario         End Sub
                                           agregaremos un
                                           objeto "ListView" que     Yo he decidido utilizar un Select Case, pero sería totalmente válido
                                           nos muestre las           hacerlo con sentencias condicionales de tipo "If". Ejecutamos y
                                           cantidades de helados     vemos que al pulsar sobre "Stock" se nos abre el formulario, pero
                                           que      tenemos,         lo hace de manera independiente, como ignorando al MDI, ya que
                                           separadas por             si cerramos el MDI, el formulario de Stock seguiría abierto, y esto
                                           marcas.                   no es lo que hemos dicho. Lo que aquí falta es que le digamos a


PC PASO A PASO Nº 13                                                                                                       Página 31
Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad




la venta de stock que es hija del principal. Esto se hace poniendo    El siguiente paso sería mostrar todos los datos contenidos en la
a verdadero la propiedad "MDIChild" que todo formulario tiene, y      tabla "Stock" por la lista. El código necesario para esto sería el
en nuestro caso, lo aplicaremos al formulario "stock" y a todos los   siguiente, que pasamos a comentar
que vayamos agregando a partir de ahora.
                                                                                      Set Rs = New ADODB.Recordset
                                                                                      Rs.Open "stock", Conn.ConnectionString, adOpenDynamic, adLockOptimistic

                                                                                      While Not Rs.EOF
                                                                                        With Lista.ListItems.Add(, , Rs("Nombre"))
                                                                                          .SubItems(1) = Rs("Sabor")
                                                                                          .SubItems(2) = Rs("Cantidad")
                                                                                        End With
                                                                                        Rs.MoveNext
                                                                                      Wend




                                                                                      !                Si al intentar...

                                                                                       Si al intentar abrir la conexión esta devuelve un
                                                                                       error de seguridad, revisa los usuarios en el gestor
                                                                                       MySql y los permisos de estos sobre la base de
                                                                                       datos Micosoft, e intenta cambiarlos de tal manera
                                                                                       que cualquier usuario pueda atacar a la base de
                                                                                       datos con instrucciones SQL (Insert, Update,
                                                                                       Select...).

Sigamos en este formulario. Vamos a las propiedades de la lista
y cambiamos la propiedad "View" a "lvwReport", para que el diseño     Es bastante sencillo de entender. La primera línea instancia el
del ListView visualice al estilo"detallado".                          objeto Recordset, mientras que la segunda lo abre. Inmediatamente
                                                                      después creamos un bucle que va añadiendo "Items" a la lista
También podemos cambiar más propiedades de la lista, por ejemplo,     hasta que lleguemos al final del fichero. Vemos que los datos a
en esta imagen vemos como la tengo configurada.                       mostrar son Nombre, Sabor y Cantidad.


                                                                      No se nos debe olvidar mover el objeto Recordset al siguiente
                                                                      registro (Rs.MoveNext), de lo contrario estaríamos creando un
                                                                      bucle infinito que acabaría provocando un desbordamiento de
                                                                      memoria




                                                                          !             La instrucción...

                                                                          La instrucción "with" indica al editor que, al encontrar el
                                                                          carácter "." al comienzo de una instrucción, este hará
                                                                          referencia a lo que tenemos justamente después del "with".
                                                                          Por ejemplo, si pusiéramos la línea "With Rs" cada vez
                                                                          que pulsáramos el carácter "." Se nos desplegaría la lista
                                                                          de propiedades del Recordset "Rs". La instrucción "with"
                                                                          se cierra con "End with"



 Página 32                                                                                                              PC PASO A PASO Nº 13
Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad




            Mmmmm..., ahora que hemos llegado a este punto,
            me doy cuenta de que falta algo en la base de
            datos. Para ser más exactos, un campo clave en la
            tabla stock. Y es que una tabla sin campos clave es
            como un coche sin luces, funciona pero es poco
            recomendable.


  !            ¿Qué es un...

 ¿Qué es un "campo clave"? Para quienes trabajan                      2.- También puedes establecer lo que se llama un campo
 normalmente con bases de datos, esta explicación sobra;              clave combinado. Es cuando la combinación de dos campos
 pero hay muchas personas que nunca han creado una base               (por ejemplo la combinación del campo "nombre" y campo
 de datos y seguro que agradecerán esta nota. Sin entrar en           "apellido") nunca puede dar un valor repetido. En este caso
 tecnicismos diremos que un CAMPO CLAVE es                            no se cumple, porque podemos tener dos amigos que se
 simplemente un campo existente de la tabla creada que                llamen igual y tengan los mismos apellidos.
 no puede en ningún caso contener valores repetidos.

                                                                  Por eso vamos a analizar cual podría ser nuestro
 Para que se entienda: Si estuviésemos creando una agenda
                                                                  campo clave. Sólo disponemos de 3. El primero,
 de nuestros amigos con los campos "nombre" (en este              Nombre, por si solo no puede serlo, ya que pueden
 campo introduciríamos los nombres de nuestras amistades),        haber varios helados con la misma marca (o nombre)
 campos "apellido" (en este campo introduciríamos los             y diferentes sabores, así que rompería la
 apellidos correspondientes a cada nombre) y campos "DNI"         lógica de un campo clave. El segundo tampoco, ya
 (en este campo introduciríamos el DNI correspondiente a          que puede haber decenas de helados con sabor a
 cada nombre), el "campo clave" debería ser el campo              fresa, y el campo cantidad es absurdo. ¿Qué
 "DNI". Está claro que no existirán dos personas con el           hacer entonces?, pues tenemos varias posibilidades,
 mismo DNI :)                                                     pero yo voy a exponer aquí las que encuentro más
                                                                  lógicas. La primera sería convertir en campos clave
 Un par de apuntes:                                               en nombre y el sabor (claro caso de campo
                                                                  combinado), ya que estos si que no se deben repetir
 1.- Imagina que en nuestra agenda no queremos que figuren
                                                                  nunca. No podemos tener en un registro 300
 los DNI. Nos quedarían dos campos ("nombre" y "apellido")
                                                                  Calipos de sabor fresa y en otro 130 Calipos
 y no podemos hacer que uno de ellos sea campo clave
                                                                  más del mismo sabor, ya que en este caso se
 porque podemos tener a dos amigos que se llamen Pedro            sumarían, y tendríamos 430 Calipos de sabor
 o dos amigos que se apelliden González… ¿Qué hacemos             fresa, pero en un solo registro. La otra posibilidad
 entonces? Pues la practica habitual es crear un nuevo campo      es la de añadir un nuevo campo, Llamado
 (llamado por ejemplo "identificador") donde pondremos            Id (identificador), que actúe como campo
 una serie auto-numérica.                                         clave, y se incremente progresivamente por cada
                                                                  registro que añadamos (claro caso de campo clave
 ¿Qué es una serie auto-numérica? Pues muy sencillo,              auto-numérico)
 cuando introduzcamos PEDRO en el campo nombre,                   .
 automáticamente rellenará el campo "identificador" con           Vamos al Control Center de MySql y buscamos la
 un 1, cuando introduzcamos el nombre de un nuevo amigo,          tabla stock. La editamos y creamos el nuevo campo
                                                                  clave "Id", indicando que será AUTO_INCREMENT
 automáticamente se rellenará al campo "identificador" con
                                                                  (auto incremental).
 un dos, el siguiente con un tres y así hasta que nos cansemos.
 De esta forma se consigue un CAMPO CLAVE y nos
                                                                  Añadamos también la correspondiente columna a la
 despreocupamos de todo puesto que encima es automático.          lista y agreguémosla en el código.


PC PASO A PASO Nº 13                                                                                                     Página 33
Hxc13
Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad




          With Lista.ListItems.Add(, , Rs("Id"))                 Private Sub Lista_DblClick()
                 .SubItems(1) = Rs("Nombre")                       MoverDatosACampos
                 .SubItems(2) = Rs("Sabor")                      End Sub
                 .SubItems(3) = Rs("Cantidad")
               End With                                          Ahora deberían cargarse las cajas de texto al efectuar doble click
                                                                 en algún "Item" de la lista.
          Bien, lo que vamos a hacer ahora es crear dos
          procedimientos que habiliten y deshabiliten los        Perfecto, lancémonos entonces a por el primer mantenimiento, por
          botones Aceptar Cancelar, así como las cajas de        ejemplo, el botón modificar. Lo primero que vamos a hacer es una
          texto.                                                 función que compruebe que los campos tienen valores totalmente
                                                                 válidos, ya que de lo contrario tendríamos un error. Por ejemplo,
          Sub Deshabilitar()                                     yo la he llamado "CamposOK", que devolverá verdadero si son
            CmdAceptar.Enabled = False                           correctos y falso si no lo son.
            CmdCancelar.Enabled = False
            Txtnombre.Enabled = False                            Function CamposOK() As Boolean
            TxtSabor.Enabled = False                               If Txtnombre.Text = "" Then
            TxtCantidad.Enabled = False                               MsgBox "Debe rellenar el campo nombre", vbExclamation, "Aviso"
          End Sub                                                     CamposOK = False
          Sub Habilitar()                                             Exit Function
            CmdAceptar.Enabled = True                              End If
            CmdCancelar.Enabled = True                             If Not IsNumeric(TxtCantidad) Then
            Txtnombre.Enabled = True                                  MsgBox "El campo cantidad debe ser numérico", vbExclamation, "Aviso"
            TxtSabor.Enabled = True                                  CamposOK = False
            TxtCantidad.Enabled = True                               Exit Function
          End Sub                                                  End If
                                                                   CamposOK = True
          También vamos a hacer otro procedimiento que nos       End Function
          moverá los datos del "Item" seleccionado en la lista
          a las cajas de texto.                                  Vemos que se trata de una función y no un procedimiento porque
                                                                 debe devolver un valor indicándonos si los campos son correctos
          Sub MoverDatosACampos()
                                                                 o no. También podemos apreciar que no comprobamos el valor del
              Txtnombre = Lista.SelectedItem.SubItems(1)
                                                                 campo Sabor, ya que lo hemos declarado como que acepta valores
               TxtSabor = Lista.SelectedItem.SubItems(2)
                                                                 nulos, porque puede que un helado no tenga un sabor específico
              TxtCantidad = Lista.SelectedItem.SubItems(3)
                                                                 o sea único en su gama.
          End Sub

          Estos dos métodos serán llamados, para empezar,
          después de la primera carga en el evento                   !              La función...
          "Form_Load".

            MoverDatosACampos
                                                                     La función "IsNumeric" devuelve verdadero cuando el
            Deshabilitar                                             valor de lo que introducimos entre los paréntesis es un
          End Sub                                                    número.

          (Este "End Sub" pertenece al Form_Load)
          Si todo ha ido bien, ahora debería cargarse los        Para ser más pulcros, también codificaremos la caja de texto
          campos con los datos del "Item" de la lista al picar   "Cantidad" para que solo acepte números. Por ejemplo, podríamos
          en el botón "Stock" del MDI. También llamaremos        borrar el contenido de esta cuando el usuario, inteligente él como
          a este procedimiento desde el evento doble click       nadie, intente introducir letras en un campo cuyo nombre es
          del ListView                                           "Cantidad" (aunque parezca ilógico, "ellos" son capaces de hacerlo)


PC PASO A PASO Nº 13                                                                                                       Página 35
Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad



            Private Sub TxtCantidad_KeyUp(KeyCode As Integer, Shift As Integer)       CmdBorrar.Enabled = True
               If Not IsNumeric(TxtCantidad) Or KeyCode = 46 Or KeyCode = 44 Then     CmdNuevo.Enabled = True
                TxtCantidad = 1                                                     End Sub
              End If
            End Sub                                                                 En el botón Aceptar comprobaremos el valor de la variable "Estado",
                                                                                     y dependiendo del resultado, modificaremos, daremos de alta o
            Le estamos diciendo que, en el caso de que se                           borraremos. Para modificar, debemos posicionarnos al principio del
            introduzca un valor no numérico, o se introduzca                        Recordset, buscar el registro que deseamos modificar por el campo
            un punto o una coma, el contenido de la caja de                         clave y mover los datos al registro. Este es un posible código
            texto pase a ser "1".
                                                                                    Private Sub CmdAceptar_Click()
                                                                                      Select Case Estado
  !             La variable...                                                           Case "MODIFICAR"
                                                                                           If CamposOK = True Then
                                                                                              Rs.MoveFirst
  La variable KeyCode contiene el código ASCII de la tecla                                    Rs.Find "Id=" & Lista.SelectedItem.Text
  pulsada cuando el foco está en la caja de texto.                                            If Not Rs.EOF Then
                                                                                                 MoverDatosARegistro
                                                                                                 Rs.Update
                                                                                                 MsgBox "Registro modificado"
            Vamos ahora al botón Modificar. Para saber que                                       Lista.ListItems.Clear
            opción hemos pulsado nos declararemos una variable                                   Call Form_Load
            que variará dependiendo si hemos picado en                                        Else
            Modificar, Nuevo o Borrar. La llamaremos "Estado"                                    MsgBox "No se ha encontrado el registro seleccionado, se
                                                                                                 va a recargar la lista", vbCritical, "Error"
            Option Explicit                                                                      call Form_Load
            Dim Estado As String                                                              End If
                                                                                           End If
            Desde el evento Click del botón modificar únicamente                      End Select
            cargaremos esta variable con su correspondiente                           HabilitarBotones
            valor, habilitaremos los botones Aceptar Cancelar y                       Deshabilitar
            deshabilitaremos los botones Nuevo, Modificar y                         End Sub
            Borrar. Este sería el código, rutinas incluidas
                                                                                    Sub MoverDatosARegistro()
            Private Sub CmdModificar_Click()                                          Rs("Nombre") = Txtnombre
              Habilitar                                                               Rs("Sabor") = TxtSabor
              Estado = "MODIFICAR"                                                    Rs("Cantidad") = TxtCantidad
              DeshabilitarBotones                                                   End Sub
            End Sub
                                                                                    Vemos que después del mensaje "Registro modificado", escribimos
                                                                                    "Call Form_Load". Esta es la manera que tiene Visual Basic para
            Sub DeshabilitarBotones()                                               llamar a un evento. En este caso, para recargar la lista, llamamos
              CmdModificar.Enabled = False                                          al evento Form_Load, pero bien podríamos haber codificado la
              CmdBorrar.Enabled = False                                             carga de la lista en una rutina y llamarla en este momento.
              CmdNuevo.Enabled = False
            End Sub                                                                 El mantenimiento "nuevo" es prácticamente igual que el de
                                                                                    modificación, con la diferencia que deberemos hacer un "AddNew"
            Sub HabilitarBotones()                                                  antes de pasar los datos a los campos.
              CmdModificar.Enabled = True                                           El código del botón "Nuevo" sería este:


Página 36                                                                                                                    PC PASO A PASO Nº 13
Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad




Private Sub CmdNuevo_Click()                           innecesario habilitar las cajas de texto.
  Habilitar                                            Para borrar, en el botón aceptar buscaremos el registro seleccionado y lo
  Estado = "NUEVO"                                     eliminaremos con el método "Delete".
  DeshabilitarBotones
  LimpiarCampos                                            Case "BORRAR"
End Sub                                                      Rs.MoveFirst
                                                             Rs.Find "Id=" & Lista.SelectedItem.Text
Sub LimpiarCampos()                                          If Not Rs.EOF Then
  Txtnombre.Text = ""                                           Rs.Delete
  TxtSabor.Text = ""                                            MsgBox "Registro borrado"
  TxtCantidad.Text = 1                                          Lista.ListItems.Clear
End Sub                                                         Call Form_Load
                                                             Else
Si le echamos un vistazo, estamos haciendo lo                   MsgBox "No se ha encontrado el registro seleccionado, se va a recargar la lista", vbCritical, "Error"
mismo que en botón "Modificar" con la diferencia                Call Form_Load
que borramos el contenido de las cajas de texto.              End If
Ahora, codificamos en el botón "Aceptar" para que
haga las operaciones necesarias al intentar dar de     Como veis, tanto Modificar, Borrar y Nuevo son muy parecidos. Tal vez la diferencia
alta.                                                  más visible es que cuando queremos hacer algo contra un registro en concreto
                                                       (Modificar o Eliminar), antes debemos posicionarnos, por ejemplo, con el método
                                                       "Find", mientras que cuando queremos dar de alta no nos hacer falta.
     Case "NUEVO"
                                                       Y que no se me olvide, los botones "Cancelar" y "Salir"
      If CamposOK = True Then
         Rs.AddNew
                                                       Private Sub CmdCancelar_Click()
         MoverDatosARegistro
                                                         Deshabilitar
         Rs.Update
                                                         HabilitarBotones
         MsgBox "Registro dado de alta"
                                                       End Sub
         Lista.ListItems.Clear
         Call Form_Load
                                                       Private Sub CmdSalir_Click()
      End If
                                                         Unload Me
                                                       End Sub
También muy parecido, pero con la diferencia que
en vez de buscar un registro para modificar, hacemos
                                                       Bueno, pues con esto hemos acabado por hoy. Este formulario ha quedado
un "AddNew" para añadir uno nuevo.                     altamente mejorable, así que poneros manos a la obra. En la próxima entrega
                                                       seguiremos con el resto, que aunque serán parecidos, haremos una introducción
He dejado en estas líneas lo que yo consideraría un    al SQL. También podréis tener la gratificación de haber hecho un proyecto
"gazapo"(no es un error de código), que si habéis      medianamente importante, que bien podréis modificar a vuestro antojo e intentar
leído todo el artículo, lo tendríais que ver.          generalizar para que funcionen en varios tipos de negocio. Un saludo, y nos
Posteriormente lo explicaré, pero me gustaría que      vemos!!! --Si no te gusta teclear, en la Web tienes el código completo--
vierais si es lógico lo que estamos haciendo.
Y para acabar, el botón "Borrar"

Private Sub CmdBorrar_Click()                            !                GAZAPO
  CmdAceptar.Enabled = True
  CmdCancelar.Enabled = True
                                                        Gazapo: Pues si nos fijamos en el código para dar de alta, nos damos cuenta que
  Estado = "BORRAR"                                     ignora totalmente si ya existe un helado con ese nombre y ese sabor. Debería sumar
  DeshabilitarBotones                                   las cantidades, es decir, modificar el registro original sumándole el contenido de
End Sub                                                 TxtCantidad, mientras que ahora, erróneamente, está añadiendo un nuevo registro.
                                                        ¿Os veis capaces de hacerlo sin mi ayuda? ---en la próxima entrega os daré la
No llamamos a la función "Habilitar" porque es          solución ;) ---


  PC PASO A PASO Nº 13                                                                                                                            Página 37
RAW                7 : http
              (HyperText Transfer Protocol)




            De nuevo nos adentramos en el conocimiento de los protocolos, esta vez le toca el turno
            al HTTP, para que nos entendamos, el que utilizamos al visualizar una Web :)



            1.      Un poco de historia                        un libro electrónico con el que pudieses
                                                               interactuar escogiendo diversos finales, etc.
            Cuando en el año 1965 Ted Nelson acuñó el          (algo así como los “Elige tu propia aventura”
            término “hipertexto”, difícilmente podría          pero en plan futurista).
            imaginar la extensión que llegaría a alcanzar
            su idea. En realidad, aunque la idea de crear      A pesar de que el primer navegador fue gráfico,
            un sistema de texto con enlaces es muy anterior,   éste sólo existía para plataforma NeXT, por lo
            no fue hasta 1989-1990 cuando Tim Berners-         que los usuarios que tuviesen otros sistemas
            Lee, informático del CERN (Organización Europa     tenían que conformarse con un simple navegador
            de Investigación Nuclear), desarrolló el primer    en modo texto. No fue hasta 1993 cuando
            sistema web para que los científicos del           apareció la primera versión del antes popular
            CERN pudieran compartir información. El            navegador “Mosaic” para X-Windows, que era
            navegador que utilizaban estos científicos para    quizá por aquel entonces la plataforma más
            acceder al sistema fue precisamente el primer      extendida entre los usuarios de Internet
            navegador web de la historia, se llamaba           (formada en su mayor parte por científicos y
            “WorldWideWeb” (posteriormente llamado             algunos estudiantes). A partir de la aparición
            “Nexus”).                                          de Mosaic (que pocos meses después también
                                                               estaba disponible para PC y Macintosh) comenzó
            Aun hoy podemos ver una copia de esta primera      la gran explosión de la WWW, con un crecimiento
            página tal y como era en el año 1992 (no hay       exponencial de vértigo.
            una copia de la página en su primera aparición)
            en la dirección:                                   Mi primer contacto con la WWW fue en el año
            http://www.w3.org/History/19921103-                1995 y, a pesar de que ya existían navegadores
            hypertext/hypertext/WWW/TheProject.html.           gráficos, di mis primeros pasos con el navegador
                                                               en modo texto “Lynx”, en un sistema VMS (uno
            Quizá nos pueda parecer ahora algo totalmente      de esos muchos sistemas operativos que suenan
            cotidiano, e incluso increíblemente simple, el     a chino para la mayoría). No fue hasta el año
            concepto del hipertexto y la www, pero hay         siguiente cuando entré en contacto por primera
            que imaginarse la visión que se podría tener       vez con un navegador gráfico, Netscape, al
            de estas cosas hace 40 años, cuando sólo           conectar por primera vez desde mi casa con un
            pertenecían a la ciencia-ficción. Sin irme tan     modem último modelo de 14400, y el entonces
            lejos, yo aún recuerdo cuando vi por primera       popular Trumpet Winsock. Recuerdo también
            vez la película BIG, en el año 88 (poco antes      cómo hice entonces mi primera página web,
            de que comenzase todo), y me quedé                 escribiendo código HTML a pelo en el bloc de
            maravillado con la idea de que pudiese existir     notas de Windows... Que tiempos!!! XDDD


Página 38                                                                                          PC PASO A PASO Nº 13
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




             2.         Documentación
                                                                                    !             En el número 12...
             No se puede hablar del protocolo HTTP sin
             hablar de otras cosas íntimamente ligadas,                             En el número 12 de PC PASO A PASO recomendamos la
             como son el lenguaje HTML, el estándar MIME,                           lectura de un artículo que, a pesar de su antigüedad, explica
                                                                                    de forma muy amena términos como MIME, ASCII, ISO,
             etc. Si bien la especificación del protocolo
                                                                                    UUENCODE, UUDECODE, BASE64… No dejes de
             propiamente dicho se encuentra en el RFC                               leerlo,          puedes          encontrarlo              en
             2 6 1 6 ( f t p : / / f t p . r f c - e d i t o r. o r g / i n -       http://bitassa.com/articles/babel.html
             n o t e s / r f c 2 6 1 6 . t x t ) , p a ra t e n e r u n a
             documentación completa sobre el tema no
             basta con centrarse en los RFCs, si no que hay                     Pero empecemos aclarando un poco este barullo.
             que documentarse también adecuadamente                             ¿Qué relación guardan entre sí el HTTP, el
             sobre estos otros aspectos.                                        HTML, y el MIME?

                                                                                El HTTP (HyperText Transfer Protocol) no es
  !               Para los nuevos...                                            más que un protocolo que funciona sobre TCP/IP.
                                                                                Al igual que los demás protocolos que hemos
  Para los nuevos lectores, simplemente recordarles que                         ido viendo a lo largo de la serie RAW, el protocolo
  hemos explicado ampliamente en números anteriores qué                         HTTP está formado por una serie de comandos
  son los RFC. En http://www.rfc-es.org encontrarás los
                                                                                y una serie de respuestas que el servidor
  RFC que han sido traducidos al Español, si el inglés no es
  lo tuyo, esta Web es de visita obligada. Por cierto, si eres                  proporciona a esos comandos. Los comandos
  un portento en esto de las traducciones puedes aportar tu                     son muy pocos, pero la complicación del
  granito de arena ofreciéndote a traducir alguno de los                        protocolo se encuentra en los llamados
  muchos RFC que todavía no han sido traducidos :)                              campos de cabecera que son, en cierto modo,
                                                                                como los parámetros que se pasan con cada
             Podéis encontrar en Google o en cualquier                          comando y con cada respuesta.
             librería miles de tutoriales de HTML.
                                                                                El HTML (HyperText Mark-up Language), como
             Por poner un ejemplo, tenéis uno en:                               supongo que todos sabréis, es un lenguaje de
             http://www.davesite.com/webstation/html/                           representación de hipertexto. Podríamos decir
             (lo único que he hecho para encontrar esta                         que el HTTP es como un FTP muy simple pero
             página ha sido pinchar en el primer resultado                      limitado a transferir sólo un tipo de contenidos.
             que me daba Google al buscar “html tutorial”                       En FTP puedes transferir cualquier tipo de
               -->     http://www.google.com <--).                              archivos, y en HTTP transfieres básicamente
                                                                                sólo código HTML.
             Con respecto al MIME, se encuentra también
             definido en varios RFCs. En la página:                             Con respecto al MIME (Multipurpose Internet
             http://www.mhonarc.org/~ehood/MIME/ podéis                         Mail Extensions), hay que tener en cuenta que
             encontrar una lista de RFCs que especifican                        el lenguaje HTML permite la inclusión de
             éste estándar. Si no queréis leeros los 5                          cualquier tipo de contenidos (texto en diferentes
             capítulos completos (RFC 2045, RFC 2046,                           idiomas, incluidos algunos como el japonés que
             RFC 2047, RFC 2048, y RFC 2049) podéis                             no utilizan los mismos caracteres que el inglés,
             haceros una idea básica leyendo el ya obsoleto                     imágenes en diferentes formatos, audio, vídeo,
             RFC 1521 (ftp://ftp.rfc-editor.org/in-                             etc., etc.). El MIME es un estándar para la
             notes/rfc1521.txt).                                                representación de estos contenidos, que no
                                                                                sólo es usado en la WWW, si no también en

PC PASO A PASO Nº 13                                                                                                                  Página 39
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




            cualquier entorno de Internet que sea               una URL, y la respuesta suele ser el contenido
            susceptible de transportar diferentes contenidos.   HTML de esa página web.
            De hecho, si repasáis los números anteriores
            de la serie RAW, veréis que ya comenté algo
            acerca del MIME en los artículos sobre POP3
            y SMTP. HTTP y MIME no son totalmente
            compatibles. En el apéndice 19.4 del RFC
            2616 podéis encontrar detalladas las
            diferencias entre ambos estándares.

            Como podéis suponer, con este artículo os
            ahorraré el leer toda esta documentación si lo
            único que queréis es tener una visión global
            sobre el tema, y no queréis convertiros en los
            nuevos gurus de la www. :-D                            !            Para los lectores novatos

            Me centraré tan sólo en el protocolo HTTP, ya
            que el MIME y el HTML merecerían artículos             Cada vez que abres el Internet Explorer (o cualquier otro
                                                                   navegador de Internet) y le metes una dirección Web (por
            aparte, aunque no de la serie RAW, ya que no
                                                                   ejemplo www.mocosoft.com) estás estableciendo una
            son protocolos. ;-)                                    conexión básica de HTTP. Tu eres el CLIENTE (el que
                                                                   pide) y el SERVIDOR WEB (el que sirve) donde está
            3. Arquitectura HTTP                                   alojada la página www.mocosoft.com responderá a tu
                                                                   petición enviándote (sirviéndote) el contenido HTML de
            El protocolo HTTP ha sufrido algunas                   la página. Tu "querido" Internet Explorer interpretará ese
                                                                   código HTML y mostrará el resultado en tu monitor.
            modificaciones desde su aparición, y
            actualmente se encuentra en su versión 1.1.

            * La primera versión, HTTP/ 0.9, era un             En cambio, la arquitectura puede ser más
            protocolo muy simple para la transmisión de         compleja (uno de los motivos por los cuales se
            datos sin formato, poco más que un FTP              hizo conveniente la aparición de HTTP/ 1.1),
            simplificado.                                       incluyendo varias máquinas intermediarias en
            * La versión HTTP/ 1.0 (RFC 1945) soportaba         la comunicación. Estos intermediarios pueden
            ya los contenidos MIME, pero no estaba              ser básicamente de 3 tipos: proxies, gateways,
            preparada para soportar algunas características     y túneles.
            avanzadas de la www, como la cache, los virtual
            hosts, etc.                                         Un túnel es simplemente un intermediario que
                                                                retransmite todo lo que recibe sin siquiera tener
            * La actual versión HTTP/ 1.1 surge de la           que comprender ninguno de los contenidos que
            necesidad de dar soporte a estas características.   circulan a través de él. Un gateway, en cambio,
            En el apéndice 19.6.1 del RFC 2616 se               puede realizar traducciones de protocolos cuando
            detallan las diferencias entre HTTP/ 1.0 y          las arquitecturas a ambos lados son
            HTTP/ 1.1.                                          incompatibles, pero los contenidos no se verán
                                                                afectados y las traducciones serán transparentes
            Una conexión básica de HTTP consiste en una         para ambas máquinas. Por último, un proxy,
            petición de un cliente, y una respuesta del         puede modificar los datos transferidos,
            servidor. Típicamente, esta petición suele ser      modificando, por ejemplo, las cabeceras de las

Página 40                                                                                             PC PASO A PASO Nº 13
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




          peticiones (¿recuerdas cuando explicamos en         4. Niveles de conexión
          números anteriores a navegar anónimamente
          mediante proxy? ;p)                                 Hacer todo el estudio del protocolo HTTP con
                                                                           un cliente de Telnet puede ser
                                                                           duro, ya que a veces nos bastará
                                                                           una herramienta que abstraiga
                                                                           algunos parámetros que no nos
                                                                           interesen.

                                                                            Todos conocemos la herramienta
                                                                            principal de más alto nivel de la
          Otra de las características avanzadas de la         que disponemos para manejar el protocolo
          arquitectura que permite manejar el protocolo       HTTP: los navegadores (browsers). Existe
          HTTP/ 1.1 es la cache. En el escenario anterior,    una cantidad enorme de navegadores para
          en el que un cliente conecta con un servidor        todos los sistemas y arquitecturas, y no sólo
          a través de varias máquinas intermedias, puede      Internet Explorer (IE), como parece que muchos
          que la respuesta que reciba el cliente no           quieren hacernos creer.
          provenga directamente del servidor final,
          aunque esto habrá de ser transparente para          Ya que menciono IE, os recuerdo que es una
          el usuario. Alguna de las máquinas intermedias      de las aplicaciones más inseguras que existen
          podría tener una copia de la respuesta del          hoy día. Para que comprobéis que mi afirmación
          servidor ante esa petición, y enviarla              no es gratuita, os propongo que hagáis el
          directamente al cliente sin necesidad de recorrer   experimento de visitar las más importantes
          de nuevo todo el camino de ida y de vuelta          páginas de seguridad informática, y realizar
          hasta el servidor final.                            una búsqueda de la cadena “Internet Explorer”.
                                                              Os pongo como ejemplo una lista de páginas
          Normalmente, las máquinas intermedias tendrán       de seguridad que he consultado, y el número
          en cache las respuestas que ya han sido             de avisos de seguridad que aparecen en esa
          solicitadas previamente por otros clientes (o       página sobre IE:
          incluso por ese mismo cliente), aunque pueden
          incluso tener copias de cache de las páginas        - www.securityfocus.com (569 coincidencias)
          Más solicitadas distribuidas en CD.                 - www.securitytracker.com (301 coincidencias)
                                                                           - www.cert.org (1538
                                                                           coincidencias)
                                                                           - www.theregister.co.uk (447
                                                                           coincidencias)
                                                                           - www.hispasec.com (superado el
                                                                           límite de 50 coincidencias)
                                                                           - neworder.box.sk (superado el
                                                                           límite de 20 coincidencias en la
          El tema de la cache en HTTP es realmente                         sección de exploits, el límite de
          complejo, y podría duplicar la extensión de         30 coincidencias en la sección de exploits
          este artículo, por lo que lo obviaré, al no ser     antiguos, el límite de 20 coincidencias en la
          necesario para una comprensión básica del           sección de artículos, y el límite de 20
          protocolo.                                          coincidencias en la sección de noticias breves)


PC PASO A PASO Nº 13                                                                                            Página 41
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




            Por supuesto, entre todas esas entradas, alguna               HTTP es el 80. En cambio, si es necesario,
            se habrá colado que no sea un aviso de                        podemos especificar cualquier otro puerto.
            seguridad, pero podéis realizar el experimento                * El campo path es un nombre de directorio
            por vosotros mismos y comprobar que la                        relativo al directorio configurado como raíz para
            inmensa mayoría de las coincidencias son                      el servidor web. Esto es totalmente transparente
            referentes a la “seguridad” de IE.                            al usuario, por lo que desde el punto de vista
                                                                          del cliente se puede decir que se trata de un
            Tenéis muchas alternativas a IE en sistemas                   directorio absoluto. En realidad, como ya
            Windows, y no solo Netscape, como también                     sabemos, existen formas de saltarse esto del
            intentan hacernos creer (de hecho, Netscape                   directorio raíz del servidor web, y acceder a
            será quizá más seguro que IE, pero por mi                     cualquier otro directorio de la máquina. ;-)
            experiencia personal puedo afirmar que funciona               * El campo consulta es opcional, y es sólo para
            realmente mal). Yo personalmente, en Windows                  páginas de contenido dinámico (PHP, ASP, CGI,
            me quedo con el navegador Opera. La versión                   ...) en las que se puedan introducir parámetros.
            shareware (gratis, para que nos entendamos)
            es totalmente funcional y simplemente añade
            un banner de publicidad en una de las esquinas.                   !            A partir de ahora...
            En realidad se puede utilizar perfectamente
            con el banner, que molesta poco, pero si queréis                 A partir de ahora, si eres de los que poseen una mente
            quitarlo no tenéis más que pagar el módico                       inquieta, te recomendamos que cuando visites una página
            precio del registro. Porque claro, doy por hecho                 Web no pierdas de vista el campo dirección de tu navegador.
                                                                             Podrás ver "en directo" lo "interesantes" que pueden ser
            que estoy hablando con gente legal, y que no
                                                                             algunas peticiones(vease imagen siguiente)
            se os ocurrirá visitar http://astalavista.box.sk
            para buscar un serial number de Opera y                          Por otro lado, recuerda que cuando introduces en tu
            registrarlo gratuitamente... :p                                  Navegador una dirección Web (por ejemplo
                                                                             www.astalavista.com), el Navegador intenta por defecto
                                                                             acceder al puerto 80. No tienes mas que probarlo, escribe
            En Linux uso también Opera, por costumbre                        por ejemplo http://www.astalavista.con:80 en tu navegador
            más que nada, pero tenéis también un                             y verás que el resultado es el mismo que si escribieses
            amplísimo repertorio de navegadores (Mozilla,                    http://www.astalavista.com. Lo que no sabe todo el mundo
            Ko n q u e r o r, G a l e o n , N e t s c a p e , e t c ) .      es la cantidad de Servidores Web que hay en Internet tras
                                                                             otros puertos, si has seguido el curso del Servidor Web
                                                                             APACHE (en anteriores números de PC PASO A PASO)
            Centrándonos de nuevo en el tema, si queremos                    sabes que puedes activar un Servidor Web en cualquier
            utilizar un navegador (sea el que sea) como                      puerto, por ejemplo en el puerto 4415… no te imaginas la
            herramienta HTTP, tenemos que conocer                            cantidad de Servidores Web que en el Puerto 80 tienen
            perfectamente el formato de una URL (Uniform                     páginas Web de lo más normalitas y en "otros puertos"
                                                                             tienen las páginas interesantes ;p
            Resource Locator), que es el siguiente:
                                                                             Si www.astalavista.com tuviese una web oculta en el puerto
            http://host[:puerto][/path][?consulta]                           9010, para acceder a ella tendrías que introducir en tu
                                                                             navegador www.astalavista.com:9010. Ya, ahora me pedirás
            * El campo host es el único obligatorio, y es                    una lista de Webs "ocultas", pues lo siento pero eso sería
                                                                             suficiente para que esta revista fuese repudiada en ciertos
            donde ponemos la dirección del servidor HTTP.                    círculos, sería como publicar el acceso a uno de los muchos
            Podemos poner bien una dirección IP                              FTP de los que utiliza la scene… si quieres adentrarte en
            (217.174.193.62), o bien un nombre DNS                           este tema, empieza por trabajarte los foros de FXP ;) …
            (www.hackxcrack.com).                                            ¿Cómo? ¿Qué no sabes lo que es eso? Pues repasa los
                                                                             anteriores números de PC PASO A PASO ;p
            * El campo puerto normalmente no será
            necesario, ya que el puerto por defecto para

Página 42                                                                                                       PC PASO A PASO Nº 13
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




          La combinación de un navegador de los de          SamSpade), y que la página de la que venimos
          toda la vida, y un sniffer, puede ser una         es www.alqaeda.org. En el parámetro Request
          herramienta muy útil para estudiar el             Type podemos especificar el comando HTTP a
          funcionamiento del protocolo HTTP.                enviar. Más adelante veremos cada uno de estos
          Existen también herramientas intermedias entre    comandos en detalle.
          esto y un simple cliente de Telnet, como por
          ejemplo la aplicación SamSpade, que no sólo       Por último, como no, hay que mencionar el
          puede ser descargada como aplicación para         cliente de Telnet como aplicación universal
          usar localmente en tu PC, si no que también       para el estudio de los protocolos. ;-) Si utilizamos
          puede ser utilizada online desde el propio        el cliente de Telnet tenemos que tener en cuenta
          servidor de SamSpade: www.samspade.org.           dos aspectos. El primero, es que el puerto por
                                                            defecto para HTTP es el 80. Y por último, que
                                 En la imagen podemos       no podemos incluir el path al lanzar la conexión
                                 ver la configuración de    mediante Telnet, si no sólo el host. Para incluir
                                 la herramienta Browse      un path, tendremos que hacerlo una vez
                                 We b i n c l u i d a e n   establecida la conexión con el servidor, enviando
                                 SamSpade, en la que        la cabecera adecuada, tal y como veremos más
                                 configuramos la            adelante.
                                 aplicación para que se
                                 c o n e c t e          a   5. El protocolo HTTP
                                 www.withehouse.org
                                 haciéndole creer que       Una vez establecida la conexión (asumimos que
                                 nuestro navegador es       estamos trabajando con un cliente de Telnet),
                                 un Internet Explorer 5.0   el servidor se queda en espera de que enviemos
                                 (cuando en realidad        un comando, al cual responderá después tal y
                                 nuestro cliente es          como iremos viendo.

PC PASO A PASO Nº 13                                                                                               Página 43
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




Teniendo en cuenta que el RFC 2616, que            comandos RAW, para luego hablar de los campos de cabecera. Por último,
especifica el protocolo HTTP /1.1, consta de       hablaré sobre as respuestas del servidor.
175 páginas, no podemos hacer en este
artículo una especificación detallada y
precisa del protocolo, por lo que nos                         !            Para los nuevos lectores
 limitaremos a ver casos típicos y relativamente
sencillos.
                                                             ¿TELNET? ¿SNIFFER? ¿Qué es eso? ¿Cómo se utiliza?
                                                             En los números anteriores mostramos paso a paso como
En primer lugar, tenemos que tener en cuenta                 utilizar estas herramientas, si es la primera vez que lees
que no todos los servidores aceptan todos los                esta revista y no dominas el tema seguro que ya te has
comandos HTTP. Cuando un servidor no acepte                  perdido. La solución ideal pasa por comprar los números
un determinado comando, nos responderá con                   atrasados de PC PASO A PASO, claro, pero estamos
un error 405 (method not allowed). Si ni                     estudiando una alternativa que esperamos poder poner en
                                                             marcha a mediados de Noviembre (máximo Diciembre).
siquiera conoce ese comando, nos responderá
con un error 501 (Not Implemented). Sólo                     Lo que tenemos pensado es hacer en una especie de FAQ
los comandos GET y HEAD han de ser                           y colgarla en la Web (www.hackxcrack.com), en realidad
implementados obligatoriamente por cualquier                 será un archivo que todo el mundo podrá descargar y
servidor.                                                    contendrá esos artículos ya publicados y de nivel básico
                                                             que todo nuevo lector deberá “tener muy a mano”. No
                                                             vamos a liberar los PDF de todos los números publicados,
El protocolo HTTP consta de muy pocos
                                                             será simplemente una recopilación de todo lo que creemos
comandos RAW (tan sólo 8, de los cuales sólo                 imprescindible para que cualquier nuevo lector pueda seguir
hay 2 cuya implementación es obligatoria).                   la revista.
Toda la complejidad del protocolo no se
encuentra en los propios comandos, si no en
los parámetros adicionales que se envían con
cada petición y con cada respuesta. El número      Empiezo, por tanto, mostrándoos la sesión completa de http. Os
de estos parámetros varía de una petición a        recuerdo que a lo largo de toda la serie RAW he utilizado el color
otra, y se encuentra cada parámetro separado       azul para indicar lo que envía el cliente al servidor, y el color rojo
en una línea diferente. A cada una de estas        para las respuestas del servidor al cliente. El color verde lo utilizo
líneas se las denomina campos de cabecera          para comandos de consola, enviados fuera de la conexión TCP/IP.
(header fileds). Cuando un campo de
cabecera no se especifica explícitamente, el       GET / HTTP/1.1
estándar define una serie de decisiones a tomar    User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; UNIX) Opera 6.11              [en]
por defecto tanto por parte del servidor           Host: www.hackxcrack.com
como por parte del cliente, por lo que no existe   Accept: text/html, image/png, image/jpeg, image/gif, image/x-xbitmap, */*
                                                   Accept-Charset: windows-1252, utf-8;q=1.0, utf-16;q=1.0, iso-8859-1;q=0.6, *;q=0.1
un número fijo de campos de cabecera
                                                   Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
obligatorios.
                                                   Cookie: phpbb2mysql_data=a%3B1%5B%5etc
                                                   Cache-Control: no-cache
Para tratar de explicaros de forma ordenada
                                                   Connection: Keep-Alive, TE
todo este barullo que se encuentra repartido
                                                   TE: deflate, gzip, chunked, identity, trailers
por varios documentos diferentes, y de forma
bastante caótica, he decidido empezar
                                                   HTTP/1.1 200 OK
mostrando un ejemplo básico de sesión
                                                   Date: Thu, 09 Oct 2003 14:59:29 GMT
completa, capturada con un sniffer, para luego
                                                   Server: Apache/1.3.26 (Unix) PHP/4.2.3 mod_perl/1.26
ir explicándola paso a paso. Para esta
                                                   Last-Modified: Fri, 23 May 2003 19:52:13 GMT
explicación empezaré por comentar los 8

 Página 44                                                                                                PC PASO A PASO Nº 13
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




Accept-Ranges: bytes                                                                 A continuación, el comando sería:
Content-Length: 6291
Content-Type: text/html                                                              GET /entrada/entrada.htm HTTP/1.1
Age: 0
                                                                                     Como vemos, indicamos sólo el PATH, separado
...AQUI VENDRIA UN MONTON DE CODIGO HTML...                                          por un espacio del protocolo a utilizar que, en
                                                                                     este caso, y prácticamente en cualquier caso,
GET /imagenes/LOGOPCPASOAPASO1.jpg HTTP/1.1                                          será siempre HTTP/1.1.
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; UNIX) Opera 6.11              [en]
Host: www.hackxcrack.com                                                             Después de esta línea, debemos indicar aparte
Accept: text/html, image/png, image/jpeg, image/gif, image/x-xbitmap, */*            el HOST para completar la URL:
Accept-Charset: windows-1252, utf-8;q=1.0, utf-16;q=1.0, iso-8859-1;q=0.6, *;q=0.1

Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
                                                                                     GET /entrada/entrada.htm HTTP/1.1
Referer: http://www.hackxcrack.com/
                                                                                     Host: www.hackxcrack.com
If-Modified-Since: Thu, 03 Apr 2003 06:06:09 GMT
If-None-Match: "710029-10d4-3e8bcf51"
                                                                                     Esto permite referenciar otros HOSTs a partir
Cookie: phpbb2mysql_data=a%3A2%3A%etc
                                                                                     de uno dado, siempre que éste lo permita.
Connection: Keep-Alive, TE
                                                                                     Si el host especificado no es válido, el servidor
TE: deflate, gzip, chunked, identity, trailers
                                                                                     responderá con un error 400 (Bad Request).
                                                                                     Este campo Host que hemos visto que sigue
HTTP/1.1 304 Not Modified
                                                                                     al propio comando es precisamente uno de los
Date: Thu, 09 Oct 2003 14:59:30 GMT
                                                                                     campos de cabecera que mencioné.
Etag: "710029-10d4-3e8bcf51"
                                                                                     En el ejemplo de sesión completa que puse al
                                                                                     principio podemos ver lo siguiente:
¡¡Buf!! ¡Como podéis imaginar, tenemos mucho trabajo por delante! ;)

                                                                                     GET / HTTP/1.1
5.1.     Comandos RAW de HTTP                                                        Host: www.hackxcrack.com

Enumeraré a continuación todos los comandos HTTP, aunque nos                         En este caso, la página solicitada es la raíz del
centraremos sobre todo en el comando GET, que es el más importante.                  servidor.
Mientras explique los comandos, probablemente habrá muchas cosas que
os suenen a chino. No os preocupéis, porque más adelante explicaré todo              Conexión a través de un proxy:
en detalle.
                                                                                     Si conectasemos a través de un proxy, por
5.1.1. Comando GET                                                                   ejemplo 127.0.0.1, tendríamos que especificar
                                                                                     no sólo el PATH, si no también el HOST como
Este es, sin duda, el comando HTTP más utilizado, ya que es el que se                parámetro del comando GET. Utilizar esta IP
usa cuando queremos descargar una página web de un servidor. Vamos                   como proxy no es ninguna tontería (para los
a ve r d o s fo r m a s d i fe r e n t e s d e c o n e c t a r n o s a l a U R L     que se puedan quejar de que no ponemos IPs
http://www.hackxcrack.com/entrada/entrada.htm mediante Telnet:                       reales en los artículos), ya que podríamos estar
                                                                                     utilizando una aplicación como MultiProxy
Conexión directa:                                                                    (www.multiproxy.org –utilidad explicada en
                                                                                     números anteriores-) que crea un proxy virtual
Lo primero será lanzar el telnet al servidor:                                        en nuestro propio PC que lo que hace es manejar
                                                                                     dinámicamente listas de proxies externos.
telnet www.hackxcrack.com 80

 PC PASO A PASO Nº 13                                                                                                   Página 45
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




Si tenemos, por ejemplo, un multiproxy en el puerto 8080 de nuestra           El comando POST debe incluir, por supuesto,
máquina, empezaremos con el siguiente Telnet:                                 un cuerpo de datos con su cabecera, igual que
                                                                              hace el servidor cuando nos envía una página
telnet 127.0.0.1 8080                                                         solicitada. Más adelante veremos cómo
                                                                              construye el servidor estas cabeceras.
A continuación, lanzaremos la siguiente petición:
                                                                              5.1.5. Comando PUT
GET http://www.hackxcrack.com/entrada/entrada.htm HTTP/1.1
                                                                              Este comando es el inverso a GET, ya que
** No he probado este ejemplo concretamente con Multiproxy. Lo único          permite especificar una URL sobre la que se
que comento es el método genérico para conectar a través de un                escribirán los datos incluidos en la propia
 proxy.                                                                       petición. Si no existía previamente ese recurso,
                                                                              el servidor nos responderá con un código 201
5.1.2. Comando OPTIONS                                                        (Created), en cambio, si ya existía y ha sido
                                                                              modificado, nos responderá con un código
Este comando nos permite conocer las características de la comunicación       200 (Ok), o un código 204 (No Content).
entre nuestro cliente y un recurso determinado del servidor.                  Si el servidor no comprende los contenidos
Si, por ejemplo, enviamos:                                                    enviados, responderá con un error 501 (Not
                                                                              Implemented).
OPTIONS * HTTP/1.1
                                                                              Lo importante que hay que comprender en este
El recurso solicitado es *, que es equivalente a no especificar ningún        punto es la diferencia entre los comandos POST
recurso. Esto equivale a hacer un simple PING al servidor para ver si         y PUT. En el comando POST, la URL
responde.                                                                     especificada es la de algún recurso que sea
                                                                              capaz de procesar los datos, por ejemplo, un
Si queremos enviar un comando OPTIONS a un proxy en concreto dentro           script CGI, PHP, o ASP. Este script decidirá qué
de una cadena, en lugar de enviarlo al servidor final al que supuestamente    hacer con los datos enviados. En cambio, en el
estamos conectados, podemos utilizar el campo de cabecera Max-                comando PUT la URL especificada será
Forwards, tal y como veremos más adelante.                                    directamente sobre la que se escribirá.


5.1.3. Comando HEAD                                                           5.1.6. Comando DELETE

Es similar al comando GET, pero con la diferencia de que el servidor en       Como es fácil adivinar, sirve para eliminar el
su respuesta no incluirá los datos a enviar (típicamente el código HTML),     recurso especificado en la URL. Por supuesto,
si no tan sólo la cabecera. Con esto se puede comprobar si una URL es         este comando no funcionará con la inmensa
válida, cuál es el tipo de contenidos, si ha de ser renovada la copia de      mayoría de URLs. XDD
cache debido a algún cambio, etc.
                                                                              5.1.7. Comando TRACE
5.1.4. Comando POST
                                                                              Es prácticamente como un PING, no sólo hacia
Este comando permite que el cliente solicite el envío de datos al servidor,   el servidor final, si no también hacia alguno de
en lugar de solicitar una recepción de datos. Es, por ejemplo, el método      los proxies intermedios si se utiliza el campo
utilizado para subir un mensaje a un foro web. Si el mensaje ha sido          de cabecera Max-Fordwards. El servidor que
añadido con éxito al foro, el servidor nos responderá con un código 201       haya de responder, lo hará con un código 200
(Created).                                                                    (Ok), y la respuesta tendrá como tipo de


 Página 46                                                                                           PC PASO A PASO Nº 13
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




          contenidos message/http. Esta respuesta            que aceptará el cliente. Consiste en una lista
          puede ser utilizada por el cliente para hacer      de tipos/subtipos de contenidos. Por tanto, si
          diversos diagnósticos.                             especificamos */* significa que aceptamos
                                                             cualquier tipo de contenido.
          5.1.8. Comando CONNECT                             Por ejemplo:

          Este comando se utiliza en los proxies que         Accept: text/html, image/png
          pueden funcionar como tunel SSL. Esto es un
          tema muy complicado, así que mejor lo              Especifica al servidor que sólo aceptamos texto
          dejamos, que no es plan de escribir un             HTML e imágenes en formato PNG.
          libro. xD                                          En cambio, si enviamos:


          5.2. Campos de cabecera                            Accept: */*

          La petición se puede completar con una serie       Indicamos al servidor que aceptamos cualquier
          de campos adicionales, cada uno enviado en         tipo de contenidos.
          una línea, que permiten indicar al servidor los    Y si enviamos esto:
          tipos de contenidos que acepta el cliente, el
          lenguaje, los sistemas de codificación, etc.       Accept: text/html, text/plain, image/*

          Vamos a ver sólo alguno de los más                 Indicamos que aceptamos texto HTML, texto
          importantes. Muchos de los que no veremos          plano, y cualquier formato de imágenes.
          será debido a que son parte del complejo
          sistema de cache que ocuparía por si sólo todo     Podemos especificar, además, prioridades en
          un artículo. A continuación muestro una lista      los formatos. Por ejemplo, si preferimos que
          bastante completa de campos de cabecera, en        las imágenes nos sean enviadas en formato
          los que señalo aquellos que comentaré:             PNG, enviaremos:

          Accept, Accept-Charset, Accept-Encoding,
                                                             Accept: image/png, image/*; q=0.1
          Accept-Language, Accept-Ranges, Age,
          Allow, Authorization, Cache-Control,
                                                             Esto significa que la prioridad para cualquier
          Connection, Content-Encoding, Content-
                                                             formato de imagen que no sea image/png, es
          Language, Content-Length, Content-
                                                             0.1. El valor de prioridad por defecto es 1, por
          Location, Content-MD5, Content-Range,
                                                             lo que, al no especificar un valor de prioridad
          Content-Type, Date, ETag, Expect, Expires,
                                                             para image/png, se asume que este es 1, el
          From, Host, If-Match, If-Modified-Since, If-
                                                             cual es mayor que 0.1. Por tanto, la petición
          None-Match, If-Range, If-Unmodified-Since,
                                                             anterior sería equivalente a esta:
          Las-Modified, Location, Max-Forwards,
          Pragma, Proxy-Authenticate, Proxy-
                                                             Accept: image/png; q=1, image/*; q=0.1
          Authorization, Range, Referer, Retry-After,
          Server, TE, Trailer, Transfer-Encoding, Upgrade,
                                                             El valor de prioridad (q) puede tomar cualquier
          User-Agent, Vary, Via, Warning, WWW-
                                                             valor comprendido entre 0 y 1, con hasta 3
          Authenticate.
                                                             decimales, por lo que podemos especificar listas
          5.2.1. Accept:                                     de prioridades bastante complejas.
                                                             Podemos especificar prioridades de forma mucho
          Permite especificar el tipo de contenidos          más sencilla, simplemente mediante el orden

PC PASO A PASO Nº 13                                                                                            Página 47
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




            en que especificamos los tipos aceptados. Por       ** No incluimos “fotos” de la tabla porque
            ejemplo:                                            ocuparía varias páginas de la revista y en el
                                                                foro de hack x crack después nos echan bronca
            Accept: text/html, image/png, */*                   por desperdiciar espacio :)

            Especifica al servidor que preferimos siempre       5.2.3. Accept-Encoding:
            texto HTML a cualquier otra cosa, y en segundo
            lugar, imágenes PNG. En cambio, si no se nos        Especifica al servidor el tipo de codificación de
            puede enviar ninguna de esas dos cosas,             datos que puede comprender nuestro cliente.
            también nos conformamos con cualquier otro          Para hacer nuestras pruebas lo mejor es que
            tipo de contenido (*/*).                            utilicemos sólo la codificación identity, es decir,
                                                                sin ninguna codificación. Así, podremos ver en
            Los tipos básicos están especificados en el         texto plano todos los datos recibidos, y
            RFC 2046, y son los siguientes: text, image,        analizarlos con mayor facilidad. La codificación
            audio, video, application. Aunque también se        identity es la que se asume cuando no se indica
            puede hablar de otros tipos más complejos,          nada, y deben implementarla todos los
            como el multipart, en los que no voy a entrar       servidores. Si aún así queremos especificarlo,
            en detalle.                                         enviaremos:
            Si queréis la lista completa de tipos actualmente
            registrados, la mantiene el IANA (Internet          Accept-Encoding: identity
            Assigned Numbers Authority), y la podéis
            consultar por FTP en ftp://ftp.isi.edu/in-          Si queremos experimentar con otras
            notes/iana/assignments/media-types/                 codificaciones, el formato es el mismo que en
                                                                los casos anteriores. Por ejemplo:
            5.2.2. Accept-Charset:
                                                                Accept-Encoding: gzip; q=1, compress;
            Especifica al servidor las tablas de caracteres     q=0.8, identity; q=0.5, *; q=0.1
            que acepta nuestro cliente. El formato es el
            mismo que en Accept. Por ejemplo:                   Con esto indicamos al servidor que preferimos
                                                                la codificación gzip, seguida de la compress,
            Accept-Charset: iso-8859-1, unicode-1-              seguida de la identity y, en último caso,
            1; q=0.8                                            aceptamos cualquier otra codificación existente.
                                                                Si el servidor no es capaz de enviar una
            Indica al servidor que preferimos caracteres        respuesta en ninguna de las codificaciones
            según el estándar iso-8859-1, pero que              especificadas, responderá con un error 406
            aceptamos también unicode-1-1 (aunque con           (Not Acceptable).
            menor prioridad).
            En el número anterior de la revista ya se habló     5.2.4. Accept-Language:
            algo sobre estos estándares de juegos de
            caracteres.                                         Especifica al servidor el idioma en que preferimos
                                                                que nos sea enviado el texto. Por supuesto,
            Como ejemplo, en                                    para que nos sea enviado en un determinado
             http://www.htmlhelp.com/reference/charset/         lenguaje, el servidor tiene que tener prevista
            tenéis la tabla de caracteres del estándar iso-     esta situación y tener traducciones de los
            8859-1.                                             contenidos a diversos idiomas.


Página 48                                                                                             PC PASO A PASO Nº 13
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




          No sólo se pueden especificar idiomas, si no       Connection: Keep-Alive
          también subtipos dentro del idioma. Por
          ejemplo:                                           Por defecto, se considera que se mantiene en
                                                             el estado Keep-Alive, por lo que sólo es
          Accept-Language: en-gb; q=1, en; q=0.5,            necesario indicar explícitamente cuándo se
          *; q=0.1                                           desea cerrar la conexión.

          Indicamos así al servidor que preferimos el        5.2.7. User-Agent:
          idioma inglés de Gran Bretaña (en-gb). Existen
          otros subtipos, como por ejemplo el en-US,         Esta línea de cabecera permite indicar al servidor
          que es inglés de Estados Unidos. Como segunda      información sobre nuestro navegador, como el
          opción, admitimos cualquier tipo de inglés,        software utilizado, su versión, el sistema
          aunque no sea en-gb. Por último, con mínima        operativo, o incluso algunas compatibilidades.
          prioridad, aceptamos cualquier otro idioma.        Por ejemplo:

          Si no se especifica nada en Accept-Language,       User-Agent: Mozilla/4.0 (compatible;
          el servidor asume que no hay preferencias de       MSIE 5.0; Linux 2.4.18-14 i686) Opera
          idioma, y enviará el que más le convenga.          6.11 [en]

          5.2.5. Authorization:                              Todo esto es lo que envía por defecto Opera
                                                             6.11 para Linux cada vez que se conecta a una
          Si intentamos acceder a una página cuyo            página web. Como vemos, da información no
          contenido requiera la autenticación de un          sólo sobre la versión exacta del navegador, si
          usuario, el servidor nos responderá con un         no también sobre el sistema operativo y el
          error 401 (Unauthorized). En esta respuesta        microprocesador.
          incluirá además un campo de cabecera WWW-
          Authenticate, en el cual nos dará los datos
          necesarios para que realicemos la autenticación.       !            Imagina la cantidad...

          A continuación, tendremos que volver a pedir
                                                                 Imagina la cantidad de información que obtiene de ti
          la página, pero incluyendo los datos de                cualquier Servidor Web cuando te conectas a una Web
          autenticación, lo cual se hace mediante esta           alojada en dicho Servidor :p
          línea de cabecera. El sistema de autenticación
          de HTTP viene especificado en el RFC 2617.             Como todas las cosas, esta es un arma de doble filo. Puede
                                                                 utilizarse para, por ejemplo, saber la resolución de tu
                                                                 pantalla y servirte una página Web adaptada a dicha
          5.2.6. Connection:                                     resolución (eso es bueno), pero también puede utilizarse
                                                                 para saber, por ejemplo, la versión exactade tu navegador
          Permite especificar al servidor si queremos que        y servirte una página que “explote” un bug de esa versión
          la conexión se cierre una vez enviada la               del navegador y colarte un troyano (eso ya no es tan bueno
          respuesta:                                             ¿verdad?)


          Connection: close
                                                             5.2.8. Referer:
          O si queremos mantenerla abierta para
          posteriores peticiones:                            Si os ha preocupado ver que cada vez que


PC PASO A PASO Nº 13                                                                                              Página 49
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




            visitáis una página web se envía información        indicada en Content-Encoding debería ser
            acerca de vuestro sistema y vuestro software,       compatible con alguna de las especificadas
            supongo que más os asustará saber que además        previamente por la otra máquina en su campo
            se envía la última URL que visitasteis. Si          Accept-Encoding.
            enviamos:                                           Por ejemplo:

            Referer: http://www.hackcrack.com/                  Content-Encoding: gzip

            Indicamos al servidor que estuvimos en esa          Indica que se ha utilizado la codificación gzip
            página, antes de estar en la suya.                  en los datos enviados a continuación. Para ello,
            Esto puede suponer un gran riesgo de                la petición de esos datos tuvo que incluir un
            seguridad, ya que se podrían colar datos            campo de cabecera como el siguiente:
            importantes, como por ejemplo parámetros
            enviados en una URL (incluso datos de               Accept-Encoding: gzip; q=1, compress;
            autenticación de otras páginas web).                q=0.5, identity; q=0.1


            5.2.9. Allow:                                       Es decir, de alguna forma tenía que incluir la
                                                                codificación gzip entre las admisibles. En este
            Este campo de cabecera se incluye en las            caso concreto, además, era la codificación
            respuestas con código 405 (Method Not               preferida, así que todos contentos. :-)
            Allowed), que se envía cuando el cliente            Si no se especifica un campo Content-
            intenta utilizar un comando que el servidor no      Encoding, se asume que no se ha usado
            acepta. El servidor informará al cliente mediante   codificación, es decir, que se ha usado
            este campo de cuáles son los métodos que si         codificación identity.
            que acepta. Por ejemplo:
                                                                5.2.11.          Content-Language:
            Allow: GET, HEAD, POST
                                                                La misma relación que existe entre el Accept-
            Informa al cliente de que sólo está permitido       Encoding y el Content-Encoding, existe
            utilizar esos tres comandos. El campo Allow         entre el Accept-Language y el Content-
            también puede ser incluido como respuesta a         Language.
            un PUT, indicando así qué métodos se pueden
            utilizar sobre el nuevo recurso recién creado.      5.2.12.          Content-Length:

            5.2.10.          Content-Encoding:                  Indica la longitud en bytes de los datos enviados.
                                                                Por ejemplo:
            Este campo acompaña a cualquier mensaje en
            el que se envíen datos, tanto si es una respuesta   Content-Length: 1500
            del servidor a un GET, como si son los datos
            subidos por el cliente en un PUT o un POST.         Indica que los datos enviados (típicamente una
            Si bien el campo Accept-Encoding indica qué         página web) ocupan 1500 Bytes.
            tipos de codificación aceptamos para la próxima
            recepción, el campo Content-Encoding indica         5.2.13.          Content-Type:
            qué tipo de codificación se ha utilizado para
            un envío. Evidentemente, la codificación            Este campo combina la respuesta a los campos


Página 50                                                                                             PC PASO A PASO Nº 13
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




          de cabecera Accept y Accept-Charset, ya           5.2.16.          Max-Forwards:
          que puede indicar cuál es el tipo de datos
          enviado, así como el juego de caracteres.         Este campo de cabecera se utiliza en los
          Por ejemplo:                                      comandos OPTION y TRACE cuando se quiere
                                                            acceder a una máquina intermedia dentro de
          Content-Type: text/html; charset=ISO-             la cadena que nos comunica con el servidor
          8859-4                                            final. Como vimos al principio, para llegar a un
                                                            servidor nuestras peticiones pueden estar
          Aunque muchas veces sólo se indicará el           pasando por una serie de proxies y routers. La
          tipo/subtipo de los datos. Por ejemplo, en la     forma de acceder a estos puntos intermedios
          captura de sesión de ejemplo, vemos que ésta      es mediante esta cabecera.
          es la respuesta:
                                                            En este campo se indica como parámetro un
          Content-Type: text/html                           número, que es el número de pasos intermedios
                                                            a dar. Cada vez que pasa por un proxy esta
          5.2.14.         Date:                             petición, el proxy restará en una unidad este
                                                            número, y pasará el mensaje al próximo proxy.
          Como podemos imaginar, indica la fecha y la       Cuando el mensaje llegue con valor 0 a uno de
          hora a la que se generó el mensaje en cuestión.   los proxies de la cadena, éste ya no realizará
          Si os queréis complicar la vida, en el punto      más restas, ni retransmitirá el mensaje, si no
          3.3.1. del RFC 2616 se muestran en detalle        que lo devolverá con la respuesta pertinente.
          los formatos de fechas aceptados, pero supongo
          que a la mayoría os bastará con un ejemplo,       Este es un claro ejemplo de modificación de
                                                            las cabeceras por parte de los proxies.
          así que no tenéis más que mirar la captura de
                                                            Por ejemplo:
          sesión del ejemplo:

                                                            Max-Forwards: 3
          Date: Thu, 09 Oct 2003 14:59:29 GMT

                                                            Indica que a este mensaje habrá de responder
          Como vemos, la hora siempre se da con
                                                            el tercer proxy de la cadena. Si el servidor final
          respecto al GMT (Greenwich Mean Time, es          estuviese casualmente conectado por menos
          decir, la hora en el meridiano 0).                de 3 proxies, sería éste el que respondería.

          5.2.15.         Expect:                           5.2.17.          Proxy-Authenticate:

          Este campo lo utiliza un cliente cuando quiere    Este campo se incluye en la respuesta de un
          solicitar al servidor un determinado tipo de      proxy que requiere autenticación. El campo
          acción. Por ejemplo, se usa cuando el cliente     WWW-Authenticate requiere autenticación
          espera que el servidor le envíe un código 100     al usuario con el servidor final, y el campo
          (Continue). Todo esto lo veremos más              Proxy-Authenticate requiere autenticación
          adelante cuando comentemos las respuestas         con uno de los proxies intermedios de la cadena.
          del servidor. Cuando el servidor no pueda
          satisfacer las expectativas del cliente,          El campo Proxy-Authenticate se incluye en
          responderá con un error 417 (Expectation          las respuestas con código 407 (Proxy
          Failed).                                          Authentication Required).


PC PASO A PASO Nº 13                                                                                             Página 51
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




            5.2.18.          Proxy-Authorization:              5.2.21.          WWW-Authenticate:

            Si bien a WWW-Authenticate se                      Ya he mencionado antes la función de este
            responde con Authorization, a Proxy-               campo de cabecera. Os recuerdo que en el RFC
            Authenticate se responde con Proxy-                2617 se detalla el mecanismo de autenticación
            Authorization.                                     en HTTP.


            5.2.19.          Retry-After:                      5.3. Respuestas del Servidor
                                                               Ante cada petición realizada por el cliente, el
            Este campo se puede incluir en las respuestas      servidor siempre nos dará una respuesta con
            con código 503 (Service Unavailable),              el siquiente formato:
            indicándonos típicamente en segundos el tiempo
            que nos recomienda el servidor que esperemos       HTTP/x.x código respuesta
            antes te reintentar la petición. Por
            ejemplo:                                           Donde HTTP/x.x es la versión de HTTP, código
                                                               es un número que identifica el tipo de respuesta,
            Retry-After: 120                                   como veremos más adelante, y respuesta es
                                                               una frase de respuesta aclaratoria del código
            Nos indica que conviene que esperemos al           devuelto.
            menos 2 minutos antes de reintentar la petición.
            También se podría indicar una fecha, en lugar      Por ejemplo, si intentamos acceder a una URL
            de un tiempo en segundos.                          que no existe en un servidor, nos puede
                                                               responder algo como esto:
            5.2.20.          Server:
                                                               HTTP/1.1 404 Sorry, the page you
            Este es un campo de cabecera de respuesta          requested was not found.
            muy interesante. En él se incluye información
            acerca del servidor, la cual puede ser útil        5.3.0. Códigos de respuesta
            para alguien que quiera realizar algún
            tipo de ataque contra el servidor, ya              Según el primer dígito del código de respuesta,
            que lo primero que necesitará conocer es el        podemos saber si se trata de una respuesta
            software que utiliza el servidor. Por ejemplo,     correcta, de error, informativa, etc. Este es el
            en la captura de sesión vemos:                     significado de ese primer dígito:

            Server: Apache/1.3.26 (Unix) PHP/4.2.3             1xx – Los códigos que empiezan por 1 son
            mod_perl/1.26                                      informativos, es decir, la petición ha sido
                                                               recibida sin problemas, y el servidor se limita
            El servidor nos indica no sólo qué software        a darnos algún tipo de información. Ya veremos
            utiliza, si no también el número de                más adelante el significado de esto.
            versión completo, el sistema operativo
            (Unix), así como algunos módulos instalados.       2xx – Estas son las respuestas más habituales,
                                                               ya que son las que devuelven los datos
            Como vemos, es una información bastante            solicitados por una petición recibida y procesada
            precisa que puede facilitar en gran medida un      con éxito. Por ejemplo, es la que se envía cada
            ataque contra el servidor.                         vez que recibimos una página web.


Página 52                                                                                           PC PASO A PASO Nº 13
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




          3xx – Estas son las respuestas de redirección,                 406: Not Acceptable
          que indican que para procesar la petición es                   407: Proxy Authentication Required
          necesario realizar acciones previas. Ya lo                     408: Request Time-out
          veremos más adelante.                                          409: Conflict
                                                                         410: Gone
          4xx – Supongo que todos estaréis                               411: Length Required
          familiarizados con los códigos que empiezan                    412: Precondition Failed
          por 4 (sobre todo con el 404 y el 403), ya que                 413: Request Entity Too Large
          son los errores de cliente. Es decir, se envían                414: Request-URI Too Large
          cada vez que el cliente intenta hacer algo que                 415: Unsupported Media Type
          no está permitido o que no tiene sentido para                  416: Requested range not satisfiable
          el servidor.                                                   417: Expectation Failed

          5xx – Estos son los errores del servidor,                      500:   Internal Server Error
          que se dan cuando un cliente envía una petición                501:   Not Implemented
          válida pero, por el motivo que sea, el servidor                502:   Bad Gateway
          no puede procesarla.                                           503:   Service Unavailable
                                                                         504:   Gateway Time-out
          A continuación, os muestro la lista completa                   505:   HTTP Version not supported
          de códigos de respuesta:
                                                                         Veremos ahora en detalle el significado de
          100: Continue                                                  algunas de estas respuestas.
          101: Switching Protocols
                                                                         5.3.1. HTTP/1.1 100 Continue:
          200: OK
          201: Created                                                   Cuando el cliente desea enviar datos en un
          202: Accepted                                                  PUT o un POST, tendrá que pedir permiso
          2 0 3 : N o n -A u t h o r i t a t i ve I n fo r m a t i o n   previamente al servidor. Para ello, en su petición
          204: No Content                                                incluirá el siguiente campo de cabecera:
          205: Reset Content
          206: Partial Content                                           Expect: 100-Continue

          300: Multiple Choices                                          Cuando el servidor reciba la petición con este
          301: Moved Permanently                                         campo, tendrá que responder bien con:
          302: Found
          303: See Other                                                 HTTP/1.1 100 Continue
          304: Not Modified
          305: Use Proxy                                                 O bien con:
          307: Temporary Redirect
                                                                         HTTP/1.1 417 Expectation Failed
          400: Bad Request
          401: Unauthorized                                              En el primer caso, el cliente sabrá que el servidor
          402: Payment Required                                          le da permiso para enviar los datos. En el
          403: Forbidden                                                 segundo caso, el servidor le denegará el permiso.
          404: Not Found                                                 La acción por defecto a tomar por el cliente
          405: Method Not Allowed

PC PASO A PASO Nº 13                                                                                                           Página 53
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




            cuando no recibe ninguna respuesta, es asumir     posible localización para el recurso solicitado,
            que tiene permiso. Si luego la recepción falla,   indicará así al cliente las alternativas que tiene.
            ya lo notificará el servidor posteriormente.      Normalmente, el navegador que utilicemos
                                                              escogerá una de las opciones de forma
            5.3.2. HTTP/1.1 200 Ok:                           transparente al usuario.

            Esta es la respuesta más común, ya que es la
                                                              5.3.6. H T T P / 1 . 1        301       Moved
            que se da cada vez que se recibe una página
                                                              Permanently:
            web. En este caso, cuando es una respuesta
            a un comando GET, los datos de la página
                                                              Cuando la localización de un recurso ha
            acompañan a esta respuesta, precedidos por
                                                              cambiado y ya no se encuentra en esa URL, el
            los campos de cabecera necesarios para
                                                              servidor nos indicará la nueva localización y,
            especificar el tipo de los datos (Content-
                                                              normalmente, nuestro navegador pedirá esa
            Type), su longitud (Content-Length), etc,
                                                              nueva URL de forma transparente al usuario.
            etc.

            Si, en cambio, es respuesta a un comando          5.3.7. HTTP/1.1 304 Not Modified:
            HEAD, todas estas cabeceras se enviarán igual
            (Content-Type, etc), pero no se enviarán los      A pesar de que esta respuesta forma parte del
            datos HTML de la página.                          complejo sistema de cache que he comentado,
                                                              merece la pena mencionarla. Esta respuesta se
            Si se trata de una respuesta a un comando         da cuando solicitamos una página de la cual
            POST el servidor indicará aquí el resultado de    teníamos una copia en nuestra cache. Si nuestra
            la acción llevada a cabo.                         copia de cache se corresponde con la que hay
                                                              aún en el servidor, éste no tendrá que
            Si se trata de una respuesta a un comando         retransmitirnos la página entera (con un
            TRACE contendrá de vuelta el mensaje que          HTTP/1.1 200 Ok), si no que bastará con
            envió el cliente al servidor (o proxy).           que nos devuelva esta respuesta para que
                                                              sepamos que podemos confiar en la copia de
            5.3.3. HTTP/1.1 201 Created:                      cache.
                                                              Podemos ver un ejemplo de esta respuesta en
            Ya vimos anteriormente que esta respuesta se      la captura de sesión de ejemplo.
            utilizaba en los comandos PUT y POST, cuando
            se creaba un nuevo recurso como consecuencia      5.3.8. HTTP/1.1 400 Bad Request:
            de la ejecución del comando.
                                                              La sintaxis de la petición del cliente es incorrecta,
            5.3.4. HTTP/1.1 204 No Content:                   y por tanto no la puede procesar el servidor.

            Esta respuesta se enviará cuando un comando       5.3.9. HTTP/1.1 401 Unauthorized:
            se haya procesado con éxito, pero no sea
            necesario enviar ningún tipo de datos.            El servidor exige autenticación para que el
                                                              cliente pueda acceder a ese recurso. Esta
            5.3.5. HTTP/1.1 300 Multiple                      respuesta tendrá que ir acompañada de un
            Choices:                                          campo de cabecera WWW-Authenticate que
                                                              incluya los datos necesarios para que el cliente
            Cuando el servidor encuentra más de una           pueda realizar la autenticación.

Página 54                                                                                             PC PASO A PASO Nº 13
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




          5.3.10.    HTTP/1.1                      403        modo que ocurre con el campo WWW-
          Forbidden:                                          Authenticate y la respuesta 401.


          Seguro que todos os habréis encontrado más          5.3.14.   HTTP/1.1                       414
          de una vez con un error 403 que, sólo superado      Request-URI too long:
          por el 404, yo creo que es el más habitual. El
          servidor no permite el acceso a ese recurso,        La longitud de una petición puede llevar a
          porque el cliente no tiene privilegios para ello.   problemas de seguridad, como los conocidos
          Es lo que ocurre, por ejemplo, cuando se            bugs de buffer overflow. Por tanto, tanto el
           intenta acceder a un directorio cuyos contenidos   cliente como el servidor tienen que estar
          no quieren ser mostrados por el servidor.           preparados para peticiones de cualquier longitud
                                                              y, en caso de que se supere la longitud máxima
          ¡Ojo! Que no hay que fiarse. Si realmente no        que pueden procesar, devolver un error, en
          quieren que accedas a esos contenidos, muchas       lugar de tratar de procesarla con los problemas
          veces tratarán de engañarte, haciendo que la        que eso conllevaría. En la práctica, una gran
          respuesta a esa petición sea un error 404 en        mayoría de aplicaciones han pecado incluso
          lugar de un 403, para que ceses en tu               repetidas veces de no estar preparadas para
          empeño pensando que ni siquiera existe ese          este tipo de situaciones.
          recurso ;p
                                                              5.3.15.    HTTP/1.1                      417
          5.3.11.          HTTP/1.1 404 Not                   Expectation Failed:
          Found:
                                                              Ya hablé sobre esta respuesta, que se da cuando
          ¿Quién no conoce el archiconocido 404? Es la        un servidor no puede responder a la petición
          respuesta que da el servidor cuando intentas        expuesta por el cliente en un campo Expect,
          acceder a una URL que no conoce. :-)                por ejemplo cuando se desea que el servidor
                                                              dé el visto bueno a un comando PUT (Expect:
          5.3.12.    HTTP/1.1 405 Method                      100-Continue).
          Not Allowed:
                                                              5.3.16.     HTTP/1.1 500 Internal
          Ya mencioné anteriormente que esta respuesta        Server Error:
          se usa cuando se envía al servidor un comando
          que éste no acepta por algún motivo. Como           Esta es la respuesta genérica de error cuando
          ya dije, esta respuesta debe venir acompañada       el servidor no puede procesar una petición
          de un campo de cabecera Allow para indicarnos       válida.
          los comandos que sí podemos utilizar.
                                                              5.3.17.   HTTP/1.1 501 Not
          5.3.13.  HTTP/1.1 407 Proxy                         Implemented:
          Authentication Required:
                                                              Esta respuesta se da cuando el servidor no
          Como ya comenté, esta respuesta nos la da           conoce el comando que ha enviado el cliente.
          un proxy cuando requiere que nos                    A diferencia del error 405 (Method Not
          autentiquemos. Para ello, incluirá un campo         Allowed), en el caso del 405 sí que se conoce
          de cabecera Proxy-Authenticate, del mismo           el comando, pero el servidor no permite su uso.


PC PASO A PASO Nº 13                                                                                             Página 55
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




En cambio, en este caso, el comando es                      de la siguiente forma:
totalmente desconocido para el servidor.
                                                            GET / HTTP/1.1
5.3.18.    HTTP/1.1 503 Service                             Host: www.hackxcrack.com
Unavailable:
                                                            Por supuesto, no bastaba con lanzar el comando, si no que además mandó
El servidor no puede procesar ninguna petición              una serie de campos de cabecera.
en ese instante, quizá por una sobrecarga, o
p o r e n c o n t ra r s e e n m a n t e n i m i e n t o.   El primer campo enviado, User-Agent, ya sabemos que identifica nuestro
Supuestamente, en un futuro el servidor podría              navegador que, en este caso, es Opera para Linux:
volver a responder a las peticiones, por lo que
es conveniente que el servidor incluya un campo             User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; UNIX) Opera 6.11 [en]
de cabecera Retry-After que indique al cliente
el tiempo que aconseja esperar antes de                     A continuación, enviamos una serie de campos para especificar el formato
reintentarlo.                                               en el que queremos recibir los datos, lo cual hacemos mediante:

                                                            Accept: text/html, image/png, image/jpeg, image/gif, image/x-xbitmap, */*
6.        Resumen                                           Accept-Charset: windows-1252, utf-8;q=1.0, utf-16;q=1.0, iso-8859-1;q=0.6, *;q=0.1

                                                            Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
Por último, vamos a repasar todo este barullo
con la captura de sesión que teníamos de                    Con esto, indicamos al servidor que preferimos que el texto esté en formato
ejemplo. Como habréis podido comprobar, es                  HTML, las imágenes en PNG, JPEG, GIF, o X-XBitMap (en este orden de
difícil estructurar todo para hacer una explicación         preferencia) y, por último, que aceptamos cualquier otro tipo de contenido.
sencilla y coherente, ya que todo está
relacionado con todo, y a su vez con otros                  Indicamos también que preferimos los juegos de caracteres Windows-
aspectos externos (como el HTML o el MIME).                 1252, utf-8, utf-16. En segundo lugar, también aceptamos iso-8859-1 y,
En consecuencia, la documentación de este                   por último, si el servidor no soporta ninguno de esos caracteres, aceptaríamos
protocolo es, en mi opinión, bastante caótica,              cualquier otro.
y para redactar este artículo he tenido que
estar con una docena de RFCs abiertos                       Además, aceptamos una serie de codificaciones, que serían deflate, gzip,
simultáneamente para consulta, así como otras               x-gzip, e identity (este último no sería necesario indicarlo explícitamente).
referencias.                                                Al enviar *;q=0 estamos diciendo que no admitimos otra codificación que
                                                            no sea una de las propuestas.
Espero que haya merecido la pena, y que al                  Estos campos de cabecera:
menos este artículo os sirva como referencia
para hacer un estudio más detallado realizando              Cookie: phpbb2mysql_data=a%3B1%5B%5etc
vuestras propias capturas con un sniffer, y                 Cache-Control: no-cache
analizando los resultados con esta guía                     TE: deflate, gzip, chunked, identity, trailers
abreviada que he escrito.
                                                            Forman parte de los que no he querido comentar por falta de espacio,
Vamos a tratar de comprender ahora esa sesión
                                                            por lo que vamos a olvidarnos de ellos. Por supuesto, podéis estudiar su
de ejemplo que pusimos al principio.
                                                            significado en el RFC 2616.
Para hacer esta captura, escribí en mi navegador
la URL www.hackxcrack.com. Por tanto, al no                 Por último, el campo:
haber indicado un path, mi navegador (Opera)
solicitó en primer lugar el raíz (“/”) del servidor,        Connection: Keep-Alive, TE


 Página 56                                                                                                        PC PASO A PASO Nº 13
Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW




Indica al servidor que la conexión será persistente, es decir, que después    Esta vez incluyó como campo de cabecera
de esta petición pueden venir otras, por lo que no deseamos que cierre        adicional el Referer, diciendo que la última
la conexión TCP/IP después de satisfacer esta petición.                       URL que visitamos fue precisamente la que
                                                                              p e d i m o s a n t e r i o r m e n t e , e s d e c i r,
Vamos a ver ahora qué nos respondió el servidor:                              www.hackxcrack.com:

Empezó con un código de respuesta 200, por lo que la petición fue             Referer: http:
procesada correctamente y el servidor nos envía los datos solicitados:
                                                                              A continuación, envía una serie de campos de
HTTP/1.1 200 OK                                                               cabecera adicionales referidos al sistema de
                                                                              cache, ya que mi navegador ya tenía una copia
A continuación, nos da una serie de datos informativos, como la fecha         de esa imagen en su cache:
y hora, los datos del servidor, y otra serie de datos referidos a temas que
no he explicado por falta de espacio pero que, de nuevo, podéis estudiar      If-Modified-Since: Thu, 03 Apr 2003
por vuestra cuenta en el RFC 2616:                                            06:06:09 GMT
                                                                              If-None-Match: "710029-10d4-3e8bcf51"
Date: Thu, 09 Oct 2003 14:59:29 GMT
Server: Apache/1.3.26 (Unix) PHP/4.2.3 mod_perl/1.26                          Con estos datos, el servidor se dio cuenta de
Last-Modified: Fri, 23 May 2003 19:52:13 GMT                                  que nuestra copia de cache era la misma que
ETag: "390062-1893-3ece7bed"                                                  tenía el, por lo que no era necesario que volviese
Accept-Ranges: bytes                                                          a enviarnos la imagen en cuestión, así que nos
Age: 0                                                                        respondió con un:

Por último, nos da información acerca de los contenidos (el código HTML       HTTP/1.1 304 Not Modified
de la página servida) que nos envía. En primer lugar, nos dice la longitud
en Bytes (6291), y a continuación el tipo de contenidos de que se trata       Tras lo cual, nuestro navegador cogió del disco
que, en este caso, es texto HTML.                                             duro nuestra copia de cache de la imagen y la
                                                                              incluyó en la página que nos tenía que mostrar.
Content-Length: 6291
Content-Type: text/html                                                       Como vemos, nos resultó conveniente utilizar
                                                                              una conexión persistente, ya que dentro del
Después de esto vendría todo el chorizo de código HTML que contiene           código HTML enviado por el servidor se incluían
la página servida.                                                            nuevas URLs que teníamos que solicitar al
                                                                              servidor, por lo que resultaba mucho más
Dentro de este código HTML se encontraba lo siguiente:                        efectivo hacerlo en una única conexión TCP/IP,
                                                                              en lugar de tener que abrir una nueva cada vez
<td width="218" height="121" valign="top"><div                                que se quisiera solicitar una imagen o cualquier
align="right"><img src="imagenes/LOGOPCPASOAPASO1.jpg"                        otro contenido incluido en el código HTML de
width="144" height="105" /></div></td>                                        la página.

Nuestro navegador, al analizar este código, se dio cuenta de que tenía        Autor: PyC (LCo)
que solicitar al servidor la URL /imagenes/LOGOPCPASOAPASO1.jpg, por
lo que hizo una nueva petición:

GET /imagenes/LOGOPCPASOAPASO1.jpg HTTP/1.1
Host: www.hackxcrack.com

 PC PASO A PASO Nº 13                                                                                                  Página 57
SERVIDOR DE HXC
                                               MODO DE EMPLEO

- Hack x Crack      ha habilitado tres
servidores para que puedas realizar las                                                                 Explicamos esto porque la mayoría, seguro que piensa en
                                                                                                        un Servidor Web como en algo extraño que no saben ni
prácticas de hacking.                                                                                   donde está ni como se accede. Bueno, pues ya sabes dónde
                                                                                                        se encuentran la mayoría de IIS (en Inetpub) y cuál es
- Las IPs de los servidores de hacking las                                                              la página por defecto (Inetpubwwwrootdefault.htm). Y
encontrarás en EL FORO de la revista                                                                    ahora, piensa un poco… … ¿Cuál es uno de los objetivos de
( w w w . h a c k x c r a c k . c o m ) . Una vez en el foro entra                                      un hacker que quiere decirle al mundo que ha hackeado
en la zona COMUNICADOS DE HACK X CRACK (arriba del                                                      u n a We b ? P u e s e s t á c l a r o, e l o b j e t i vo e s c a m b i a r ( o s u s t i t u i r )
todo) y verás varios comunicados relacionados con los                                                   el archivo default.html por uno propio donde diga “hola,
servidores. No ponemos las IP aquí porque es bueno                                                      soy DIOS y he hackeado esta Web” (eso si es un lamer ;)
acostumbrarte a entrar en el foro y leer los comunicados.
Si hay alguna incidencia o cambio de IP o lo que sea, se                                                A partir de ese momento, cualquiera que acceda a ese
comunicará en EL FORO.                                                                                  s e r v i d o r, v e r á e l d e f a u l t . h t m m o d i f i c a d o p a r a v e r g ü e n z a d e l
                                                                                                        “site” hackeado. Esto es muy genérico pero os dará una
                                                                                                        idea de cómo funciona esto de hackear Webs ;)
- Actualmente tienen el BUG del Code /
D e c o d e . La forma de “explotar” este bug la explicamos                                             - Cuando accedas a nuestro servidor mediante el CODE /
extensamente en los números 2 y 3. Lo dejaremos así por                                                 DECODE BUG, crea un directorio con tu nombre (el que mas
un tiempo (bastante tiempo ;) Nuestra intención es ir                                                   te guste, no nos des tu DNI) en la unidad d: a ser
habilitando servidores a medida que os enseñemos distintos                                              posible y a partir de ahora utiliza ese directorio para hacer
tipos de Hack.                                                                                          t u s p r á c t i c a s . Ya s a b e s , s u b i r n o s p r o g r a m i t a s y p r a c t i c a r
                                                                                                        con ellos :) ... ... ¿cómo? ¿que no sabes crear directorios
- En los Servidores corre el Windows 2000 con el IIS
de Servidor Web. No hemos parcheado ningún bug, ni                                                      mediante el CODE/DECODE BUG... repasa los números 2 y
t a n s i q u i e ra e l R P C y p o r s u p u e s t o t a m p o c o h e m o s i n s t a l a d o        tres de Hack x Crack ;p
n i n g ú n S e r v i c e Pa c k . Pa ra q u i e n p i e n s e q u e e s o e s u n e r r o r
(lógico si tenemos en cuenta que el RPC provoca una caída                                               Puedes crearte tu directorio donde quieras, no es necesario
completa del sistema), solo decirte que AZIMUT ha                                                       que sea en d:mellamojuan. Tienes total libertad!!! Una
configurado un firewall desde cero que evita el bug del                                                 i d e a  e s    c r e a r l o , p o r   e j e m p l o , e n
RPC, (bloqueo de los puertos 135 (tcp/udp), 137 (udp),                                                  d:xxxsystem32default10019901mellamojuan (ya irás
138 (udp), 445 (tcp), 593 (tcp)). La intención de todo esto                                             aprendiendo que cuanto mas oculto mejor :)
es, precisamente, que puedas practicar tanto con el
CODE/DECODE como con cualquier otro “bug” que conozcas
(y hay cientos!!!). Poco a poco iremos cambiando la                                                     Es posiblemente la primera vez que tienes la oportunidad
c o n f i g u ra c i ó n e n f u n c i ó n d e l a e x p e r i e n c i a , l a i d e a e s t e n e r    de investigar en un servidor como este sin cometer un delito
los Servidores lo menos parcheados posibles                                                 pero        (nosotros te dejamos y por lo tanto nadie te perseguirá).
mantenerlos operativos las 24 horas del día. Por todo ello                                              Aprovecha la oportunidad!!! e investiga mientras dure esta
y debido a posibles cambios de configuración, no olvides                                                iniciativa (esperemos que muchos años).
visitar el foro (Zona Comunicados) antes de “penetrar” en
nuestros servidores.                                                                                    - En este momento tenemos mas de 600 carpetas de peña
                                                                                                        que, como tu, está practicando. Así que haznos caso y crea
- Cada Servidor             tiene dos unidades (discos duros duros):                                    t u p r o p i a c a r p e t a d o n d e t r a b a j a r.
* La unidad c:              --> Con 40GB y Raíz del Sistema
* La unidad d:              --> Con 40GB
* La unidad e:              --> CD-ROM

N o t a : R a í z d e l S e r v i d o r,   s i g n i f i c a q u e e l W i n d o w s A d va n c e d

                                                                                                              !
Server está instalado                      en esa unidad (la unidad c:) y
concretamente en el
Por lo tanto, la raíz
                                           directorio por defecto winnt
                                            del sistema está en c:winnt
                                                                                                                                   MUY IMPORTANTE...
- E l I I S , I n t e r n e t I n f o r m a t i o n S e r v e r, e s e l S e r v i d o r d e
páginas Web y tiene su raíz en c:inetpub (el directorio
por defecto)
                                                                                                              MUY IMPORTANTE!!!!!                                Por favor, no borres archivos
Nota: Para quien nunca ha tenido instalado el IIS, le será                                                   del Servidor si no sabes exactamente lo que estás haciendo ni
e x t ra ñ o t a n t o e l n o m b r e d e e s t a c a r p e t a ( c :  i n e t p u b ) c o m o
s u c o n t e n i d o . Pe r o b u e n o , u n d í a d e e s t o s o s e n s e ñ a r e m o s                 borres las carpetas de los demás usuarios. Si haces eso, lo único
a i n s t a l a r v u e s t r o p r o p i o S e r v i d o r We b ( I I S ) y d e t a l l a r e m o s
su funcionamiento.                                                                                           que consigues es que tengamos que reparar el sistema servidor
De momento, lo único que hay que saber es que cuando                                                         y, mientras tanto, ni tu ni nadie puede disfrutar de él :(
T Ú p o n g a s n u e s t ra I P ( l a I P d e u n o d e n u e s t r o s s e r v i d o r e s )
en tu navegador (el Internet explorer por ejemplo), lo que                                                   Es una tontería intentar “romper” el Servidor, lo hemos puesto
estás haciendo realmente es ir al directorio
c :  I n e t p u b  w w w r o o t  y l e e r u n a r c h i vo l l a m a d o d e fa u l t . h t m .        para que disfrute todo el mundo sin correr riesgos, para que todo
Nota: Como curiosidad, te diremos que APACHE es otro                                                         el mundo pueda crearse su carpeta y practicar nuestros ejercicios.
S e r v i d o r d e p á g i n a s We b ( s e g u r o q u e h a s o í d o h a b l a r d e
él). Si tuviésemos instalado el apache, cuando pusieses                                                      En el Servidor no hay ni Warez, ni Programas, ni claves, ni nada
n u e s t r a I P e n T U n a v e g a d o r, a c c e d e r í a s a u n d i r e c t o r i o                   de nada que “robar”, es un servidor limpio para TI, por lo tanto
raíz del Apache (donde se hubiese instalado) e intentarías
leer una página llamada index.html ... pero... ¿qué te                                                       cuídalo un poquito y montaremos muchos más :)
estoy contando?... si has seguido nuestra revista ya
dominas de sobras el APACHE ;)
PORT SCANNING
                     Escaneando Ordenadores
                     Remotos: Tipos de Scaneos


            Para utilizar programas/herramientas de “escaneo” como el NMAP necesitamos conocer
            la forma en que se establecen las conexiones y adentrarnos en su funcionamiento. Este
            artículo te ilustrará sobre el tema.



            1- Avanzando en el análisis de                     Ahora imagina que se publica una vulnerabilidad
            sistemas                                           para algún demonio (proceso/programa) de
                                                               algún sistema operativo como IRIX, FreeBSD
            Ya hemos comentado la importancia que tiene        o determinada versión de Linux. Nuestro usuario
            el análisis previo de un sistema de cara a         coge su lista y busca coincidencias, ¡acaba de
            saltarnos su seguridad, hoy en día existen         encontrar un centenar de máquinas vulnerables
            numerosas técnicas de ‘escaneo’ de puertos y       en las que obtener privilegios de administrador!
            la mayoría ya han sido implementadas; Un           ¿A que no te haría gracia estar en la lista de
            ejemplo claro es NMap del que ya se habló en       nuestro amigo?
            la revista.
                                                               Por ese motivo resulta interesante conocer
                                                               mejor el funcionamiento de diferentes técnicas
  !            Muy importante                                  de "port scanning" y de como usar la información
                                                               obtenida para explotar las debilidades de un
  MUY IMPORTANTE: Para cuando leas este artículo, en           sistema así como la forma de protegernos de
  la Web de PC PASO A PASO (www.hackxcrack.com)                estos ataques en la medida en que esto sea
  podrás descargarte el artículo “Técnicas del Port Scannig    posible ;-)
  y uso del NMAP”, que fue publicado en el número 9 de
  PC PASO A PASO.                                              2- Algunas nociones fundamentales

  Ambos artículos se complementan y nuestra intención es       Es interesante conocer algunas cosas acerca
  que puedas comprender este texto aunque no comprases         del protocolo TCP de cara a comprender varias
  en su momento el número 9 de PC PASO A PASO.                 cosas que leerás a continuación y por ello
                                                               volveremos a mencionar algunos de los
                                                               conceptos de artículos anteriores.
            Quizás seas de los que piensa que un 'simple
            escaneo de puertos' no es la mejor forma para      El protocolo de control de transmisión (TCP) es
            entrar en un sistema... aunque sea                 orientado a conexión y esto implica que se
            simplemente uno de los pasos previos               genera un circuito (virtual) entre dos host's
            evidentemente te equivocas, imaginemos por         cuya comunicación se considera fiable, TCP
            ejemplo que un usuario aburrido se dedica a        asegura unas condiciones
            jugar con el 'Intesné' escaneando la red y tiene   óptimas para el circuito establecido y utiliza lo
            una lista con 250.000 host's con interesante       que se denomina "acuse de recibo" para
            información acerca de su sistema operativo,        garantizar que los datos lleguen correctamente
            puertos abiertos, etc.                             a su destino. Cuando queremos establecer una


PC PASO A PASO Nº 13                                                                                               Página 59
PORT SCANING - Tipos de escaneo - PORT SCANING - Tipos de escaneo - PORT SCANING




conexión ambas partes deberán estar de acuerdo en participar   3. El número de secuencia ack (o acknowledge number) es
o dicha conexión no se podrá realizar.                         lo que permite validar los segmentos que van llegando a un
                                                               host, con este fin se coloca en el campo el número de
SEGMENTO TCP                                                   secuencia del segmento incrementado en 1, dicho byte
                                                               espera ser recibido en el siguiente envío. **
La cabecera de un segmento tcp (20 bytes normalmente)
es la siguiente:                                               ** Los puntos 2 y 3 es, para que nos entendamos, la
                                                               forma que tiene el protocolo TCP de no perder ningún
                                                               paquete. Si estamos enviando a un compañero un
                                                               archivo Word de un par de megas, este se corta en
                                                               pequeños trocitos y el receptor debe recibirlos todos,
                                                               no puede perderse un solo paquete. Vale, ya se que
                                                               explicarlo así es muy poco técnico, pero quiero que
                                                               se entienda.

                                                               4.      La longitud de la cabecera en múltiplos de 32 bits. **


                                                               ** Hemos dicho que el archivo Word es cortado en
                                                               paquetitos ¿verdad? Bueno, pues cada paquetito
                                                               es como una carta. La CABECERA de un paquete TCP
                                                               es como el sobre de una carta, es donde figuran los
                                                               datos del remitente (el que envía la carta) y del
                                                               destinatario (el que debe recibir la carta). Dentro del
Explicaré muy brevemente los campos ;) **                      sobre ¿qué encontramos?, pues lo importante, el
                                                               contenido, los DATOS, lo que quieren comunicarnos,
** Seguramente no comprenderás muchos de los                   que nos ha tocado la lotería y cosas de ese tipo ;p
conceptos que a continuación se detallarán, no te              Pues bien, un paquete TCP es exactamente igual que
preocupes demasiado, la idea es que empiecen a                 una carta, tenemos una CABECERA (el sobre) y
“sonarte” un montón de nombres “raros” y tener una             unos DATOS (en este caso un cachito del archivo
visión global del asunto. Para comprender a la                 WORD que estamos enviando).
perfección una conexión TCP/IP necesitarías
programar sockets en lenguaje C, algo que no                   5.        Ahora lo que nos interesa especialmente, el campo
tardaremos mucho en publicar… por el momento no                'flags' (banderas):
te agobies e intenta simplemente tener una visión
general. Para practicar todo lo que a partir de ahora          Tenemos varios flags para disfrute personal y son
se explicará puedes emplear el NMAP.                           URG|ACK|PSH|RST|SYN|FIN ahora te explico algo más acerca
                                                               de ellos, como verás no tienen ningún misterio :)
1. Puerto origen y destino, bastante explícito :P
                                                               URG, indica que el segmento transporta datos urgentes.
2. Número de secuencia, al intentar establecer una conexión
los host's que intervienen en el proceso eligen un número      ACK, indica que el número de secuencia ack de la cabecera
aleatorio para empezar a contabilizar bytes que viajarán en    es válido.
los segmentos de datos de la conexión. Los sucesivos
segmentos que se envíen llevarán como número de secuencia      PSH, fuerza el envío inmediato de los datos recibidos al nivel
el número aleatorio elegido al principio más el                de aplicación, que serían las aplicaciones finales a nivel de
número de bytes enviados hasta ese momento.                    usuario.

 Página 60                                                                                         PC PASO A PASO Nº 13
PORT SCANING - Tipos de escaneo - PORT SCANING - Tipos de escaneo - PORT SCANING




RST, indica que la comunicación debe reiniciarse.                 la cabecera IP y TCP así como las posibles opciones TCP si
                                                                  las hay. El host A genera una llamada a connect () para el
SYN, durante la conexión indica el proceso de sincronización.     propósito.

FIN, indica que el host desea finalizar la conexión.              2)       Ahora el host B enviará la validación para el segmento
                                                                  anterior y activará el flag ACK y en el número de secuencia
6.      El tamaño de la ventana es el número de bytes que         ack colocará el número de secuencia del segmento recibido
esperan ser recibidos sin necesidad de ser validados por          + 1, como el proceso de sincronización no ha terminado el
parte de un host y puede variar durante la conexión activa.       flag SYN sigue levantado.

7.     La integridad de los datos y la cabecera tcp se            3) El host A sabe que el host B ha validado la petición al
pueden verificar mediante el checksum o suma de verificación.     recibir el segmento pero ahora el host B está esperando a
                                                                  que se valide su segmento. El host A envía un segmento
8.        El puntero urgente (que se utiliza junto al flag URG)   colocando el valor oportuno en el número de secuencia ack
indica el número de secuencia del último byte que se considera    y activando el flag ACK, el flag SYN no viaja levantado esta
parte de los datos fuera de banda (urgentes).                     vez. En este punto la conexión se ha completado con éxito.

9.Opciones TCP como el tamaño máximo de segmento, el              ¿COMO SE FINALIZA UNA CONEXIÓN ORDENADA TCP?
‘window scale’ y otras que de momento no vamos a ver aquí.

10,11. Un campo reservado y de datos respectivamente.

¿COMO SE ESTABLECE UNA CONEXIÓN ORDENADA TCP?

El proceso se denomina three-way handshake (o saludo en
tres fases)

                                                                  Ahora te explico que significa eso, no te impacientes, ya
                                                                  sabes que aquí siempre lo explicamos todo para que no se
                                                                  nos escape ningún detalle :)

                                                                  1)       El host A genera una llamada a close() para finalizar
                                                                  la conexión y se envía un segmento con el flag FIN levantado.
Es posible que no comprendas el esquema pero tranquilidad
que ahora te lo explico paso a paso ;-) seguro que lo             2)     El host B valida cualquier información previa enviando
entenderás mejor:                                                 un segmento con el flag ACK levantado.

El proceso para recibir una petición de conexión implica estar    3)        Para que el host A pueda cerrar la conexión el host
preparado para llevar a cabo una serie de llamadas a funciones    B debe enviar un segmento con el flag FIN activado.
como lo son bind (), listen () o connect () de las que            4) Se valida el segmento anterior y la conexión se cierra con
hablaremos en el texto de forma genérica.                         éxito.

1)       Cuando el host A desea establecer una conexión           ** Todo esto ocurre de forma transparente al usuario
mediante un circuito TCP envía un segmento al host B, el          cada vez que establecemos una conexión con un pc
segmento llevará el flag SYN levantado indicando el proceso       remoto (por ejemplo cuando hacemos un simple PING
de sincronización y no suele llevar ningún tipo de datos salvo    o nos conectamos a una Web con el navegador). De

 PC PASO A PASO Nº 13                                                                                               Página 61
PORT SCANING - Tipos de escaneo - PORT SCANING - Tipos de escaneo - PORT SCANING




hecho suceden muchas más cosas, pero nos                          en lugar de eso la abortaremos mediante un paquete con
conformamos con que captes el concepto general de                 RST, ¿y eso por qué? Te preguntarás, la respuesta es muy
que establecer una conexión es un proceso de 3 pasos              sencilla, si ya sabemos que hay alguien al otro lado (tras
y cerrarla es un proceso de cuatro pasos y que los                recibir SYN|ACK) para que seguir intentando conectar ¿? así
“flags” (BANDERAS) tienen mucho que decir en este                 evitamos establecer la conexión completa y es poco probable
proceso :)                                                        que nuestro escaneo quede registrado que es de lo que se
                                                                  trata ;) este escaneo probablemente pasará desapercibido
3- Las técnicas de “port scanning”                                pero recuerda, eso sí, que se necesitan privilegios de
                                                                  administrador para usar esta técnica y que el sistema pueda
Existen muchas técnicas para descubrir qué puertos tiene          montar ese tipo de paquetes, a este tipo de escaneo se le
abiertos un host y determinar que servicios están corriendo       conoce también como escaneo “medio abierto”.
e incluso bajo que privilegios, pero lo más importante es
hacerlo de forma sigilosa sin que la actividad quede registrada   -        TCP FIN, aunque el escaneo TCP SYN no suele dejar
en los ‘logs’ de nuestra víctima y evitar que los sistemas de     rastro en los logs del sistema y su detección puede ser algo
detección de intrusos (IDS) nos apunten como origen del           complicada hay algunos entornos sensibles al escaneo SYN
escaneo. Te aseguro que a muchos usuarios no les hará             como aquellos en los que hay filtros de paquetes o “firewalls”
gracia que les toques los... puertos :P                           y por otro lado existen utilidades que registrarán los intentos
                                                                  de conexión SYN. Para estos casos puede resultar de interés
Vamos a ver detalladamente varias de las técnicas de escaneo      echar mano al escaneo sigiloso FIN (o stealth scan), se
ya conocidas, algunas son una maravilla :) y otras no tanto       fundamenta en el hecho de que los puertos abiertos ignoran
pero en cualquier caso debes conocerlas para poder adaptar        los paquetes recibidos con el flag FIN (vacío) y los cerrados
mejor el escaneo a tus necesidades jeje. Ya empezaste a           responderán con RST. Como se dijo en su momento al
leer acerca de ellas cuando tratamos en la revista el NMap        presentar Nmap los sistemas de Micro$oft entre otros no
pero ahora veremos con más detalle esas y otras técnicas          son susceptibles a este tipo de ataques pues no siguen las
como el ‘Idle Scan’ :)                                            pautas establecidas, quien lo diría xD ¿verdad?

-        TCP CONNECT (), mediante esta técnica no                 -         ACK scan, para esos “ambientes hostiles“ con la
necesitarás ningún tipo de privilegio especial como sucederá      presencia de      cortafuegos puede interesar “nmapear“ las
con otros tipos de escaneo como TCP SYN, y además es una          reglas de filtrado. Mediante esta técnica podemos enviar un
técnica muy rápida puesto que podemos efectuar varias             paquete con el flag ACK con los números de secuencia y ack
conexiones en paralelo. Su funcionamiento (la mayoría ya          de forma incorrecta o aleatoria de manera que recibamos
lo habéis deducido) es el siguiente: intentamos establecer        un paquete de control (“ICMP unreachable”, inalcanzable)
una conexión con un puerto determinado si el puerto está          o no se reciba respuesta, en tal caso el puerto se encuentra
abierto la llamada a connect () tiene éxito y se nos retornará    filtrado y en caso contrario la conexión será reiniciada y las
el valor oportuno en caso contrario la llamada fallará. El        conexiones al puerto no estarían filtradas. Como habrás
problema reside en que los intentos de conexión se registrarán    deducido, no puedes usar este tipo de escaneo para averiguar
automáticamente en el sistema y en principio no nos interesa      los puertos abiertos. Si deseas además encontrar los puertos
en absoluto dejar huellas de ningún tipo.                         abiertos y además clasifica los puertos según se encuentren
                                                                  filtrados o no, existe otra técnica conocida como ‘Window
-       TCP SYN (), hace un momento te acabo de explicar          Scan’ que además aprovecha anomalías el tamaño de la
como se establece una conexión completa, mandamos un              ventana TCP por parte de varios sistemas operativos para
paquete con el flag SYN tal y como se haría normalmente           determinar si el puerto está abierto.
al intentar establecer una conexión y ahora la máquina
remota nos responde amablemente con SYN|ACK hasta aquí            -       UDP scan (User Datagram Protocol scan), antes de
va todo perfecto pero ahora nosotros para llevar la contraria     nada aclarar que se trata de un escaneo mediante un
NO vamos a responder con ACK para establecer la conexión,         protocolo “no orientado a conexión” de manera que no existe

 Página 62                                                                                             PC PASO A PASO Nº 13
PORT SCANING - Tipos de escaneo - PORT SCANING - Tipos de escaneo - PORT SCANING




un circuito virtual entre host’s ni tampoco garantía de entrega   enviamos un paquete falso como si fuésemos el host ZOMBIE
alguna de los paquetes enviados. Se utiliza cuando queremos       de manera que la respuesta del host VICTIMA irá para el
averiguar que puertos udp (un puerto puede ser tcp y udp          host tal y como muestra el ejemplo, supondremos que el
al mismo tiempo pues difieren en el tipo de protocolo pese        IPid del zombie es ahora 100 e ignoraremos a que puerto
a tener el mismo número identificador) están abiertos, si         se dirige junto con otros datos irrelevantes para hacer el
tras mandar el paquete se recibe un mensaje de control            ejemplo un poco más inteligible:
informando del error el puerto está cerrado y en caso
contrario, no recibir nada, se encuentra abierto. Esta técnica    Lo primero es obtener el IPid del zombie escogido (100),
es muy poco precisa ya que si por ejemplo se filtran las
conexiones udp aparecerán como abiertos puertos que están
bloqueados. Además el número de conexiones udp suele
estar limitado por los sistemas de manera que el escaneo
puede ser bastante lento, y he dicho que suele limitarse
porque existe cierto sistema operativo cuyo nombre no
recuerdo ;) que no atiende a las especificaciones establecidas    Tras la primera consulta procedemos,
por los RFC’s de manera que el escaneo irá mucho más
rápido en los sistemas de la compañía Micro$oft. Por el
mismo motivo el escaneo denominado ‘Null Scan’ o escaneo
nulo que se basa en no levantar ninguna bandera tampoco
funcionará al usarlo contra una máquina Window$ :(

-       Xmas Scan: muy similar al escaneo nulo esta técnica       Chequeamos el IPid para ver si el puerto se encuentra
envía un paquete con todas las banderas levantadas. Si el         abierto,
puerto está abierto debe ignorar el paquete.

-        Idle scan, esta es para mí una de las técnicas más
interesantes y que realmente interesa poder usar siempre
que se pueda ya que es altamente sigilosa y no dejamos ni
rastro de nuestra IP :-) esto es así debido básicamente a         ¿Qué ha pasado arriba?
que no será el origen del escaneo... o mejor dicho no para
la máquina víctima de nuestro Idle scan jeje. Con lo leído        Pues lo que ha ocurrido es que ahora el IPid del zombie se
hasta ahora y para tu total comprensión del Idle Scan lo          ha incrementado en 1 tras rebotar al zombie nuestra petición
único nuevo que deberías saber es que los paquetes que se         de conexión. Ahora tu que eres una persona muy atenta
envían llevan un ‘identificador de fragmento’ que se suele        observas de nuevo el IPid de nuestro amigo el zombie xD
incrementar cada vez que se envía uno. Esta técnica de            y observas que efectivamente vale 100 + 2 = 102 y eso
escaneo utiliza host’s intermedios o los llamados “zombies”       significa que el puerto está abierto :-) pero como no siempre
para escanear un objetivo, ahora te explico la forma de           tendremos esa suerte ahora veremos que ocurre si el puerto
hacerlo:                                                          está cerrado, tomaremos los mismos datos previos pero con
                                                                  esa diferencia respecto al estado del puerto:
Elegir un host zombie para determinar su identificación IP
(IPid), ahora enviamos un paquete para probar un puerto
en nuestra víctima desde el host zombie (ya deberías saber
que podemos falsear la dirección IP tal y como se comentó
en el artículo del NMap, pero nos interesa obtener los
resultados ahora). El resultado puede ser que el puerto este
abierto o cerrado (--no me digas) en el primer caso NOSOTROS

 PC PASO A PASO Nº 13                                                                                             Página 63
PORT SCANING - Tipos de escaneo - PORT SCANING - Tipos de escaneo - PORT SCANING




                                                                       linux $ ftp ftp.netscape.com
                                                                       Connected to ftp.gftp.netscape.com.
                                                                       220-15
                                                                       220 ftpnscp.newaol.com FTP server (SunOS 5.8) ready.
                                                                       Name (ftp.netscape.com:linux): anonymous
¿Y ahora que ha ocurrido?                                              500 'AUTH SSL': command not understood.
                                                                       SSL not available
 Pues muy sencillo :-), al rebotar al zombie la petición de conexión   331 Guest login ok, send your complete e-mail address as password.
la víctima (a la que también se le puede llamar host remoto :P)        Password:
nos dice “¿SYN@#~?¿eso qué es?” Como le suena raro y                   230-The response `' is not valid.
curiosamente el puerto está cerrado nos reinicia la conexión           230-Next time please use your e-mail address as password.
mediante RST. Ahora miramos de nuevo el IPid de nuestro zombie         230 Guest login ok, access restrictions apply.
y nos damos cuenta de que solo ha incrementado en una unidad           Remote system type is UNIX.
desde la última vez por lo que el puerto estaba cerrado. Si te fijas   Using binary mode to transfer files.
la IP que recibe la víctima es siempre la de la máquina zombie ;-      ftp> syst
), muy bien pues ahora imagina que nuestra víctima tiene habilitado    215 UNIX Type: L8 Version: SUNOS
un cortafuegos que tiene “permiso” para dejar pasar los paquetes       ftp>
cuya IP coincida con la de nuestro zombie (sucede por ejemplo en
las relaciones de confianza), ¡acabas de saltarte el cortafuegos por   linux $ telnet 131.215.48.89 21
la cara!. Espero que hayas comprendido bien el funcionamiento de       Trying 131.215.48.89...
esta potente técnica de escaneo que como ves es muy efectiva.          ...
El principal problema es encontrar host’s que tengan números IPid      220 secant FTP server (Version wu-2.6.1(2) Thu Nov 29 15:02:58
predecibles como serían las dedicadas a impresión puesto que           PST 2001) ready.
tienen poca actividad o tráfico para llevar a buen término esta        ftp> syst
técnica.                                                               215 UNIX Type: L8

Hasta aquí hemos visto con detalle los tipos de escaneo más            linux $ telnet 216.127.72.117
importantes y más utilizados. Te recuerdo que explicamos en un         ...
artículo anterior la herramienta que aplica estas y otras técnicas     Red Hat Linux release 7.2 (Enigma)
de “port scanning” que fue NMap, permíteme que te sugiera dicha        Kernel 2.4.9-34 on an i686
utilidad si no te apetece programar tu propio escáner de puertos       login: ^D
ahora que ya sabes como funciona el asunto :)
                                                                       ANALIZANDO LA PILA TCP/IP
4- UN PASO MÁS: DETECCIÓN REMOTA DE SO’s
                                                                       A este método se le suele llamar “Stack FingerPrinting” y permite
Ni que decir tiene la importancia que tiene saber a que sistema
                                                                       obtener conclusiones analizando la pila de protocolos
operativo nos enfrentamos ya que resulta fundamental de cara al
                                                                       TCP/IP.
análisis y la penetración de un sistema así como la explotación
remota debido a fallas conocidas (e incluso desconocidas :P) en
                                                                       Algunas formas de discriminar según el sistema operativo conocidas
alguno de los servicios, etc. Existen varias formas y utilidades que
                                                                       se basan en:
nos permitirán obtener una huella digital (o fingerprint) de nuestra
víctima que nos sirva para discriminar un sistema operativo del
                                                                       -        Flag de fragmentación, en casos concretos se establece
resto, ahora veremos algunas.
                                                                       por parte de ciertos SO’s el flag DF (deshabilitar la fragmentación)
                                                                       de la cabecera IP.
PRIMER CONTACTO
                                                                       -        Números de secuencia, se intentan encontrar patrones
Si ya has realizado conexiones directamente desde la consola ya
                                                                       en los números iniciales escogidos al responder a una solicitud de
sea para mirar el correo, usar el FTP y/o cualquier otra cosa que
                                                                       conexión como por ejemplo incrementar un valor X cada cierto
se pueda hacer mediante telnet te habrás fijado de que en muchos
                                                                       tiempo o elegir valores totalmente aleatorios, devolver el mismo
casos se nos está dando una valiosa información de forma totalmente
                                                                       número enviado, etc.
gratuita por parte del demonio que corre en ese puerto referente
a ellos mismos y en muchos casos la plataforma sobre la que corren
                                                                       -      Limitación ICMP, el sistema operativo Linux siguiendo las
:) pero no siempre lo tendremos tan fácil por lo que ahora veremos
                                                                       normas y recomendaciones establecidas limita el número de
otras técnicas bastante más “sofisticadas” jeje.

 Página 64                                                                                                     PC PASO A PASO Nº 13
PORT SCANING - Tipos de escaneo - PORT SCANING - Tipos de escaneo - PORT SCANING




mensajes del tipo ICMP unreachable (inalcanzable) a un máximo         5- PortSentry
de 20 por segundo pero no todos los sistemas operativos siguen
las reglas establecidas tal y como he comentado                       Mediante esta interesante utilidad que te puedes descargar de su
antes ;)                                                              sitio web oficial en http://www.psionic.com (pero suele venir el
                                                                      paquete correspondiente en muchas de las distribuciones de Linux)
-        Flag no determinado, enviamos SYN y uno de los 6 bits        capaz de detectar y responder en tiempo real a un escaneo de
reservados para ver si se mantienen estos bits levantados en la       puertos contra una máquina ¡incluso puede detectar escaneos
respuesta ya que algunos sistemas cerraran la conexión tras           ocultos! aunque no en todos los casos evidentemente ;-), PortSentry
considerar el error, y como sobre gustos no hay nada escrito... :P    se pone a la escucha en los puertos no utilizados que se indican
                                                                      en /etc/portsentry.conf (por lo general) y guarda las direcciones
-         Tipo de servicio, se puede comprobar uno de los campos      IP origen del escaneo guardándolas a continuación en /etc/host.deny
del mensaje de control de errores ICMP de tipo “unreachable” para     entonces se puede dejar en un host inválido como 999.999.999.999
ver si su valor es 0 u otro ya que lo normal es que su valor sea 0    mediante TCPWrappers o utilidades similares. Evidentemente
pese haber sistemas, como es el caso de Linux, en que se devuelve     necesitarás algo más para proteger tu sistema como un cortafuegos
un 192 decimal (0xC0).                                                y una política de seguridad adecuada... :P

-       Opciones TCP, se pueden observar los valores devueltos,       La línea de comandos básica para PortSentry teniendo en cuenta
su orden o si son soportadas o no ciertas opciones como lo son        que estamos bajo Linux como super usuario es:
el window scale, o el MSS (tamaño máximo de segmento).
                                                                      root # portsentry –stcp, detectar escaneos ocultos TCP.
-         Fragmentos solapados, dependiendo de la implementación
del sistema para el tratamiento de los fragmentos solapados, el       root # portsentry –atcp, como el anterior pero en modo avanzado.
nuevo fragmento sobrescribe o es sobrescrito por el fragmento
anterior, hay que utilizar todos los fragmentos para reconstruir el   root # portsentry –tcp, detección básica TCP con atadura al puerto
paquete original completo.                                            (con binding o ligado al puerto).

Estos son algunos de los métodos que existen y que se suelen          root # portsentry –udp, detección básica UDP con atadura al puerto.
utilizar para determinar con MUCHA precisión que SO corre en
nuestra víctima pero no son los únicos y posiblemente aparecerán      root # portsentry –sudp, puede detectar escaneos UDP ocultos.
algunos otros más por lo que no es el objetivo de este artículo
profundizar en todos ellos ahora, quizás más adelante en próximos     root # portsentry –audp, como -sudp pero en modo avanzado.
artículos ;-)
                                                                      Puede que hablemos de esta y otras utilidades relacionadas en un
Por supuesto existen potentes utilidades como QUESO (Qué Sistema      futuro pero por ahora esto es más que suficiente :) para empezar.
Operativo) que puedes obtener de http://www.apostols.org con
el objetivo de detectar el SO de un host remotamente. QUESO           6- Medidas de seguridad básicas
utiliza varios paquetes con ACK=0 y un número de secuencia
aleatorio de la siguiente forma:                                      Como has podido observar existen numerosas formas de escanear
                                                                      una red y obtener información sensible acerca de la misma por
1   SYN                                                               lo que se recomienda instalar sistemas IDS que registren cualquier
2   SYN|ACK                                                           actividad sospechosa así como un buen cortafuegos (con una
6   PSH                                                               buena política restrictiva) y disponer de un buen ‘syslog’. Además
3   FIN                                                               lo ideal sería guardar todos nuestros “logs” en un servidor remoto
4   SYN|FIN                                                           junto con sumas de verificación u otros sistemas que nos aseguren
5   FIN|ACK                                                           que no se han modificado nuestros registros. Existen muchas
7   SYN|otros flags no estandarizados.                                aplicaciones para proteger nuestro sistema del exterior pero ninguna
                                                                      medida es suficiente como para proteger al 100% nuestro sistema,
QUESO es un programa bien diseñado mediante un fichero aparte         eso es lo único que es realmente seguro si tu computadora está
que contiene las respuestas que se esperan según el tipo de           conectada a la red de redes :P y lo seguiremos demostrando en
paquete enviado y que se utilizada para contrastar los resultados     los siguientes artículos ;-)
obtenidos para afirmar con bastante seguridad que SO corre en
nuestro objetivo, en fin una maravilla que ya deberías
tener :)


    PC PASO A PASO Nº 13                                                                                                    Página 65
SUSCRIBETE   A
                                      PC PASO A PASO
                                                                                                            45 EUROS (10% DE DESCUENTO)
     SUSCRIPCIÓN POR:                                                                                       +
     1 AÑO                                                                             =                    SORTEO DE UNA CONSOLA XBOX
                                                                                                            +
     11 NUMEROS                                                                                             SORTEO 2 JUEGOS PC (A ELEGIR)

 Contra                                        R e e m b o l s o Giro Post al

 Solo tienes que enviarnos un mail a preferente@hackxcrack.com                                       Envíanos un GIRO POSTAL por valor de 45 EUROS a:
 indicando:                                                                                          CALLE PERE MARTELL20, 2º 1ª.
 - Nombre                                                                                            CP 43001 TARRAGONA
 - Apellidos                                                                                         ESPAÑA
 - Dirección Completa                                                                                IMPORTANTE: En el TEXTO DEL GIRO escribe un mail de contacto
 - Población                                                                                         o un número de Teléfono.
 - Provincia
 - Cógigo Postal                                                                                     Y enviarnos un mail a preferente@hackxcrack.com indicando:
 - Mail de Contacto y/o Teléfono Contacto                                                            - Nombre
 Es imprescindible que nos facilites un mail o teléfono de contacto.                                 - Apellidos
 - Tipo de Subscripción: CONTRAREEMBOLSO                                                             - Dirección Completa
 - Número de Revista:                                                                                - Población
 Este será el número a partir del cual quieres subscribirte. Si deseas                               - Provincia
 (por ejemplo) subscribirte a partir del número 5 (incluido), debes poner                            - Cógigo Postal
 un 5 y te enviaremos desde el 5 hasta el 15 (ambos incluidos)                                       - Mail de Contacto y/o Teléfono Contacto
                                                                                                     Es imprescindible que nos facilites un mail o teléfono de contacto.
 APRECIACIONES:                                                                                      - Tipo de Subscripción: GIRO POSTAL
 * Junto con el primer número recibirás el abono de 45 euros, precio                                 - Número de Revista:
 de la subscripción por 11 números (un año) y una carta donde se te                                  Este será el número a partir del cual quieres subscribirte. Si deseas
 indicará tu número de Cliente Preferente y justificante/factura de la                               (por ejemplo) subscribirte a partir del número 5 (incluido), debes poner
 subscripción.                                                                                       un 5 y te enviaremos desde el 5 hasta el 15 (ambos incluidos)
 * Puedes hacernos llegar estos datos POR MAIL,tal como te hemos
 indicado; rellenando el formulario de nuestra WEB                                                   APRECIACIONES:
 (www.hackxcrack.com) o enviándonos una carta a la siguiente dirección:                              * Junto con el primer número recibirás una carta donde se te indicará
 CALLE PERE MARTELL Nº20, 2º-1ª                                                                      tu número de Cliente Preferente y justificante/factura de la subscripción.
 CP 43001 TARRAGONA                                                                                  * Puedes hacernos llegar estos datos POR MAIL,tal como te hemos
 ESPAÑA                                                                                              indicado; o enviándonos una carta a la siguiente dirección:
 * Cualquier consulta referente a las subscripciones puedes enviarla                                 CALLE PERE MARTELL Nº20, 2º-1ª
 por mail a preferente@hackxcrack.com                                                                CP 43001 TARRAGONA
                                                                                                     ESPAÑA
                                                                                                     * Cualquier consulta referente a las subscripciones puedes enviarla
                                                                                                     por mail a preferente@hackxcrack.com




      EL GANADOR DEL
  SORTEO DE UN SUSE                                                                                           PERSONALIZATUMOVIL
                                                                                                               PERSONALIZATUTUMOVIL
                                                                                                              PERSONALIZATUMOVIL
                                                                                                                PERSONALIZATUTUMOVIL
                                                                                                                 PERSONALIZATU TUMOVIL
                                                                                                                                      MOVIL
                                                                                                                                      MOVIL
                                                                                                                PERSONALIZATUMOVILMOVIL
                                                                                                                 PERSONALIZATUMOVIL MOVIL
                                                                                                              PERSONALIZATUMOVIL
                                                                                                                PERSONALIZATUTUMOVIL
                                                                                                                 PERSONALIZATUMOVILMOVIL
                                                                                                                  PERSONALIZATU TUMOVIL
                                                                                                               PERSONALIZATUMOVIL
                                                                                                               PERSONALIZATUMOVIL   MOVIL
                                                                                                                                    MOVIL
                                                                                                                                    MOVIL
                                                                                                                                   MOVIL
                                                                                                                                   MOVIL
                                                                                                                                   MOVIL
                                                                                                                                  MOVIL
                                                                                                                                  MOVIL
                                                                                                                  PERSONALIZATU MOVIL
                                                                                                                                  MOVIL
                                                                                                                                 MOVIL
                                                                                                                  PERSONALIZA TU MOVIL
                                                                                                                   PERSONALIZA   MOVIL
                                                                                                                                 MOVIL
 LINUX 8.2 DEL MES DE                                                                                              PERSONALIZA
                                                                                                                   PERSONALIZA
                                                                                                                       PERSONALIZATU MOVIL
                                                                                                                        PERSONALIZA TU MOVIL
                                                                                                                                       MOVIL
                                                                                                                       PERSONALIZA TU MOVIL
                                                                                                                                       MOVIL
                                                                                                                       PERSONALIZA TU MOVIL
                                                                                                                        PERSONALIZA
            SEPTIEMBRE                                                     ES:
 JOSE RUIZ BALLESTER
                             MADRID
SEGUIR LLAMANDO, EL PROXIMO
 PODRIA SER PARA TI (PAG 66)




             SI TE GUSTA LA INFORMÁTICA.
    SI ESTAS “CABREADO” CON GÜINDOUS ;)
        SI QUIERES PROGRESAR DE VERDAD
                                                                                 Incluye 7 CD’s y 1 DVD
                 PC PASO A PASO                                                  Manual de Instalación.
            SORTEA CADA MES UN S.O.                                              Manual de Administracion

   SUSE LINUX PROFESSION AL 8.2
     SIMPLEMENTE ENVIA LA PALABRA
                       PCCON AL 5099
                      DESDE TU MOVIL
  PRECIO DEL MENSAJE: 0,90€ + IVA. VALIDO PARA (MOVISTAR - VODAFONE Y AMENA)
                              IVA. VALIDO PARA (MOVISTAR


               EL PREMIO PUEDE SER CANJEABLE POR UN JUEGO
                                                                                                                          HAY MUCHOS MAS EN
                   DE PC O CONSOLA QUE NO SUPERELOS 85€                                                                http://pclog.buscalogos.com/
  EL GANADOR SALDRA PUBLICADO AQUÍ 2 NÚMEROS DESPUES DE LA PUBLICACIÓN.
NÚMERO1:                                                                   NÚMERO 2:
                                                                             -CODE/DECODE BUG: INTRODUCCIÓN.
  -CREA TU PRIMER TROYANO                                                    -CODE/DECODE BUG: LOCALIZACIÓN DEL OBJETIVO.
  INDETECTABLE POR LOS ANTIVIRUS.                                            -CODE/DECODE BUG: LÍNEA DE COMANDOS.
  -FLASHFXP: SIN LÍMITE DE VELOCIDAD.                                        -CODE/DECODE BUG: SUBIENDO ARCHIVOS AL SERVIDOR REMOTO.
  -FTP SIN SECRETOS: PASVMODE.                                               -OCULTACIÓN DE IP: PRIMEROS PASOS.
  -PORT MODE/PASV MODE Y LOS FIREWALL: LA UTILIDAD DE LO APRENDIDO.          -LA FLECHA ÁCIDA: LA SS DIGITAL.
  -TCP-IP:INICIACIÓN (PARTE 1).                                               AZNAR AL FRENTE DE LA SS DEL SIGLO XXI.
  -EL MEJOR GRUPO DE SERVIDORES FTP DE HABLA HISPANA.
  -EDONKEY 2000 Y SPANISHARE.
  -LA FLECHA ÁCIDA.




NÚMERO 3:                                                             NÚMERO 4:
 -PROXY: OCULTANDO NUESTRA IP.                                         - CREA TU SEGUNDO TROYANO, INDETECTABLE E INMUNE A LOS ANTIVIRUS.
          ASUMIENDO CONCEPTOS.                                                  CONOCIENDO EL RADMIN.
 -PROXY: OCULTANDO NUESTRA IP.                                                  GESTIONANDO UNA SALA
          ENCADENANDO PROXIES.                                                  DE ORDENADORES.
 -PROXY: OCULTANDO NUESTRA IP.                                                  OCULTANDO EL RADMIN.
          OCULTANDO TODOS NUESTROS PROGRAMAS TRAS LAS                           INSTALANDO EL RADMIN
         CADENAS DE PROXIES.                                                    EN EQUIPOS REMOTOS.
 -EL SERVIDOR DE HACKXCRACK: CONFIGURACIÓN Y MODO DE EMPLEO.           - OCULTACIÓN DE IP POR NOMBRE DE DOMINIO.
 -SALA DE PRACTICAS: EXPLICACIÓN.                                      - CREA LETRAS DE IMPACTO PARA TUS DOCUMENTOS (LETRAS DE FUEGO).
 -PRÁCTICA 1ª: SUBIENDO UN ARCHIVO A NUESTRO SERVIDOR.                 - CONSIGUE UNA IP FIJA.
 -PRÁCTICA 2ª: MONTANDO UN DUMP CON EL SERV-U.
 PRÁCTICA 3ª: CODE/DECODE BUG. LÍNEA DE COMANDOS.
 -PREGUNTAS Y DUDAS.




                                                                          NÚMERO 6:
  NÚMERO 5:
                                                                          - PASA TUS PELICULAS A DIVX (STREAMING)
  -HACK-OPINION: LA PIRATERÍA EN INTERNET.                                - PASA TUS PELICULAS A DIVX II (CODEC DIVX)
  -ROOTKITS: LA PESADILLA DE CUALQUIER ADMINISTRADOR.                     - PUERTOS & SERVICIOS
  -ROOTKITS: EL SR. NTROOT.                                               - eMule: EL NUEVO REY DEL P2P
  -WAREZ: APPZ, GAMEZ, MP3Z, DIVX,    FTPZ, 0-DAY.                        - NUEVA SECCION: PROGRAMACION DESDE 0
  -APRENDIENDO A COMPILAR PROGRAMAS. COMPILA TU PROPIO NETCAT.            - CURSO DE VISUAL BASIC
  -BUGS, ERRORES Y OTRAS FORMA DE JOD...                                  - IPHXC: EL TERCER TROYANO DE HXC
  -NETBIOS: ESTUDIO Y PENETRACIÓN DE SISTEMAS.                            - TENDENCIAS ACTUALES EN CODIGO MALICIOSO
  -ASESINADOS POR LA LSSI.                                                - OCULTACION DE FICHEROS. METODO STREAM (ads)
  -LISTADO DE ORDENES PARA NETBIOS.                                       - TRASTEANDO CON EL HARDWARE DE UNA LAN
  -HACK-OPINION: PAGOS POR INTERNET SEGUROS YÁ.
NÚMERO 8:

NÚMERO 7:                                           - CURSO DE LINUX
- PROTOCOLOS: POP3                                  - APACHE: COMPARTE ARCHIVOS
- PASA TUS PELICULAS A DIVX III (EL AUDIO)          - REVERSE SHELL
- PASA TUS PELICULAS A DIVX IV (MULTIPLEXADO)       - CURSO DE VISUAL BASIC: MAS
- CURSO DE VISUAL BASIC: LA CALCULADORA               CALCULADORA
- IPHXC: EL TERCER TROYANO DE HXC II                - PROTOCOLOS Y SU SEGURIDAD: SMTP
- APACHE: UN SERVIDOR WEB EN NUESTRO PC
- CCPROXY: IV TROYANO DE PC PASO A PASO
- TRASTEANDO CON EL HARDWARE DE UNA LAN




                                                    NÚMERO 10:
 NÚMERO 9:
                                                    - CURSO DE LINUX (Gestión de usuários)
 - CURSO DE LINUX (Sistema de archivos)             - APACHE + MySQL + PHP=Trio de Ases
 - APACHE: COMPARTE ARCHIVOS MEDIANTE        WEB.   - CURSO DE VISUAL BASIC: ACCESO A DATOS(II)
 - CURSO DE VISUAL BASIC: MI 1ª DLL  ACCESO A      - XML: El futuro de la trasferencia de datos
   DATOS                                            - SERIE RAW: DCC
 - PORT SCANING: NMAP
 - SERIE RAW: IRC




NÚMERO 11:                                           NÚMERO 12:
- Curso de linux: programacion                       - Curso de linux: programacion C.
- Visual Basic: IIS bug exploit                      - Visual Basic: IIS bug exploit. Nuestro primer Scanner.
- Apache como proxy                                  - APACHE: Configuralo de forma segura.
- Serie Raw: FTP                                     - Serie Raw: FTP(II)
- Validacion XML: DTD                                - VALIDACION XML: DTD (II)
- Historia: Lady Augusta Ada Byron

Más contenido relacionado

PDF
Hxc12
PDF
Hxc15
PDF
Hxc18
PDF
Ejecutivos España
PDF
Secwepemc artisan catalogue
PPT
Flores piran lafuente-olaizola-subira
PDF
Drugs in sports list 2009
Hxc12
Hxc15
Hxc18
Ejecutivos España
Secwepemc artisan catalogue
Flores piran lafuente-olaizola-subira
Drugs in sports list 2009

Similar a Hxc13 (20)

PDF
Hxc14
PDF
Hxc16
PDF
Hxc19
PDF
Hxc21
PDF
Hxc17
PDF
Hxc9
PDF
Hxc20
PDF
Hxc23
PDF
Hxc10
PDF
Hxc11
PDF
Hxc8
PDF
Hxc22
PDF
Haxcra8.pdf
PDF
Hxc7
PDF
Hd magazine No 3
PDF
Hd magazine nro2
PDF
Hxc5
PPSX
Mapas C.
DOCX
ensayo para erick de alan bodro
PDF
Hxc14
Hxc16
Hxc19
Hxc21
Hxc17
Hxc9
Hxc20
Hxc23
Hxc10
Hxc11
Hxc8
Hxc22
Haxcra8.pdf
Hxc7
Hd magazine No 3
Hd magazine nro2
Hxc5
Mapas C.
ensayo para erick de alan bodro
Publicidad

Más de rubenroa (20)

PPTX
Estudios epidemiologicos
PPTX
Efectividad de la vacunacion Covid-19 en variante delta
PPTX
Causalidad
PPTX
Evaluacion de tecnologias sanitarias
PPT
Epidemiologia
PPT
Pediatrics 2008 jul 122(1) 143 8, figure-1
PPT
Introducción análisis farmacoepidemiológico sss&farma-taller15jun2011
PPTX
Maceira sss&farma-taller15jun2011
PPTX
Datos cohorte chilena sida (1)
PPT
Ferinject
PPTX
Kappos fingolimod moa-clin_results_vfinal_buenosaires1a
PPT
Uso Racional de Medicamentos
PPS
tabaquismo
PPT
Sesion ppt -2641_
PPT
Auditoria em
PPS
Indice tobillo brazo
PPS
indice tobillo brazo
PPTX
Epistemología y paradigmas
PPS
Vertigo acv
PPS
Apendicectomia
Estudios epidemiologicos
Efectividad de la vacunacion Covid-19 en variante delta
Causalidad
Evaluacion de tecnologias sanitarias
Epidemiologia
Pediatrics 2008 jul 122(1) 143 8, figure-1
Introducción análisis farmacoepidemiológico sss&farma-taller15jun2011
Maceira sss&farma-taller15jun2011
Datos cohorte chilena sida (1)
Ferinject
Kappos fingolimod moa-clin_results_vfinal_buenosaires1a
Uso Racional de Medicamentos
tabaquismo
Sesion ppt -2641_
Auditoria em
Indice tobillo brazo
indice tobillo brazo
Epistemología y paradigmas
Vertigo acv
Apendicectomia
Publicidad

Último (20)

PDF
MANUAL TECNOLOGÍA SER MINISTERIO EDUCACIÓN
PDF
TRABAJO DE TECNOLOGIA.pdf...........................
DOCX
Contenido Fundamentos de comunicaciones Fibra Optica (1).docx
PPTX
modulo seguimiento 1 para iniciantes del
PDF
CyberOps Associate - Cisco Networking Academy
PPTX
Presentación de Redes de Datos modelo osi
PPTX
Sesion 1 de microsoft power point - Clase 1
DOCX
Zarate Quispe Alex aldayir aplicaciones de internet .docx
PPTX
Power Point Nicolás Carrasco (disertación Roblox).pptx
PDF
programa-de-estudios-2011-guc3ada-para-el-maestro-secundarias-tecnicas-tecnol...
PPTX
Historia Inteligencia Artificial Ana Romero.pptx
PDF
Estrategia de Apoyo de Daylin Castaño (5).pdf
PDF
Documental Beyond the Code (Dossier Presentación - 2.0)
PDF
Instrucciones simples, respuestas poderosas. La fórmula del prompt perfecto.
PDF
capacitación de aire acondicionado Bgh r 410
PDF
Influencia-del-uso-de-redes-sociales.pdf
PDF
PRESENTACIÓN GENERAL MIPIG - MODELO INTEGRADO DE PLANEACIÓN
PDF
clase auditoria informatica 2025.........
PPT
introduccion a las_web en el 2025_mejoras.ppt
PPTX
Curso de generación de energía mediante sistemas solares
MANUAL TECNOLOGÍA SER MINISTERIO EDUCACIÓN
TRABAJO DE TECNOLOGIA.pdf...........................
Contenido Fundamentos de comunicaciones Fibra Optica (1).docx
modulo seguimiento 1 para iniciantes del
CyberOps Associate - Cisco Networking Academy
Presentación de Redes de Datos modelo osi
Sesion 1 de microsoft power point - Clase 1
Zarate Quispe Alex aldayir aplicaciones de internet .docx
Power Point Nicolás Carrasco (disertación Roblox).pptx
programa-de-estudios-2011-guc3ada-para-el-maestro-secundarias-tecnicas-tecnol...
Historia Inteligencia Artificial Ana Romero.pptx
Estrategia de Apoyo de Daylin Castaño (5).pdf
Documental Beyond the Code (Dossier Presentación - 2.0)
Instrucciones simples, respuestas poderosas. La fórmula del prompt perfecto.
capacitación de aire acondicionado Bgh r 410
Influencia-del-uso-de-redes-sociales.pdf
PRESENTACIÓN GENERAL MIPIG - MODELO INTEGRADO DE PLANEACIÓN
clase auditoria informatica 2025.........
introduccion a las_web en el 2025_mejoras.ppt
Curso de generación de energía mediante sistemas solares

Hxc13

  • 1. HACK X CRACK: “PORT SCANNING” -- APRENDE A ESCANEAR LA RED P A S O P A S Oa a a a a a a aa a a a a a ANALIZANDO EQUIPOS TOS REMOTOS BASES DE DATOS DISEÑO DE FORMULARIOS Y ORGANIZACION PROGRAMANDO VARIABLES Y PUNTEROS Nº 13 -- P.V.P. 4,5 EUROS 00013 8 414090 202756
  • 2. P A S O aa P A S Oaa aa a a aa a a a a a a aa EDITORIAL: EDITOTRANS S.L. Director de la Publicación J. Sentís C.I.F: B43675701 PERE MARTELL Nº 20, 2º - 1ª E-mail contacto 43001 TARRAGONA (ESPAÑA) director@hackxcrack.com Director Editorial Diseño gráfico: I. SENTIS J. M. Velasco E-mail contacto director@editotrans.com E-mail contacto: Título de la publicación Los Cuadernos de HACK X CRACK. grafico@hackxcrack.com Nombre Comercial de la publicacíón PC PASO A PASO Redactores Web: www.hackxcrack.com AZIMUT, ROTEADO, FASTIC, MORDEA, FAUSTO, Dirección: PERE MARTELL Nº 20, 2º - 1ª. ENTROPIC, MEIDOR, HASHIMUIRA, BACKBONE, 43001 TARRAGONA (ESPAÑA) ZORTEMIUS, AK22, DORKAN, KMORK, MAILA, TITINA, SIMPSIM... ... ... ... ... ¿Quieres insertar publicidad en PC PASO A Contacto redactores PASO? Tenemos la mejor relación precio-difusión redactores@hackxcrack.com del mercado editorial en España. Contacta con nosotros!!! Colaboradores Mas de 130 personas: de España, de Brasil, de Director de Marketing Argentina, de Francia, de Alemania, de Japón y Sr. Miguel Mellado algún Estadounidense. Tfno. directo: 652 495 607 Tfno. oficina: 877 023 356 E-mail: miguel@editotrans.com E-mail contacto colaboradores@hackxcrack.com Imprime I.G. PRINTONE S.A. Tel 91 808 50 15 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 TELÉFONO DE ATENCIÓN AL CLIENTE: 977 22 45 80 Petición de Números atrasados y Suscripciones (Srta. Genoveva) HORARIO DE ATENCIÓN: DE 9:30 A 13:30 (LUNES A VIERNES) © Copyright Editotrans S.L. NUMERO 13 -- PRINTED IN SPAIN PERIOCIDAD MENSUAL Deposito legal: B.26805-2002 Código EAN: 8414090202756
  • 4. EDITORIAL PREPARANDO EL FUTURO Cuando uno forma parte de un proyecto, como por ejemplo la publicación de una revista, debe preocuparse tanto de los mil y un problemas diarios como de “el futuro”. Hasta hace muy poco, PC PASO A PASO (Los Cuadernos de Hack x Crack), ha sido publicada siguiendo una filosofía tipo “vivir al día”, algo que 4 EDIT ORIAL está muy bien en los inicios pero que no debe 5 XML:DOM mantenerse demasiado tiempo. 14 C OLAB ORA C ON NOSO TR OS Ahora estamos preparando toda una serie de cambios cuyos resultados empezarán a “verse” en poco tiempo, 1 6 PR OGRAMA CION BA JO LINUX: LENGU A JE C desde la Web hasta la revista… nuevos contenidos, publicidad, más páginas, nuevos colaboradores y, 27 CURSO VISUAL BASIC: UN CLIENTE, UNA NECESIDAD(I). sobre todo, mayor diversidad en las temáticas. 38 SERIE RAW (7): HTTP (I) Hasta ahora nos hemos centrado en temas relacionados con la Seguridad Informática orientada a Internet y 5 8 S E RV I D O R D E H XC . M O D O D E E M P L EO hemos intentado “picar” al lector para que empiece a programar. Ambos temas RED y CURSOS seguirán 66 C ONCURSO DE SUSE LINUX 8.2 siendo los principales pilares de PC PASO A PASO, 6 6 B A JAT E N U E S T R O S L O G O S Y M E L O D I A S pero estamos trabajando duro para ofrecer mucho más… tiempo al tiempo :) 66GANADOR DEL CONCURSO DE SUSE LINUX Para nosotros está siendo muy difícil “madurar”, sería 66 SUSCRIPCIONES sencillo tomar una línea tipo “análisis de productos” y ganar de esta forma publicitantes y lectores tipo 67 NUMER OS ATRAS ADOS “PC ACTUAL”, de hecho, hay publicaciones en el mercado cuyas ventas ni siquiera cubren el precio de la Imprenta pero que tienen importantes beneficios por la publicidad. Nosotros estamos trabajando en la cuadratura del círculo, seguiremos con nuestra temática y la ampliaremos, seguiremos siendo educativos en lugar de destructivos, pero empezaremos a diversificar y, sobre todo, aumentar páginas. Esperamos poder demostrar todo este trabajo (que hasta ahora permanece “en la sombra”) para los primeros meses del próximo año. Tratar la temática Hack es tratar la Seguridad Informática, al contrario de lo que muchos piensan ambas cosas son exactamente lo mismo. Algunos creyeron que era imposible hacer una revista de este tipo sin caer en la vulgaridad y sin “empujar” al lector a cometer todo tipo de actos ilícitos, se equivocaron… si algo hemos hecho es enseñar y educar hasta la saciedad. GRACIAS POR LEERNOS
  • 5. MANIPULACION DE DOCUMENTOS XML: EL DOM Primera parte: Teoria del DOM e interfaz DOMDocument Por Joaquim Roca Verges XML es una apuesta segura. El común de los mortales lo utilizamos cada día sin saberlo y es un estándar universal implementada en cualquier aplicación que se precie. Hasta ahora hemos visto lo que es el xml (nº10) y archivo Power Designer versión 7. lo que son las DTD (nº 11 y 12). Recordamos que el XML es un lenguaje de intercambio de datos, que Hará cosa de un año, fui a una presentación Microsoft hoy en día es prácticamente universal (todo el de una herramienta BizTalk que sirve para procesar mundo lo entiende), y las DTD son reglas que podéis archivos generados con SAP. Los archivos generados aplicar al XML. Ahora vamos a ver como procesar, con SAP se guardaban... en formato XML. como recorrer, como extraer la información de los documentos XML. ! Para quien se... Y lo vamos a hacer con el DOM. Para quien se esté preguntando qué es eso del SAP, le damos otro Para daros ánimos e intentar inculcaros mi par de siglas: ERP y CMR. Un ERP es, para que nos entendamos, entusiasmo me gustaría explicaros un par de las un programa de gestión empresarial, pero no un "programita" muchas experiencias favorables y satisfactorias que tipo "facturación/nominas", sino todo un sistema de gestión he tenido con este lenguaje. integral, para que te hagas una idea, los bancos y grandes Hace poco estuve diseñando una base de datos multinacionales utilizan sistemas tipo ERP para gestionar desde bastante grande conjuntamente con otra empresa los datacenters (centros de datos que pueden llegar a ocupar varias que llamaremos XXX. Nos reuníamos semanalmente plantas de un edificio e incluso varios edificios) hasta la sucursal con los usuarios y fruto de las conversaciones con de un pequeño pueblo o un simple punto de venta. Alguno estará ellos íbamos diseñando la base de datos. El diseño pensando como es posible "instalar" un ERP (algo tan se hacia con Power Designer (podéis bajároslo de aparentemente "grande") en un punto de venta (por ejemplo en http://crm.sybase.com/sybase/www/eBD/my_03/ un pequeño McDonals), pues bien, es posible porque un sistema pd952_dwnld_eval.jsp una vez os hayáis registrado), ERP contiene infinidad de pequeños módulos especialmente una herramienta de modelado de base de datos de adaptados para cada una de las áreas que puede tener una empresa. la casa Sybase. La empresa XXX utilizaba Power Pero un ERP es mucho más, porque permite a las empresas Designer 7, y mi empresa disponía de Power Designer ampliar, personalizar e incluso crear módulos completamente 8 y 9. nuevos que se adapten perfectamente a cualquier tarea. Pero lo verdaderamente importante no es ni su capacidad ni su Si la empresa XXX hacia modificaciones y nos las modularidad, lo realmente importante es que un ERP permite un mandaba a mi empresa ningún problema ya que análisis global y en tiempo real de cualquier aspecto de una las versiones 8 y 9 entendían a la perfección la empresa, desde una visión financiera de alto nivel (activos/pasivos versión 7, sin embargo si nosotros hacíamos globales de toda una multinacional) hasta las ventas en la última modificaciones ellos no podían abrir nuestros hora de una diminuta sucursal de un pequeño pueblo de Murcia. documentos. Pues bien, SAP es uno de los ERP más difundidos. Microsoft, Lo solucionamos guardando nuestras modificaciones como no podía ser menos, compró una empresa especializada en como archivo XML, y entonces sí, entonces el colega la creación de Software tipo ERP y comercializa su producto ERP de la empresa XXX cogía el XML y lo convertía a un bajo el nombre de AXAPTA-NAVISION. Y nos queda el CMR, PC PASO A PASO Nº 13 Página 5
  • 6. XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM <DOCUMENTO> <!-- solo se mostrará a partir de la una del mediodía --> que para no extendernos más diremos que es un importante <BIENVENIDA hora="13:00"> Hola, buenas tardes </BIENVENIDA> módulo del Sistema ERP que se encarga de "los contactos", </DOCUMENTO> vamos, como el Outlook pero a lo grande ;p (espero que se capte la ironía, comparar Outlook con un CMR es de tan mal gusto este comentario también formaría parte del DOM. como comparar el vinagre con un buen vino :) Y (atención!!) el texto "Hola, buenas tardes" también es parte del No creo que en esta revista se trate nunca en profundidad los DOM sistemas ERP, de hecho, la temática que rodea al mundo de los ERPs es tan basta que daría para hacer una revista solo dedicada El DOM es el conjunto de todos los componentes (elementos, a ello. Lo malo es que, como todo lo bueno, apenas vendería un atributos, comentarios, entidades, texto...) que conforman el millar de ejemplares… aunque la cosa quizá está cambiando… documento XML. hasta hace poco únicamente las grandes corporaciones podían acceder a un sistema de este calibre (no solo por el precio, sino Todos estos componentes se denominan objetos. por lo complejo de su puesta en marcha, implantación, gestión, mantenimiento…); pero actualmente las empresas que crean este Por ejemplo, si nuestro PC fuera un documento XML, el DOM estaría tipo de productos están haciendo un guiño a las medianas e incluso formado por el disco duro, la memoria, el procesador, la pantalla, pequeñas empresas sacando al mercado "mini-ERPs" diseñados la frecuencia de la pantalla.... específicamente para determinados sectores empresariales. El DOM es independiente del lenguaje de programación con el que Con esta nota, simplemente pretendemos abrir un poco tus estemos trabajando. Podemos acceder al DOM XML tanto con Java, horizontes. Los usuarios de informática muchas veces creemos como con Visual Basic, C, JavaScript... conocer los programas más importantes/difundidos, pero seguro que muy pocos lectores habrán instalado alguna vez un ERP en Está basado en lo que se denomina interfaz de nodos = un su ordenador. Si tenemos en cuenta que los ERP dominan el conjunto de métodos (funciones) y propiedades para los objetos mundo y que son los programas utilizados por las grandes (elementos, comentarios, atributos, entidades... del documento empresas/instituciones… ¿cómo es posible que la inmensa mayoría XML) DOM. de los usuarios no tengan/tengamos ni idea del tema?... Desde aquí te invitamos a que investigues sobre ello ;) El DOM es una vista estructurada de un documento XML. Podemos verlo como un árbol, y sus hojas: Una estructura de tipo árbol y las hojas se llaman nodos. ¿QUE ES EL DOM? Recordemos el XML de ordenes de compra: DOM = Document Object Model, es decir modelo de objetos del documento xml. <?xml versión="1.0" standalone="yes"?> <ORDEN_DE_COMPRA> Hemos visto que un XML puede ser lo siguiente: <CLIENTE> <DOCUMENTO> <NUMERO_DE_CUENTA>12345678</NUMERO_DE_CUENTA> <BIENVENIDA> Hola, buenas tardes </BIENVENIDA> <NOMBRE_COMPLETO> </DOCUMENTO> <NOMBRE>Sam</NOMBRE> <APELLIDO1>Bass</APELLIDO1> Pues el modelo de objetos de este documento estaría formado por <APELLIDO2></APELLIDO2> TODOS los elementos que lo componen, o sea por el elemento </NOMBRE_COMPLETO> DOCUMENTO, y por el elemento BIENVENIDA y si por ejemplo el </CLIENTE> elemento BIENVENIDA tuviera un atributo que se llamara "hora": </ORDEN_DE_COMPRA> <DOCUMENTO> Los elementos, comentarios, atributos, entidades, texto <BIENVENIDA hora="13:00"> Hola, buenas tardes </BIENVENIDA> etc. que contiene el documento xml , se denominan todos </DOCUMENTO> como NODOS, así tenemos que <NOMBRE> es un NODO y "Sam" es otro NODO. también sería parte del DOM, y si hubiéramos escrito un comentario: Y el conjunto de NODOS con sus funciones (lo que podemos Página 6 PC PASO A PASO Nº 13
  • 7. XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM hacer sobre los nodos) y propiedades se denomina INTERFAZ DE NODOS. Y ve á m o s l o r e p r e s e n t a d o c o m o u n c o n j u n t o d e n o d o s que dibujaremos con elipses, y su contenido(el texto) q u e re p r e s e n t a r e m o s c o n n o d o s re c t á n g u l o s ( e s u s u a l dibujarlo todo en rectángulos, pero he preferido hacer esta primera aproximación de esta manera): Si esto fuese un objeto Visual Basic, nos gustaría ser capaces de manipular estos nodos, y leer y manipular sus valores. El objeto Visual Basic que contiene el documento xml se llama DocumentObject y los nodos son una matriz de objetos de tipo NODE. Con lo que la instrucción DocumentObject.Node (index).value nos proporciona el valor de un nodo en particular. Y esto es básicamente lo que el DOM (Document Object Model) XML hace: carga en memoria el documento (con todos sus nodos) y accede, modifica, añade, elimina… Pero no nos adelantemos. TIPOS DE NODOS QUE PUEDE CONTENER UN DOCUMENTO XML Todos los nodos comparten propiedades y métodos comunes, pero dependiendo del tipo de nodo que sea, tiene unas propiedades y métodos particulares. PC PASO A PASO Nº 13 Página 7
  • 8. XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM Cuando estemos programando el DOM, podremos Los elementos y el Texto, se tratan con las tres primeras interfaces hacer referencia al nodo indicando el tipo de nodo (DOMDocument, XMLDOMNode y XMLDOMNodeList) (NODE_ ATTRIBUTE por ejemplo) o a su valor Los atributos, no son hijos de ningún otro elemento, sino que númerico (2 para el NODE_ ATTRIBUTE) forman parte de un elemento. Como caracterizan a un elemento, es decir describen características de un elemento, son diferentes Siguiendo el ejemplo anterior: a los otros nodos, no están considerados como hijos de ningún padre y se tratan con la interfaz XMLDOMNamedNodeMap Serían NODE_ELEMENT: INTERFAZ DOMDocument <ORDEN_DE_COMPRA>;<CLIENTE>;<NUMERO _DE_CUENTA>;<NOMBRE_COMPLETO>;<NOMB Es la interfaz del objeto documento (nodo documento), que RE>; <APELLIDO1> y <APELLIDO2> incorpora propiedades y métodos para trabajar con el nodo raíz del DOM. Serían NODE_TEXT: "Sam" Y "Bass" El nodo raíz del DOM representa TODO el documento XML y no lo debemos confundirlo con el elemento raíz del documento. Si miráis el diagrama de nodos que hemos dibujado antes, podéis ¿CÓMO MANIPULAMOS EL ARCHIVO observar el nodo raíz del DOM arriba del todo, con la leyenda XML. XML CON EL DOM? Seguidamente y colgando de el podéis ver el elemento raíz del documento que seria el nodo ORDEN_DE_COMPRA. Para manipular un documento XML, lo primero que tenemos que hacer es cargarlo en la memoria de Vamos a irlo viendo todo con un ejemplo. nuestro ordenador con un parser XML. Nosotros Cread en la raíz de vuestro sistema de archivos una carpeta que utilizaremos el parser de Microsoft: el Msxml, tal se llame xmlDom ("C:xmlDom") como ya hicimos en el ejemplo de la primera entrega (nº 10). Primero crearemos un DTD, contra el cual se validará nuestro xml. Una vez el documento está en memoria, ya lo Abrid un editor de texto y escribid: podemos manipular utilizando el DOM <!ELEMENT ORDEN_DE_COMPRA (CLIENTE)> <!ELEMENT CLIENTE (NUMERO_DE_CUENTA,NOMBRE_COMPLETO)> El DOM, trata el documento XML como un árbol. El DocumentElement es el elemento superior o raíz <!ELEMENT NUMERO_DE_CUENTA ( #PCDATA)> <!ELEMENT NOMBRE_COMPLETO ( NOMBRE, APELLIDO1, APELLIDO2) > del árbol. Este elemento raíz puede tener uno o <!ELEMENT NOMBRE (#PCDATA)> mas nodos (nodes) hijos (child) que representarían <!ELEMENT APELLIDO1 (#PCDATA)> las hojas del árbol. <!ELEMENT APELLIDO2 (#PCDATA)> Una interfaz, como hemos avanzado antes es un Guardad el archivo como ordenCompra.dtd dentro de la carpeta conjunto de métodos (funciones) y propiedades xmlDom para los objetos (elementos, comentarios, atributos, entidades... del documento XML) DOM. Abrid de nuevo el editor de texto y escribid Para acceder a los objetos del dom (los nodos del <?xml version "1.0" standalone="no" ?> DOM) disponemos de cuatro interfaces principales, "ordenCompra.dtd"> que trataremos una a una a continuación: <ORDEN_DE_COMPRA> <CLIENTE> 1. DOMDocument <NUMERO_DE_CUENTA>12345678</NUMERO_DE_CUENTA> 2. XMLDOMNode <NOMBRE_COMPLETO> 3. XMLDOMNodeList <NOMBRE>Sam</NOMBRE> 4. XMLDOMNamedNodeMap <APELLIDO1>Bass</APELLIDO1> <APELLIDO2></APELLIDO2> Para la mayoría de documentos XML, los tipos de </NOMBRE_COMPLETO> nodos más comunes son: </CLIENTE> • Elementos </ORDEN_DE_COMPRA> • Atributos • Texto y guardad el archivo como Compra.xml Página 8 PC PASO A PASO Nº 13
  • 10. XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM Abrid el Visual Basic y cread un proyecto nuevo tal '**************Escribid******************** y como indicamos en el nº 10 (asumimos que tenéis Dim xmlDocument As DOMDocument conocimientos básicos de visual basic): esto es Dim xmlString as String • Abrid el Visual Basic Dim blnValido As Boolean • Seleccionar un Standard exe Set xmlDocument = New DOMDocument • Añadid una referencia al DOM. Para ello '**************************************** seleccionar del menú PROYECTO la opción REFERENCIAS. • Cargar el documento xml en memoria, en el objeto de • Buscad una que pone Microsoft XML, v3.0 tipo DOMDocument (método load()), asignarle algunas propiedades y seleccionarla, haciendo click en el y comprobar que está bien formado. cuadradito que hay a la izquierda de modo que quede marcado. Y dadle al botón de '**************Escribid******************** Aceptar (yo lo tengo en inglés podéis ver 'Antes de cargarlo en memoria, damos valor a alguna de sus propiedades: que en la pantalla se puede leer OK.) 'primero le indicamos que se ejecute de manera síncrona, esto es que se ejecute 'inmediatamente, que se cargue inmediatamente xmlDocument.async = False 'le indicamos que se valide contra el DTD xmlDocument.validateOnParse = True 'y si hay referencias externas, que las resuelva. Por ejemplo, controlar que el DTD que 'referenciamos existe donde le indicamos, en el path que le indicamos. xmlDocument.resolveExternals = True 'si el documento es valido, el método Load que es el carga el documento devolverá un valor true, en caso contrario un valor false blnValido= xmlDocument.Load ("C:XmlDomCompra.xml") if blnValido then MsgBox "El documento es válido" Else MsgBox "El documento no cumple con el DTD" Exit sub End If '**************************************************** Fijaros que el nombre de la referencia es a la dll ! Nota aclaratoria msxml3. Cuando asignamos un valor a una variable: A. DOMDocument CARGAR DEL DOCUMENTO, Dim i as integer CREAR UN NUEVO DOCUMENTO XML I= 8 Lo que estamos diciéndole al ordenador es: Colocad un botón en el formulario, id a las Dim i as integer => Resérvame un espacio en memoria para un tipo integer propiedades y poner: I= 8 => En el espacio que me has reservado, colócame un 8 • name = cmdCargar • caption = &Cargar En el ejemplo, cuando escribimos Dim xmlDocument As DOMDocument documento xml Set xmlDocument = New DOMDocument xmlDocument.Load ("C:XmlDomCompra.xml") Codificad el evento click del Lo que estamos diciendo al ordenador es: botón: Dim xmlDocument As DOMDocument Set xmlDocument = New DOMDocument =>resérvame un • Estas líneas de código espacio en memoria para un tipo DomDocument lo que hacen es crear un xmlDocument.Load ("C:XmlDomCompra.xml") => ponme en objeto de tipo el espacio reservado el archivo Compra.xml DOMDocument: Página 10 PC PASO A PASO Nº 13
  • 11. XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM • Pedimos que nos muestre el texto del xml en un mensaje: B. DOMDocument ACCEDER AL ARBOL DESDE EL ELEMENTO RAIZ, '**************Escribid******************** CONTENIDO DE UN NODO EN MsgBox xmlDocument.Text '**************************************** PARTICULAR Si todo va bien, os mostrará el siguiente Podemos acceder al árbol del DOM, empezando por message box, con todo el texto del la raíz y navegando hacia abajo del árbol (de el documento: nodo mas externo al mas interno) o bien podemos hacer una consulta de un nodo en particular. • Vamos a Crear el documento Navegaremos desde el elemento raíz utilizando la xml Compras2.xml de manera dinámica, propiedad del domdocument documentElement , con el método LoadXML que nos devuelve el elemento raíz, convertido en un objeto de tipo XMLDOMNode (un objeto de la '**************Escribid*********** interfaz XMLDOMNode). 'Ponemos todo el texto del xml en una variable de tipo String 'Fijaros en que he sustituido las dobles comillas de ‘version, de standalone y de la ubicación del dtd por ‘comillas simples ! Al igual que... xmlString = "<?xml version='1.0' standalone='no' ?>" & _ al igual que una propiedad nos puede devolver un valor de " <!DOCTYPE ORDEN_DE_COMPRA SYSTEM 'C:XmlDomordenCompra.dtd'> "&_ tipo booleano, también nos puede devolver un valor de " <ORDEN_DE_COMPRA> " & _ tipo objeto de una clase. En este caso nos devuelve un " <CLIENTE> " & _ " <NUMERO_DE_CUENTA>87654321</NUMERO_DE_CUENTA> " & _ objeto de la interfaz documentElement. Por eso hemos " <NOMBRE_COMPLETO> " & _ tenido que declarar una variable de este tipo. Veréis este " <NOMBRE>Pat</NOMBRE> " & _ tipo de asignaciones muy frecuentemente cuando trabajéis " <APELLIDO1>Garret</APELLIDO1> " & _ con el Dom. " <APELLIDO2></APELLIDO2> " & _ " </NOMBRE_COMPLETO> " & _ " </CLIENTE> " & _ Necesitaremos pues, referenciar de alguna manera " </ORDEN_DE_COMPRA>" la interfaz IXMLDOMElement (el DOM tiene mas interfaces que las cuatro principales; esta se utiliza 'el método loadXML carga en memoria, en el dom, la cadena que le pasamos para nodos de tipo elemento. Es una ampliación de de XMLDomNode) y la interfaz XMLDOMNode. Lo xmlDocument.loadXML xmlString haremos con dos variables de estos tipos. (Mirad MsgBox xmlDocument.Text el ejemplo) '**************************************************** Para navegar por el documento, vamos a crear un El texto del segundo mensaje será distinto, ahora os saldrá. nuevo DTD y un nuevo XML muy parecidos a los que hemos estado utilizando hasta ahora. • Finalmente, Guardamos el archivo Vamos a cambiar solamente el nodo raíz, vamos a xml generado, con un nombre distinto, hacer que ORDEN_DE_COMPRA cuelgue de un nuevo con el método save elemento que llamaremos PEDIDOS. Y ampliaremos la información que puede tener ORDEN_DE_COMPRA añadiéndole el elemento PRODUCTO. '**************Escribid******************************** 'el método save guarda el documento generado o modificado. Finalmente vamos a indicar a ORDEN_DE_COMPRA xmlDocument.save ("C:XmlDomCompra2.xml") que tiene puede tener mas de un orden de compra 'liberamos memoria con el signo +. On Error Resume Next Set xmlDocument = Nothing '**************************************************** Abrid un editor de texto y escribid: PC PASO A PASO Nº 13 Página 11
  • 12. XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM <!ELEMENT PEDIDOS (ORDEN_DE_COMPRA+)> Codificad el evento click del botón: <!ELEMENT ORDEN_DE_COMPRA (CLIENTE, PRODUCTO)> <!ELEMENT CLIENTE (NUMERO_DE_CUENTA,NOMBRE_COMPLETO)> Private Sub cmdArbolDoc_Click() <!ELEMENT PRODUCTO (#PCDATA)> Dim xmlDocument As DOMDocument <!ELEMENT NUMERO_DE_CUENTA ( #PCDATA)> Dim raizDocumento As IXMLDOMElement <!ELEMENT NOMBRE_COMPLETO ( NOMBRE, APELLIDO1, APELLIDO2) > Dim nodohijo As IXMLDOMNode <!ELEMENT NOMBRE (#PCDATA)> Dim xmlString As String <!ELEMENT APELLIDO1 (#PCDATA)> Set xmlDocument = New DOMDocument <!ELEMENT APELLIDO2 (#PCDATA)> 'síncrono, externas y DTD xmlDocument.async = False Guardad el archivo como pedidos.dtd 'le indicamos que se valide contra el DTD Abrid de nuevo el editor de texto y escribid: xmlDocument.validateOnParse = True 'y si hay referencias externas, que las resuelva. <?xml version="1.0" standalone="no" ?> xmlDocument.resolveExternals = True <!DOCTYPE PEDIDOS SYSTEM If xmlDocument.Load("C:xmlDompedidos.xml") Then "pedidos.dtd"> MsgBox "El documento es válido" <PEDIDOS> Else <ORDEN_DE_COMPRA> MsgBox "El documento no cumple con el DTD" <CLIENTE> Exit Sub End If <NUMERO_DE_CUENTA>12345678</NUMERO_DE_CUENTA> 'le decimos que raizDocumento = PEDIDOS <NOMBRE_COMPLETO> Set raizDocumento = xmlDocument.documentElement <NOMBRE>Sam</NOMBRE> 'Navegamos por los nodos hijos del elemento raíz <APELLIDO1>Bass</APELLIDO1> For Each nodohijo In raizDocumento.childNodes <APELLIDO2></APELLIDO2> MsgBox nodohijo.Text </NOMBRE_COMPLETO> Next </CLIENTE> 'liberamos la memoria <PRODUCTO>LIBRO</PRODUCTO> On Error Resume Next </ORDEN_DE_COMPRA> Set nodohijo = Nothing <ORDEN_DE_COMPRA> Set raizDocumento = Nothing <CLIENTE> Set xmlDocument = Nothing <NUMERO_DE_CUENTA>987654321</NUMERO_DE_CUENTA> End Sub <NOMBRE_COMPLETO> <NOMBRE>Jesse</NOMBRE> Fijaros en los dos mensajes que os han salido por <APELLIDO1>James</APELLIDO1> pantalla: <APELLIDO2></APELLIDO2> </NOMBRE_COMPLETO> </CLIENTE> Seguido de <PRODUCTO>DISCO DE VINILO</PRODUCTO> </ORDEN_DE_COMPRA> </PEDIDOS> Vamos a interpretarlo. Volved al Visual Basic Colocad un botón en el formulario, id a las propiedades y poner: El DOM, ha leído el primer nodo que contenía el • name = cmdArbol nodo raíz. El nodo raíz es PEDIDOS, y el texto que • caption = &árbol del documento xml ha leído el DOM es el texto que tenia su primer nodo hijo ORDEN_DE_COMPRA, y el texto que tenia su primer nodo hijo era TODO el texto que contenía ORDEN_DE_COMPRA. ¿Y cual es todo el texto que tiene el primer nodo ORDEN_DE_COMPRA?, pues nada más y nada menos Página 12 PC PASO A PASO Nº 13
  • 13. XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM que el texto que tienen todos sus nodos hijos: Si lo entendéis, si os ha entrado bien en la cabeza, • 12345678 lo tenéis muy pero que muy bien. • Sam Para consultar un nodo en particular, podemos • Bass utilizar el método getElementsByTagName que • LIBRO devuelve todos los nodos elemento de un tag en concreto. Devuelve un array que contiene todos los Y para el segundo nodo ORDEN_DE_COMPRA lo elementos del documento que tienen ese nombre. mismo, todo el texto que tienen todos sus nodos Recordad que un tag es otra manera de llamar a un hijos: elemento: Al elemento <ORDEN_DE_COMPRA> • 987654321 también podéis llámalo tag <ORDEN_DE_COMPRA> • Jesse • James Volved al Visual Basic • DISCO DE VINILO Colocad un botón en el formulario, id a las propiedades y poner: Para verlo mas claro, pensemos en el explorador • name = cmdUnElemento de windows. • caption = &Un elemento concreto del árbol Supongamos esta estructura de directorios: Codificad el evento click del botón: Private Sub cmdUnElemento_Click() Dim ListaDeNodos As IXMLDOMNodeList Dim xmlDocument As New DOMDocument Dim i As Integer xmlDocument.async = False xmlDocument.validateOnParse = True xmlDocument.resolveExternals = True If xmlDocument.Load("C:xmlDompedidos.xml") Then MsgBox "El documento es válido" Else MsgBox "El documento no cumple con el DTD" Exit Sub End If Supongamos que ordenCompra tiene un archivo MsgBox xmlDocument.xml que se llama 12345678.txt Set ListaDeNodos = xmlDocument.getElementsByTagName("NOMBRE") Supongamos que Apellido1 tiene un archivo que se For i = 0 To (ListaDeNodos.length - 1) llama Sam.txt MsgBox ListaDeNodos.Item(i).xml Supongamos que Apellido2 tiene un archivo que se MsgBox ListaDeNodos.Item(i).Text llama Bass.txt Next Supongamos que Producto tiene un archivo que se On Error Resume Next llama LIBRO.txt Set ListaDeNodos = Nothing Set xmlDocument = Nothing Y pedimos al Sistema Operativo que nos liste todos End Sub los archivos que contiene la carpeta Pedidos.... Efectivamente nos devolverá lo mismo que nos ha Utilizamos la interfaz IXMLDOMNodeList, interfaz devuelto el DOM de XML. que nos permite trabajar con la lista de nodos del Pararos un segundo en pensar y analizar este código. DOM, tal como su nombre indica. PC PASO A PASO Nº 13 Página 13
  • 14. XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM Fijaros en que el atributo xmlDocument.xml os a true, preserva los espacios en blanco del documento devuelve el contenido de todo el xml, y el atributo • ReadyState = nos indica el estado en que del ListaDeNodos.Item(i).xml nos devuelve también se encuentra el documento en este momento. Por el contenido de todo el xml que contiene ese nodo, ejemplo el documento puede hallarse en estado y así como el atributo xmlDocument.text nos LOADING (cargando) o en estado COMPLETE (carga devuelve el contenido de texto de todo el documento completa y el DOM disponible) xml, el atributo de la interfaz ixmldomnodelist ListaDeNodos.Item(i).text también nos devuelve el • url = devuelve una cadena (string) que nos informa de la url de Internet donde se halla texto del nodo que hemos seleccionado. nuestro xml Con ello os quiero demostrar que aunque son interfaces diferentes, el comportamiento es el mismo, Los métodos mas importantes de la interfaz si encontráis en alguna otra interfaz las propiedades DomDocument, son los que hemos visto (load, xml, o text, sin hacer ninguna prueba ya podéis loadXML, getElementsbyTagName y Save) y saber lo que devuelve. los de creación de fragmento de xml. Supongamos que queremos añadir otro C. DOMDocument CREAR UN ORDEN_DE_COMPRA a nuestro xml: el modo de FRAGMENTO DE XML hacerlo es creando un nuevo nodo ORDEN_DE_COMPRA de acuerdo con el DTD(con Hemos visto hasta ahora las principales propiedades todos sus nodos hijos tal como se especifica en el de la interfaz DomDocument, pero no todas. Las DTD) y una vez creado lo insertaremos en el otras propiedades son informativas del documento: documento xml. El tiempo en que este nuevo nodo esta desvinculado • Doctype= devuelve el tipo de documento de nuestro documento XML, tiempo en el que le asociado al xml, en nuestro ejemplo nos devolvería estamos añadiendo sus nodos hijos es el tiempo de el dtd. creación de un fragmento xml, que es un trozo • PreserveWhiteSpace = que si ponemos de xml a anexar al xml principal. ¿QUIERES COLABORAR CON PC PASO A PASO? PC PASO A PASO busca personas que posean conocimientos de informática y deseen publicar sus trabajos. SABEMOS que muchas personas (quizás tu eres una de ellas) han creado textos y cursos para “consumo propio” o “de unos pocos”. SABEMOS que muchas personas tienen inquietudes periodísticas pero nunca se han atrevido a presentar sus trabajos a una editorial. SABEMOS que hay verdaderas “obras de arte” creadas por personas como tu o yo y que nunca verán la luz. PC PASO A PASO desea contactar contigo! NOSOTROS PODEMOS PUBLICAR TU OBRA!!! SI DESEAS MÁS INFORMACIÓN, envíanos un mail a empleo@editotrans.com y te responderemos concretando nuestra oferta. Página 14 PC PASO A PASO Nº 13
  • 15. XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM - XML - DOM Todo nuevo nodo se construye con los métodos de con los métodos la interfaz DOMdocument que comienzan con la palabra create+tipodenodo. Por ejemplo para • InsertBefore crear un nodo de tipo elemento haremos createElement, y para crear un atributo haremos • RemoveChild createAttribute etc. • ReplaceChild Veremos un ejemplo de cómo crear un nuevo nodo, Listado de métodos create que se utilizan en el próximo capítulo, cuando tratemos la interfaz para crear un fragmento xml: XMLDOMNode ya que es necesaria para "enganchar" un nodo hijo a su padre, por ejemplo <NOMBRE_COMPLETO> a <CLIENTE>, o para borrar • CreateAttribute un nodo hijo, necesitaremos de muchas de las • CreateCDATASection propiedades y métodos que tiene esta interfaz • CreateComment • CreateDocumentFragment Tenéis la lista completa de propiedades y métodos de DOMDocument en la dirección: • CreateElement • CreateEntityReference http://msdn.microsoft.com/library/default.asp?url • CreateNode =/library/en-us/xmlsdk30/htm/ • CreateProcessingInstruction xmobjxmldomdocument.asp • CreateTextNode ¡Saludos compañeros! también podemos, sustituir, insertar los nodos
  • 16. Programacion en GNU/LiNUX Desarrollo de aplicaciones en entornos UNiX e iniciaciaon al lenguaje C (II) el_chaman. Luis U. Rodriguez Paniagua Este mes, en nuestra entrega habitual de LINUX entraremos en el temido mundo de los punteros en C (entre otras cosas). Coged aire y ADELANTE!!! 1. Introducción. 2.1. Arrays o vectores A casi todos nos sonará el término vector de haberlo visto en En el artículo anterior vimos como a la hora de matemáticas. Allí considerábamos un vector o arreglo como una realizar un proyecto en un entorno UNiX se suele colección de bloques de datos. En la programación sucederá algo emplear una modularización del mismo para mejorar similar: Un array o vector será una colección de datos del mismo la productividad. Así mismo comenzamos una breve tipo. introducción al lenguaje C que enlazaba con las Además de esta definición, surgen dos términos asociados al estructuras de control de dicho lenguaje vistas en término vector: la dimensión y el índice el primer artículo de esta serie. Para entender qué es un vector y cómo funcionan estos dos nuevos conceptos, vamos a imaginarnos lo siguiente: Este artículo, tal vez por la necesidad de la temática, está orientado a la práctica. Se propondrán Tal como vimos en el anterior número podemos definir las variables algunos ejercicios y búsqueda de información, que como cajas en las que meter datos. Así mismo vimos que los tipos espero hagan de su lectura y estudio un tema de dichas variables nos decían de qué tamaño eran dichas cajas. ameno. Dicho esto podremos definir un vector como un conjunto de cajas Continuando con lo visto, hoy seguiremos viendo del mismo tamaño colocadas en fila. El índice será la posición de algunos de los tipos disponibles en C. En el número una determinada caja dentro de estas cajas y la dimensión será anterior se quedaron en el tintero los tipos derivados cómo podemos colocar en el espacio las distintas filas, columnas, debido a que he considerado que el tema de los etc... que formarán la geometría de este conjunto de cajas. punteros, vectores y matrices, merece un tratamiento más profundo que el de los tipos básicos. Y sin entretenernos más pasemos ya a los tipos /* Ejemplo de declaración de varios tipos de vectores o arrays */ derivados. /* Vector unidimensional de números enteros */ int un_vector[5]; 2. Tipos Derivados. /* Vector bidimensional o matriz de números reales */ Los tipos derivados serán aquellos que se generen float una_matriz[5][5]; a partir de los tipos fundamentales o de otros tipos /* Vector tridimensional de caracteres */ derivados. Nosotros veremos los arrays o vectores, char un_cubo[5][5][5]; punteros, estructuras, uniones y campos de bits. Página 16 PC PASO A PASO Nº 13
  • 17. Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II)- Como podemos observar en el ejemplo, la declaración Así por ejemplo, para introducir datos en una casilla de un vector corresponde al siguiente esquema: teclearemos algo como: tipo_array nombre_array[dim1][dim2]..[dimN] un_vector[0] = 34; Donde tipo_array será el tipo de datos que contiene un_vector[1] = 2 + 3; el array (es decir el tamaño de cada una de las una_matriz[2][3] = 3.1416 * 34; cajas que lo componen), nombre_array será el un_cubo[0][2][1] = 'a'; nombre que demos al array y [dimX] será el tamaño tope de cada una de las dimensiones, o dicho de Para acceder al contenido se hará de manera similar: otro modo: el número máximo de cajas que se int suma; admite en una dimensión. char respuesta; ... Para entender mejor el concepto de dimensión, suma = un_vector[0] + un_vector[1]; representemos gráficamente el código arriba visto: printf("%f", una_matriz[2][3]); ... printf(" Teclee una letra: "); scanf("%c", &respuesta); if( un_cubo[0][2][1]==respuesta) printf("Ha pulsado una a"); ! No se intente... No se intente buscar sentido alguno a los dos últimos ejemplos: Están hechos con la intención de mostrar el acceso a los componentes de un array. Fíjense en cómo se acceden a los datos, no en lo que se hace con ellos. Este será un tema que trataremos a lo largo del curso. En el primer ejemplo mostramos como introducir datos en casillas concretas de los distintos arrays dependiendo del tipo de estos, y en el segundo caso mostramos como sacar datos de dichos arrays. A continuación vamos a hacer un programa que cree una matriz de dimensión 3x4 (tres filas y cuatro Observando el gráfico arriba expuesto, accederemos columnas) y la llene de con sus coordenadas de la al contenido de cada casilla mediante sus siguiente manera: El número almacenado en cada coordenadas. Obsérvese algo muy importante: En casilla mostrará en su parte entera el número de C, siempre los índices empiezan a contar desde 0. fila, y en su parte decimal en número de columna. Esto quiere decir que si declaramos un vector con Así las segunda casilla de la primera fila contendrá cinco casillas, a la hora de poner su dimensión un 0.1 (Recordemos que las coordenadas empiezan pondremos int un_vector[5] pero a la hora de a contar en C siempre desde 0). acceder a todas sus casillas pondremos un_vector[0], /* un_vector[1], un_vector[2], un_vector[3] y * Programa: ej00.c un_vector[4] siendo el número total de casillas * cinco, pero siendo el valor máximo del índice una * Descripción: Crea una matriz de dimensión 3x4, llena cada casilla unidad menor que la dimensión total del vector. * con sus coordenadas de la siguiente manera: PC PASO A PASO Nº 13 Página 17
  • 18. Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II) * _____ _____ _____ _____ representar las coordenadas de la casilla en un único * |_0.0_|_0.1_|_0.2_|_0.3_| número. Puesto de otra forma: * |_1.0_|_1.1_|_1.2_|_1.3_| matriz[num_fila][num_col]= num_fila + (num_col * 0.1); * |_2.0_|_2.1_|_2.2_|_2.3_| * Así para la casilla matriz[0][2] tendremos que su * e imprime el contenido de la matriz por pantalla. contenido será 0 + ( 0.2 ) = 0.2. * * Compilación: Hasta ahí todos de acuerdo. Ahora bien: ¿ Qué * gcc ej00.c -o ej00 significa eso de poner (float) delante de las variables contadoras i y j?. */ #include <stdio.h> A esto se le denomina casting y consiste en main() transformar el tipo del resultado que nos devuelve { una operación cuyos operadores son den tipo distinto /* Declaración de la matriz de tres filas por cuatro columnas */ a quien va a recibir el dato. Dicho de otra manera: /* Tiene que ser de números reales */ Sirve para cambiar el tipo de un dato en tiempo de float matriz[3][4]; ejecución. /* Declaración de variables auxiliares contadoras */ Si prestamos atención a la línea de la que estamos int i,j; hablando, veremos que los operadores son de tipo /* Llenamos la matriz con datos */ entero, pero no así el resultado que esperamos /* i contará filas */ conseguir tras la operación. Es por ello que ese for(i=0;i<3;i++) resultado lo tenemos que convertir a real. En próximos { ejemplos veremos más usos del casting. /* j contará columnas dentro de cada fila */ for(j=0;j<4;j++) 2.1.1. Ejercicio 0.0 { Se desea hacer un juego del tres en raya para dos matriz[i][j]= (float)(i + (j * 0.1)); jugadores humanos muy sencillo. Las posibles } pantallas a mostrar a lo largo del juego pueden ser } las siguientes: /* Imprimimos la matriz */ for(i=0;i<3;i++) ___|___|___ _X_|___|___ { for(j=0;j<4;j++) ___|___|___ ___|_O_|___ { ___|___|___ ___|___|_O_ printf(" %1.1f ",matriz[i][j]); } Se pide además que el estado del tablero actual se /* Después de imprimir una fila, debemos de saltar una línea*/ conserve en una matriz de dimensión 3x3 de números printf("n"); enteros. } Entrada y Salida } La entrada y la salida en C se realizan habitualmente En este programa de ejemplo, debemos de abundar sobre los dispositivos de entrada estándar ( stdin ) en una línea un tanto extraña: y salida estándar ( stdout). Tradicionalmente se asocia la entrada estándar al teclado y la salida matriz[i][j]= (float)(i + (j * 0.1)); estándar a la pantalla de la consola, pero esto no tiene porqué ser así siempre. Ya trataremos con En un principio puede parecer que efectivamente ficheros y veremos que stdin y stdout no son más estamos empleando la fórmula adecuada para que dos de los muchos flujos de datos que podremos Página 18 PC PASO A PASO Nº 13
  • 19. Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II) emplear en un programa. que estamos tratando : A efectos prácticos nosotros consideraremos por Tabla 1. Formatos de tipos de dato ahora que la entrada estándar (stdin) es el teclado y tiene una función de lectura asociada llamada scanf y que la salida estándar (stdout) es la consola del ordenador y tiene asociada la función printf. En conclusión: La lectura de datos del teclado se hará mediante scanf y la impresión de datos en la pantalla de la consola se hará mediante printf. Un ejemplo de lectura de datos puede ser: int coor_x, coor_y; ... printf("n Deme la coordenada X: ") scanf("%i",&coor_x); printf("n Deme la coordenada Y: "); scanf("%i",&coor_y); ... Para estos formatos podemos también especificar el Observese el & que ponemos delante de la variable ancho de caracteres reservados para expresar un donde queremos depositar el dato leído por teclado. número. Asi %5i reservaría 5 caracteres para imprimir Al término del artículo de hoy seremos capaces de un número entero, independientemente de la longitud comprender qué significa ese & y por qué lo ponemos de este. %5.2f reservaría 5 caracteres para imprimir ahí. Por ahora baste decir que estamos depositando la parte entera y dos para la parte decimal, etc... el dato leído en la posición de memoria donde se Obsérvese también, que debemos de poner la cadena encuentra la variable donde queremos que se guarde de formato en el lugar exacto donde queremos que dicho dato. se imprima el dato, y, posteriormente una lista de Un ejemplo de impresión de datos puede ser: variables que irán en el mismo orden el que queremos que aparezca el dato. int var_entera=3; float var_real=3.14; Dadas las siguientes variables: char cadena[8]="Hola0"; int varA=3; char var_char='a'; float varB=4; printf("Valores: %i, %f, %s, %c. ", var_entera, var_real, cadena, var_char); char varC[6]="Hola0"; A la hora de imprimir el contenido de una variable, char varD='e'; (o de leerlo, observar el ejemplo anterior de scanf, Serán ejemplos correctos: tenemos que decir de alguna manera a las funciones printf(" %3i ", varA); de lectura o escritura de datos por entrada y salida estándar respectivamente ( scanf y printf ) qué es scanf("%f",&varB); lo que van a leer o escribir. Para ello se emplean printf("Una cadena: %s y un real: %3.6f ",varC, varB); printf("Una letra %c y un número: %i", varD, varA); las cadenas de formato. Las cadenas de formato printf("Una letra %c y otra letra %c", varD, varC[1]); son esas letras que comienzan por % y que en printf("Decimal: %i, Octal: %o, Hexadecimal: %x ", varA, varA, varA); función de su valor, indican el tipo de dato con el PC PASO A PASO Nº 13 Página 19
  • 20. Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II) E incorrectos: Prescindiendo de esa oscura mitología y de historias printf(" %i ", varC); espeluznantes que se cuentan relacionadas con los scanf("%f",&varA); mismos, trataremos de presentar los punteros de printf("Una cadena: %s y un real: %f ",varD, varA); una manera clara y asequible, de manera que les printf("Una letra %c y un número: %i", varA, varD); perdamos el miedo pero nunca el respeto, dado que printf("Una letra %c y otra letra %c", varD, varC); son una de las herramientas más potentes que nos printf("Decimal: %i, Octal: %o, Hexadecimal: %x ", varA) suministra el lenguaje C. Además de las cadenas de formato, printf admite 2.2.1. ¿Qué son los punteros?: una serie de caracteres no imprimibles o secuencias Desmitificando al monstruo de estape como son: Un puntero no es más que una variable que cuyo Tabla 2. Secuencias de escape para printf contenido, en vez de datos, son direcciones de memoria. Dicho de otra forma: Hasta ahora utilizábamos las variables para guardar cantidades numéricas, caracteres o cadenas de texto. Ahora utilizaremos un tipo especial de variable que será capaz de guardar una dirección de memoria. Contemplemos el siguiente esquema que nos resultará familiar del anterior artículo (PC PASO A PASO 12): El programa debe se capaz de verificar cuando se ha hecho tres en línea y cuándo ha habido tablas. Así mismo debe de verificar que las coordenadas están dentro del rango permitido y el turno de cada jugador. 2.2. Punteros Los punteros suelen ser el caballo de batalla al que se enfrentan los programadores que se adentran por primera vez en lenguajes como C o Pascal. Página 20 PC PASO A PASO Nº 13
  • 21. Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II) En la primera línea resaltada char *var_puntero;, Otros ejemplos de declaración de punteros serán: lo que hacemos es declarar una variable de tipo puntero que es capaz de apuntar a int *p_entero; direcciones de memoria (es decir, es capaz float *p_real; de guardar direcciones de memoria), que contengan un dato char. Esto puede causar char *p_caracter; confusión dado que si sabemos que los punteros contienen direcciones de memoria, ¿qué necesidad hay de asociarlos un tipo? Esta pregunta, ! Existe un tipo de... que en principio puede parecer compleja, queda explicada cuando más adelante veamos que como el resto de las variables podemos realizar operaciones Existe un tipo de puntero denominado void que virtualmente aritméticas con el contenido de las mismas, como en conjunción con el casting es capaz de apuntar a cualquier por ejemplo el incremento. Claro que no es lo mismo tipo de variable o dirección de memoria. Recomiendo que incrementar una dirección que apunta a caracteres el lector investigue por su cuenta este tipo de punteros pues la cual se incrementará (siempre según la figura) muy pronto los veremos. Ya sabes: www.google.com ;) de un byte en un byte, que incrementar la dirección que apunta a un número real, que aumentará de cuatro en cuatro bytes. Es decir, el puntero "debe conocer a qué apunta". 2.2.2. Operadores sobre punteros Dos son los principales operadores que se utilizan en relación con ! Aunque esta... los punteros: Aunque esta explicación no sea muy formal, creo que sirva & (ampersand) para comprender alguno de los comportamientos particulares de los punteros. El operador & nos devuelve la dirección de memoria donde se encuentra una determinada variable. No es la primera vez que en esta serie de artículos se prescinde del rigor informático en favor de la claridad de Algunos ejemplos de este operador son: la exposición del tema. Por poner un ejemplo, en el esquema var_puntero=&caracter; de arriba (ya presente en el anterior artículo) existe un gazapo muy sutil. Está relacionado en la manera en como /* El ejemplo visto arriba. A var puntero le asignamos la dirección se guardan los números reales en la memoria de un de memoria donde reside caracter. En la figura la variable ordenador. Dejo al lector la tarea de encontrar este gazapo. En esta búsqueda, espero, aprenderá y comprenderá mucho caracter se encuentra en la posición 00, luego var_puntero sobre las representaciones de datos en la memoria de una contendrá dicha dirección (apuntará a dicha dirección) */ computadora. int cosa1, cosa2; int *pent; pent=&cosa1; Tras examinar esta línea llegamos a la conclusión de que un puntero se declara siempre según el printf("La dirección de cosa1 es %m", &cosa1); siguiente esquema: pent=&cosa2; printf("La dirección de cosa2 es %m y el puntero apunta a %m",&cosa2,pent); tipo_dato *nombre_variable_puntero; printf("El puntero pent que está en %m apunta a %m", &pent, pent); Como vemos es el asterisco precediendo al nombre * (asterisco) de la variable el que convierte a esta en un puntero: El asterisco, en el caso de la declaración de variables, Este operador nada tiene que ver con lo explicado arriba sobre es quien dice si la variable es un puntero y no una como se declara una variable puntero. variable normal. PC PASO A PASO Nº 13 Página 21
  • 22. Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II) Este operador que precede siempre a una variable char *pchar1, *pchar2; puntero, nos devuelve el contenido de la dirección /* Inicializamos las variables */ almacenada por el puntero. Ojo: El contenido de la vchar1='a'; dirección almacenada por el puntero. Por poner un vchar2='b'; ejemplo, imaginemos que el código de la figura lo /* Inicializamos los punteros */ cambiamos a: pchar1=&vchar1; #include <stdio.h> pchar2=&vchar2; main() /* Imprimimos información */ { printf("n Tras ejecutar las siguientes instrucciones:nn"); char caracter; printf("t033[31;1m vchar1='a';n"); char *var_puntero; printf("t vchar2='b';nn"); /* código ignorado por carecer de importancia */ printf("t pchar1=&vchar1;n"); caracter=10; var_puntero=&caracter; printf("t pchar2=&vchar2;033[0;0mnn"); printf("%c", *var_puntero); printf(" El contenido de las variables y los punterosn"); } printf(" es el siguiente:n"); printf("n 033[34;1m Dir Variable tt ContenidottContenido de lo apuntado 033[0;0m"); En este programa imprimiremos lo que hay almacenado en la dirección que contiene la variable printf("n &vchar1 = %x,t vchar1 = %c", &vchar1, vchar1); puntero; es decir, en la dirección donde apunta el printf("n &vchar2 = %x,t vchar2 = %c", &vchar2, vchar2); puntero. Como hemos hecho que el puntero contenga printf("n &pchar1 = %x,t pchar1 = %x,t *pchar1 = %c", &pchar1, pchar1, *pchar1); la dirección (apunte) de la variable caracter (la printf("n &pchar2 = %x,t pchar2 = %x,t *pchar2 = %c", &pchar2, pchar2, *pchar2); dirección 00 en el diagrama) en la instrucción printf("n"); var_puntero=&caracter, el contenido de lo apuntado por el puntero será el contenido de la variable a la } que apunta el puntero: el caracter correspondiente al decimal 10 (salto de línea). Tras su ejecución, obtendremos una salida similar a esta: A este acceso al contenido de una variable mediante luis@nostromo:~/hxc/articulo6_el_chaman$ ./ej01 un puntero se le denomina indirección. Tras ejecutar las siguientes instrucciones: A continuación muestro un pequeño programa que vchar1='a'; puede llegar a facilitar la comprensión de los vchar2='b'; operadores & y * pchar1=&vchar1; /* pchar2=&vchar2; * Programa: ej01.c * El contenido de las variables y los punteros es el siguiente: * Descripción: * Este programa muestra el comportamiento básico de los punteros. Dir Variable Contenido Contenido de lo apuntado * * Compilación: &vchar1 = bffff9f7, vchar1 = a * gcc ej01.c -o ej01 */ &vchar2 = bffff9f6, vchar2 = b #include <stdio.h> main() &pchar1 = bffff9f0, pchar1 = bffff9f7, *pchar1 = a { char vchar1, vchar2; &pchar2 = bffff9ec, pchar2 = bffff9f6, *pchar2 = b Página 22 PC PASO A PASO Nº 13
  • 23. Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II) ! Ejercicio 0.1 * Ejercicio 0.1 * Compilación: * gcc ej02.c -o ej02 Teniendo el siguiente código: * */ /* #include <stdio.h> * Programa: ej02.c main() * * Descripción: Segundo ejercicio del artículo 6 { * int a,b, *pInt; * Compilación: * gcc ej02.c -o ej02 * pInt=&a; */ *pInt=3; #include <stdio.h> pInt=&b; main() *pInt=5; { int a, b, *pInt; printf("n a = %i, b = %i n",a,b); } ........ ........ ........ ........ 2.2.3. Operando con punteros printf("n a = %i, b = %i n", a, b); } Anteriormente hemos mencionado que los punteros se pueden incrementar y decrementar. Cuando Sustituir las líneas punteadas por las instrucciones necesarias hagamos esto tendremos que tener presente que lo para que el resultado sea: que se incrementa o decrementa es el contenido del puntero, o dicho de otra forma: una dirección de memoria. luis@nostromo:~/hxc/articulo6_el_chaman$ ./ej02 Prestemos atención a este código: a = 3, b = 5 /* ¡Ah! Se me olvidaba. Para este ejercicio están prohibidas * Programa: ej03a.c las siguientes instrucciones: * a = 3; * Descripción: * Muestra el uso de los operadores incremento y decremento b = 5; * con un puntero. * * Compilación: ! Solución del ejercicio * gcc ej03a.c -o ej03a * Solución del ejercicio */ include <stdio.h> /* main() * Programa: ej02.c { * /* Declaramos las variables necesarias */ * Descripción: Segundo ejercicio del artículo 6 int vector[5]; PC PASO A PASO Nº 13 Página 23
  • 24. Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II) int i, *pEntero; * Compilación: /* Llenamos el vector con los números 1, 2, 3, 4 y 5 */ * gcc ej03b.c -o ej03b for(i=0;i<5;i++) * { */ vector[i]=i+1; #include <stdio.h> } main() /* Hacemos que el puntero apunte al array */ { pEntero = vector; /* Declaramos las variables necesarias */ printf(" %i n", *pEntero); int vectorE[5]; pEntero++; /* Equivale a pEntero = pEntero +1 */ int i, *pEntero; printf(" %i n", *pEntero); char vectorC[5], *pCaracter; pEntero++; float vectorR[5], *pReal; printf(" %i n", *pEntero); /* Llenamos los vectores con datos */ pEntero++; for(i=0;i<5;i++) printf(" %i n", *pEntero); { pEntero++; vectorE[i]=i+1; printf(" %i n", *pEntero); vectorC[i]=i+40; } vectorR[i]=(float)i*0.1; } En este código lo primero que nos debería de llamar /* Hacemos que el puntero apunte al array */ la atención es la instrucción pEntero = vector;. Es pEntero = vectorE; fácil pensar que la instrucción adecuada sería pEntero pCaracter = vectorC; = &vector;. Pero no olvidemos que pEntero es un pReal = vectorR; puntero que apunta a una variable de tipo entero mientras que vector representa un conjunto de printf("n Los puntero se incrementarán es:"); variables de tipo entero que sólo puede accederse printf("n pEntero: %i bytes", sizeof(int)); a ellas a través de los índices. printf("n pCaracter: %i bytes", sizeof(char)); printf("n pReal: %i bytes", sizeof(float)); Para rizar más el rizo, el programa sería igual de printf("n Cada vez que pongamos "puntero++"n"); válido si en vez de escribir pEntero = vector;, printf(" %i, %c, %f n", *pEntero, *pCaracter, *pReal); hubiésemos escrito pEntero = &vector[0];. pEntero++; /* Equivale a pEntero = pEntero +1 */ Y esto es porque los vectores y los arrays en general, pCaracter++; /* Equivale a pCaracter = pCaracter +1 */ a efectos prácticos, son punteros... Y viceversa... pReal++; /* Equivale a pReal = pReal +1 */ printf(" %i, %c, %f n", *pEntero, *pCaracter, *pReal); Al ir aumentando de uno en uno el puntero, podría pEntero++; parecer que estamos incrementando en un byte la pCaracter++; dirección de memoria, pero el siguiente código nos pReal++; va a sacar de dudas: printf(" %i, %c, %f n", *pEntero, *pCaracter, *pReal); /* pEntero++; * Programa: ej03b.c pCaracter++; * pReal++; * Descripción: printf(" %i, %c, %f n", *pEntero, *pCaracter, *pReal); * Muestra el uso de los operadores incremento y decremento pEntero++; * con un puntero, así como las peculiaridades de cada tipo pCaracter++; * de puntero. pReal++; * printf(" %i, %c, %f n", *pEntero, *pCaracter, *pReal); } Página 24 PC PASO A PASO Nº 13
  • 25. Linux - Programación en C (II) - Linux - Programación en C (II) - Linux - Programación en C (II) ¿Por qué sabe cada puntero sabe en cuántas casillas Obsérvese que en el segundo bucle for, pEntero se debe incrementarse cuando nosotros tan sólo le comporta como si de un array se tratase, accediendo incrementamos en una posición? Pues porque al contenido de las distintas posiciones de memoria nosotros hemos dicho a cada puntero a qué familia mediante pEntero[i] donde i es el índice. Observando de punteros pertenece al declararlos (int, float, char...., de manera que automáticamente los punteros el tercer bucle for podemos llegar a la conclusión de se incrementarán tantos bytes como ocupen en que pEntero[i] es una manera abreviada de escribir memoria sus tipos base. *(pEntero + i).... Y no estaremos en absoluto equivocados. Otra particularidad de poder incrementar el contenido de un puntero, es la utilización de éste como si de un vector se tratase. Veámoslo, porque es cuando 3. Cierre menos curioso: Y con esto termina el artículo de hoy. Ya sólo nos /* quedan un par de cosillas del lenguaje C (estructuras, * Programa: ej03c.c uniones, campos de bits, funciones, etc.... ) y pronto * podremos meternos en el C puro y duro. * Descripción: * Muestra el comportamiento de un puntero como vector Puede parecer que en este artículo hemos dejado * en la cuneta la parte de la programación modular. * Considero que no ha sido así pues en este artículo * Compilación: ya se manda realizar alguna práctica con lo que * gcc ej03c.c -o ej03c espero que os vayáis familiarizando con el compilador * de GNU. */ #include <stdio.h> En el número que viene, explicaremos el tema de main() las funciones con un pequeño proyecto que ya usará { Makefiles, archivos de cabecera y, como no, funciones, /* Declaramos las variables necesarias */ estructuras de datos, punteros, muchos punteros y int vector[5]; alguna que otra macro. int i, *pEntero; Obviamente, antes de enfrentarnos a todo esto, /* Llenamos el vector con los números 1, 2, 3, 4 y 5 */ debemos de tener muy claro que lo que vamos for(i=0;i<5;i++) viendo lo debemos de manejar con cierta soltura. { Espero que este artículo os ayude a ello. Nos vemos vector[i]=i+1; en el foro. Saludos y gracias por vuestra atención. } /* Hacemos que el puntero apunte al array */ pEntero = vector; Bibliografía /* Comportamiento de un puntero como un array "normal" */ man printf; man scanf, Varios. for(i=0;i<5;i++) { UNiX Programación Avanzada, Fco. Manuel Márquez, printf(" %i ", pEntero[i]); Editado por Ra-Ma, ISBN: 84-7897-239-0. } printf("n"); Slackware Linux Unleashed, Bao Ha y Tina Nguyen, /* Comportamiento de un puntero como "base + indirección" */ Editado por Pearson Education, ISBN: 0-672-31768- for(i=0;i<5;i++) 0. { printf(" %i ", *(pEntero + i)); Advanced Linux Programming, Mark Mitchel, Jeffrey } Oldham, y Alex Samuel, Editado por New Riders, } ISBN: 0-7357-1043-0. PC PASO A PASO Nº 13 Página 25
  • 27. Curso de VISUAL BASIC UN CLIENTE, UNA NECESIDAD, TENEMOS UN PROYECTO (PARTE I) VISUAL BASIC es la forma más rápida de crear un programa. Vamos a aplicar los conocimientos acumulados y a crear un ” proyecto real”. Aquí estamos de nuevo con nuestro particular curso medianamente decente, que les gestione de Visual Basic. Después de varios meses escribiendo el stock de helados. Nosotros, como proveedores, para vosotros he decido que la temática ha damos una respuesta comercial, y le indicamos llegado a su fin, con esto quiero decir que q u e s o b ra d a m e n t e p o d e m o s a b a r c a r e l esta será la última entrega del curso de proyecto. Ellos nos comentan que necesitan aprendizaje de Visual Basic y constará de dos o tres un software de gestión que catalogue los partes. helados por su nombre, y si fuera necesario, su sabor. También cree necesario que se Os quiero recordar que la finalidad de esta serie de controlen las entradas de productos y, como artículos era despertaros el gusanillo de la no, las ventas de estos. La base de datos programación y animaros a crear vuestros debe estar en un servidor central, mientras propios programas. Ciertamente, no hemos que las terminales deben poder interactuar dedicado mucho tiempo a ningún tema con él. El programa se instalará en diferentes relacionado con la seguridad, y creo que ha puntos de venta, así como en el almacén, sido lo correcto, ya que la revista dedica desde donde se controlarán las entradas. gran parte de su contenido a esta temática, Por último, nos piden que elaboremos un y si dejamos a parte la programación como módulo capaz de crear estadísticas sobre tal, estaríamos montando una mesa con tres las ventas. patas. Parece difícil, ¿no?, pues veréis que realmente, así Por eso, en este curso, hemos aprendido es, difícil como lo parece, sobre todo porque el cliente Visual Basic desde cero 0, y hemos ido nunca queda satisfecho. subiendo el nivel progresivamente. Estoy seguro que vosotros habéis dedicado horas Empecemos pues. Lo primero que voy a hacer es de vuestro tiempo libre para realizar los introduciros en un nuevo concepto de organización ejercicios y ampliarlos a vuestro gusto, de formularios, el menú conocido como eso me enorgullece. Así que, para acabar y MDI. despedirnos, plantearemos un ejercicio con acceso a base de datos, diseño de formularios, El MDI no es más que un "padre de formularios", es organización, etc, etc... decir, un formulario gigante que abarca todos los demás. Cuando creamos un formulario MDI, es lógico Y es que nos vamos a imaginar a un cliente que hacerlo padre de los demás formularios que creemos tiene una necesidad, y nosotros, como proveedores posteriormente. Abramos un nuevo proyecto. Lo vamos a darle una solución a un altísimo coste, primero que vamos a hacer es agregar el formulario claro... ;) de tipo MDI en el explorador de proyectos. Lo haremos picando con el botón derecho sobre él y Nuestro cliente podría ser Micosoft (conocida eligiendo la opción "Formulario MDI" del menú marca de helados), y necesitan un software, "agregar". PC PASO A PASO Nº 13 Página 27
  • 28. Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad Vamos ahora al cuadro de propiedades del formulario MDI. Indiquémosle que se abra, por defecto, a pantalla completa. Para hacer esto tenemos que cambiar la propiedad "WindowsState" a "Maximized". Ejecutamos y vemos que aparece una pantalla que ocupa todo nuestro área de trabajo, exceptuando claro está, la barra de tareas. Cabe decir que estamos empezando la Apreciaremos que se nos ha agregado al proyecto casa por el tejado, pero quería dejar claro el concepto un formulario más oscuro de lo normal. Tenemos de formulario MDI antes de empezar a diseñar que decirle al proyecto que este será nuestro nuestra base de datos. formulario principal, y que los demás son hijos de él. Para vuestra sorpresa, dejaremos el Access y nos introduciremos en el maravilloso mundo de MySql, que aunque parezca increíble, también se pueden ! Posteriormente... gestionar desde Visual Basic. Voy a intentar hacer un resumen de cómo instalarse una base de datos MySql en local. Seré breve, ya que existen cientos Posteriormente veremos como hacer que los formularios de manuales que lo explican detalladamente, y sean hijos (child) de un MDI. porque si lo explicase todo con pelos y señales, nos ocuparía prácticamente toda esta entrega. Para indicar al proyecto que debe iniciarse por Bien, existen varias formas de tener y gestionar uno u otro MySql en tu PC. Una es instalando directamente el formulario, vamos gestor que podemos encontrar en al menú http://www.mysql.org (el "database server") y usar "Proyecto", el "Control Center" que podemos encontrar en la "Propiedades" y misma página. Otra opción es descargar el servidor en el combo web Apache, instalarlo y descargar también el "Objeto inicial" conocido "PHPMyAdmin", conjunto al script necesario seleccionamos el para hacer funcionar PHP en Apache web Server. nombre de Por supuesto esta opción es mucho más complicada, n u e s t r o pero lo dejo a vuestra elección. Lo que si debemos formulario MDI (al descargar obligatoriamente en los dos casos es el cual yo he "Database Server" y el "Conector/ODBC", que nos l l a m a d o va a ayudar a crear la conexión con la base de datos. Página 28 PC PASO A PASO Nº 13
  • 29. Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad Una vez creada la base de datos, vamos a crear una tabla, para poder hacer pruebas. Esta tabla será la encargada de gestionar el stock de helados, por lo tanto, llamémosla "stock". Los campos serán Nombre, Sabor y Cantidad, siendo Sabor un campo que aceptará valores nulos. Una vez descargados, debemos instalar el servidor de base de datos, el driver de ODBC y el "Control Center", en este orden a ser posible. Una vez instalado todo, y si lo hemos hecho correctamente, deberíamos tener en la barra de tareas el icono de un semáforo, con la luz verde encendida, que viene a indicar que está arrancado el servicio de MySql. ! En el curso de apache... Introduzcamos algunos registros para poder hacer En el curso de APACHE, publicado en los anteriores una prueba primero de acceso a la base de datos, números de la revista, ya instalamos el MySQL paso a por ejemplo, con un par de ellos, tenemos de sobra. paso. De todas maneras, si tienes problemas durante la instalación, recuerda que en el foro de la revista (www.hackxcrack.com) puedes contactar con muchos de nuestros lectores y hacer las consultas que quieras, seguro que recibes la ayuda que necesitas :) Ejecutamos entonces el "Control Center" y deberíamos ver un listado de todas las bases de datos de prueba que MySql nos ha creado. Vamos a crear nuestra base de datos. Con el botón derecho en el explorador de bases de datos, Muy bien. Ahora intentemos un acceso fugaz a la seleccionamos "New Database" y la llamamos tabla. Volvamos al proyecto de Visual Basic y micosoft. agreguemos las referencias de acceso a PC PASO A PASO Nº 13 Página 29
  • 30. Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad datos (Microsoft Active Data Objects) y el ADO DataControl. También vamos a agregar el "Microsoft Windows Common Controls 6.0". Vamos a ayudarnos con el ADO Data Control para generar una cadena de conexión que utilizaremos temporalmente para esta prueba. Creo que ya expliqué los pasos a seguir para generar una cadena de conexión, pero los volveré a explicar. Añadimos el Data Control. Vamos a la propiedad "ConnectionString" y picamos en el botón con puntos que aparece. Nos debería aparecer un pequeño formulario con una opción para generar la cadena de conexión, seleccionamos esa. Nos volverá a aparecer otro formulario con diferentes proveedores OLE DB, ignorémoslos. Vamos a la segunda pestaña y volvemos picar en "Usar cadena de conexión", "Generar". En la siguiente ventana elegimos la segunda pestaña y picamos en "Nuevo". Elegimos la segunda opción, "Orígenes de datos del sistema", para que todo el que se conecte al equipo ! La dirección IP... lo pueda utilizar. En la siguiente ventana, elegimos el driver correspondiente a MySql, que seguramente La dirección IP que se aparece en la imagen es una dirección estará de los últimos, y le ponemos un nombre al de red interna. Para no tener problemas de acceso, yo origen de datos. introduciré el literal "LocalHost". Aceptamos varias veces, hasta llegar al punto en que tenemos una preciosa cadena de conexión a la base de datos. Agregamos un módulo a nuestro proyecto, un módulo que contendrá, por ahora, una variable global con la cadena de conexión, una variable de tipo Connection y otra Recordset, además de una función para inicializarlos. Option Explicit Global Cadena As String Global Conn As ADODB.Connection Global Rs As ADODB.Recordset Public Function Conectar() As Long On Error GoTo Errores Cadena = "DSN=micosoft;DESC=MySQL ODBC 3.51 Driver DSN;DATABASE=micosoft;SERVER=localhost;UID=;PASSWORD=;PORT=3306; OPTION=3;STMT=;" Set Conn = New ADODB.Connection Conn.ConnectionString = Cadena También podríamos introducir la dirección IP en vez Conn.Open del literal "LocalHost" en el cuadro de configuración, Exit Function y testear la conexión inmediatamente después (no Errores: os olvidéis de poner el nombre de vuestra BD, no Conextar = Err.Number dejéis puesta la que viene por defecto, "test"). End Function Página 30 PC PASO A PASO Nº 13
  • 31. Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad También agregaremos algunos Labels y botones, para poder realizar ! La función... mantenimientos del stock. Este es uno de los posibles aspectos del formulario. La función "On Error goto Errores" es la manera que tiene Volvemos un segundo al MDI. La función principal, como ya he el Visual Basic de controlar los errores. Esta función está dicho, del MDI es actuar como menú principal del proyecto. Ya que esta es su función, debemos agregar los módulos necesarios indicando que, en caso de que se produzca un error en la para poder abrir los formularios según el usuario final lo necesite. conexión a la base de datos, el código haga un salto de Para hacer este acceso más atractivo, nosotros vamos a agregar línea hasta la etiqueta "Errores", donde podemos ver que una "ToolBar". La podemos añadir simplemente haciendo doble inmediatamente después hace que el valor de la función click sobre ella en el cuadro de herramientas, ya que se posicionará sea el número de error que se ha producido, ya que el objeto automáticamente en su lugar. Vamos ahora a su cuadro de "Err" nos puede indicar tanto el número como la descripción. propiedades y picamos sobre "personalizado". En la primera pestaña Un ejemplo para entender mejor esto sería provocar un tenemos una gran cantidad de opciones que, principalmente, error voluntariamente (cambiando caracteres de la cadena cambian el diseño de la "ToolBar". A nosotros nos interesa la de conexión, por ejemplo) y poniendo un "MsgBox segunda pestaña, "Botones". Vamos agregando botones a la barra, Err.Descripción", recibiendo así un mensaje con la usando el botón "Insertar Botón", pudiendo a su vez descripción del error. incluir iconos para dar un aspecto más atractivo a la "ToolBar". Para ver que no hay errores, llamaremos a la función abrir desde el "Form_Load" del MDI. ! Para agregar... Para agregar iconos o imágenes a la ToolBar es necesario Option Explicit antes añadir al formulario un objeto del tipo "ImageList" Dim Error As Integer y agregar aquí las imágenes. Posteriormente podemos indicar a la ToolBar que va a utilizar esta ImageList en la Private Sub MDIForm_Load() primera pestaña, e indicar también que imagen corresponde Error = Conectar a que botón en la pestaña "Botones", propiedad "Image" End Sub ¿Va bien?, perfecto. Va m o s a d i s e ñ a r Una vez acabada la barra de herramientas con los menús, vamos nuestro primer a indicarle que, al pulsar stock, se abra el formulario que estamos formulario, que será diseñando. Vamos entonces a codificar el evento "Click" de la en parte nuestro ToolBar. La cosa quedaría así. formulario de prueba. Este nos mostrará Private Sub Toolbar1_ButtonClick(ByVal Button As MSComctlLib.Button) el Stock de productos, Select Case Button.Caption además de permitir Case "Stock" dar de alta, modificar Stock.Show y borrar estos. End Select Al formulario End Sub agregaremos un objeto "ListView" que Yo he decidido utilizar un Select Case, pero sería totalmente válido nos muestre las hacerlo con sentencias condicionales de tipo "If". Ejecutamos y cantidades de helados vemos que al pulsar sobre "Stock" se nos abre el formulario, pero que tenemos, lo hace de manera independiente, como ignorando al MDI, ya que separadas por si cerramos el MDI, el formulario de Stock seguiría abierto, y esto marcas. no es lo que hemos dicho. Lo que aquí falta es que le digamos a PC PASO A PASO Nº 13 Página 31
  • 32. Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad la venta de stock que es hija del principal. Esto se hace poniendo El siguiente paso sería mostrar todos los datos contenidos en la a verdadero la propiedad "MDIChild" que todo formulario tiene, y tabla "Stock" por la lista. El código necesario para esto sería el en nuestro caso, lo aplicaremos al formulario "stock" y a todos los siguiente, que pasamos a comentar que vayamos agregando a partir de ahora. Set Rs = New ADODB.Recordset Rs.Open "stock", Conn.ConnectionString, adOpenDynamic, adLockOptimistic While Not Rs.EOF With Lista.ListItems.Add(, , Rs("Nombre")) .SubItems(1) = Rs("Sabor") .SubItems(2) = Rs("Cantidad") End With Rs.MoveNext Wend ! Si al intentar... Si al intentar abrir la conexión esta devuelve un error de seguridad, revisa los usuarios en el gestor MySql y los permisos de estos sobre la base de datos Micosoft, e intenta cambiarlos de tal manera que cualquier usuario pueda atacar a la base de datos con instrucciones SQL (Insert, Update, Select...). Sigamos en este formulario. Vamos a las propiedades de la lista y cambiamos la propiedad "View" a "lvwReport", para que el diseño Es bastante sencillo de entender. La primera línea instancia el del ListView visualice al estilo"detallado". objeto Recordset, mientras que la segunda lo abre. Inmediatamente después creamos un bucle que va añadiendo "Items" a la lista También podemos cambiar más propiedades de la lista, por ejemplo, hasta que lleguemos al final del fichero. Vemos que los datos a en esta imagen vemos como la tengo configurada. mostrar son Nombre, Sabor y Cantidad. No se nos debe olvidar mover el objeto Recordset al siguiente registro (Rs.MoveNext), de lo contrario estaríamos creando un bucle infinito que acabaría provocando un desbordamiento de memoria ! La instrucción... La instrucción "with" indica al editor que, al encontrar el carácter "." al comienzo de una instrucción, este hará referencia a lo que tenemos justamente después del "with". Por ejemplo, si pusiéramos la línea "With Rs" cada vez que pulsáramos el carácter "." Se nos desplegaría la lista de propiedades del Recordset "Rs". La instrucción "with" se cierra con "End with" Página 32 PC PASO A PASO Nº 13
  • 33. Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad Mmmmm..., ahora que hemos llegado a este punto, me doy cuenta de que falta algo en la base de datos. Para ser más exactos, un campo clave en la tabla stock. Y es que una tabla sin campos clave es como un coche sin luces, funciona pero es poco recomendable. ! ¿Qué es un... ¿Qué es un "campo clave"? Para quienes trabajan 2.- También puedes establecer lo que se llama un campo normalmente con bases de datos, esta explicación sobra; clave combinado. Es cuando la combinación de dos campos pero hay muchas personas que nunca han creado una base (por ejemplo la combinación del campo "nombre" y campo de datos y seguro que agradecerán esta nota. Sin entrar en "apellido") nunca puede dar un valor repetido. En este caso tecnicismos diremos que un CAMPO CLAVE es no se cumple, porque podemos tener dos amigos que se simplemente un campo existente de la tabla creada que llamen igual y tengan los mismos apellidos. no puede en ningún caso contener valores repetidos. Por eso vamos a analizar cual podría ser nuestro Para que se entienda: Si estuviésemos creando una agenda campo clave. Sólo disponemos de 3. El primero, de nuestros amigos con los campos "nombre" (en este Nombre, por si solo no puede serlo, ya que pueden campo introduciríamos los nombres de nuestras amistades), haber varios helados con la misma marca (o nombre) campos "apellido" (en este campo introduciríamos los y diferentes sabores, así que rompería la apellidos correspondientes a cada nombre) y campos "DNI" lógica de un campo clave. El segundo tampoco, ya (en este campo introduciríamos el DNI correspondiente a que puede haber decenas de helados con sabor a cada nombre), el "campo clave" debería ser el campo fresa, y el campo cantidad es absurdo. ¿Qué "DNI". Está claro que no existirán dos personas con el hacer entonces?, pues tenemos varias posibilidades, mismo DNI :) pero yo voy a exponer aquí las que encuentro más lógicas. La primera sería convertir en campos clave Un par de apuntes: en nombre y el sabor (claro caso de campo combinado), ya que estos si que no se deben repetir 1.- Imagina que en nuestra agenda no queremos que figuren nunca. No podemos tener en un registro 300 los DNI. Nos quedarían dos campos ("nombre" y "apellido") Calipos de sabor fresa y en otro 130 Calipos y no podemos hacer que uno de ellos sea campo clave más del mismo sabor, ya que en este caso se porque podemos tener a dos amigos que se llamen Pedro sumarían, y tendríamos 430 Calipos de sabor o dos amigos que se apelliden González… ¿Qué hacemos fresa, pero en un solo registro. La otra posibilidad entonces? Pues la practica habitual es crear un nuevo campo es la de añadir un nuevo campo, Llamado (llamado por ejemplo "identificador") donde pondremos Id (identificador), que actúe como campo una serie auto-numérica. clave, y se incremente progresivamente por cada registro que añadamos (claro caso de campo clave ¿Qué es una serie auto-numérica? Pues muy sencillo, auto-numérico) cuando introduzcamos PEDRO en el campo nombre, . automáticamente rellenará el campo "identificador" con Vamos al Control Center de MySql y buscamos la un 1, cuando introduzcamos el nombre de un nuevo amigo, tabla stock. La editamos y creamos el nuevo campo clave "Id", indicando que será AUTO_INCREMENT automáticamente se rellenará al campo "identificador" con (auto incremental). un dos, el siguiente con un tres y así hasta que nos cansemos. De esta forma se consigue un CAMPO CLAVE y nos Añadamos también la correspondiente columna a la despreocupamos de todo puesto que encima es automático. lista y agreguémosla en el código. PC PASO A PASO Nº 13 Página 33
  • 35. Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad With Lista.ListItems.Add(, , Rs("Id")) Private Sub Lista_DblClick() .SubItems(1) = Rs("Nombre") MoverDatosACampos .SubItems(2) = Rs("Sabor") End Sub .SubItems(3) = Rs("Cantidad") End With Ahora deberían cargarse las cajas de texto al efectuar doble click en algún "Item" de la lista. Bien, lo que vamos a hacer ahora es crear dos procedimientos que habiliten y deshabiliten los Perfecto, lancémonos entonces a por el primer mantenimiento, por botones Aceptar Cancelar, así como las cajas de ejemplo, el botón modificar. Lo primero que vamos a hacer es una texto. función que compruebe que los campos tienen valores totalmente válidos, ya que de lo contrario tendríamos un error. Por ejemplo, Sub Deshabilitar() yo la he llamado "CamposOK", que devolverá verdadero si son CmdAceptar.Enabled = False correctos y falso si no lo son. CmdCancelar.Enabled = False Txtnombre.Enabled = False Function CamposOK() As Boolean TxtSabor.Enabled = False If Txtnombre.Text = "" Then TxtCantidad.Enabled = False MsgBox "Debe rellenar el campo nombre", vbExclamation, "Aviso" End Sub CamposOK = False Sub Habilitar() Exit Function CmdAceptar.Enabled = True End If CmdCancelar.Enabled = True If Not IsNumeric(TxtCantidad) Then Txtnombre.Enabled = True MsgBox "El campo cantidad debe ser numérico", vbExclamation, "Aviso" TxtSabor.Enabled = True CamposOK = False TxtCantidad.Enabled = True Exit Function End Sub End If CamposOK = True También vamos a hacer otro procedimiento que nos End Function moverá los datos del "Item" seleccionado en la lista a las cajas de texto. Vemos que se trata de una función y no un procedimiento porque debe devolver un valor indicándonos si los campos son correctos Sub MoverDatosACampos() o no. También podemos apreciar que no comprobamos el valor del Txtnombre = Lista.SelectedItem.SubItems(1) campo Sabor, ya que lo hemos declarado como que acepta valores TxtSabor = Lista.SelectedItem.SubItems(2) nulos, porque puede que un helado no tenga un sabor específico TxtCantidad = Lista.SelectedItem.SubItems(3) o sea único en su gama. End Sub Estos dos métodos serán llamados, para empezar, después de la primera carga en el evento ! La función... "Form_Load". MoverDatosACampos La función "IsNumeric" devuelve verdadero cuando el Deshabilitar valor de lo que introducimos entre los paréntesis es un End Sub número. (Este "End Sub" pertenece al Form_Load) Si todo ha ido bien, ahora debería cargarse los Para ser más pulcros, también codificaremos la caja de texto campos con los datos del "Item" de la lista al picar "Cantidad" para que solo acepte números. Por ejemplo, podríamos en el botón "Stock" del MDI. También llamaremos borrar el contenido de esta cuando el usuario, inteligente él como a este procedimiento desde el evento doble click nadie, intente introducir letras en un campo cuyo nombre es del ListView "Cantidad" (aunque parezca ilógico, "ellos" son capaces de hacerlo) PC PASO A PASO Nº 13 Página 35
  • 36. Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad Private Sub TxtCantidad_KeyUp(KeyCode As Integer, Shift As Integer) CmdBorrar.Enabled = True If Not IsNumeric(TxtCantidad) Or KeyCode = 46 Or KeyCode = 44 Then CmdNuevo.Enabled = True TxtCantidad = 1 End Sub End If End Sub En el botón Aceptar comprobaremos el valor de la variable "Estado", y dependiendo del resultado, modificaremos, daremos de alta o Le estamos diciendo que, en el caso de que se borraremos. Para modificar, debemos posicionarnos al principio del introduzca un valor no numérico, o se introduzca Recordset, buscar el registro que deseamos modificar por el campo un punto o una coma, el contenido de la caja de clave y mover los datos al registro. Este es un posible código texto pase a ser "1". Private Sub CmdAceptar_Click() Select Case Estado ! La variable... Case "MODIFICAR" If CamposOK = True Then Rs.MoveFirst La variable KeyCode contiene el código ASCII de la tecla Rs.Find "Id=" & Lista.SelectedItem.Text pulsada cuando el foco está en la caja de texto. If Not Rs.EOF Then MoverDatosARegistro Rs.Update MsgBox "Registro modificado" Vamos ahora al botón Modificar. Para saber que Lista.ListItems.Clear opción hemos pulsado nos declararemos una variable Call Form_Load que variará dependiendo si hemos picado en Else Modificar, Nuevo o Borrar. La llamaremos "Estado" MsgBox "No se ha encontrado el registro seleccionado, se va a recargar la lista", vbCritical, "Error" Option Explicit call Form_Load Dim Estado As String End If End If Desde el evento Click del botón modificar únicamente End Select cargaremos esta variable con su correspondiente HabilitarBotones valor, habilitaremos los botones Aceptar Cancelar y Deshabilitar deshabilitaremos los botones Nuevo, Modificar y End Sub Borrar. Este sería el código, rutinas incluidas Sub MoverDatosARegistro() Private Sub CmdModificar_Click() Rs("Nombre") = Txtnombre Habilitar Rs("Sabor") = TxtSabor Estado = "MODIFICAR" Rs("Cantidad") = TxtCantidad DeshabilitarBotones End Sub End Sub Vemos que después del mensaje "Registro modificado", escribimos "Call Form_Load". Esta es la manera que tiene Visual Basic para Sub DeshabilitarBotones() llamar a un evento. En este caso, para recargar la lista, llamamos CmdModificar.Enabled = False al evento Form_Load, pero bien podríamos haber codificado la CmdBorrar.Enabled = False carga de la lista en una rutina y llamarla en este momento. CmdNuevo.Enabled = False End Sub El mantenimiento "nuevo" es prácticamente igual que el de modificación, con la diferencia que deberemos hacer un "AddNew" Sub HabilitarBotones() antes de pasar los datos a los campos. CmdModificar.Enabled = True El código del botón "Nuevo" sería este: Página 36 PC PASO A PASO Nº 13
  • 37. Visual Basic - Un cliente - Una necesidad - Visual Basic - Un cliente - Una necesidad Private Sub CmdNuevo_Click() innecesario habilitar las cajas de texto. Habilitar Para borrar, en el botón aceptar buscaremos el registro seleccionado y lo Estado = "NUEVO" eliminaremos con el método "Delete". DeshabilitarBotones LimpiarCampos Case "BORRAR" End Sub Rs.MoveFirst Rs.Find "Id=" & Lista.SelectedItem.Text Sub LimpiarCampos() If Not Rs.EOF Then Txtnombre.Text = "" Rs.Delete TxtSabor.Text = "" MsgBox "Registro borrado" TxtCantidad.Text = 1 Lista.ListItems.Clear End Sub Call Form_Load Else Si le echamos un vistazo, estamos haciendo lo MsgBox "No se ha encontrado el registro seleccionado, se va a recargar la lista", vbCritical, "Error" mismo que en botón "Modificar" con la diferencia Call Form_Load que borramos el contenido de las cajas de texto. End If Ahora, codificamos en el botón "Aceptar" para que haga las operaciones necesarias al intentar dar de Como veis, tanto Modificar, Borrar y Nuevo son muy parecidos. Tal vez la diferencia alta. más visible es que cuando queremos hacer algo contra un registro en concreto (Modificar o Eliminar), antes debemos posicionarnos, por ejemplo, con el método "Find", mientras que cuando queremos dar de alta no nos hacer falta. Case "NUEVO" Y que no se me olvide, los botones "Cancelar" y "Salir" If CamposOK = True Then Rs.AddNew Private Sub CmdCancelar_Click() MoverDatosARegistro Deshabilitar Rs.Update HabilitarBotones MsgBox "Registro dado de alta" End Sub Lista.ListItems.Clear Call Form_Load Private Sub CmdSalir_Click() End If Unload Me End Sub También muy parecido, pero con la diferencia que en vez de buscar un registro para modificar, hacemos Bueno, pues con esto hemos acabado por hoy. Este formulario ha quedado un "AddNew" para añadir uno nuevo. altamente mejorable, así que poneros manos a la obra. En la próxima entrega seguiremos con el resto, que aunque serán parecidos, haremos una introducción He dejado en estas líneas lo que yo consideraría un al SQL. También podréis tener la gratificación de haber hecho un proyecto "gazapo"(no es un error de código), que si habéis medianamente importante, que bien podréis modificar a vuestro antojo e intentar leído todo el artículo, lo tendríais que ver. generalizar para que funcionen en varios tipos de negocio. Un saludo, y nos Posteriormente lo explicaré, pero me gustaría que vemos!!! --Si no te gusta teclear, en la Web tienes el código completo-- vierais si es lógico lo que estamos haciendo. Y para acabar, el botón "Borrar" Private Sub CmdBorrar_Click() ! GAZAPO CmdAceptar.Enabled = True CmdCancelar.Enabled = True Gazapo: Pues si nos fijamos en el código para dar de alta, nos damos cuenta que Estado = "BORRAR" ignora totalmente si ya existe un helado con ese nombre y ese sabor. Debería sumar DeshabilitarBotones las cantidades, es decir, modificar el registro original sumándole el contenido de End Sub TxtCantidad, mientras que ahora, erróneamente, está añadiendo un nuevo registro. ¿Os veis capaces de hacerlo sin mi ayuda? ---en la próxima entrega os daré la No llamamos a la función "Habilitar" porque es solución ;) --- PC PASO A PASO Nº 13 Página 37
  • 38. RAW 7 : http (HyperText Transfer Protocol) De nuevo nos adentramos en el conocimiento de los protocolos, esta vez le toca el turno al HTTP, para que nos entendamos, el que utilizamos al visualizar una Web :) 1. Un poco de historia un libro electrónico con el que pudieses interactuar escogiendo diversos finales, etc. Cuando en el año 1965 Ted Nelson acuñó el (algo así como los “Elige tu propia aventura” término “hipertexto”, difícilmente podría pero en plan futurista). imaginar la extensión que llegaría a alcanzar su idea. En realidad, aunque la idea de crear A pesar de que el primer navegador fue gráfico, un sistema de texto con enlaces es muy anterior, éste sólo existía para plataforma NeXT, por lo no fue hasta 1989-1990 cuando Tim Berners- que los usuarios que tuviesen otros sistemas Lee, informático del CERN (Organización Europa tenían que conformarse con un simple navegador de Investigación Nuclear), desarrolló el primer en modo texto. No fue hasta 1993 cuando sistema web para que los científicos del apareció la primera versión del antes popular CERN pudieran compartir información. El navegador “Mosaic” para X-Windows, que era navegador que utilizaban estos científicos para quizá por aquel entonces la plataforma más acceder al sistema fue precisamente el primer extendida entre los usuarios de Internet navegador web de la historia, se llamaba (formada en su mayor parte por científicos y “WorldWideWeb” (posteriormente llamado algunos estudiantes). A partir de la aparición “Nexus”). de Mosaic (que pocos meses después también estaba disponible para PC y Macintosh) comenzó Aun hoy podemos ver una copia de esta primera la gran explosión de la WWW, con un crecimiento página tal y como era en el año 1992 (no hay exponencial de vértigo. una copia de la página en su primera aparición) en la dirección: Mi primer contacto con la WWW fue en el año http://www.w3.org/History/19921103- 1995 y, a pesar de que ya existían navegadores hypertext/hypertext/WWW/TheProject.html. gráficos, di mis primeros pasos con el navegador en modo texto “Lynx”, en un sistema VMS (uno Quizá nos pueda parecer ahora algo totalmente de esos muchos sistemas operativos que suenan cotidiano, e incluso increíblemente simple, el a chino para la mayoría). No fue hasta el año concepto del hipertexto y la www, pero hay siguiente cuando entré en contacto por primera que imaginarse la visión que se podría tener vez con un navegador gráfico, Netscape, al de estas cosas hace 40 años, cuando sólo conectar por primera vez desde mi casa con un pertenecían a la ciencia-ficción. Sin irme tan modem último modelo de 14400, y el entonces lejos, yo aún recuerdo cuando vi por primera popular Trumpet Winsock. Recuerdo también vez la película BIG, en el año 88 (poco antes cómo hice entonces mi primera página web, de que comenzase todo), y me quedé escribiendo código HTML a pelo en el bloc de maravillado con la idea de que pudiese existir notas de Windows... Que tiempos!!! XDDD Página 38 PC PASO A PASO Nº 13
  • 39. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW 2. Documentación ! En el número 12... No se puede hablar del protocolo HTTP sin hablar de otras cosas íntimamente ligadas, En el número 12 de PC PASO A PASO recomendamos la como son el lenguaje HTML, el estándar MIME, lectura de un artículo que, a pesar de su antigüedad, explica de forma muy amena términos como MIME, ASCII, ISO, etc. Si bien la especificación del protocolo UUENCODE, UUDECODE, BASE64… No dejes de propiamente dicho se encuentra en el RFC leerlo, puedes encontrarlo en 2 6 1 6 ( f t p : / / f t p . r f c - e d i t o r. o r g / i n - http://bitassa.com/articles/babel.html n o t e s / r f c 2 6 1 6 . t x t ) , p a ra t e n e r u n a documentación completa sobre el tema no basta con centrarse en los RFCs, si no que hay Pero empecemos aclarando un poco este barullo. que documentarse también adecuadamente ¿Qué relación guardan entre sí el HTTP, el sobre estos otros aspectos. HTML, y el MIME? El HTTP (HyperText Transfer Protocol) no es ! Para los nuevos... más que un protocolo que funciona sobre TCP/IP. Al igual que los demás protocolos que hemos Para los nuevos lectores, simplemente recordarles que ido viendo a lo largo de la serie RAW, el protocolo hemos explicado ampliamente en números anteriores qué HTTP está formado por una serie de comandos son los RFC. En http://www.rfc-es.org encontrarás los y una serie de respuestas que el servidor RFC que han sido traducidos al Español, si el inglés no es lo tuyo, esta Web es de visita obligada. Por cierto, si eres proporciona a esos comandos. Los comandos un portento en esto de las traducciones puedes aportar tu son muy pocos, pero la complicación del granito de arena ofreciéndote a traducir alguno de los protocolo se encuentra en los llamados muchos RFC que todavía no han sido traducidos :) campos de cabecera que son, en cierto modo, como los parámetros que se pasan con cada Podéis encontrar en Google o en cualquier comando y con cada respuesta. librería miles de tutoriales de HTML. El HTML (HyperText Mark-up Language), como Por poner un ejemplo, tenéis uno en: supongo que todos sabréis, es un lenguaje de http://www.davesite.com/webstation/html/ representación de hipertexto. Podríamos decir (lo único que he hecho para encontrar esta que el HTTP es como un FTP muy simple pero página ha sido pinchar en el primer resultado limitado a transferir sólo un tipo de contenidos. que me daba Google al buscar “html tutorial” En FTP puedes transferir cualquier tipo de --> http://www.google.com <--). archivos, y en HTTP transfieres básicamente sólo código HTML. Con respecto al MIME, se encuentra también definido en varios RFCs. En la página: Con respecto al MIME (Multipurpose Internet http://www.mhonarc.org/~ehood/MIME/ podéis Mail Extensions), hay que tener en cuenta que encontrar una lista de RFCs que especifican el lenguaje HTML permite la inclusión de éste estándar. Si no queréis leeros los 5 cualquier tipo de contenidos (texto en diferentes capítulos completos (RFC 2045, RFC 2046, idiomas, incluidos algunos como el japonés que RFC 2047, RFC 2048, y RFC 2049) podéis no utilizan los mismos caracteres que el inglés, haceros una idea básica leyendo el ya obsoleto imágenes en diferentes formatos, audio, vídeo, RFC 1521 (ftp://ftp.rfc-editor.org/in- etc., etc.). El MIME es un estándar para la notes/rfc1521.txt). representación de estos contenidos, que no sólo es usado en la WWW, si no también en PC PASO A PASO Nº 13 Página 39
  • 40. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW cualquier entorno de Internet que sea una URL, y la respuesta suele ser el contenido susceptible de transportar diferentes contenidos. HTML de esa página web. De hecho, si repasáis los números anteriores de la serie RAW, veréis que ya comenté algo acerca del MIME en los artículos sobre POP3 y SMTP. HTTP y MIME no son totalmente compatibles. En el apéndice 19.4 del RFC 2616 podéis encontrar detalladas las diferencias entre ambos estándares. Como podéis suponer, con este artículo os ahorraré el leer toda esta documentación si lo único que queréis es tener una visión global sobre el tema, y no queréis convertiros en los nuevos gurus de la www. :-D ! Para los lectores novatos Me centraré tan sólo en el protocolo HTTP, ya que el MIME y el HTML merecerían artículos Cada vez que abres el Internet Explorer (o cualquier otro navegador de Internet) y le metes una dirección Web (por aparte, aunque no de la serie RAW, ya que no ejemplo www.mocosoft.com) estás estableciendo una son protocolos. ;-) conexión básica de HTTP. Tu eres el CLIENTE (el que pide) y el SERVIDOR WEB (el que sirve) donde está 3. Arquitectura HTTP alojada la página www.mocosoft.com responderá a tu petición enviándote (sirviéndote) el contenido HTML de El protocolo HTTP ha sufrido algunas la página. Tu "querido" Internet Explorer interpretará ese código HTML y mostrará el resultado en tu monitor. modificaciones desde su aparición, y actualmente se encuentra en su versión 1.1. * La primera versión, HTTP/ 0.9, era un En cambio, la arquitectura puede ser más protocolo muy simple para la transmisión de compleja (uno de los motivos por los cuales se datos sin formato, poco más que un FTP hizo conveniente la aparición de HTTP/ 1.1), simplificado. incluyendo varias máquinas intermediarias en * La versión HTTP/ 1.0 (RFC 1945) soportaba la comunicación. Estos intermediarios pueden ya los contenidos MIME, pero no estaba ser básicamente de 3 tipos: proxies, gateways, preparada para soportar algunas características y túneles. avanzadas de la www, como la cache, los virtual hosts, etc. Un túnel es simplemente un intermediario que retransmite todo lo que recibe sin siquiera tener * La actual versión HTTP/ 1.1 surge de la que comprender ninguno de los contenidos que necesidad de dar soporte a estas características. circulan a través de él. Un gateway, en cambio, En el apéndice 19.6.1 del RFC 2616 se puede realizar traducciones de protocolos cuando detallan las diferencias entre HTTP/ 1.0 y las arquitecturas a ambos lados son HTTP/ 1.1. incompatibles, pero los contenidos no se verán afectados y las traducciones serán transparentes Una conexión básica de HTTP consiste en una para ambas máquinas. Por último, un proxy, petición de un cliente, y una respuesta del puede modificar los datos transferidos, servidor. Típicamente, esta petición suele ser modificando, por ejemplo, las cabeceras de las Página 40 PC PASO A PASO Nº 13
  • 41. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW peticiones (¿recuerdas cuando explicamos en 4. Niveles de conexión números anteriores a navegar anónimamente mediante proxy? ;p) Hacer todo el estudio del protocolo HTTP con un cliente de Telnet puede ser duro, ya que a veces nos bastará una herramienta que abstraiga algunos parámetros que no nos interesen. Todos conocemos la herramienta principal de más alto nivel de la Otra de las características avanzadas de la que disponemos para manejar el protocolo arquitectura que permite manejar el protocolo HTTP: los navegadores (browsers). Existe HTTP/ 1.1 es la cache. En el escenario anterior, una cantidad enorme de navegadores para en el que un cliente conecta con un servidor todos los sistemas y arquitecturas, y no sólo a través de varias máquinas intermedias, puede Internet Explorer (IE), como parece que muchos que la respuesta que reciba el cliente no quieren hacernos creer. provenga directamente del servidor final, aunque esto habrá de ser transparente para Ya que menciono IE, os recuerdo que es una el usuario. Alguna de las máquinas intermedias de las aplicaciones más inseguras que existen podría tener una copia de la respuesta del hoy día. Para que comprobéis que mi afirmación servidor ante esa petición, y enviarla no es gratuita, os propongo que hagáis el directamente al cliente sin necesidad de recorrer experimento de visitar las más importantes de nuevo todo el camino de ida y de vuelta páginas de seguridad informática, y realizar hasta el servidor final. una búsqueda de la cadena “Internet Explorer”. Os pongo como ejemplo una lista de páginas Normalmente, las máquinas intermedias tendrán de seguridad que he consultado, y el número en cache las respuestas que ya han sido de avisos de seguridad que aparecen en esa solicitadas previamente por otros clientes (o página sobre IE: incluso por ese mismo cliente), aunque pueden incluso tener copias de cache de las páginas - www.securityfocus.com (569 coincidencias) Más solicitadas distribuidas en CD. - www.securitytracker.com (301 coincidencias) - www.cert.org (1538 coincidencias) - www.theregister.co.uk (447 coincidencias) - www.hispasec.com (superado el límite de 50 coincidencias) - neworder.box.sk (superado el límite de 20 coincidencias en la El tema de la cache en HTTP es realmente sección de exploits, el límite de complejo, y podría duplicar la extensión de 30 coincidencias en la sección de exploits este artículo, por lo que lo obviaré, al no ser antiguos, el límite de 20 coincidencias en la necesario para una comprensión básica del sección de artículos, y el límite de 20 protocolo. coincidencias en la sección de noticias breves) PC PASO A PASO Nº 13 Página 41
  • 42. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW Por supuesto, entre todas esas entradas, alguna HTTP es el 80. En cambio, si es necesario, se habrá colado que no sea un aviso de podemos especificar cualquier otro puerto. seguridad, pero podéis realizar el experimento * El campo path es un nombre de directorio por vosotros mismos y comprobar que la relativo al directorio configurado como raíz para inmensa mayoría de las coincidencias son el servidor web. Esto es totalmente transparente referentes a la “seguridad” de IE. al usuario, por lo que desde el punto de vista del cliente se puede decir que se trata de un Tenéis muchas alternativas a IE en sistemas directorio absoluto. En realidad, como ya Windows, y no solo Netscape, como también sabemos, existen formas de saltarse esto del intentan hacernos creer (de hecho, Netscape directorio raíz del servidor web, y acceder a será quizá más seguro que IE, pero por mi cualquier otro directorio de la máquina. ;-) experiencia personal puedo afirmar que funciona * El campo consulta es opcional, y es sólo para realmente mal). Yo personalmente, en Windows páginas de contenido dinámico (PHP, ASP, CGI, me quedo con el navegador Opera. La versión ...) en las que se puedan introducir parámetros. shareware (gratis, para que nos entendamos) es totalmente funcional y simplemente añade un banner de publicidad en una de las esquinas. ! A partir de ahora... En realidad se puede utilizar perfectamente con el banner, que molesta poco, pero si queréis A partir de ahora, si eres de los que poseen una mente quitarlo no tenéis más que pagar el módico inquieta, te recomendamos que cuando visites una página precio del registro. Porque claro, doy por hecho Web no pierdas de vista el campo dirección de tu navegador. Podrás ver "en directo" lo "interesantes" que pueden ser que estoy hablando con gente legal, y que no algunas peticiones(vease imagen siguiente) se os ocurrirá visitar http://astalavista.box.sk para buscar un serial number de Opera y Por otro lado, recuerda que cuando introduces en tu registrarlo gratuitamente... :p Navegador una dirección Web (por ejemplo www.astalavista.com), el Navegador intenta por defecto acceder al puerto 80. No tienes mas que probarlo, escribe En Linux uso también Opera, por costumbre por ejemplo http://www.astalavista.con:80 en tu navegador más que nada, pero tenéis también un y verás que el resultado es el mismo que si escribieses amplísimo repertorio de navegadores (Mozilla, http://www.astalavista.com. Lo que no sabe todo el mundo Ko n q u e r o r, G a l e o n , N e t s c a p e , e t c ) . es la cantidad de Servidores Web que hay en Internet tras otros puertos, si has seguido el curso del Servidor Web APACHE (en anteriores números de PC PASO A PASO) Centrándonos de nuevo en el tema, si queremos sabes que puedes activar un Servidor Web en cualquier utilizar un navegador (sea el que sea) como puerto, por ejemplo en el puerto 4415… no te imaginas la herramienta HTTP, tenemos que conocer cantidad de Servidores Web que en el Puerto 80 tienen perfectamente el formato de una URL (Uniform páginas Web de lo más normalitas y en "otros puertos" tienen las páginas interesantes ;p Resource Locator), que es el siguiente: Si www.astalavista.com tuviese una web oculta en el puerto http://host[:puerto][/path][?consulta] 9010, para acceder a ella tendrías que introducir en tu navegador www.astalavista.com:9010. Ya, ahora me pedirás * El campo host es el único obligatorio, y es una lista de Webs "ocultas", pues lo siento pero eso sería suficiente para que esta revista fuese repudiada en ciertos donde ponemos la dirección del servidor HTTP. círculos, sería como publicar el acceso a uno de los muchos Podemos poner bien una dirección IP FTP de los que utiliza la scene… si quieres adentrarte en (217.174.193.62), o bien un nombre DNS este tema, empieza por trabajarte los foros de FXP ;) … (www.hackxcrack.com). ¿Cómo? ¿Qué no sabes lo que es eso? Pues repasa los anteriores números de PC PASO A PASO ;p * El campo puerto normalmente no será necesario, ya que el puerto por defecto para Página 42 PC PASO A PASO Nº 13
  • 43. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW La combinación de un navegador de los de SamSpade), y que la página de la que venimos toda la vida, y un sniffer, puede ser una es www.alqaeda.org. En el parámetro Request herramienta muy útil para estudiar el Type podemos especificar el comando HTTP a funcionamiento del protocolo HTTP. enviar. Más adelante veremos cada uno de estos Existen también herramientas intermedias entre comandos en detalle. esto y un simple cliente de Telnet, como por ejemplo la aplicación SamSpade, que no sólo Por último, como no, hay que mencionar el puede ser descargada como aplicación para cliente de Telnet como aplicación universal usar localmente en tu PC, si no que también para el estudio de los protocolos. ;-) Si utilizamos puede ser utilizada online desde el propio el cliente de Telnet tenemos que tener en cuenta servidor de SamSpade: www.samspade.org. dos aspectos. El primero, es que el puerto por defecto para HTTP es el 80. Y por último, que En la imagen podemos no podemos incluir el path al lanzar la conexión ver la configuración de mediante Telnet, si no sólo el host. Para incluir la herramienta Browse un path, tendremos que hacerlo una vez We b i n c l u i d a e n establecida la conexión con el servidor, enviando SamSpade, en la que la cabecera adecuada, tal y como veremos más configuramos la adelante. aplicación para que se c o n e c t e a 5. El protocolo HTTP www.withehouse.org haciéndole creer que Una vez establecida la conexión (asumimos que nuestro navegador es estamos trabajando con un cliente de Telnet), un Internet Explorer 5.0 el servidor se queda en espera de que enviemos (cuando en realidad un comando, al cual responderá después tal y nuestro cliente es como iremos viendo. PC PASO A PASO Nº 13 Página 43
  • 44. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW Teniendo en cuenta que el RFC 2616, que comandos RAW, para luego hablar de los campos de cabecera. Por último, especifica el protocolo HTTP /1.1, consta de hablaré sobre as respuestas del servidor. 175 páginas, no podemos hacer en este artículo una especificación detallada y precisa del protocolo, por lo que nos ! Para los nuevos lectores limitaremos a ver casos típicos y relativamente sencillos. ¿TELNET? ¿SNIFFER? ¿Qué es eso? ¿Cómo se utiliza? En los números anteriores mostramos paso a paso como En primer lugar, tenemos que tener en cuenta utilizar estas herramientas, si es la primera vez que lees que no todos los servidores aceptan todos los esta revista y no dominas el tema seguro que ya te has comandos HTTP. Cuando un servidor no acepte perdido. La solución ideal pasa por comprar los números un determinado comando, nos responderá con atrasados de PC PASO A PASO, claro, pero estamos un error 405 (method not allowed). Si ni estudiando una alternativa que esperamos poder poner en marcha a mediados de Noviembre (máximo Diciembre). siquiera conoce ese comando, nos responderá con un error 501 (Not Implemented). Sólo Lo que tenemos pensado es hacer en una especie de FAQ los comandos GET y HEAD han de ser y colgarla en la Web (www.hackxcrack.com), en realidad implementados obligatoriamente por cualquier será un archivo que todo el mundo podrá descargar y servidor. contendrá esos artículos ya publicados y de nivel básico que todo nuevo lector deberá “tener muy a mano”. No vamos a liberar los PDF de todos los números publicados, El protocolo HTTP consta de muy pocos será simplemente una recopilación de todo lo que creemos comandos RAW (tan sólo 8, de los cuales sólo imprescindible para que cualquier nuevo lector pueda seguir hay 2 cuya implementación es obligatoria). la revista. Toda la complejidad del protocolo no se encuentra en los propios comandos, si no en los parámetros adicionales que se envían con cada petición y con cada respuesta. El número Empiezo, por tanto, mostrándoos la sesión completa de http. Os de estos parámetros varía de una petición a recuerdo que a lo largo de toda la serie RAW he utilizado el color otra, y se encuentra cada parámetro separado azul para indicar lo que envía el cliente al servidor, y el color rojo en una línea diferente. A cada una de estas para las respuestas del servidor al cliente. El color verde lo utilizo líneas se las denomina campos de cabecera para comandos de consola, enviados fuera de la conexión TCP/IP. (header fileds). Cuando un campo de cabecera no se especifica explícitamente, el GET / HTTP/1.1 estándar define una serie de decisiones a tomar User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; UNIX) Opera 6.11 [en] por defecto tanto por parte del servidor Host: www.hackxcrack.com como por parte del cliente, por lo que no existe Accept: text/html, image/png, image/jpeg, image/gif, image/x-xbitmap, */* Accept-Charset: windows-1252, utf-8;q=1.0, utf-16;q=1.0, iso-8859-1;q=0.6, *;q=0.1 un número fijo de campos de cabecera Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0 obligatorios. Cookie: phpbb2mysql_data=a%3B1%5B%5etc Cache-Control: no-cache Para tratar de explicaros de forma ordenada Connection: Keep-Alive, TE todo este barullo que se encuentra repartido TE: deflate, gzip, chunked, identity, trailers por varios documentos diferentes, y de forma bastante caótica, he decidido empezar HTTP/1.1 200 OK mostrando un ejemplo básico de sesión Date: Thu, 09 Oct 2003 14:59:29 GMT completa, capturada con un sniffer, para luego Server: Apache/1.3.26 (Unix) PHP/4.2.3 mod_perl/1.26 ir explicándola paso a paso. Para esta Last-Modified: Fri, 23 May 2003 19:52:13 GMT explicación empezaré por comentar los 8 Página 44 PC PASO A PASO Nº 13
  • 45. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW Accept-Ranges: bytes A continuación, el comando sería: Content-Length: 6291 Content-Type: text/html GET /entrada/entrada.htm HTTP/1.1 Age: 0 Como vemos, indicamos sólo el PATH, separado ...AQUI VENDRIA UN MONTON DE CODIGO HTML... por un espacio del protocolo a utilizar que, en este caso, y prácticamente en cualquier caso, GET /imagenes/LOGOPCPASOAPASO1.jpg HTTP/1.1 será siempre HTTP/1.1. User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; UNIX) Opera 6.11 [en] Host: www.hackxcrack.com Después de esta línea, debemos indicar aparte Accept: text/html, image/png, image/jpeg, image/gif, image/x-xbitmap, */* el HOST para completar la URL: Accept-Charset: windows-1252, utf-8;q=1.0, utf-16;q=1.0, iso-8859-1;q=0.6, *;q=0.1 Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0 GET /entrada/entrada.htm HTTP/1.1 Referer: http://www.hackxcrack.com/ Host: www.hackxcrack.com If-Modified-Since: Thu, 03 Apr 2003 06:06:09 GMT If-None-Match: "710029-10d4-3e8bcf51" Esto permite referenciar otros HOSTs a partir Cookie: phpbb2mysql_data=a%3A2%3A%etc de uno dado, siempre que éste lo permita. Connection: Keep-Alive, TE Si el host especificado no es válido, el servidor TE: deflate, gzip, chunked, identity, trailers responderá con un error 400 (Bad Request). Este campo Host que hemos visto que sigue HTTP/1.1 304 Not Modified al propio comando es precisamente uno de los Date: Thu, 09 Oct 2003 14:59:30 GMT campos de cabecera que mencioné. Etag: "710029-10d4-3e8bcf51" En el ejemplo de sesión completa que puse al principio podemos ver lo siguiente: ¡¡Buf!! ¡Como podéis imaginar, tenemos mucho trabajo por delante! ;) GET / HTTP/1.1 5.1. Comandos RAW de HTTP Host: www.hackxcrack.com Enumeraré a continuación todos los comandos HTTP, aunque nos En este caso, la página solicitada es la raíz del centraremos sobre todo en el comando GET, que es el más importante. servidor. Mientras explique los comandos, probablemente habrá muchas cosas que os suenen a chino. No os preocupéis, porque más adelante explicaré todo Conexión a través de un proxy: en detalle. Si conectasemos a través de un proxy, por 5.1.1. Comando GET ejemplo 127.0.0.1, tendríamos que especificar no sólo el PATH, si no también el HOST como Este es, sin duda, el comando HTTP más utilizado, ya que es el que se parámetro del comando GET. Utilizar esta IP usa cuando queremos descargar una página web de un servidor. Vamos como proxy no es ninguna tontería (para los a ve r d o s fo r m a s d i fe r e n t e s d e c o n e c t a r n o s a l a U R L que se puedan quejar de que no ponemos IPs http://www.hackxcrack.com/entrada/entrada.htm mediante Telnet: reales en los artículos), ya que podríamos estar utilizando una aplicación como MultiProxy Conexión directa: (www.multiproxy.org –utilidad explicada en números anteriores-) que crea un proxy virtual Lo primero será lanzar el telnet al servidor: en nuestro propio PC que lo que hace es manejar dinámicamente listas de proxies externos. telnet www.hackxcrack.com 80 PC PASO A PASO Nº 13 Página 45
  • 46. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW Si tenemos, por ejemplo, un multiproxy en el puerto 8080 de nuestra El comando POST debe incluir, por supuesto, máquina, empezaremos con el siguiente Telnet: un cuerpo de datos con su cabecera, igual que hace el servidor cuando nos envía una página telnet 127.0.0.1 8080 solicitada. Más adelante veremos cómo construye el servidor estas cabeceras. A continuación, lanzaremos la siguiente petición: 5.1.5. Comando PUT GET http://www.hackxcrack.com/entrada/entrada.htm HTTP/1.1 Este comando es el inverso a GET, ya que ** No he probado este ejemplo concretamente con Multiproxy. Lo único permite especificar una URL sobre la que se que comento es el método genérico para conectar a través de un escribirán los datos incluidos en la propia proxy. petición. Si no existía previamente ese recurso, el servidor nos responderá con un código 201 5.1.2. Comando OPTIONS (Created), en cambio, si ya existía y ha sido modificado, nos responderá con un código Este comando nos permite conocer las características de la comunicación 200 (Ok), o un código 204 (No Content). entre nuestro cliente y un recurso determinado del servidor. Si el servidor no comprende los contenidos Si, por ejemplo, enviamos: enviados, responderá con un error 501 (Not Implemented). OPTIONS * HTTP/1.1 Lo importante que hay que comprender en este El recurso solicitado es *, que es equivalente a no especificar ningún punto es la diferencia entre los comandos POST recurso. Esto equivale a hacer un simple PING al servidor para ver si y PUT. En el comando POST, la URL responde. especificada es la de algún recurso que sea capaz de procesar los datos, por ejemplo, un Si queremos enviar un comando OPTIONS a un proxy en concreto dentro script CGI, PHP, o ASP. Este script decidirá qué de una cadena, en lugar de enviarlo al servidor final al que supuestamente hacer con los datos enviados. En cambio, en el estamos conectados, podemos utilizar el campo de cabecera Max- comando PUT la URL especificada será Forwards, tal y como veremos más adelante. directamente sobre la que se escribirá. 5.1.3. Comando HEAD 5.1.6. Comando DELETE Es similar al comando GET, pero con la diferencia de que el servidor en Como es fácil adivinar, sirve para eliminar el su respuesta no incluirá los datos a enviar (típicamente el código HTML), recurso especificado en la URL. Por supuesto, si no tan sólo la cabecera. Con esto se puede comprobar si una URL es este comando no funcionará con la inmensa válida, cuál es el tipo de contenidos, si ha de ser renovada la copia de mayoría de URLs. XDD cache debido a algún cambio, etc. 5.1.7. Comando TRACE 5.1.4. Comando POST Es prácticamente como un PING, no sólo hacia Este comando permite que el cliente solicite el envío de datos al servidor, el servidor final, si no también hacia alguno de en lugar de solicitar una recepción de datos. Es, por ejemplo, el método los proxies intermedios si se utiliza el campo utilizado para subir un mensaje a un foro web. Si el mensaje ha sido de cabecera Max-Fordwards. El servidor que añadido con éxito al foro, el servidor nos responderá con un código 201 haya de responder, lo hará con un código 200 (Created). (Ok), y la respuesta tendrá como tipo de Página 46 PC PASO A PASO Nº 13
  • 47. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW contenidos message/http. Esta respuesta que aceptará el cliente. Consiste en una lista puede ser utilizada por el cliente para hacer de tipos/subtipos de contenidos. Por tanto, si diversos diagnósticos. especificamos */* significa que aceptamos cualquier tipo de contenido. 5.1.8. Comando CONNECT Por ejemplo: Este comando se utiliza en los proxies que Accept: text/html, image/png pueden funcionar como tunel SSL. Esto es un tema muy complicado, así que mejor lo Especifica al servidor que sólo aceptamos texto dejamos, que no es plan de escribir un HTML e imágenes en formato PNG. libro. xD En cambio, si enviamos: 5.2. Campos de cabecera Accept: */* La petición se puede completar con una serie Indicamos al servidor que aceptamos cualquier de campos adicionales, cada uno enviado en tipo de contenidos. una línea, que permiten indicar al servidor los Y si enviamos esto: tipos de contenidos que acepta el cliente, el lenguaje, los sistemas de codificación, etc. Accept: text/html, text/plain, image/* Vamos a ver sólo alguno de los más Indicamos que aceptamos texto HTML, texto importantes. Muchos de los que no veremos plano, y cualquier formato de imágenes. será debido a que son parte del complejo sistema de cache que ocuparía por si sólo todo Podemos especificar, además, prioridades en un artículo. A continuación muestro una lista los formatos. Por ejemplo, si preferimos que bastante completa de campos de cabecera, en las imágenes nos sean enviadas en formato los que señalo aquellos que comentaré: PNG, enviaremos: Accept, Accept-Charset, Accept-Encoding, Accept: image/png, image/*; q=0.1 Accept-Language, Accept-Ranges, Age, Allow, Authorization, Cache-Control, Esto significa que la prioridad para cualquier Connection, Content-Encoding, Content- formato de imagen que no sea image/png, es Language, Content-Length, Content- 0.1. El valor de prioridad por defecto es 1, por Location, Content-MD5, Content-Range, lo que, al no especificar un valor de prioridad Content-Type, Date, ETag, Expect, Expires, para image/png, se asume que este es 1, el From, Host, If-Match, If-Modified-Since, If- cual es mayor que 0.1. Por tanto, la petición None-Match, If-Range, If-Unmodified-Since, anterior sería equivalente a esta: Las-Modified, Location, Max-Forwards, Pragma, Proxy-Authenticate, Proxy- Accept: image/png; q=1, image/*; q=0.1 Authorization, Range, Referer, Retry-After, Server, TE, Trailer, Transfer-Encoding, Upgrade, El valor de prioridad (q) puede tomar cualquier User-Agent, Vary, Via, Warning, WWW- valor comprendido entre 0 y 1, con hasta 3 Authenticate. decimales, por lo que podemos especificar listas 5.2.1. Accept: de prioridades bastante complejas. Podemos especificar prioridades de forma mucho Permite especificar el tipo de contenidos más sencilla, simplemente mediante el orden PC PASO A PASO Nº 13 Página 47
  • 48. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW en que especificamos los tipos aceptados. Por ** No incluimos “fotos” de la tabla porque ejemplo: ocuparía varias páginas de la revista y en el foro de hack x crack después nos echan bronca Accept: text/html, image/png, */* por desperdiciar espacio :) Especifica al servidor que preferimos siempre 5.2.3. Accept-Encoding: texto HTML a cualquier otra cosa, y en segundo lugar, imágenes PNG. En cambio, si no se nos Especifica al servidor el tipo de codificación de puede enviar ninguna de esas dos cosas, datos que puede comprender nuestro cliente. también nos conformamos con cualquier otro Para hacer nuestras pruebas lo mejor es que tipo de contenido (*/*). utilicemos sólo la codificación identity, es decir, sin ninguna codificación. Así, podremos ver en Los tipos básicos están especificados en el texto plano todos los datos recibidos, y RFC 2046, y son los siguientes: text, image, analizarlos con mayor facilidad. La codificación audio, video, application. Aunque también se identity es la que se asume cuando no se indica puede hablar de otros tipos más complejos, nada, y deben implementarla todos los como el multipart, en los que no voy a entrar servidores. Si aún así queremos especificarlo, en detalle. enviaremos: Si queréis la lista completa de tipos actualmente registrados, la mantiene el IANA (Internet Accept-Encoding: identity Assigned Numbers Authority), y la podéis consultar por FTP en ftp://ftp.isi.edu/in- Si queremos experimentar con otras notes/iana/assignments/media-types/ codificaciones, el formato es el mismo que en los casos anteriores. Por ejemplo: 5.2.2. Accept-Charset: Accept-Encoding: gzip; q=1, compress; Especifica al servidor las tablas de caracteres q=0.8, identity; q=0.5, *; q=0.1 que acepta nuestro cliente. El formato es el mismo que en Accept. Por ejemplo: Con esto indicamos al servidor que preferimos la codificación gzip, seguida de la compress, Accept-Charset: iso-8859-1, unicode-1- seguida de la identity y, en último caso, 1; q=0.8 aceptamos cualquier otra codificación existente. Si el servidor no es capaz de enviar una Indica al servidor que preferimos caracteres respuesta en ninguna de las codificaciones según el estándar iso-8859-1, pero que especificadas, responderá con un error 406 aceptamos también unicode-1-1 (aunque con (Not Acceptable). menor prioridad). En el número anterior de la revista ya se habló 5.2.4. Accept-Language: algo sobre estos estándares de juegos de caracteres. Especifica al servidor el idioma en que preferimos que nos sea enviado el texto. Por supuesto, Como ejemplo, en para que nos sea enviado en un determinado http://www.htmlhelp.com/reference/charset/ lenguaje, el servidor tiene que tener prevista tenéis la tabla de caracteres del estándar iso- esta situación y tener traducciones de los 8859-1. contenidos a diversos idiomas. Página 48 PC PASO A PASO Nº 13
  • 49. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW No sólo se pueden especificar idiomas, si no Connection: Keep-Alive también subtipos dentro del idioma. Por ejemplo: Por defecto, se considera que se mantiene en el estado Keep-Alive, por lo que sólo es Accept-Language: en-gb; q=1, en; q=0.5, necesario indicar explícitamente cuándo se *; q=0.1 desea cerrar la conexión. Indicamos así al servidor que preferimos el 5.2.7. User-Agent: idioma inglés de Gran Bretaña (en-gb). Existen otros subtipos, como por ejemplo el en-US, Esta línea de cabecera permite indicar al servidor que es inglés de Estados Unidos. Como segunda información sobre nuestro navegador, como el opción, admitimos cualquier tipo de inglés, software utilizado, su versión, el sistema aunque no sea en-gb. Por último, con mínima operativo, o incluso algunas compatibilidades. prioridad, aceptamos cualquier otro idioma. Por ejemplo: Si no se especifica nada en Accept-Language, User-Agent: Mozilla/4.0 (compatible; el servidor asume que no hay preferencias de MSIE 5.0; Linux 2.4.18-14 i686) Opera idioma, y enviará el que más le convenga. 6.11 [en] 5.2.5. Authorization: Todo esto es lo que envía por defecto Opera 6.11 para Linux cada vez que se conecta a una Si intentamos acceder a una página cuyo página web. Como vemos, da información no contenido requiera la autenticación de un sólo sobre la versión exacta del navegador, si usuario, el servidor nos responderá con un no también sobre el sistema operativo y el error 401 (Unauthorized). En esta respuesta microprocesador. incluirá además un campo de cabecera WWW- Authenticate, en el cual nos dará los datos necesarios para que realicemos la autenticación. ! Imagina la cantidad... A continuación, tendremos que volver a pedir Imagina la cantidad de información que obtiene de ti la página, pero incluyendo los datos de cualquier Servidor Web cuando te conectas a una Web autenticación, lo cual se hace mediante esta alojada en dicho Servidor :p línea de cabecera. El sistema de autenticación de HTTP viene especificado en el RFC 2617. Como todas las cosas, esta es un arma de doble filo. Puede utilizarse para, por ejemplo, saber la resolución de tu pantalla y servirte una página Web adaptada a dicha 5.2.6. Connection: resolución (eso es bueno), pero también puede utilizarse para saber, por ejemplo, la versión exactade tu navegador Permite especificar al servidor si queremos que y servirte una página que “explote” un bug de esa versión la conexión se cierre una vez enviada la del navegador y colarte un troyano (eso ya no es tan bueno respuesta: ¿verdad?) Connection: close 5.2.8. Referer: O si queremos mantenerla abierta para posteriores peticiones: Si os ha preocupado ver que cada vez que PC PASO A PASO Nº 13 Página 49
  • 50. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW visitáis una página web se envía información indicada en Content-Encoding debería ser acerca de vuestro sistema y vuestro software, compatible con alguna de las especificadas supongo que más os asustará saber que además previamente por la otra máquina en su campo se envía la última URL que visitasteis. Si Accept-Encoding. enviamos: Por ejemplo: Referer: http://www.hackcrack.com/ Content-Encoding: gzip Indicamos al servidor que estuvimos en esa Indica que se ha utilizado la codificación gzip página, antes de estar en la suya. en los datos enviados a continuación. Para ello, Esto puede suponer un gran riesgo de la petición de esos datos tuvo que incluir un seguridad, ya que se podrían colar datos campo de cabecera como el siguiente: importantes, como por ejemplo parámetros enviados en una URL (incluso datos de Accept-Encoding: gzip; q=1, compress; autenticación de otras páginas web). q=0.5, identity; q=0.1 5.2.9. Allow: Es decir, de alguna forma tenía que incluir la codificación gzip entre las admisibles. En este Este campo de cabecera se incluye en las caso concreto, además, era la codificación respuestas con código 405 (Method Not preferida, así que todos contentos. :-) Allowed), que se envía cuando el cliente Si no se especifica un campo Content- intenta utilizar un comando que el servidor no Encoding, se asume que no se ha usado acepta. El servidor informará al cliente mediante codificación, es decir, que se ha usado este campo de cuáles son los métodos que si codificación identity. que acepta. Por ejemplo: 5.2.11. Content-Language: Allow: GET, HEAD, POST La misma relación que existe entre el Accept- Informa al cliente de que sólo está permitido Encoding y el Content-Encoding, existe utilizar esos tres comandos. El campo Allow entre el Accept-Language y el Content- también puede ser incluido como respuesta a Language. un PUT, indicando así qué métodos se pueden utilizar sobre el nuevo recurso recién creado. 5.2.12. Content-Length: 5.2.10. Content-Encoding: Indica la longitud en bytes de los datos enviados. Por ejemplo: Este campo acompaña a cualquier mensaje en el que se envíen datos, tanto si es una respuesta Content-Length: 1500 del servidor a un GET, como si son los datos subidos por el cliente en un PUT o un POST. Indica que los datos enviados (típicamente una Si bien el campo Accept-Encoding indica qué página web) ocupan 1500 Bytes. tipos de codificación aceptamos para la próxima recepción, el campo Content-Encoding indica 5.2.13. Content-Type: qué tipo de codificación se ha utilizado para un envío. Evidentemente, la codificación Este campo combina la respuesta a los campos Página 50 PC PASO A PASO Nº 13
  • 51. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW de cabecera Accept y Accept-Charset, ya 5.2.16. Max-Forwards: que puede indicar cuál es el tipo de datos enviado, así como el juego de caracteres. Este campo de cabecera se utiliza en los Por ejemplo: comandos OPTION y TRACE cuando se quiere acceder a una máquina intermedia dentro de Content-Type: text/html; charset=ISO- la cadena que nos comunica con el servidor 8859-4 final. Como vimos al principio, para llegar a un servidor nuestras peticiones pueden estar Aunque muchas veces sólo se indicará el pasando por una serie de proxies y routers. La tipo/subtipo de los datos. Por ejemplo, en la forma de acceder a estos puntos intermedios captura de sesión de ejemplo, vemos que ésta es mediante esta cabecera. es la respuesta: En este campo se indica como parámetro un Content-Type: text/html número, que es el número de pasos intermedios a dar. Cada vez que pasa por un proxy esta 5.2.14. Date: petición, el proxy restará en una unidad este número, y pasará el mensaje al próximo proxy. Como podemos imaginar, indica la fecha y la Cuando el mensaje llegue con valor 0 a uno de hora a la que se generó el mensaje en cuestión. los proxies de la cadena, éste ya no realizará Si os queréis complicar la vida, en el punto más restas, ni retransmitirá el mensaje, si no 3.3.1. del RFC 2616 se muestran en detalle que lo devolverá con la respuesta pertinente. los formatos de fechas aceptados, pero supongo que a la mayoría os bastará con un ejemplo, Este es un claro ejemplo de modificación de las cabeceras por parte de los proxies. así que no tenéis más que mirar la captura de Por ejemplo: sesión del ejemplo: Max-Forwards: 3 Date: Thu, 09 Oct 2003 14:59:29 GMT Indica que a este mensaje habrá de responder Como vemos, la hora siempre se da con el tercer proxy de la cadena. Si el servidor final respecto al GMT (Greenwich Mean Time, es estuviese casualmente conectado por menos decir, la hora en el meridiano 0). de 3 proxies, sería éste el que respondería. 5.2.15. Expect: 5.2.17. Proxy-Authenticate: Este campo lo utiliza un cliente cuando quiere Este campo se incluye en la respuesta de un solicitar al servidor un determinado tipo de proxy que requiere autenticación. El campo acción. Por ejemplo, se usa cuando el cliente WWW-Authenticate requiere autenticación espera que el servidor le envíe un código 100 al usuario con el servidor final, y el campo (Continue). Todo esto lo veremos más Proxy-Authenticate requiere autenticación adelante cuando comentemos las respuestas con uno de los proxies intermedios de la cadena. del servidor. Cuando el servidor no pueda satisfacer las expectativas del cliente, El campo Proxy-Authenticate se incluye en responderá con un error 417 (Expectation las respuestas con código 407 (Proxy Failed). Authentication Required). PC PASO A PASO Nº 13 Página 51
  • 52. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW 5.2.18. Proxy-Authorization: 5.2.21. WWW-Authenticate: Si bien a WWW-Authenticate se Ya he mencionado antes la función de este responde con Authorization, a Proxy- campo de cabecera. Os recuerdo que en el RFC Authenticate se responde con Proxy- 2617 se detalla el mecanismo de autenticación Authorization. en HTTP. 5.2.19. Retry-After: 5.3. Respuestas del Servidor Ante cada petición realizada por el cliente, el Este campo se puede incluir en las respuestas servidor siempre nos dará una respuesta con con código 503 (Service Unavailable), el siquiente formato: indicándonos típicamente en segundos el tiempo que nos recomienda el servidor que esperemos HTTP/x.x código respuesta antes te reintentar la petición. Por ejemplo: Donde HTTP/x.x es la versión de HTTP, código es un número que identifica el tipo de respuesta, Retry-After: 120 como veremos más adelante, y respuesta es una frase de respuesta aclaratoria del código Nos indica que conviene que esperemos al devuelto. menos 2 minutos antes de reintentar la petición. También se podría indicar una fecha, en lugar Por ejemplo, si intentamos acceder a una URL de un tiempo en segundos. que no existe en un servidor, nos puede responder algo como esto: 5.2.20. Server: HTTP/1.1 404 Sorry, the page you Este es un campo de cabecera de respuesta requested was not found. muy interesante. En él se incluye información acerca del servidor, la cual puede ser útil 5.3.0. Códigos de respuesta para alguien que quiera realizar algún tipo de ataque contra el servidor, ya Según el primer dígito del código de respuesta, que lo primero que necesitará conocer es el podemos saber si se trata de una respuesta software que utiliza el servidor. Por ejemplo, correcta, de error, informativa, etc. Este es el en la captura de sesión vemos: significado de ese primer dígito: Server: Apache/1.3.26 (Unix) PHP/4.2.3 1xx – Los códigos que empiezan por 1 son mod_perl/1.26 informativos, es decir, la petición ha sido recibida sin problemas, y el servidor se limita El servidor nos indica no sólo qué software a darnos algún tipo de información. Ya veremos utiliza, si no también el número de más adelante el significado de esto. versión completo, el sistema operativo (Unix), así como algunos módulos instalados. 2xx – Estas son las respuestas más habituales, ya que son las que devuelven los datos Como vemos, es una información bastante solicitados por una petición recibida y procesada precisa que puede facilitar en gran medida un con éxito. Por ejemplo, es la que se envía cada ataque contra el servidor. vez que recibimos una página web. Página 52 PC PASO A PASO Nº 13
  • 53. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW 3xx – Estas son las respuestas de redirección, 406: Not Acceptable que indican que para procesar la petición es 407: Proxy Authentication Required necesario realizar acciones previas. Ya lo 408: Request Time-out veremos más adelante. 409: Conflict 410: Gone 4xx – Supongo que todos estaréis 411: Length Required familiarizados con los códigos que empiezan 412: Precondition Failed por 4 (sobre todo con el 404 y el 403), ya que 413: Request Entity Too Large son los errores de cliente. Es decir, se envían 414: Request-URI Too Large cada vez que el cliente intenta hacer algo que 415: Unsupported Media Type no está permitido o que no tiene sentido para 416: Requested range not satisfiable el servidor. 417: Expectation Failed 5xx – Estos son los errores del servidor, 500: Internal Server Error que se dan cuando un cliente envía una petición 501: Not Implemented válida pero, por el motivo que sea, el servidor 502: Bad Gateway no puede procesarla. 503: Service Unavailable 504: Gateway Time-out A continuación, os muestro la lista completa 505: HTTP Version not supported de códigos de respuesta: Veremos ahora en detalle el significado de 100: Continue algunas de estas respuestas. 101: Switching Protocols 5.3.1. HTTP/1.1 100 Continue: 200: OK 201: Created Cuando el cliente desea enviar datos en un 202: Accepted PUT o un POST, tendrá que pedir permiso 2 0 3 : N o n -A u t h o r i t a t i ve I n fo r m a t i o n previamente al servidor. Para ello, en su petición 204: No Content incluirá el siguiente campo de cabecera: 205: Reset Content 206: Partial Content Expect: 100-Continue 300: Multiple Choices Cuando el servidor reciba la petición con este 301: Moved Permanently campo, tendrá que responder bien con: 302: Found 303: See Other HTTP/1.1 100 Continue 304: Not Modified 305: Use Proxy O bien con: 307: Temporary Redirect HTTP/1.1 417 Expectation Failed 400: Bad Request 401: Unauthorized En el primer caso, el cliente sabrá que el servidor 402: Payment Required le da permiso para enviar los datos. En el 403: Forbidden segundo caso, el servidor le denegará el permiso. 404: Not Found La acción por defecto a tomar por el cliente 405: Method Not Allowed PC PASO A PASO Nº 13 Página 53
  • 54. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW cuando no recibe ninguna respuesta, es asumir posible localización para el recurso solicitado, que tiene permiso. Si luego la recepción falla, indicará así al cliente las alternativas que tiene. ya lo notificará el servidor posteriormente. Normalmente, el navegador que utilicemos escogerá una de las opciones de forma 5.3.2. HTTP/1.1 200 Ok: transparente al usuario. Esta es la respuesta más común, ya que es la 5.3.6. H T T P / 1 . 1 301 Moved que se da cada vez que se recibe una página Permanently: web. En este caso, cuando es una respuesta a un comando GET, los datos de la página Cuando la localización de un recurso ha acompañan a esta respuesta, precedidos por cambiado y ya no se encuentra en esa URL, el los campos de cabecera necesarios para servidor nos indicará la nueva localización y, especificar el tipo de los datos (Content- normalmente, nuestro navegador pedirá esa Type), su longitud (Content-Length), etc, nueva URL de forma transparente al usuario. etc. Si, en cambio, es respuesta a un comando 5.3.7. HTTP/1.1 304 Not Modified: HEAD, todas estas cabeceras se enviarán igual (Content-Type, etc), pero no se enviarán los A pesar de que esta respuesta forma parte del datos HTML de la página. complejo sistema de cache que he comentado, merece la pena mencionarla. Esta respuesta se Si se trata de una respuesta a un comando da cuando solicitamos una página de la cual POST el servidor indicará aquí el resultado de teníamos una copia en nuestra cache. Si nuestra la acción llevada a cabo. copia de cache se corresponde con la que hay aún en el servidor, éste no tendrá que Si se trata de una respuesta a un comando retransmitirnos la página entera (con un TRACE contendrá de vuelta el mensaje que HTTP/1.1 200 Ok), si no que bastará con envió el cliente al servidor (o proxy). que nos devuelva esta respuesta para que sepamos que podemos confiar en la copia de 5.3.3. HTTP/1.1 201 Created: cache. Podemos ver un ejemplo de esta respuesta en Ya vimos anteriormente que esta respuesta se la captura de sesión de ejemplo. utilizaba en los comandos PUT y POST, cuando se creaba un nuevo recurso como consecuencia 5.3.8. HTTP/1.1 400 Bad Request: de la ejecución del comando. La sintaxis de la petición del cliente es incorrecta, 5.3.4. HTTP/1.1 204 No Content: y por tanto no la puede procesar el servidor. Esta respuesta se enviará cuando un comando 5.3.9. HTTP/1.1 401 Unauthorized: se haya procesado con éxito, pero no sea necesario enviar ningún tipo de datos. El servidor exige autenticación para que el cliente pueda acceder a ese recurso. Esta 5.3.5. HTTP/1.1 300 Multiple respuesta tendrá que ir acompañada de un Choices: campo de cabecera WWW-Authenticate que incluya los datos necesarios para que el cliente Cuando el servidor encuentra más de una pueda realizar la autenticación. Página 54 PC PASO A PASO Nº 13
  • 55. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW 5.3.10. HTTP/1.1 403 modo que ocurre con el campo WWW- Forbidden: Authenticate y la respuesta 401. Seguro que todos os habréis encontrado más 5.3.14. HTTP/1.1 414 de una vez con un error 403 que, sólo superado Request-URI too long: por el 404, yo creo que es el más habitual. El servidor no permite el acceso a ese recurso, La longitud de una petición puede llevar a porque el cliente no tiene privilegios para ello. problemas de seguridad, como los conocidos Es lo que ocurre, por ejemplo, cuando se bugs de buffer overflow. Por tanto, tanto el intenta acceder a un directorio cuyos contenidos cliente como el servidor tienen que estar no quieren ser mostrados por el servidor. preparados para peticiones de cualquier longitud y, en caso de que se supere la longitud máxima ¡Ojo! Que no hay que fiarse. Si realmente no que pueden procesar, devolver un error, en quieren que accedas a esos contenidos, muchas lugar de tratar de procesarla con los problemas veces tratarán de engañarte, haciendo que la que eso conllevaría. En la práctica, una gran respuesta a esa petición sea un error 404 en mayoría de aplicaciones han pecado incluso lugar de un 403, para que ceses en tu repetidas veces de no estar preparadas para empeño pensando que ni siquiera existe ese este tipo de situaciones. recurso ;p 5.3.15. HTTP/1.1 417 5.3.11. HTTP/1.1 404 Not Expectation Failed: Found: Ya hablé sobre esta respuesta, que se da cuando ¿Quién no conoce el archiconocido 404? Es la un servidor no puede responder a la petición respuesta que da el servidor cuando intentas expuesta por el cliente en un campo Expect, acceder a una URL que no conoce. :-) por ejemplo cuando se desea que el servidor dé el visto bueno a un comando PUT (Expect: 5.3.12. HTTP/1.1 405 Method 100-Continue). Not Allowed: 5.3.16. HTTP/1.1 500 Internal Ya mencioné anteriormente que esta respuesta Server Error: se usa cuando se envía al servidor un comando que éste no acepta por algún motivo. Como Esta es la respuesta genérica de error cuando ya dije, esta respuesta debe venir acompañada el servidor no puede procesar una petición de un campo de cabecera Allow para indicarnos válida. los comandos que sí podemos utilizar. 5.3.17. HTTP/1.1 501 Not 5.3.13. HTTP/1.1 407 Proxy Implemented: Authentication Required: Esta respuesta se da cuando el servidor no Como ya comenté, esta respuesta nos la da conoce el comando que ha enviado el cliente. un proxy cuando requiere que nos A diferencia del error 405 (Method Not autentiquemos. Para ello, incluirá un campo Allowed), en el caso del 405 sí que se conoce de cabecera Proxy-Authenticate, del mismo el comando, pero el servidor no permite su uso. PC PASO A PASO Nº 13 Página 55
  • 56. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW En cambio, en este caso, el comando es de la siguiente forma: totalmente desconocido para el servidor. GET / HTTP/1.1 5.3.18. HTTP/1.1 503 Service Host: www.hackxcrack.com Unavailable: Por supuesto, no bastaba con lanzar el comando, si no que además mandó El servidor no puede procesar ninguna petición una serie de campos de cabecera. en ese instante, quizá por una sobrecarga, o p o r e n c o n t ra r s e e n m a n t e n i m i e n t o. El primer campo enviado, User-Agent, ya sabemos que identifica nuestro Supuestamente, en un futuro el servidor podría navegador que, en este caso, es Opera para Linux: volver a responder a las peticiones, por lo que es conveniente que el servidor incluya un campo User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; UNIX) Opera 6.11 [en] de cabecera Retry-After que indique al cliente el tiempo que aconseja esperar antes de A continuación, enviamos una serie de campos para especificar el formato reintentarlo. en el que queremos recibir los datos, lo cual hacemos mediante: Accept: text/html, image/png, image/jpeg, image/gif, image/x-xbitmap, */* 6. Resumen Accept-Charset: windows-1252, utf-8;q=1.0, utf-16;q=1.0, iso-8859-1;q=0.6, *;q=0.1 Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0 Por último, vamos a repasar todo este barullo con la captura de sesión que teníamos de Con esto, indicamos al servidor que preferimos que el texto esté en formato ejemplo. Como habréis podido comprobar, es HTML, las imágenes en PNG, JPEG, GIF, o X-XBitMap (en este orden de difícil estructurar todo para hacer una explicación preferencia) y, por último, que aceptamos cualquier otro tipo de contenido. sencilla y coherente, ya que todo está relacionado con todo, y a su vez con otros Indicamos también que preferimos los juegos de caracteres Windows- aspectos externos (como el HTML o el MIME). 1252, utf-8, utf-16. En segundo lugar, también aceptamos iso-8859-1 y, En consecuencia, la documentación de este por último, si el servidor no soporta ninguno de esos caracteres, aceptaríamos protocolo es, en mi opinión, bastante caótica, cualquier otro. y para redactar este artículo he tenido que estar con una docena de RFCs abiertos Además, aceptamos una serie de codificaciones, que serían deflate, gzip, simultáneamente para consulta, así como otras x-gzip, e identity (este último no sería necesario indicarlo explícitamente). referencias. Al enviar *;q=0 estamos diciendo que no admitimos otra codificación que no sea una de las propuestas. Espero que haya merecido la pena, y que al Estos campos de cabecera: menos este artículo os sirva como referencia para hacer un estudio más detallado realizando Cookie: phpbb2mysql_data=a%3B1%5B%5etc vuestras propias capturas con un sniffer, y Cache-Control: no-cache analizando los resultados con esta guía TE: deflate, gzip, chunked, identity, trailers abreviada que he escrito. Forman parte de los que no he querido comentar por falta de espacio, Vamos a tratar de comprender ahora esa sesión por lo que vamos a olvidarnos de ellos. Por supuesto, podéis estudiar su de ejemplo que pusimos al principio. significado en el RFC 2616. Para hacer esta captura, escribí en mi navegador la URL www.hackxcrack.com. Por tanto, al no Por último, el campo: haber indicado un path, mi navegador (Opera) solicitó en primer lugar el raíz (“/”) del servidor, Connection: Keep-Alive, TE Página 56 PC PASO A PASO Nº 13
  • 57. Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW - HTTP - Serie RAW Indica al servidor que la conexión será persistente, es decir, que después Esta vez incluyó como campo de cabecera de esta petición pueden venir otras, por lo que no deseamos que cierre adicional el Referer, diciendo que la última la conexión TCP/IP después de satisfacer esta petición. URL que visitamos fue precisamente la que p e d i m o s a n t e r i o r m e n t e , e s d e c i r, Vamos a ver ahora qué nos respondió el servidor: www.hackxcrack.com: Empezó con un código de respuesta 200, por lo que la petición fue Referer: http: procesada correctamente y el servidor nos envía los datos solicitados: A continuación, envía una serie de campos de HTTP/1.1 200 OK cabecera adicionales referidos al sistema de cache, ya que mi navegador ya tenía una copia A continuación, nos da una serie de datos informativos, como la fecha de esa imagen en su cache: y hora, los datos del servidor, y otra serie de datos referidos a temas que no he explicado por falta de espacio pero que, de nuevo, podéis estudiar If-Modified-Since: Thu, 03 Apr 2003 por vuestra cuenta en el RFC 2616: 06:06:09 GMT If-None-Match: "710029-10d4-3e8bcf51" Date: Thu, 09 Oct 2003 14:59:29 GMT Server: Apache/1.3.26 (Unix) PHP/4.2.3 mod_perl/1.26 Con estos datos, el servidor se dio cuenta de Last-Modified: Fri, 23 May 2003 19:52:13 GMT que nuestra copia de cache era la misma que ETag: "390062-1893-3ece7bed" tenía el, por lo que no era necesario que volviese Accept-Ranges: bytes a enviarnos la imagen en cuestión, así que nos Age: 0 respondió con un: Por último, nos da información acerca de los contenidos (el código HTML HTTP/1.1 304 Not Modified de la página servida) que nos envía. En primer lugar, nos dice la longitud en Bytes (6291), y a continuación el tipo de contenidos de que se trata Tras lo cual, nuestro navegador cogió del disco que, en este caso, es texto HTML. duro nuestra copia de cache de la imagen y la incluyó en la página que nos tenía que mostrar. Content-Length: 6291 Content-Type: text/html Como vemos, nos resultó conveniente utilizar una conexión persistente, ya que dentro del Después de esto vendría todo el chorizo de código HTML que contiene código HTML enviado por el servidor se incluían la página servida. nuevas URLs que teníamos que solicitar al servidor, por lo que resultaba mucho más Dentro de este código HTML se encontraba lo siguiente: efectivo hacerlo en una única conexión TCP/IP, en lugar de tener que abrir una nueva cada vez <td width="218" height="121" valign="top"><div que se quisiera solicitar una imagen o cualquier align="right"><img src="imagenes/LOGOPCPASOAPASO1.jpg" otro contenido incluido en el código HTML de width="144" height="105" /></div></td> la página. Nuestro navegador, al analizar este código, se dio cuenta de que tenía Autor: PyC (LCo) que solicitar al servidor la URL /imagenes/LOGOPCPASOAPASO1.jpg, por lo que hizo una nueva petición: GET /imagenes/LOGOPCPASOAPASO1.jpg HTTP/1.1 Host: www.hackxcrack.com PC PASO A PASO Nº 13 Página 57
  • 58. SERVIDOR DE HXC MODO DE EMPLEO - Hack x Crack ha habilitado tres servidores para que puedas realizar las Explicamos esto porque la mayoría, seguro que piensa en un Servidor Web como en algo extraño que no saben ni prácticas de hacking. donde está ni como se accede. Bueno, pues ya sabes dónde se encuentran la mayoría de IIS (en Inetpub) y cuál es - Las IPs de los servidores de hacking las la página por defecto (Inetpubwwwrootdefault.htm). Y encontrarás en EL FORO de la revista ahora, piensa un poco… … ¿Cuál es uno de los objetivos de ( w w w . h a c k x c r a c k . c o m ) . Una vez en el foro entra un hacker que quiere decirle al mundo que ha hackeado en la zona COMUNICADOS DE HACK X CRACK (arriba del u n a We b ? P u e s e s t á c l a r o, e l o b j e t i vo e s c a m b i a r ( o s u s t i t u i r ) todo) y verás varios comunicados relacionados con los el archivo default.html por uno propio donde diga “hola, servidores. No ponemos las IP aquí porque es bueno soy DIOS y he hackeado esta Web” (eso si es un lamer ;) acostumbrarte a entrar en el foro y leer los comunicados. Si hay alguna incidencia o cambio de IP o lo que sea, se A partir de ese momento, cualquiera que acceda a ese comunicará en EL FORO. s e r v i d o r, v e r á e l d e f a u l t . h t m m o d i f i c a d o p a r a v e r g ü e n z a d e l “site” hackeado. Esto es muy genérico pero os dará una idea de cómo funciona esto de hackear Webs ;) - Actualmente tienen el BUG del Code / D e c o d e . La forma de “explotar” este bug la explicamos - Cuando accedas a nuestro servidor mediante el CODE / extensamente en los números 2 y 3. Lo dejaremos así por DECODE BUG, crea un directorio con tu nombre (el que mas un tiempo (bastante tiempo ;) Nuestra intención es ir te guste, no nos des tu DNI) en la unidad d: a ser habilitando servidores a medida que os enseñemos distintos posible y a partir de ahora utiliza ese directorio para hacer tipos de Hack. t u s p r á c t i c a s . Ya s a b e s , s u b i r n o s p r o g r a m i t a s y p r a c t i c a r con ellos :) ... ... ¿cómo? ¿que no sabes crear directorios - En los Servidores corre el Windows 2000 con el IIS de Servidor Web. No hemos parcheado ningún bug, ni mediante el CODE/DECODE BUG... repasa los números 2 y t a n s i q u i e ra e l R P C y p o r s u p u e s t o t a m p o c o h e m o s i n s t a l a d o tres de Hack x Crack ;p n i n g ú n S e r v i c e Pa c k . Pa ra q u i e n p i e n s e q u e e s o e s u n e r r o r (lógico si tenemos en cuenta que el RPC provoca una caída Puedes crearte tu directorio donde quieras, no es necesario completa del sistema), solo decirte que AZIMUT ha que sea en d:mellamojuan. Tienes total libertad!!! Una configurado un firewall desde cero que evita el bug del i d e a e s c r e a r l o , p o r e j e m p l o , e n RPC, (bloqueo de los puertos 135 (tcp/udp), 137 (udp), d:xxxsystem32default10019901mellamojuan (ya irás 138 (udp), 445 (tcp), 593 (tcp)). La intención de todo esto aprendiendo que cuanto mas oculto mejor :) es, precisamente, que puedas practicar tanto con el CODE/DECODE como con cualquier otro “bug” que conozcas (y hay cientos!!!). Poco a poco iremos cambiando la Es posiblemente la primera vez que tienes la oportunidad c o n f i g u ra c i ó n e n f u n c i ó n d e l a e x p e r i e n c i a , l a i d e a e s t e n e r de investigar en un servidor como este sin cometer un delito los Servidores lo menos parcheados posibles pero (nosotros te dejamos y por lo tanto nadie te perseguirá). mantenerlos operativos las 24 horas del día. Por todo ello Aprovecha la oportunidad!!! e investiga mientras dure esta y debido a posibles cambios de configuración, no olvides iniciativa (esperemos que muchos años). visitar el foro (Zona Comunicados) antes de “penetrar” en nuestros servidores. - En este momento tenemos mas de 600 carpetas de peña que, como tu, está practicando. Así que haznos caso y crea - Cada Servidor tiene dos unidades (discos duros duros): t u p r o p i a c a r p e t a d o n d e t r a b a j a r. * La unidad c: --> Con 40GB y Raíz del Sistema * La unidad d: --> Con 40GB * La unidad e: --> CD-ROM N o t a : R a í z d e l S e r v i d o r, s i g n i f i c a q u e e l W i n d o w s A d va n c e d ! Server está instalado en esa unidad (la unidad c:) y concretamente en el Por lo tanto, la raíz directorio por defecto winnt del sistema está en c:winnt MUY IMPORTANTE... - E l I I S , I n t e r n e t I n f o r m a t i o n S e r v e r, e s e l S e r v i d o r d e páginas Web y tiene su raíz en c:inetpub (el directorio por defecto) MUY IMPORTANTE!!!!! Por favor, no borres archivos Nota: Para quien nunca ha tenido instalado el IIS, le será del Servidor si no sabes exactamente lo que estás haciendo ni e x t ra ñ o t a n t o e l n o m b r e d e e s t a c a r p e t a ( c : i n e t p u b ) c o m o s u c o n t e n i d o . Pe r o b u e n o , u n d í a d e e s t o s o s e n s e ñ a r e m o s borres las carpetas de los demás usuarios. Si haces eso, lo único a i n s t a l a r v u e s t r o p r o p i o S e r v i d o r We b ( I I S ) y d e t a l l a r e m o s su funcionamiento. que consigues es que tengamos que reparar el sistema servidor De momento, lo único que hay que saber es que cuando y, mientras tanto, ni tu ni nadie puede disfrutar de él :( T Ú p o n g a s n u e s t ra I P ( l a I P d e u n o d e n u e s t r o s s e r v i d o r e s ) en tu navegador (el Internet explorer por ejemplo), lo que Es una tontería intentar “romper” el Servidor, lo hemos puesto estás haciendo realmente es ir al directorio c : I n e t p u b w w w r o o t y l e e r u n a r c h i vo l l a m a d o d e fa u l t . h t m . para que disfrute todo el mundo sin correr riesgos, para que todo Nota: Como curiosidad, te diremos que APACHE es otro el mundo pueda crearse su carpeta y practicar nuestros ejercicios. S e r v i d o r d e p á g i n a s We b ( s e g u r o q u e h a s o í d o h a b l a r d e él). Si tuviésemos instalado el apache, cuando pusieses En el Servidor no hay ni Warez, ni Programas, ni claves, ni nada n u e s t r a I P e n T U n a v e g a d o r, a c c e d e r í a s a u n d i r e c t o r i o de nada que “robar”, es un servidor limpio para TI, por lo tanto raíz del Apache (donde se hubiese instalado) e intentarías leer una página llamada index.html ... pero... ¿qué te cuídalo un poquito y montaremos muchos más :) estoy contando?... si has seguido nuestra revista ya dominas de sobras el APACHE ;)
  • 59. PORT SCANNING Escaneando Ordenadores Remotos: Tipos de Scaneos Para utilizar programas/herramientas de “escaneo” como el NMAP necesitamos conocer la forma en que se establecen las conexiones y adentrarnos en su funcionamiento. Este artículo te ilustrará sobre el tema. 1- Avanzando en el análisis de Ahora imagina que se publica una vulnerabilidad sistemas para algún demonio (proceso/programa) de algún sistema operativo como IRIX, FreeBSD Ya hemos comentado la importancia que tiene o determinada versión de Linux. Nuestro usuario el análisis previo de un sistema de cara a coge su lista y busca coincidencias, ¡acaba de saltarnos su seguridad, hoy en día existen encontrar un centenar de máquinas vulnerables numerosas técnicas de ‘escaneo’ de puertos y en las que obtener privilegios de administrador! la mayoría ya han sido implementadas; Un ¿A que no te haría gracia estar en la lista de ejemplo claro es NMap del que ya se habló en nuestro amigo? la revista. Por ese motivo resulta interesante conocer mejor el funcionamiento de diferentes técnicas ! Muy importante de "port scanning" y de como usar la información obtenida para explotar las debilidades de un MUY IMPORTANTE: Para cuando leas este artículo, en sistema así como la forma de protegernos de la Web de PC PASO A PASO (www.hackxcrack.com) estos ataques en la medida en que esto sea podrás descargarte el artículo “Técnicas del Port Scannig posible ;-) y uso del NMAP”, que fue publicado en el número 9 de PC PASO A PASO. 2- Algunas nociones fundamentales Ambos artículos se complementan y nuestra intención es Es interesante conocer algunas cosas acerca que puedas comprender este texto aunque no comprases del protocolo TCP de cara a comprender varias en su momento el número 9 de PC PASO A PASO. cosas que leerás a continuación y por ello volveremos a mencionar algunos de los conceptos de artículos anteriores. Quizás seas de los que piensa que un 'simple escaneo de puertos' no es la mejor forma para El protocolo de control de transmisión (TCP) es entrar en un sistema... aunque sea orientado a conexión y esto implica que se simplemente uno de los pasos previos genera un circuito (virtual) entre dos host's evidentemente te equivocas, imaginemos por cuya comunicación se considera fiable, TCP ejemplo que un usuario aburrido se dedica a asegura unas condiciones jugar con el 'Intesné' escaneando la red y tiene óptimas para el circuito establecido y utiliza lo una lista con 250.000 host's con interesante que se denomina "acuse de recibo" para información acerca de su sistema operativo, garantizar que los datos lleguen correctamente puertos abiertos, etc. a su destino. Cuando queremos establecer una PC PASO A PASO Nº 13 Página 59
  • 60. PORT SCANING - Tipos de escaneo - PORT SCANING - Tipos de escaneo - PORT SCANING conexión ambas partes deberán estar de acuerdo en participar 3. El número de secuencia ack (o acknowledge number) es o dicha conexión no se podrá realizar. lo que permite validar los segmentos que van llegando a un host, con este fin se coloca en el campo el número de SEGMENTO TCP secuencia del segmento incrementado en 1, dicho byte espera ser recibido en el siguiente envío. ** La cabecera de un segmento tcp (20 bytes normalmente) es la siguiente: ** Los puntos 2 y 3 es, para que nos entendamos, la forma que tiene el protocolo TCP de no perder ningún paquete. Si estamos enviando a un compañero un archivo Word de un par de megas, este se corta en pequeños trocitos y el receptor debe recibirlos todos, no puede perderse un solo paquete. Vale, ya se que explicarlo así es muy poco técnico, pero quiero que se entienda. 4. La longitud de la cabecera en múltiplos de 32 bits. ** ** Hemos dicho que el archivo Word es cortado en paquetitos ¿verdad? Bueno, pues cada paquetito es como una carta. La CABECERA de un paquete TCP es como el sobre de una carta, es donde figuran los datos del remitente (el que envía la carta) y del destinatario (el que debe recibir la carta). Dentro del Explicaré muy brevemente los campos ;) ** sobre ¿qué encontramos?, pues lo importante, el contenido, los DATOS, lo que quieren comunicarnos, ** Seguramente no comprenderás muchos de los que nos ha tocado la lotería y cosas de ese tipo ;p conceptos que a continuación se detallarán, no te Pues bien, un paquete TCP es exactamente igual que preocupes demasiado, la idea es que empiecen a una carta, tenemos una CABECERA (el sobre) y “sonarte” un montón de nombres “raros” y tener una unos DATOS (en este caso un cachito del archivo visión global del asunto. Para comprender a la WORD que estamos enviando). perfección una conexión TCP/IP necesitarías programar sockets en lenguaje C, algo que no 5. Ahora lo que nos interesa especialmente, el campo tardaremos mucho en publicar… por el momento no 'flags' (banderas): te agobies e intenta simplemente tener una visión general. Para practicar todo lo que a partir de ahora Tenemos varios flags para disfrute personal y son se explicará puedes emplear el NMAP. URG|ACK|PSH|RST|SYN|FIN ahora te explico algo más acerca de ellos, como verás no tienen ningún misterio :) 1. Puerto origen y destino, bastante explícito :P URG, indica que el segmento transporta datos urgentes. 2. Número de secuencia, al intentar establecer una conexión los host's que intervienen en el proceso eligen un número ACK, indica que el número de secuencia ack de la cabecera aleatorio para empezar a contabilizar bytes que viajarán en es válido. los segmentos de datos de la conexión. Los sucesivos segmentos que se envíen llevarán como número de secuencia PSH, fuerza el envío inmediato de los datos recibidos al nivel el número aleatorio elegido al principio más el de aplicación, que serían las aplicaciones finales a nivel de número de bytes enviados hasta ese momento. usuario. Página 60 PC PASO A PASO Nº 13
  • 61. PORT SCANING - Tipos de escaneo - PORT SCANING - Tipos de escaneo - PORT SCANING RST, indica que la comunicación debe reiniciarse. la cabecera IP y TCP así como las posibles opciones TCP si las hay. El host A genera una llamada a connect () para el SYN, durante la conexión indica el proceso de sincronización. propósito. FIN, indica que el host desea finalizar la conexión. 2) Ahora el host B enviará la validación para el segmento anterior y activará el flag ACK y en el número de secuencia 6. El tamaño de la ventana es el número de bytes que ack colocará el número de secuencia del segmento recibido esperan ser recibidos sin necesidad de ser validados por + 1, como el proceso de sincronización no ha terminado el parte de un host y puede variar durante la conexión activa. flag SYN sigue levantado. 7. La integridad de los datos y la cabecera tcp se 3) El host A sabe que el host B ha validado la petición al pueden verificar mediante el checksum o suma de verificación. recibir el segmento pero ahora el host B está esperando a que se valide su segmento. El host A envía un segmento 8. El puntero urgente (que se utiliza junto al flag URG) colocando el valor oportuno en el número de secuencia ack indica el número de secuencia del último byte que se considera y activando el flag ACK, el flag SYN no viaja levantado esta parte de los datos fuera de banda (urgentes). vez. En este punto la conexión se ha completado con éxito. 9.Opciones TCP como el tamaño máximo de segmento, el ¿COMO SE FINALIZA UNA CONEXIÓN ORDENADA TCP? ‘window scale’ y otras que de momento no vamos a ver aquí. 10,11. Un campo reservado y de datos respectivamente. ¿COMO SE ESTABLECE UNA CONEXIÓN ORDENADA TCP? El proceso se denomina three-way handshake (o saludo en tres fases) Ahora te explico que significa eso, no te impacientes, ya sabes que aquí siempre lo explicamos todo para que no se nos escape ningún detalle :) 1) El host A genera una llamada a close() para finalizar la conexión y se envía un segmento con el flag FIN levantado. Es posible que no comprendas el esquema pero tranquilidad que ahora te lo explico paso a paso ;-) seguro que lo 2) El host B valida cualquier información previa enviando entenderás mejor: un segmento con el flag ACK levantado. El proceso para recibir una petición de conexión implica estar 3) Para que el host A pueda cerrar la conexión el host preparado para llevar a cabo una serie de llamadas a funciones B debe enviar un segmento con el flag FIN activado. como lo son bind (), listen () o connect () de las que 4) Se valida el segmento anterior y la conexión se cierra con hablaremos en el texto de forma genérica. éxito. 1) Cuando el host A desea establecer una conexión ** Todo esto ocurre de forma transparente al usuario mediante un circuito TCP envía un segmento al host B, el cada vez que establecemos una conexión con un pc segmento llevará el flag SYN levantado indicando el proceso remoto (por ejemplo cuando hacemos un simple PING de sincronización y no suele llevar ningún tipo de datos salvo o nos conectamos a una Web con el navegador). De PC PASO A PASO Nº 13 Página 61
  • 62. PORT SCANING - Tipos de escaneo - PORT SCANING - Tipos de escaneo - PORT SCANING hecho suceden muchas más cosas, pero nos en lugar de eso la abortaremos mediante un paquete con conformamos con que captes el concepto general de RST, ¿y eso por qué? Te preguntarás, la respuesta es muy que establecer una conexión es un proceso de 3 pasos sencilla, si ya sabemos que hay alguien al otro lado (tras y cerrarla es un proceso de cuatro pasos y que los recibir SYN|ACK) para que seguir intentando conectar ¿? así “flags” (BANDERAS) tienen mucho que decir en este evitamos establecer la conexión completa y es poco probable proceso :) que nuestro escaneo quede registrado que es de lo que se trata ;) este escaneo probablemente pasará desapercibido 3- Las técnicas de “port scanning” pero recuerda, eso sí, que se necesitan privilegios de administrador para usar esta técnica y que el sistema pueda Existen muchas técnicas para descubrir qué puertos tiene montar ese tipo de paquetes, a este tipo de escaneo se le abiertos un host y determinar que servicios están corriendo conoce también como escaneo “medio abierto”. e incluso bajo que privilegios, pero lo más importante es hacerlo de forma sigilosa sin que la actividad quede registrada - TCP FIN, aunque el escaneo TCP SYN no suele dejar en los ‘logs’ de nuestra víctima y evitar que los sistemas de rastro en los logs del sistema y su detección puede ser algo detección de intrusos (IDS) nos apunten como origen del complicada hay algunos entornos sensibles al escaneo SYN escaneo. Te aseguro que a muchos usuarios no les hará como aquellos en los que hay filtros de paquetes o “firewalls” gracia que les toques los... puertos :P y por otro lado existen utilidades que registrarán los intentos de conexión SYN. Para estos casos puede resultar de interés Vamos a ver detalladamente varias de las técnicas de escaneo echar mano al escaneo sigiloso FIN (o stealth scan), se ya conocidas, algunas son una maravilla :) y otras no tanto fundamenta en el hecho de que los puertos abiertos ignoran pero en cualquier caso debes conocerlas para poder adaptar los paquetes recibidos con el flag FIN (vacío) y los cerrados mejor el escaneo a tus necesidades jeje. Ya empezaste a responderán con RST. Como se dijo en su momento al leer acerca de ellas cuando tratamos en la revista el NMap presentar Nmap los sistemas de Micro$oft entre otros no pero ahora veremos con más detalle esas y otras técnicas son susceptibles a este tipo de ataques pues no siguen las como el ‘Idle Scan’ :) pautas establecidas, quien lo diría xD ¿verdad? - TCP CONNECT (), mediante esta técnica no - ACK scan, para esos “ambientes hostiles“ con la necesitarás ningún tipo de privilegio especial como sucederá presencia de cortafuegos puede interesar “nmapear“ las con otros tipos de escaneo como TCP SYN, y además es una reglas de filtrado. Mediante esta técnica podemos enviar un técnica muy rápida puesto que podemos efectuar varias paquete con el flag ACK con los números de secuencia y ack conexiones en paralelo. Su funcionamiento (la mayoría ya de forma incorrecta o aleatoria de manera que recibamos lo habéis deducido) es el siguiente: intentamos establecer un paquete de control (“ICMP unreachable”, inalcanzable) una conexión con un puerto determinado si el puerto está o no se reciba respuesta, en tal caso el puerto se encuentra abierto la llamada a connect () tiene éxito y se nos retornará filtrado y en caso contrario la conexión será reiniciada y las el valor oportuno en caso contrario la llamada fallará. El conexiones al puerto no estarían filtradas. Como habrás problema reside en que los intentos de conexión se registrarán deducido, no puedes usar este tipo de escaneo para averiguar automáticamente en el sistema y en principio no nos interesa los puertos abiertos. Si deseas además encontrar los puertos en absoluto dejar huellas de ningún tipo. abiertos y además clasifica los puertos según se encuentren filtrados o no, existe otra técnica conocida como ‘Window - TCP SYN (), hace un momento te acabo de explicar Scan’ que además aprovecha anomalías el tamaño de la como se establece una conexión completa, mandamos un ventana TCP por parte de varios sistemas operativos para paquete con el flag SYN tal y como se haría normalmente determinar si el puerto está abierto. al intentar establecer una conexión y ahora la máquina remota nos responde amablemente con SYN|ACK hasta aquí - UDP scan (User Datagram Protocol scan), antes de va todo perfecto pero ahora nosotros para llevar la contraria nada aclarar que se trata de un escaneo mediante un NO vamos a responder con ACK para establecer la conexión, protocolo “no orientado a conexión” de manera que no existe Página 62 PC PASO A PASO Nº 13
  • 63. PORT SCANING - Tipos de escaneo - PORT SCANING - Tipos de escaneo - PORT SCANING un circuito virtual entre host’s ni tampoco garantía de entrega enviamos un paquete falso como si fuésemos el host ZOMBIE alguna de los paquetes enviados. Se utiliza cuando queremos de manera que la respuesta del host VICTIMA irá para el averiguar que puertos udp (un puerto puede ser tcp y udp host tal y como muestra el ejemplo, supondremos que el al mismo tiempo pues difieren en el tipo de protocolo pese IPid del zombie es ahora 100 e ignoraremos a que puerto a tener el mismo número identificador) están abiertos, si se dirige junto con otros datos irrelevantes para hacer el tras mandar el paquete se recibe un mensaje de control ejemplo un poco más inteligible: informando del error el puerto está cerrado y en caso contrario, no recibir nada, se encuentra abierto. Esta técnica Lo primero es obtener el IPid del zombie escogido (100), es muy poco precisa ya que si por ejemplo se filtran las conexiones udp aparecerán como abiertos puertos que están bloqueados. Además el número de conexiones udp suele estar limitado por los sistemas de manera que el escaneo puede ser bastante lento, y he dicho que suele limitarse porque existe cierto sistema operativo cuyo nombre no recuerdo ;) que no atiende a las especificaciones establecidas Tras la primera consulta procedemos, por los RFC’s de manera que el escaneo irá mucho más rápido en los sistemas de la compañía Micro$oft. Por el mismo motivo el escaneo denominado ‘Null Scan’ o escaneo nulo que se basa en no levantar ninguna bandera tampoco funcionará al usarlo contra una máquina Window$ :( - Xmas Scan: muy similar al escaneo nulo esta técnica Chequeamos el IPid para ver si el puerto se encuentra envía un paquete con todas las banderas levantadas. Si el abierto, puerto está abierto debe ignorar el paquete. - Idle scan, esta es para mí una de las técnicas más interesantes y que realmente interesa poder usar siempre que se pueda ya que es altamente sigilosa y no dejamos ni rastro de nuestra IP :-) esto es así debido básicamente a ¿Qué ha pasado arriba? que no será el origen del escaneo... o mejor dicho no para la máquina víctima de nuestro Idle scan jeje. Con lo leído Pues lo que ha ocurrido es que ahora el IPid del zombie se hasta ahora y para tu total comprensión del Idle Scan lo ha incrementado en 1 tras rebotar al zombie nuestra petición único nuevo que deberías saber es que los paquetes que se de conexión. Ahora tu que eres una persona muy atenta envían llevan un ‘identificador de fragmento’ que se suele observas de nuevo el IPid de nuestro amigo el zombie xD incrementar cada vez que se envía uno. Esta técnica de y observas que efectivamente vale 100 + 2 = 102 y eso escaneo utiliza host’s intermedios o los llamados “zombies” significa que el puerto está abierto :-) pero como no siempre para escanear un objetivo, ahora te explico la forma de tendremos esa suerte ahora veremos que ocurre si el puerto hacerlo: está cerrado, tomaremos los mismos datos previos pero con esa diferencia respecto al estado del puerto: Elegir un host zombie para determinar su identificación IP (IPid), ahora enviamos un paquete para probar un puerto en nuestra víctima desde el host zombie (ya deberías saber que podemos falsear la dirección IP tal y como se comentó en el artículo del NMap, pero nos interesa obtener los resultados ahora). El resultado puede ser que el puerto este abierto o cerrado (--no me digas) en el primer caso NOSOTROS PC PASO A PASO Nº 13 Página 63
  • 64. PORT SCANING - Tipos de escaneo - PORT SCANING - Tipos de escaneo - PORT SCANING linux $ ftp ftp.netscape.com Connected to ftp.gftp.netscape.com. 220-15 220 ftpnscp.newaol.com FTP server (SunOS 5.8) ready. Name (ftp.netscape.com:linux): anonymous ¿Y ahora que ha ocurrido? 500 'AUTH SSL': command not understood. SSL not available Pues muy sencillo :-), al rebotar al zombie la petición de conexión 331 Guest login ok, send your complete e-mail address as password. la víctima (a la que también se le puede llamar host remoto :P) Password: nos dice “¿SYN@#~?¿eso qué es?” Como le suena raro y 230-The response `' is not valid. curiosamente el puerto está cerrado nos reinicia la conexión 230-Next time please use your e-mail address as password. mediante RST. Ahora miramos de nuevo el IPid de nuestro zombie 230 Guest login ok, access restrictions apply. y nos damos cuenta de que solo ha incrementado en una unidad Remote system type is UNIX. desde la última vez por lo que el puerto estaba cerrado. Si te fijas Using binary mode to transfer files. la IP que recibe la víctima es siempre la de la máquina zombie ;- ftp> syst ), muy bien pues ahora imagina que nuestra víctima tiene habilitado 215 UNIX Type: L8 Version: SUNOS un cortafuegos que tiene “permiso” para dejar pasar los paquetes ftp> cuya IP coincida con la de nuestro zombie (sucede por ejemplo en las relaciones de confianza), ¡acabas de saltarte el cortafuegos por linux $ telnet 131.215.48.89 21 la cara!. Espero que hayas comprendido bien el funcionamiento de Trying 131.215.48.89... esta potente técnica de escaneo que como ves es muy efectiva. ... El principal problema es encontrar host’s que tengan números IPid 220 secant FTP server (Version wu-2.6.1(2) Thu Nov 29 15:02:58 predecibles como serían las dedicadas a impresión puesto que PST 2001) ready. tienen poca actividad o tráfico para llevar a buen término esta ftp> syst técnica. 215 UNIX Type: L8 Hasta aquí hemos visto con detalle los tipos de escaneo más linux $ telnet 216.127.72.117 importantes y más utilizados. Te recuerdo que explicamos en un ... artículo anterior la herramienta que aplica estas y otras técnicas Red Hat Linux release 7.2 (Enigma) de “port scanning” que fue NMap, permíteme que te sugiera dicha Kernel 2.4.9-34 on an i686 utilidad si no te apetece programar tu propio escáner de puertos login: ^D ahora que ya sabes como funciona el asunto :) ANALIZANDO LA PILA TCP/IP 4- UN PASO MÁS: DETECCIÓN REMOTA DE SO’s A este método se le suele llamar “Stack FingerPrinting” y permite Ni que decir tiene la importancia que tiene saber a que sistema obtener conclusiones analizando la pila de protocolos operativo nos enfrentamos ya que resulta fundamental de cara al TCP/IP. análisis y la penetración de un sistema así como la explotación remota debido a fallas conocidas (e incluso desconocidas :P) en Algunas formas de discriminar según el sistema operativo conocidas alguno de los servicios, etc. Existen varias formas y utilidades que se basan en: nos permitirán obtener una huella digital (o fingerprint) de nuestra víctima que nos sirva para discriminar un sistema operativo del - Flag de fragmentación, en casos concretos se establece resto, ahora veremos algunas. por parte de ciertos SO’s el flag DF (deshabilitar la fragmentación) de la cabecera IP. PRIMER CONTACTO - Números de secuencia, se intentan encontrar patrones Si ya has realizado conexiones directamente desde la consola ya en los números iniciales escogidos al responder a una solicitud de sea para mirar el correo, usar el FTP y/o cualquier otra cosa que conexión como por ejemplo incrementar un valor X cada cierto se pueda hacer mediante telnet te habrás fijado de que en muchos tiempo o elegir valores totalmente aleatorios, devolver el mismo casos se nos está dando una valiosa información de forma totalmente número enviado, etc. gratuita por parte del demonio que corre en ese puerto referente a ellos mismos y en muchos casos la plataforma sobre la que corren - Limitación ICMP, el sistema operativo Linux siguiendo las :) pero no siempre lo tendremos tan fácil por lo que ahora veremos normas y recomendaciones establecidas limita el número de otras técnicas bastante más “sofisticadas” jeje. Página 64 PC PASO A PASO Nº 13
  • 65. PORT SCANING - Tipos de escaneo - PORT SCANING - Tipos de escaneo - PORT SCANING mensajes del tipo ICMP unreachable (inalcanzable) a un máximo 5- PortSentry de 20 por segundo pero no todos los sistemas operativos siguen las reglas establecidas tal y como he comentado Mediante esta interesante utilidad que te puedes descargar de su antes ;) sitio web oficial en http://www.psionic.com (pero suele venir el paquete correspondiente en muchas de las distribuciones de Linux) - Flag no determinado, enviamos SYN y uno de los 6 bits capaz de detectar y responder en tiempo real a un escaneo de reservados para ver si se mantienen estos bits levantados en la puertos contra una máquina ¡incluso puede detectar escaneos respuesta ya que algunos sistemas cerraran la conexión tras ocultos! aunque no en todos los casos evidentemente ;-), PortSentry considerar el error, y como sobre gustos no hay nada escrito... :P se pone a la escucha en los puertos no utilizados que se indican en /etc/portsentry.conf (por lo general) y guarda las direcciones - Tipo de servicio, se puede comprobar uno de los campos IP origen del escaneo guardándolas a continuación en /etc/host.deny del mensaje de control de errores ICMP de tipo “unreachable” para entonces se puede dejar en un host inválido como 999.999.999.999 ver si su valor es 0 u otro ya que lo normal es que su valor sea 0 mediante TCPWrappers o utilidades similares. Evidentemente pese haber sistemas, como es el caso de Linux, en que se devuelve necesitarás algo más para proteger tu sistema como un cortafuegos un 192 decimal (0xC0). y una política de seguridad adecuada... :P - Opciones TCP, se pueden observar los valores devueltos, La línea de comandos básica para PortSentry teniendo en cuenta su orden o si son soportadas o no ciertas opciones como lo son que estamos bajo Linux como super usuario es: el window scale, o el MSS (tamaño máximo de segmento). root # portsentry –stcp, detectar escaneos ocultos TCP. - Fragmentos solapados, dependiendo de la implementación del sistema para el tratamiento de los fragmentos solapados, el root # portsentry –atcp, como el anterior pero en modo avanzado. nuevo fragmento sobrescribe o es sobrescrito por el fragmento anterior, hay que utilizar todos los fragmentos para reconstruir el root # portsentry –tcp, detección básica TCP con atadura al puerto paquete original completo. (con binding o ligado al puerto). Estos son algunos de los métodos que existen y que se suelen root # portsentry –udp, detección básica UDP con atadura al puerto. utilizar para determinar con MUCHA precisión que SO corre en nuestra víctima pero no son los únicos y posiblemente aparecerán root # portsentry –sudp, puede detectar escaneos UDP ocultos. algunos otros más por lo que no es el objetivo de este artículo profundizar en todos ellos ahora, quizás más adelante en próximos root # portsentry –audp, como -sudp pero en modo avanzado. artículos ;-) Puede que hablemos de esta y otras utilidades relacionadas en un Por supuesto existen potentes utilidades como QUESO (Qué Sistema futuro pero por ahora esto es más que suficiente :) para empezar. Operativo) que puedes obtener de http://www.apostols.org con el objetivo de detectar el SO de un host remotamente. QUESO 6- Medidas de seguridad básicas utiliza varios paquetes con ACK=0 y un número de secuencia aleatorio de la siguiente forma: Como has podido observar existen numerosas formas de escanear una red y obtener información sensible acerca de la misma por 1 SYN lo que se recomienda instalar sistemas IDS que registren cualquier 2 SYN|ACK actividad sospechosa así como un buen cortafuegos (con una 6 PSH buena política restrictiva) y disponer de un buen ‘syslog’. Además 3 FIN lo ideal sería guardar todos nuestros “logs” en un servidor remoto 4 SYN|FIN junto con sumas de verificación u otros sistemas que nos aseguren 5 FIN|ACK que no se han modificado nuestros registros. Existen muchas 7 SYN|otros flags no estandarizados. aplicaciones para proteger nuestro sistema del exterior pero ninguna medida es suficiente como para proteger al 100% nuestro sistema, QUESO es un programa bien diseñado mediante un fichero aparte eso es lo único que es realmente seguro si tu computadora está que contiene las respuestas que se esperan según el tipo de conectada a la red de redes :P y lo seguiremos demostrando en paquete enviado y que se utilizada para contrastar los resultados los siguientes artículos ;-) obtenidos para afirmar con bastante seguridad que SO corre en nuestro objetivo, en fin una maravilla que ya deberías tener :) PC PASO A PASO Nº 13 Página 65
  • 66. SUSCRIBETE A PC PASO A PASO 45 EUROS (10% DE DESCUENTO) SUSCRIPCIÓN POR: + 1 AÑO = SORTEO DE UNA CONSOLA XBOX + 11 NUMEROS SORTEO 2 JUEGOS PC (A ELEGIR) Contra R e e m b o l s o Giro Post al Solo tienes que enviarnos un mail a preferente@hackxcrack.com Envíanos un GIRO POSTAL por valor de 45 EUROS a: indicando: CALLE PERE MARTELL20, 2º 1ª. - Nombre CP 43001 TARRAGONA - Apellidos ESPAÑA - Dirección Completa IMPORTANTE: En el TEXTO DEL GIRO escribe un mail de contacto - Población o un número de Teléfono. - Provincia - Cógigo Postal Y enviarnos un mail a preferente@hackxcrack.com indicando: - Mail de Contacto y/o Teléfono Contacto - Nombre Es imprescindible que nos facilites un mail o teléfono de contacto. - Apellidos - Tipo de Subscripción: CONTRAREEMBOLSO - Dirección Completa - Número de Revista: - Población Este será el número a partir del cual quieres subscribirte. Si deseas - Provincia (por ejemplo) subscribirte a partir del número 5 (incluido), debes poner - Cógigo Postal un 5 y te enviaremos desde el 5 hasta el 15 (ambos incluidos) - Mail de Contacto y/o Teléfono Contacto Es imprescindible que nos facilites un mail o teléfono de contacto. APRECIACIONES: - Tipo de Subscripción: GIRO POSTAL * Junto con el primer número recibirás el abono de 45 euros, precio - Número de Revista: de la subscripción por 11 números (un año) y una carta donde se te Este será el número a partir del cual quieres subscribirte. Si deseas indicará tu número de Cliente Preferente y justificante/factura de la (por ejemplo) subscribirte a partir del número 5 (incluido), debes poner subscripción. un 5 y te enviaremos desde el 5 hasta el 15 (ambos incluidos) * Puedes hacernos llegar estos datos POR MAIL,tal como te hemos indicado; rellenando el formulario de nuestra WEB APRECIACIONES: (www.hackxcrack.com) o enviándonos una carta a la siguiente dirección: * Junto con el primer número recibirás una carta donde se te indicará CALLE PERE MARTELL Nº20, 2º-1ª tu número de Cliente Preferente y justificante/factura de la subscripción. CP 43001 TARRAGONA * Puedes hacernos llegar estos datos POR MAIL,tal como te hemos ESPAÑA indicado; o enviándonos una carta a la siguiente dirección: * Cualquier consulta referente a las subscripciones puedes enviarla CALLE PERE MARTELL Nº20, 2º-1ª por mail a preferente@hackxcrack.com CP 43001 TARRAGONA ESPAÑA * Cualquier consulta referente a las subscripciones puedes enviarla por mail a preferente@hackxcrack.com EL GANADOR DEL SORTEO DE UN SUSE PERSONALIZATUMOVIL PERSONALIZATUTUMOVIL PERSONALIZATUMOVIL PERSONALIZATUTUMOVIL PERSONALIZATU TUMOVIL MOVIL MOVIL PERSONALIZATUMOVILMOVIL PERSONALIZATUMOVIL MOVIL PERSONALIZATUMOVIL PERSONALIZATUTUMOVIL PERSONALIZATUMOVILMOVIL PERSONALIZATU TUMOVIL PERSONALIZATUMOVIL PERSONALIZATUMOVIL MOVIL MOVIL MOVIL MOVIL MOVIL MOVIL MOVIL MOVIL PERSONALIZATU MOVIL MOVIL MOVIL PERSONALIZA TU MOVIL PERSONALIZA MOVIL MOVIL LINUX 8.2 DEL MES DE PERSONALIZA PERSONALIZA PERSONALIZATU MOVIL PERSONALIZA TU MOVIL MOVIL PERSONALIZA TU MOVIL MOVIL PERSONALIZA TU MOVIL PERSONALIZA SEPTIEMBRE ES: JOSE RUIZ BALLESTER MADRID SEGUIR LLAMANDO, EL PROXIMO PODRIA SER PARA TI (PAG 66) SI TE GUSTA LA INFORMÁTICA. SI ESTAS “CABREADO” CON GÜINDOUS ;) SI QUIERES PROGRESAR DE VERDAD Incluye 7 CD’s y 1 DVD PC PASO A PASO Manual de Instalación. SORTEA CADA MES UN S.O. Manual de Administracion SUSE LINUX PROFESSION AL 8.2 SIMPLEMENTE ENVIA LA PALABRA PCCON AL 5099 DESDE TU MOVIL PRECIO DEL MENSAJE: 0,90€ + IVA. VALIDO PARA (MOVISTAR - VODAFONE Y AMENA) IVA. VALIDO PARA (MOVISTAR EL PREMIO PUEDE SER CANJEABLE POR UN JUEGO HAY MUCHOS MAS EN DE PC O CONSOLA QUE NO SUPERELOS 85€ http://pclog.buscalogos.com/ EL GANADOR SALDRA PUBLICADO AQUÍ 2 NÚMEROS DESPUES DE LA PUBLICACIÓN.
  • 67. NÚMERO1: NÚMERO 2: -CODE/DECODE BUG: INTRODUCCIÓN. -CREA TU PRIMER TROYANO -CODE/DECODE BUG: LOCALIZACIÓN DEL OBJETIVO. INDETECTABLE POR LOS ANTIVIRUS. -CODE/DECODE BUG: LÍNEA DE COMANDOS. -FLASHFXP: SIN LÍMITE DE VELOCIDAD. -CODE/DECODE BUG: SUBIENDO ARCHIVOS AL SERVIDOR REMOTO. -FTP SIN SECRETOS: PASVMODE. -OCULTACIÓN DE IP: PRIMEROS PASOS. -PORT MODE/PASV MODE Y LOS FIREWALL: LA UTILIDAD DE LO APRENDIDO. -LA FLECHA ÁCIDA: LA SS DIGITAL. -TCP-IP:INICIACIÓN (PARTE 1). AZNAR AL FRENTE DE LA SS DEL SIGLO XXI. -EL MEJOR GRUPO DE SERVIDORES FTP DE HABLA HISPANA. -EDONKEY 2000 Y SPANISHARE. -LA FLECHA ÁCIDA. NÚMERO 3: NÚMERO 4: -PROXY: OCULTANDO NUESTRA IP. - CREA TU SEGUNDO TROYANO, INDETECTABLE E INMUNE A LOS ANTIVIRUS. ASUMIENDO CONCEPTOS. CONOCIENDO EL RADMIN. -PROXY: OCULTANDO NUESTRA IP. GESTIONANDO UNA SALA ENCADENANDO PROXIES. DE ORDENADORES. -PROXY: OCULTANDO NUESTRA IP. OCULTANDO EL RADMIN. OCULTANDO TODOS NUESTROS PROGRAMAS TRAS LAS INSTALANDO EL RADMIN CADENAS DE PROXIES. EN EQUIPOS REMOTOS. -EL SERVIDOR DE HACKXCRACK: CONFIGURACIÓN Y MODO DE EMPLEO. - OCULTACIÓN DE IP POR NOMBRE DE DOMINIO. -SALA DE PRACTICAS: EXPLICACIÓN. - CREA LETRAS DE IMPACTO PARA TUS DOCUMENTOS (LETRAS DE FUEGO). -PRÁCTICA 1ª: SUBIENDO UN ARCHIVO A NUESTRO SERVIDOR. - CONSIGUE UNA IP FIJA. -PRÁCTICA 2ª: MONTANDO UN DUMP CON EL SERV-U. PRÁCTICA 3ª: CODE/DECODE BUG. LÍNEA DE COMANDOS. -PREGUNTAS Y DUDAS. NÚMERO 6: NÚMERO 5: - PASA TUS PELICULAS A DIVX (STREAMING) -HACK-OPINION: LA PIRATERÍA EN INTERNET. - PASA TUS PELICULAS A DIVX II (CODEC DIVX) -ROOTKITS: LA PESADILLA DE CUALQUIER ADMINISTRADOR. - PUERTOS & SERVICIOS -ROOTKITS: EL SR. NTROOT. - eMule: EL NUEVO REY DEL P2P -WAREZ: APPZ, GAMEZ, MP3Z, DIVX, FTPZ, 0-DAY. - NUEVA SECCION: PROGRAMACION DESDE 0 -APRENDIENDO A COMPILAR PROGRAMAS. COMPILA TU PROPIO NETCAT. - CURSO DE VISUAL BASIC -BUGS, ERRORES Y OTRAS FORMA DE JOD... - IPHXC: EL TERCER TROYANO DE HXC -NETBIOS: ESTUDIO Y PENETRACIÓN DE SISTEMAS. - TENDENCIAS ACTUALES EN CODIGO MALICIOSO -ASESINADOS POR LA LSSI. - OCULTACION DE FICHEROS. METODO STREAM (ads) -LISTADO DE ORDENES PARA NETBIOS. - TRASTEANDO CON EL HARDWARE DE UNA LAN -HACK-OPINION: PAGOS POR INTERNET SEGUROS YÁ.
  • 68. NÚMERO 8: NÚMERO 7: - CURSO DE LINUX - PROTOCOLOS: POP3 - APACHE: COMPARTE ARCHIVOS - PASA TUS PELICULAS A DIVX III (EL AUDIO) - REVERSE SHELL - PASA TUS PELICULAS A DIVX IV (MULTIPLEXADO) - CURSO DE VISUAL BASIC: MAS - CURSO DE VISUAL BASIC: LA CALCULADORA CALCULADORA - IPHXC: EL TERCER TROYANO DE HXC II - PROTOCOLOS Y SU SEGURIDAD: SMTP - APACHE: UN SERVIDOR WEB EN NUESTRO PC - CCPROXY: IV TROYANO DE PC PASO A PASO - TRASTEANDO CON EL HARDWARE DE UNA LAN NÚMERO 10: NÚMERO 9: - CURSO DE LINUX (Gestión de usuários) - CURSO DE LINUX (Sistema de archivos) - APACHE + MySQL + PHP=Trio de Ases - APACHE: COMPARTE ARCHIVOS MEDIANTE WEB. - CURSO DE VISUAL BASIC: ACCESO A DATOS(II) - CURSO DE VISUAL BASIC: MI 1ª DLL ACCESO A - XML: El futuro de la trasferencia de datos DATOS - SERIE RAW: DCC - PORT SCANING: NMAP - SERIE RAW: IRC NÚMERO 11: NÚMERO 12: - Curso de linux: programacion - Curso de linux: programacion C. - Visual Basic: IIS bug exploit - Visual Basic: IIS bug exploit. Nuestro primer Scanner. - Apache como proxy - APACHE: Configuralo de forma segura. - Serie Raw: FTP - Serie Raw: FTP(II) - Validacion XML: DTD - VALIDACION XML: DTD (II) - Historia: Lady Augusta Ada Byron