En las publicaciones anteriores hemos ido tomando una formación en Javascript que nos va a permitr ahora poder ver cómo de forma sencilla podemos trabajar con todos los elementos que constituyen una página web. Ya conocemos como trabajar con variables en el lenguaje javascript, como crear nuestras propias funciones javacript para crear pequeños scripts de código que realicen cualquier acción que necesitemos. Conocemos las estructuras de control que nos permiten dentro de una función o código tomar decisiones, realizar repeticiones múltiples de acciones y controlar el flujo de ejecución de nuestro programa o script.
En nuestra última publicación estuvimos viendo a fondo todo lo que son los objetos en javascript, la cual ya era una publicación que se apoyaba en un alto grado en todas las publicaciones anteriores. Todo esto era necesario puesto que la definición de DOM no es ni mas ni menos que Document Object Model (‘Modelo de Objetos del Documento‘ o ‘Modelo en Objetos para la Representación de Documentos’).
Resumen
- 1 DOM web html y seguridad informática
- 2 DOM javascript, tutorial de control
- 3 Propiedades, métodos y manejadores HtmlElment
- 4 Propiedades, métodos y manejadores Objeto Window
- 5 Propiedades y métodos Objeto Document
- 6 Propiedades y métodos Objeto Link
- 7 Propiedades, métodos y manejadores Objeto INPUT
- 8 Propiedades, métodos y manejadores Objeto FORM
- 9 Objetos HTML de Formularios
- 10 Controlando la página web con javascript
DOM web html y seguridad informática
El DOM en una página web es la jerarquía de objetos del lado del cliente, que son los objetos que representan todos los elementos gráficos de la pantalla. ¿Qué quiere decir esto? Que controlando el DOM nosotros podemos controlar todos los objetos que componene la página web; como son: formularios html, imágenes mostradas en la web, las capas (divs), las tablas, los enlaces existentes, los estilos css… en definitiva todo lo que el usuario ve en la página web.
Cuando estas programando tu propia página web, ya sea en un hosting en la nube o en un servidor virtual como vimos en la publicación sobre cómo virtualizar un ubuntu server puedes utilizar javascript para programar acciones, eventos y funciones que mejoren la experiencia del usuario en tu página web. Sin embargo, desde el punto de vista de la seguridad informática cuando se realiza una inyección de código javascript un atacante adquiere la capacidad de modificar todo el DOM de tu página web. Lo cual significa que podrá modificar todo el contenido de la misma.
Este es el motivo por el que llevamos ya varias semanas estudiando a fondo el lenguaje javascript. Como auditores de seguridad, una vez encontrada una vulnerabilidad es necesario medir el impacto de la misma para poder definir con precisión su nivel de impacto en nuestra página web. No es lo mismo conseguir inyectar un código javascript que permita modificar contenido no crítico de la página web que conseguir inyectar un código javascript que sea capaz de controlar el formulario donde el usuario tiene preguardada su contraseña y enviarla por correo al atacante. En el caso de un foro si ha conseguido inyectar un código como el que acabamos de comentar todos los usuarios pertenecientes a dicho foro estarán expuestos a que su contraseña sea capturada por el atacante.
Pero esto no es todo lo que un atacante experimentado podría logar a hacer mediante la inyección de código javascript. Un atacante podría inyectar un pequeño script que autopublicara bajo el nombre del usuario que está visitando el foro un mensaje que el atacante a predefinido, esto podría ser parte de un plan de apoyo para aplicar ingeniería social y hacer que el administrador del foro crea que alguien le ha pedido cierta información crítica. Del mismo modo un atacante podría inyectar un código que hiciera una redirección a un sitio web que tuviera alojado algún tipo de malware y que se autodescargara al ordenador del visitante desde algún servidor FTP del atacante.
Las posibilidades que se presetan cuando alguien consigue controlar el DOM de una página web son casi infinitas. El límite lo pone la formación que el auditor de seguridad o el atacante tenga. Por ello alguien que se mete en el mundo de la seguridad informática pretendiendo sólamente utilizar programas y scripts ya creados por otros sin entender los conceptos fundamentales no podrá explotar al máximo las posibildades que una vulnerabilidad web permite, y este hecho le incapacitará en la mayoría de las ocasiones a conseguir su objetivo puesto que cada web, cada programa, cada código tiene diferencias y dificultadas que tendrán que ser tratados de forma individualizada.
DOM javascript, tutorial de control
Antes de poder ver las técnicas de inyección de código capaces de realizar todo lo expuesto anteriormente se debe aprender a controlar el DOM de un sitio web con javascript. De nada te servirá ser capaz de inyectar código si luego no eres capaz de programar las acciones que pretendes llevar a cabo. Como auditor de seguridad también necesitarás conocer cómo se trabaja el DOM con javascript por si te encuentras un script ya inyectado y deseas analizarlo. En multitud de ocasiones conocer lo que un atacante prentende hacer puede llevarte a dar con el. Si conoces su estrategia puedes adelantarte, enviarle datos falsos, o iniciar un rastreo hasta intentar dar con la persona que ha conseguido hacer la intrusión en tu web.
Lo que vamos a ver ahora es cómo se organiza la jerarquía de objetos en el DOM y mostrar cómo se puede acceder a ellos insertando un código javascript en cualquier lugar de la página web.
Objeto WINDOW del DOM
Veamos sus características para poder enteder correctamente el concepto que reprenta:
Un Explorador (Cliente Web) muestra las páginas HTML.
Cada página HTML será representada por un objeto «Document», que es desplegado en un objeto Window, (en una ventana).
Un «document» es desplegado en una ventana o frame, cada uno de estos objetos se representa con un objeto “Window”. Cada uno de estos frames o ventanas constituyen un contexto general de ejecución, es decir un «lugar» donde se ejecutará el código Javascript, donde se verán los diferentes objetos que intervienen. En principio cada ambiente es independiente pero ya veremos como se pueden comunicar. Cada frame tiene un contexto global de ejecución.
Las variables y funciones globales que definiremos en nuestro código constituirán las propiedades y métodos del objeto «Window». Todo frame, toda ventana va a tener ahora una jerarquía de objetos.
Una propiedad de «Window» de particular importancia es «document», que es en sí el objeto “Document” que contiene o representa el documento. Existen dos propiedades especiales «autoreferenciados» en «Window», self y window.
Vamos a ver todo esto en un pequeño ejemplo prático para ayudar a aclararlo:
<html><script>
var a = 4; // Variable global propiedad del objeto Window.
alert(window.a); // Que a su vez, equivale a escribir…
alert(self.a);
</script></html>
Document contendrá una familia de objetos con jerarquía, esta jerarquía refiere a un árbol de objetos, cuya raíz es el objeto Window. Esta jerarquía es la siguiente:
Como podeís observar; este diagrama nos muestra cuales son los objetos que conforman el DOM y su jerarquía, el objeto Window es el más «grande» y por tanto quien contiene todos los restantes. Para ayudar a leer este esquema, vamos a analizar una posible lectura…
El objeto Document, contenido en el objeto Window, contiene un array de objetos Form (todos los formularios), un array de objetos Anchor (todos los links), un array de objetos Image (todas las imágenes), un array de objetos Applet Java (todos los applets que tengamos en la página) y un array de objetos embebidos. A su vez cada objeto Form contiene un array de objetos element, estos son justamente los elementos html que componen el formulario, como pueden ser objetos Button, CheckBox, Hidden, Password, Radio, Reset, Select, Submit, Text, Textarea (todos objetos HtmlElement, que herederán de la clase HtmlElement).
Pasemos a ver el objeto HtmlElement con sus propiedades, métodos y handlers. Estos son heredados por los objetos de las clases Button, CheckBox, FileUpload, Hidden, Password, Radio, Reset, Select, Submit, Text, Textarea, teniendo acceso a todos ellos. HTMLElement es la superclase de todos los elementos HTML.
Propiedades, métodos y manejadores HtmlElment
Propiedad | Descripción |
---|---|
className | Propiedad de L/E que especifica el valor del atributo class (CSS) |
id | Propiedad de L/E que especifica el valor del atributo id (CSS). |
innerHTML | Propiedad de L/E que especifica el contenido de un tag HTML. |
style | Propiedad de L/E que especifica el inline style de un tag HTML. |
tagNam | Propiedad de L que especifica el nombre del tag HTML |
title | Propiedad de L/E que especifica el tooltip de un tag HTML. |
Método | Descripción |
---|---|
contains() | Determina si el elemento contiene un elemento determinado |
getAttribute() | Devuelve el valor de un atributo por su nombre |
handleEvent() | Pasa un objeto evento al manejador correspondiente |
insertAdjacentHTML(w,t) | Inserta el texto ‘t’ (HTML) en el documento en el lugar indicado por ‘w’ (“BeforeBegin”, “AfterBegin”, “BeforeEnd”, “AfterEnd |
insertAdjacentText(w,t) | Inserta el texto ‘t’ (texto) en el documento en el lugar indicado por ‘w’ (“BeforeBegin”, “AfterBegin”, “BeforeEnd”, “AfterEnd” |
removeAttribute() | Elimina un atributo junto con su valor de un elemento |
scrollIntoView() | Desplaza el documento para que el elemento aparezca visible. |
setAttribute() | Indica el valor de un atributo del elemento |
Manejador | Descripción |
---|---|
onclick | Invocado cuando se hace click en el elemento html. |
ondblclick | Invocado cuando se hace doble click en el elemento html |
onkeydown | Invocado cuando se oprime una tecla con el foco en el elemento html. |
onkeypress | Invocado cuando se oprime y suelta una tecla con el foco en el elemento htm |
onkeyup | Invocado cuando se suelta una tecla con el foco en el elemento html. |
onmousedown | Invocado cuando se oprime un botón del mouse en el elemento html. |
onmousemove | Invocado cuando se mueve el mouse sobre un elemento html. |
onmouseout | Invocado cuando se sale de un elemento html. |
onmouseover | Invocado cuando se entra a un elemento html. |
onmouseup | Invocado cuando se suelta un botón del mouse sobre un elemento html. |
Propiedades, métodos y manejadores Objeto Window
Propiedad | Descripción |
---|---|
closed | Valor booleano que es verdadero solo si la ventana fue cerrada. |
defaultStatus | Texto por defecto en la barra de estado del navegador. |
document | El objeto que me representa el documento HTML activo en el Navegador. |
frames[] | Un Array con todos los frames de la ventana (Window) que los contiene. |
history | El historial de navegación. Podremos recorrerlo hacia atrás y adelante. |
location | Esta propiedad contiene la URL actual del documento. |
name | El nombre que quiero darle a la ventana (es para referencia en JavaScript). |
navigator | Contiene información acerca del navegador: nombre, compañía, versión, etc. |
opener | Si una ventana abre a otra, esta otra puede saber quien la abrió con opener |
parent | Indica el “padre” de un frame, puede ser otro frame o la misma ventana. |
screen | Contiene las propiedades de la pantalla del usuario: alto, ancho, colores, etc. |
self | Es un sinónimo de window. |
status | Texto en la barra de estado del navegador |
top | Nos indica la ventana a que pertenece un frame. |
window | Referencia a la ventana activa (Navegador activo). |
Método | Descripción |
---|---|
alert() | Despliega un mensaje de información al usuario. |
blur() | Hace perder el foco a la ventana (navegador). |
close() | Cierra el navegador. |
confirm() | Consulta al usuario por si o por no a una pregunta. Devuelve true o false. |
focus() | Entrega el foco a la ventana (navegador). |
moveBy() | Mueve el navegador relativamente a la posición actual. |
moveTo() | Mueve el navegador a una posición absoluta. |
open() | Abre una nueva ventana (Window) del navegador |
print() | Imprime la ventana (Window) o frame actual |
prompt() | Consulta al usuario para que ingrese información. Devuelve esa información. |
resizeBy() | Redimensiona el tamaño del navegador relativo al tamaño actual. |
resizeTo() | Redimensiona el tamaño del navegador a un tamaño dado. |
scrollBy() | Mueve el documento mostrado relativamente a la posición actual. |
scrollTo() | Mueve el documento mostrado a una posición absoluta. |
setInterval() | Ejecuta una función a intervalos regulares. Retorna identidicador “i”. |
clearInterval(i) | Detiene las siguientes ejecuciones de la función lanzada con id: “i”. |
setTimeout() | Ejecuta una función una vez transcurrido un cierto tiempo. Retorna identidicador “i”. |
clearTimeout(i) | Impide la ejecución de la función lanzada con id: “i”. |
Manejador | Descripción |
---|---|
onblur | Invocado cuando la ventana (navegador) pierde foco. |
onerror | Invocado cuando ocurre un error en JavaScript. |
onfocus | Invocado cuando la ventana (navegador) gana el foco. |
onload | Invocado cuando el documento es totalmente cargado. |
onresize | Invocado cuando la ventana (navegador) es redimensionada. |
onunload | Invocado cuando el navegador abandona el documento. |
En el siguiente ejemplo tenemos un cartel que nos hace una pregunta y nos permite si “aceptar” o “no aceptar”, en caso afirmativo la variable que definamos tendrá el valor «verdadero» en caso contrario será «falso», en base a esta pregunta redireccionaremos al usuario o no:
<html><script>
entrar = confirm (‘Pregunta’)
if (entrar == 1){
window.location=»https://cursohacker.es» }
else {
alert («El usuario ha dicho que no») }
</script></html>
Como véis hemos hecho uso del método «confirm» para lanzar una pregunta la usuario, y luego modificanod la propiedad «location» hemos redirigido al usuario a la web cursohacker.es
Propiedades y métodos Objeto Document
Propiedad | Descripción |
---|---|
alinkColor | Un String que especifica el color de los links activados |
anchors[] | Un Array de objetos Anchor. Uno por cada <a name=“…”> … </a> |
applets[] | Un Array de applets Java. Uno por cada applet Java en el documento. |
bgColor | Un String que especifica el color de fondo del cocumento |
cookie | Un String que es el valor de un cookie asociado a este documento. |
domain | Un String que contiene el dominio a donde pertenece el documento. |
embeds[] | Un Array de objetos embebidos. Uno por tag <EMBED> del doc. |
fgColor | Un String que especifica el color de texto del cocumento |
forms[] | Un Array de objetos Form, uno por cada tag <FORM> en el documento |
images[] | Un Array de objetos Image, uno por cada tag <IMG> en el documento. |
lastModified | Un String (solo lectura) que indica la ultima fecha de modificación del doc. |
linkColor | Un String que especifica el color de los links no visitados |
links[] | Un Array de objetos Link, uno por cada <a href=“…”> … </a> |
referrer | Un String (solo lectura) que especifica la URL del doc. con el link a este doc. |
title | Un String (solo lectura) que especifica el título (<TITLE>) del documento. |
URL | Un String (solo lectura) que especifica la URL del documento. |
vlinkColor | Un String que especifica el color de los links visitados (nombre o hexa) |
all | Un Array con todoslos objetos que contiene el documento |
Método | Descripción |
---|---|
close() | Cierra un flujo de documento abierto por open(). |
open() | Abre un flujo para escribir contenido en el documento. |
write() | Inserta el String especificado en el documento. |
writeln() | Igual que write(), pero agrega un carácter de nueva línea al final. |
getElementsByName(nombre) | Retorna todos los elementos html del documento con el nombre que se pase por parámetro. |
getElementsByTagName(nombreTag) | Retorna todos los elemntos html del documento que tengan como tag tagName |
getElementById(nombreId) | Retorna el elemento html del documento con id nombreId. Un id es único por elemento. |
Pasamos a ver algunos ejemplos.
En el primer ejemplo vamos a mostrar por pantalla varios datos interesantes del navegador y finalmente vamos a cerrar la ventana:
<html><body>
<script>
alert(window.navigator.appVersion);
alert(window.navigator.appName);
alert(window.navigator.userAgent);
alert(window.navigator.appCodeName);
alert(window.navigator.platform);
alert(window.screen.width);
alert(window.screen.height);
alert(window.screen.colorDepth);
window.close();
</script>
</body></html>
En el siguiente ejemplo utilizamos una propiedad de “document” para mostrar mediante un alert() de que color es el único link que tenemos en la página.
<html><body link=»#FF0000″>
<a href=»https://cursohacker.es»> CURSOHACKER en ROJO </a>
<script>
alert(document.linkColor);
</script>
</body></html>
Veamos como crear y cerrar ventanas pertenecientes a una misma familia, primero hacemos una una página:
<html><body name =»Ventanita» bgcolor=»green»>
<p>
<input type=»button» value=»Abrir Otra»
onclick=»w=open(‘otra.html’,’_blank’,’menubar’,’status’,’location’,’resi
zable’,false);»>
</p></body></html>
Y luego otra llamada “otra.html” con…
<html><body name =»Cerradora» bgcolor=»red»><p>
<input type=»button» value=»Cierro Ventana inicial»
onclick=»opener.close();»>
</p></body></html>
Observad que cuando se trata de cerrar la ventana “madre” aparece un mensaje de confirmación. Esta es una característica del método close() sólo para cuando se trata de cerrar la ventana “más madre”, es decir la primer ventana, dicho de otra forma: de la que se fueron abriendo todas las demás.
Otro ejemplo en el que vemos como capturar el evento doble click en una página:
<html>
<body ondblclick=»document.write(‘…Has hecho doble click!’);»>
Haz doble click!!!</body></html>
Propiedades y métodos Objeto Link
Propiedad | Descripción |
---|---|
hash | El anchor de la URL especificada en HREF. (incluyendo la marca de hash ‘#’). |
host | Combinación de servidor y puerto de la URL especificada en HREF. |
hostname | El nombre del servidor de la URL especificada en HREF. |
href | La URL completa de especificada en HREF. |
pathname | El camino especificado en la URL de REF.. |
port | El puerto de la URL especificada en HREF. |
protocol | El protocolo de la URL especificada en REF. (incluye los ‘:’). |
search | La búsqueda o consulta de la URL especificada en HREF. (con el signo ‘?’). |
target | La ventana donde debe mostrase la URL especificada en HREF.. |
Manejador | Descripción |
---|---|
onclick | Al hacer click en lo que encierra el link (texto o imagen). |
ondblclick | Al hacer doble click en lo que encierra el link (texto o imagen). |
onmousedown | Al apretar un boton del mouse en lo que encierra el link (texto o imagen). |
onmouseout | Al sacar el ratón fuera de lo que encierra el link (texto o imagen). |
onmouseover | Al mover el ratón dentro de lo que encierra el link (texto o imagen). |
onmouseup | Al soltar un boton del ratón en lo que encierra el link (texto o imagen). |
En este ejemplo vamos a trabajar con dos links en la página:
<html><body>
<a href=»https://cursohacker.es»>Curso Hacker</a>
</br>
<a href=»https://cursohacker.es/forum»>Foro CursoHacker</a>
<script>
alert(document.links[0].host);
alert(document.links[1].host);
</script></body></html>
Otro ejemplo interesante con función del mouse incorporada:
<html><body>
<a onmouseover=»document.write(‘El ratón pasó por encima’);»>
Pasa el ratón por encima </a>
</body></html>
Propiedades, métodos y manejadores Objeto INPUT
Input hereda de HTMLElement y define o sobrescribe las siguientes…
Propiedad | Descripción |
---|---|
checked | Propiedad de L/E que indica el estado de selección para Checkbox y Radio. |
defaultChecked | Propiedad de L que indica en Checkbox y Radio si tienen att. “checked”. |
defaultValue | Propiedad de L que indica el valor inicial de Text, Textarea y Password. |
form | Propiedad de L que contiene una referencia al formulario contenedor. |
length | Propiedad de L/E que indica la cantidad de elems (Options) de un Select. |
name | Propiedad de L que se corresponde con el atributo “name” de HTML. |
options[] | El array de opciones del Select. |
selectedIndex | Propiedad de L/E que indica el nº la opción seleccionada en un Select. |
type | Propiedad de L que indica el tipo del elemento seleccionado. |
value | Propiedad de L/E que se corresponde con el atributo “value” de HTML. |
Método | Descripción |
---|---|
blur() | Quita el foco de teclado del elemento. |
click() | Simula un click de mouse sobre el elemento. |
focus() | Coloca el foco del teclado sobre el elemento. |
select() | Para elementos con texto editable lo selecciona. |
Manejador | Descripción |
---|---|
onblur | Invocado cuando se pierde el foco de teclado sobre el elemento. |
onchange | Para elementos (no botones) se invoca cuando cambia su contenido. |
onclick | Invocado cuando se hace clic sobre el elemento. |
onfocus | Invocado cuando el elemento gana el foco del teclado. |
Un ejemplo en el que cambiamos el valor de un elemento input de tipo botón:
<html><head><script>
function cambiarValue(){
if (document.getElementById(«PEPE»))
document.getElementById(«PEPE»).value=»Pedro»;
else
alert(«NO»);
}
</script>
<body>
<input type=»button» id=»PEPE» value=»Juan»
onclick=»cambiarValue()»;»/>
</body></html>
Propiedades, métodos y manejadores Objeto FORM
Hereda de HTMLElement y define o sobrescribe…
Propiedad | Descripción |
---|---|
action | Propiedad de L/E correspondiente al atributo HTML de igual nombre. |
elements[] | Array con todos los elementos HTML que aparecen en el formulario. |
encoding | Propiedad de L/E correspondiente al atributo “enctype” de HTML. |
length | El número de elementos en el formulario (equivalente a elements.length). |
method | Propiedad de L/E correspondiente al atributo HTML de igual nombre. |
name | Propiedad de L/E correspondiente al atributo HTML de igual nombre. |
target | Propiedad de L/E correspondiente al atributo HTML de igual nombre. |
Método | Descripción |
---|---|
reset() | Resetea el formulario a los valores de los elementos por defecto. |
submit() | Envía el formulario a la url indicada por “action” |
Manejador | Descripción |
---|---|
onreset | Invocado previo al reseteo del formulario. Si se retorna “false” no se resetea. |
onsubmit | Invocado previo al envío del formulario. Si se retorna “false” no se envía (evento muy utilizado para validar campos antes de enviar el formulario). |
Y un pequeño ejemplo de uso:
<html><head><script>
function mostrarUsuario(formulario){
document.writeln («El usuario es: » +formulario.usu.value);
}
</script>
</head>
<body>
<form action=»index.html» method=»get»
onsubmit=»mostrarUsuario(this);»>
USUARIO: <input type=»text» id=»usu» name=»usuario» value=»»>
</br>
<input type=»radio» id=»hom» name=»sex» value=»male»> hombre
</input>
</br>
<input type=»radio» id=»fem» name=»sex» value=»female»>
mujer</input>
</br>
<input type=»submit» value=»ENVIAR»>
</br>
<select name=»color»>
<optgroup label=»colores primarios»>
<option value=»red»>rojo </option>
<option value=»green»>verde </option>
</optgroup>
<option value=»blue»>azul </option>
</select></form></body></html>
Objetos HTML de Formularios
En este apartado vamos a ver los distintos objetos HTML que pueden estar dentro de un formulario:
Objeto | Tag HTML | Propiedad “type” | Evento principal |
---|---|---|---|
Button | <input type =“button”> | “button” | onclick. |
Checkbox | <input type =checkbox> | “checkbox” | onclick. |
FileUpload | <input type =file> | “file” | onchange. |
Hidden | <input type =hidden> | “hidden” | NO TIENE |
Option | <option> | NO TIENE | NO TIENE |
Password | <input type =password> | “password” | onchange. |
Radio | <input type =radio> | “radio” | onclick. |
Reset | <input type =reset> | “reset” | onclick. |
Select | <select multiple> | “selectmultiple” | onchange. |
Submit | <input type =submit> | “submit” | onclick. |
Text | <input type =text> | “text” | onchange. |
Textarea | <textarea> | “textarea” | onchange. |
Controlando la página web con javascript
Con todos estos datos ya estás en posicón para poder acceder meidante javascript a cualquier elemento de la página web, y no solo eso, además puedes abrir páginas en el navegador que está ejecutando tus scripts y leer la información que hay en dichas páginas que has abierto. En publicaciones posteriores veremos cómo detectar vulnerabilidades que permitan realizar inyecciones de código javascript. Pero para ello antes debes tener muy claro lo que puedes y lo que no, hacer con javascript accediendo al DOM.