Sei sulla pagina 1di 244

El problema de la seguridad en el

software
[1.1] ¿Cómo estudiar este tema?

[1.2] Introducción al problema de la seguridad en el software

[1.3] Vulnerabilidades y su clasificación

[1.4] Propiedades software seguro

[1.5] Referencias

TEMA
El problema de la seguridad del software
Esquema

TEMA 1 – Esquema
Introducción al problema de Vulnerabilidades y su Propiedades software seguro
seguridad del software clasificación

Ciclo de vida de una vulnerabilidad Esenciales:


Confidencialidad
Integridad
Gestión de vulnerabilidades Disponibilidad

2
Clasificación de vulnerabilidades Complementarias:
Fiabilidad
Escáneres de vulnerabilidades
Autenticación
Trazabilidad
Robustez
Resiliencia
Tolerancia
Seguridad en el Software

© Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Ideas clave

1.1. ¿Cómo estudiar este tema?

Para estudiar este tema lee las Ideas clave que te presentamos a continuación.

Actualmente las tecnologías de seguridad red pueden ayudar a aliviar y mitigar los
ciberataques, pero no resuelven el problema de seguridad real ya que una vez que el
ciberatacante consigue vencer esas defensas, por ejemplo mediante ingeniería social, y
comprometer una máquina del interior, a través de la misma podrá atacar las demás
empezando por las más vulnerables. Se hace necesario por tanto, el disponer de software
seguro que funcione en un entorno agresivo y malicioso.

El objetivo del presente tema es introducir al alumno en los principales conceptos que
abarca la seguridad del software, en cuanto a los beneficios que produce, su
importancia en la seguridad global de un sistema, las vulnerabilidades como principal
fuente de inseguridad en el software y propiedades de un software seguro.

1.2. Introducción al problema de la seguridad en el software

Hoy en día, los ataques cibernéticos son cada vez más frecuentes, organizados y
costosos en el daño que infligen a las administraciones públicas, empresas privadas,
redes de transporte, redes de suministro y otras infraestructuras críticas desde la energía
a las finanzas, hasta el punto de poder llegar a ser una amenaza a la prosperidad, la
seguridad y la estabilidad de un país.

En la figura-1 se puede observar un gráfico cualitativo en el que se muestran diversos


incidentes ocurridos a lo largo de los últimos doce años en relación con su nivel de
complejidad. Como se puede observar la amenaza es creciente con los años y cada
vez su nivel de complejidad es mayor.

TEMA 1 – Ideas clave 3 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Figura 1. Incidentes de seguridad.

La sociedad está cada vez más vinculada al ciberespacio, un elemento importante del
mismo lo constituye el software o las aplicaciones que proporcionan los servicios,
utilidades y funcionalidades. Sin embargo estas aplicaciones presentan defectos,
debilidades de diseño o configuraciones inseguras que originan
vulnerabilidades pueden ser explotadas por atacantes de diversa índole desde
aficionados hasta organizaciones de cibercrimen o incluso estados en acciones de
ciberguerra, utilizándolas como plataformas de ataque comprometiendo los sistemas y
redes de la organización.

Nadie quiere software defectuoso, especialmente los desarrolladores, cuyo código


incorrecto es el problema. En un informe de Klocwork (2004) se indica que las
principales causas de la aparición de vulnerabilidades son las siguientes:

» Tamaño excesivo y complejidad de las aplicaciones.


» Mezcla de código proveniente de varios orígenes como compras a otra compañía,
reutilización de otros existentes, etc., lo que puede producir comportamientos e
interacciones no esperados de los componentes del software.
» Integración de los componentes del software defectuosa, estableciendo
relaciones de confianza inadecuadas entre ellos, etc.
» Debilidades y fallos en la especificación de requisitos y diseño no basados
en valoraciones de riesgo y amenazas.
» No realización de pruebas seguridad basadas en riesgo.

TEMA 1 – Ideas clave 4 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Uso entornos de ejecución con componentes que contienen vulnerabilidades


o código malicioso embebido, como pueden ser capas de middleware, sistema
operativo u otros componentes COTS.
» Falta de la herramientas y un entorno de pruebas adecuados que simule
adecuadamente el real de ejecución.
» Cambios de requisitos del proyecto durante la etapa de codificación.
» Mezcla de equipos de desarrolladores, entre los que podemos tener, equipos
propios de desarrollos, asistencias técnicas, entidades subcontratadas, etc.
» Falta de conocimiento de prácticas de programación segura de los
desarrolladores en el uso de lenguajes de programación propensos a cometer errores
como C y C++ y utilización de herramientas de desarrollo inadecuadas.
» No control de la cadena de suministro del software, lo puede dar lugar a la
introducción de código malicioso en origen.
» No seguimiento, por los desarrolladores, de guías de normalizadas de estilo en
la codificación.
» Fechas límite de entrega de proyectos inamovibles.
» Cambio en la codificación en base al requerimiento de nuevas funcionalidades.
» Tolerancia a los defectos.
» No tener actualizadas las aplicaciones en producción con los parches
correspondientes, configuraciones erróneas, etc.

Las aplicaciones son amenazadas y atacadas, no solo en su fase de operación, sino que
también en todas las fases de su ciclo de vida (Goertzel. 2009):

» Desarrollo. Un desarrollador puede alterar de forma intencionada o no el software bajo


desarrollo de forma que se comprometa su fiabilidad futura durante la fase de operación.
» Distribución e instalación. Ocurre cuando no se protege el software evitando
manipulaciones antes de enviarlo o publicarlo. Del mismo modo, si el instalador del
software no bastiona la plataforma en la que lo instala o la configura de forma
insegura, queda vulnerable a merced de los atacantes.
» Operación. Cualquier software que se ejecuta en una plataforma conectada a la red
tiene sus vulnerabilidades expuestas durante su funcionamiento. El nivel de
exposición variará dependiendo de si la red es privada o pública, conectada o no a
Internet, y si el entorno de ejecución del software ha sido configurado para
minimizar sus vulnerabilidades.

TEMA 1 – Ideas clave 5 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Mantenimiento o sostenimiento. No publicación de parches de las


vulnerabilidades detectadas en el momento oportuno o incluso introducción de
código malicioso por el personal de mantenimiento en las versiones actualizadas del
código.

Según el informe «2011 Top Cyber Security Risks Report», las vulnerabilidades
detectadas en aplicaciones alcanzaron su punto máximo en el año 2006 iniciando a partir
de ese año un lento declive, como vemos en la figura 2.

Figura 2. Vulnerabilidades descubiertas por OSVDB (Vulnerability information from the Open Source
Vulnerability Database), 2000–2011.

Esta disminución de vulnerabilidades detectadas no significa que el software sea cada


vez más seguro, es una sensación de seguridad falsa, pues el número de
vulnerabilidades de alta severidad está creciendo a un ritmo más rápido que los otros
niveles de vulnerabilidad (CVSS 8 a 10, clasificación definida en la OSVDB ─
http://osvdb.org/ ─). En la figura 3 se pone de manifiesto cómo el porcentaje de
vulnerabilidades de alta severidad se ha incrementado en los últimos 10 años.

Common Vulnerability Scoring System (CVSS). Es un sistema que categoriza la severidad


de una vulnerabilidad, de manera estricta a través de fórmulas, proporcionando un
estándar para comunicar las características y el impacto de una vulnerabilidad en el
software.

TEMA 1 – Ideas clave 6 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Figura 3. Gravedad de las vulnerabilidades OSVDB en 10 años.

Las vulnerabilidades de alta severidad dan lugar a que un atacante pueda


explotarlas rápidamente y hacerse con el control total del sistema. Su explotación
requiere un conocimiento poco especializado de la aplicación al alcance, no solo de
organizaciones cibercriminales, si no de cualquiera con conocimientos de informática.

En el informe HP Security Research del año 2015, se incluye un gráfico que muestra la
vulnerabilidades descubiertas durante el año 2014, en él se indica que la aplicación más
explotada fue Internet Explorer debido a la vulnerabilidad CVE-2014-0322 del tipo use
affter free, es decir, uso de la memoria después de liberarla, del producto Adobe Flash
El exploit fue visto por primera vez en la operación SnowMan, dirigido a entidades del
gobierno de Estados Unidos y sus compañías de defensa.

Figura 4. Vulnerabilidades descubiertas en el año 2014.

Otros aspectos importantes que influyen en el número de vulnerabilidades conocidas de


una aplicación son: su complejidad, su extensión en líneas de código y el nivel exposición
a los ataques, en este sentido las aplicaciones web en Internet, son las que tienen más

TEMA 1 – Ideas clave 7 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

probabilidades de ser atacadas y, por tanto, suelen tener mayor número de


vulnerabilidades conocidas.

Además, a pesar de los datos convincentes de lo contrario, erróneamente se sigue


confiando en que la implantación de tecnologías y dispositivos de seguridad de
red como cortafuegos, sistemas de gestión y correlación de eventos (SIEM─ Sistema de
Centralización y Monitorización de la Información de Eventos y datos infraestructura
como, logs, etc.─), sistemas de detección de intrusos, sistemas de gestión de acceso y
cifrado del tráfico, etc., son medidas suficientes para proteger los sistemas de la
organización. Los atacantes buscan el descubrimiento de fallos en el software
relacionados con la seguridad del sistema, que den lugar a una vulnerabilidad explotable.

En base a lo expuesto anteriormente, se considera necesario que las diferentes


organizaciones públicas o privadas dispongan de software fiable y resistente a los
ataques, es decir de confianza, con número de vulnerabilidades explotables que
sea el mínimo posible.

En respuesta a lo expuesto anteriormente nace la Seguridad del Software, en el


documento de referencia de SAFECode se define como: «La confianza que el software,
hardware y servicios están libres de vulnerabilidades intencionadas o no intencionadas
y que funcionan conforme a lo especificado y deseado» (SafeCode, 2011).

El Departamento de Defensa de los Estados Unidos (DoD) la define como «El nivel de
confianza de que el software funciona según lo previsto y está libre de vulnerabilidades,
ya sean intencionada o no, diseñada o insertada en el marco de su ciclo de vida de
desarrollo».

En este sentido, en base a la definición anterior y los párrafos anteriores, se puede definir
la seguridad del software como:

«El conjunto de principios de diseño y buenas prácticas a implantar en el SDLC,


para detectar, prevenir y corregir los defectos de seguridad en el desarrollo y
adquisición de aplicaciones, de forma que se obtenga software de confianza y
robusto frente ataques maliciosos, que realice solo las funciones para las
que fue diseñado, que esté libre de vulnerabilidades, ya sean intencionalmente
diseñadas o accidentalmente insertadas durante su ciclo de vida y se asegure su
integridad, disponibilidad y confidencialidad».

TEMA 1 – Ideas clave 8 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Hasta principios de la década anterior, la mayoría de las aplicaciones se desarrollaban


sin tener en cuenta requisitos y pruebas de seguridad específicos. Los desarrolladores de
software no eran conscientes de las vulnerabilidades que se pueden crear al programar
y descuidaban los aspectos de seguridad, dando primacía al cumplimiento de las
especificaciones funcionales, sin tener en cuenta casos en los que el software fuera
maliciosamente atacado. Este proceso de desarrollo de software ofrece, aparte de los
errores no intencionados producidos al codificar, oportunidades de insertar código
malicioso en el software en origen.

Como se ha comentado anteriormente, las tecnologías de seguridad red pueden ayudar


a aliviar los ataques, pero no resuelven el problema de seguridad real, ya que una
vez que el ciberatacante consigue vencer esas defensas, por ingeniería social por ejemplo,
mediante ingeniería social, y comprometer una máquina del interior, a través de la
misma podrá atacar a otras de la red (pivoting) empezando por las más vulnerables. Este
es el caso de las Amenazas Avanzadas Persistentes (APT) uno de los ciberataques más
peligrosos y dañinos de hoy en día. Se hace necesario por tanto el disponer de
software seguro que funcione en un entorno agresivo y malicioso.

APT
Tipo sofisticado de ciberataque organizado, de rápida progresión y largo plazo,
diseñado específicamente para acceder y obtener información de los sistemas de la
organización objetivo.

Un aspecto importante de la seguridad del software es la confianza y garantía de


funcionamiento conforme a su especificación y diseño y de que es lo
suficientemente robusto para soportar las amenazas que puedan comprometer su
funcionamiento esperado en su entorno de operación.

Para conseguir lo anterior y minimizar al máximo los ataques en la capa de


aplicación y, por tanto, en número de vulnerabilidades explotables, es
necesario el incluir la seguridad desde principio en el ciclo de vida de
desarrollo del software (SDLC), incluyendo requisitos, casos de abuso, análisis de
riesgo, análisis de código, pruebas de penetración dinámicas, etc. En este sentido es
importante el aprovechamiento de las buenas prácticas de ingeniería de
software ya existentes.

TEMA 1 – Ideas clave 9 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Un beneficio importante que se obtendría de incluir un proceso sistemático que


aborde la seguridad desde las primeras etapas del SDLC, sería la reducción
de los costes de corrección de errores y vulnerabilidades, pues estos son más
altos conforme más tarde son detectados. Acorde a lo publicado por NIST (National
Institute of Standards and Technology), el coste que tiene la corrección de código o
vulnerabilidades después de la publicación de una versión, es hasta treinta veces
mayor que su detección y corrección en etapas tempranas del desarrollo.

Figura 5. Coste relativo de corrección de vulnerabilidades en función de la etapa de desarrollo. Fuente:


http://www.microsoft.com/security/sdl/learn/costeffective.aspx

En el informe de Klocwork (2004), se incluye a su vez una figura en el coste que tiene la
corrección de código o vulnerabilidades después de la publicación de una versión es
incluso 100 veces mayor. Se basan en ratios desarrollados por Barry Boehm de la
Universidad del Sur de California.

TEMA 1 – Ideas clave 10 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Figura 6. Efectos de la detección de defecto tardía. Fuente: Klocwork Inc. (2004).

1.3. Vulnerabilidades y su clasificación

Vulnerabilidad
Es un fallo de programación, configuración o diseño que permite, de alguna
manera, a los atacantes, de alguna manera, alterar el comportamiento normal de un
programa y realizar algo malicioso como alterar información sensible, interrumpir o
destruir una aplicación o tomar su control.

Se puede decir que son un subconjunto del fenómeno más grande que constituyen los
bugs de software.

TEMA 1 – Ideas clave 11 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Sus fuentes se deben a:

» Fallos de implementación. Fallos provenientes de la codificación de los diseños


del software realizados. Como ejemplos tenemos desbordamientos de búfer, formato,
condiciones de carrera, path traversal, cross-site scripting, inyección SQL, etc.
» Fallos de diseño. Los sistemas hardware o software contienen frecuentemente
fallos de diseño o debilidades (flaws) que pueden ser utilizados para realizar un
ataque. Por ejemplo TELNET no fue diseñado para su uso en entornos hostiles, para
eso se implementó SSH.
» Fallos de configuración. La instalación de software por defecto implica por lo
general la instalación de servicios que no se usan, pero que pueden presentar
debilidades que comprometan la máquina.

Tipos de vulnerabilidades del software

Fallos de implementación

Fallos de diseño

Fallos de configuración

Casi todos los fallos que se producen en un software provienen de fallos de


implementación y diseño, pero solamente algunos resultan ser vulnerabilidades de
seguridad. Un fallo debe tener algún impacto o característica relevante para ser
considerado un error de seguridad, es decir tiene que permitir a los atacantes la
posibilidad de lanzar un exploits que les permita hacerse con el control de un sistema.

Exploits
Es una instancia particular de un ataque a un sistema informático que aprovecha una
vulnerabilidad específica o un conjunto de ellas.

Una vulnerabilidad se define (INTECO, 2011), básicamente, por cinco factores o


parámetros que deben identificarla.

» Producto: productos a los que afecta, versión o conjunto de ellas.


» Dónde: Componente o módulo del programa donde se localiza la vulnerabilidad.
» Causa y consecuencia: Fallo técnico concreto que cometió el programador a la hora
de crear la aplicación que es el origen de la vulnerabilidad.

TEMA 1 – Ideas clave 12 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Impacto: Define la gravedad de la vulnerabilidad, indica lo que puede conseguir un


atacante que la explotase.
» Vector: Técnica del atacante para aprovechar la vulnerabilidad se le conoce como
«vector de ataque».

El ciclo de vida de una vulnerabilidad

El ciclo de vida de una vulnerabilidad consta de las siguientes fases:

» Descubrimiento: detección de un fallo en el software que puede producirse durante


el desarrollo del mismo o una vez está en producción.
» Utilización: Los agentes maliciosos desarrollan el exploit adecuado para poder
lanzar ataques.
» Verificación inicial de la vulnerabilidad: una vez se recibe una notificación de error
esta será aceptada para su tratamiento comprobando su veracidad, o bien será
rechazada en caso de que no se pueda reproducirse y se compruebe no existe.
» Solución: los programadores del software buscan solución en entornos controlados.
» Difusión: los medios de comunicación dan publicidad al incidente.
» Medidas: si es posible las organizaciones afectadas toman medidas para mitigar las
posibles pérdidas.
» Corrección y nueva verificación: el proceso de corrección de la vulnerabilidad,
llevado a cabo por programadores, será verificado nuevamente de manera iterativa
hasta comprobar la resolución del error.
» Búsqueda. Los técnicos buscan vulnerabilidades similares (el ciclo vuelve a
comenzar).
» Actualización: Los sitios no actualizados vuelven a ser víctimas.

Descubrir Utilización Verificación Solución Difusión Medidas Corrección Búsqueda Actualizar

Figura 7. Ciclo de vida una vulnerabilidad.

En la siguiente figura se muestra un gráfica que representa el riesgo en función de los


tiempos tardados en parchear la vulnerabilidad de una aplicación, como se puede
observar el riesgo aumenta de forma muy rápida desde que se descubre la vulnerabilidad
hasta que se parchea.

TEMA 1 – Ideas clave 13 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Figura 8. Riesgo de una vulnerabilidad en función del tiempo. Fuente:


http://resources.computerworld.com/ccd/assets/61660/detail

Gestión de vulnerabilidades

Dada la gran cantidad de vulnerabilidades descubiertas se hace necesario el disponer de


estándares que permitan referenciarlas unívocamente, para poder conocer su gravedad
de forma objetiva y obtener el conocimiento necesario para mitigarlas.

Existen varios estándares, catálogos o bases de datos, que a continuación pasamos a


comentar:

» Common Vulnerabilities and Exposures (CVE) (http://cve.mitre.org). Es un


diccionario o catálogo público de vulnerabilidades, administrado por MITRE, que
normaliza su descripción y las organiza desde diferentes tipos de vista
(vulnerabilidades Web, de diseño, implementación, etc.).

TEMA 1 – Ideas clave 14 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

MITRE
Organización sin ánimo de lucro, de carácter público que trabaja en las áreas de
ingeniería de sistemas, tecnologías de la información, concepto de operación y
modernización de empresas

Cada identificador CVE incluye:

o Identificador con el siguiente formato:

CVE-2012-4212

CVE, seguido del año en el que se asignó el código a la vulnerabilidad.

Número de cuatro cifras que identifica la vulnerabilidad en el año.

Figura 9. Identificador CVE

o Breve descripción de la vulnerabilidad.


o Referencias.

» Common Vulnerability Scoring System (CVSS) (http://nvd.nist.gov/cvss.cfm).


Es básicamente un sistema que escalona la severidad de una vulnerabilidad, de
manera estricta a través de fórmulas, proporcionando un estándar para comunicar las
características y el impacto de una vulnerabilidad identificada con su código CVE. Su
modelo cuantitativo asegura una medición exacta y repetible a la vez que permite ver
características subyacentes que se usaron para generar su puntuación.

Permite organizar la priorización de las actividades de remediación o parcheo de las


vulnerabilidades. En la figura se muestra el proceso de cálculo de una severidad:

TEMA 1 – Ideas clave 15 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Figura 10. Cálculo puntuación CVSS.

El cálculo se realiza en base a tres tipos de métricas base, temporales y ambientales,


siendo las dos últimas opcionales. En cuanto a las métricas base se tienen dos
subconjuntos

o Explotabilidad: vectores de acceso, complejidad de acceso y autenticación.


o Impacto: confidencialidad, integridad y disponibilidad.

» Vulnerability information from the Open Source Vulnerability Database


(OSVDB) (http://osvdb.org). Proporciona una radiografía excelente de las
vulnerabilidades existentes, particularmente de aplicaciones. Sin embargo, debido a
la naturaleza de los informes vulnerabilidad, OSVDB solo puede contar con las
vulnerabilidades que se hagan públicas o se hayan insertado directamente en la base
de datos por particulares.
» Common Vulnerability Reporting Framework (CVRF). Es un formato XML
que permite compartir información crítica sobre vulnerabilidades en un esquema
abierto y legible por cualquier equipo. Hasta el momento no había ningún estándar
para informar de vulnerabilidades de los sistemas de la Tecnologías de la Información
y Comunicaciones (TIC), este viene a cubrir una necesidad manifestada por los
distintos actores de la industria, organismos de investigación y de la administración
en cuanto a un marco común, ya que hasta ahora, cada proveedor creaba sus informes
según su criterio. La disponibilidad de CVRF acelera el intercambio y procesamiento
de información entre distintas plataformas.
Originalmente deriva del proyecto Incident Object Description Exchange Format
(IODEF), su propósito es el reemplazar los múltiples formatos previamente en uso no
estándar de presentación de informes, lo que permite acelerar el intercambio de
información y proceso.

TEMA 1 – Ideas clave 16 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» National Vulnerability Database (NVD) (http://nvd.nist.gov/). Base de datos


del gobierno estadounidense que permite la automatización de la gestión
vulnerabilidades y la medición del nivel de riesgo. Incluye bases de datos con listas de
comprobación de configuraciones de seguridad de productos, defectos de seguridad
del software relacionados, malas configuraciones, los nombres de producto y
métricas de impacto. Contiene:

o 54337 CVE Vulnerabilidades.


o 202 Listas de comprobación de configuraciones de seguridad de productos.
8140 Consultas a OVAL.

Open Vulnerability and Assessment Languajes (OVAL)


Esfuerzo de comunidad internacional para normalizar los informes de seguridad de
vulnerabilidades y estado de seguridad de un sistema TIC. Incluye un lenguaje de
codificación de los detalles de sistema. http://oval.mitre.org/

» Common Weakness Enumeration (CWE) (http://cwe.mitre.org/). Estándar


International y de libre uso que ofrece un conjunto unificado de debilidades o defectos
del software medibles, que permite un análisis, descripción, selección y uso de
herramientas de auditoría de seguridad de software y servicios que pueden encontrar
debilidades en el código fuente y sistemas, así como una mejor comprensión y gestión
de los puntos débiles de un software relacionados con la arquitectura y el diseño. Sus
principales objetivos son:

o Proporcionar un lenguaje común para describir los defectos y debilidades de


seguridad de software en su arquitectura, diseño y codificación.
o Proporcionar un estándar de comparación de herramientas de auditoría seguridad
de software.
o Proporcionar una línea base para la identificación de vulnerabilidades, su
mitigación y los esfuerzos de prevención.

En la figura siguiente se puede ver un diagrama de contexto de las diferentes


organizaciones y estándares que usan CWE.

TEMA 1 – Ideas clave 17 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Figura 11. Diagrama de contexto de CWE. Fuente: http://cwe.mitre.org/

Incluye los siguientes tipos de debilidades del software: desbordamientos del búfer,
formato de cadenas, estructura y problemas de validación, errores de ruta, interfaz de
usuario, autenticación, gestión de recursos, manipulación de datos, verificación de
datos, inyección de código, etc.

Cada identificador CWE incluye los siguientes campos de información:

Figura 12. Campos de información de cada entrada CWE.

TEMA 1 – Ideas clave 18 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Clasificación de las vulnerabilidades

Existen muchas clasificaciones o taxonomías de vulnerabilidades unas se adaptan a todo


tipo de aplicaciones, como son MITRE Top 25 y SANS Top 20 y otras solo a aplicaciones
web como son OWASP Top 10 y WASC Threat Clasification v2.0. A continuación
describimos algunas de las mencionadas.

Consulta aquí más información sobre las diferentes clasificaciones:


» MITRE Top 25: http://cwe.mitre.org/top25/
» SANS Top 20: http://www.sans.org/top20/
» OWASP Top 10: http://www.owasp.org/images/e/e8/OWASP_Top_10_2007.pdf
» WASC Threat Clasification v2.0: http://www.webappsec.org/projects/threat/

» MITRE TOP 25. La lista es el resultado de la colaboración entre el Instituto SANS,


MITRE y muchos de los mejores expertos en software de EE.UU. y Europa. Contiene
los mayores errores de programación que pueden causar vulnerabilidades en el
software. Es una herramienta destinada a ayudar a los programadores y auditores de
seguridad del software, para prevenir este tipo de vulnerabilidades que afectan a la
industria de las TIC.

o Todo tipo de aplicaciones Web y no Web.


o Dan lugar a vulnerabilidades graves en el software.
o Prevención, mitigación y principios de programación seguros.

En la siguiente tabla se pueden consultar las 25 principales vulnerabilidades:

RANK ID NOMBRE
Improper Neutralization of Special Elements used in an SQL
[1] CWE-89
Command ('SQL Injection')
Improper Neutralization of Special Elements used in an OS
[2] CWE-78
Command ('OS Command Injection')
Buffer Copy without Checking Size of Input ('Classic Buffer
[3] CWE-120
Overflow')
Improper Neutralization of Input During Web Page Generation
[4] CWE-79
('Cross-site Scripting')
[5] CWE-306 Missing Authentication for Critical Function
[6] CWE-862 Missing Authorization
[7] CWE-798 Use of Hard-coded Credentials
[8] CWE-311 Missing Encryption of Sensitive Data

TEMA 1 – Ideas clave 19 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

[9] CWE-434 Unrestricted Upload of File with Dangerous Type


[10] CWE-807 Reliance on Untrusted Inputs in a Security Decision
[11] CWE-250 Execution with Unnecessary Privileges
[12] CWE-352 Cross-Site Request Forgery (CSRF)
Improper Limitation of a Pathname to a Restricted Directory
[13] CWE-22
('Path Traversal')
[14] CWE-494 Download of Code Without Integrity Check
[15] CWE-863 Incorrect Authorization
[16] CWE-829 Inclusion of Functionality from Untrusted Control Sphere
[17] CWE-732 Incorrect Permission Assignment for Critical Resource
[18] CWE-676 Use of Potentially Dangerous Function
[19] CWE-327 Use of a Broken or Risky Cryptographic Algorithm
[20] CWE-131 Incorrect Calculation of Buffer Size
[21] CWE-307 Improper Restriction of Excessive Authentication Attempts
[22] CWE-601 URL Redirection to Untrusted Site ('Open Redirect')
[23] CWE-134 Uncontrolled Format String
[24] CWE-190 Integer Overflow or Wraparound
[25] CWE-759 Use of a One-Way Hash without a Salt
Veinticinco vulnerabilidades MITRE TOP 25. Fuente: MITRE (2011).

Para cada entrada de la tabla se proporciona la siguiente información:

o Clasificación. La clasificación de la debilidad CVSS.


o Identificador CWE.
o Información adicional sobre la debilidad que puede ser útil para adoptar decisiones
de priorización de acciones de mitigación.
o Breve discusión informal sobre la naturaleza de la debilidad y de sus
consecuencias.
o Los pasos que los desarrolladores pueden tomar para mitigar o eliminar las
debilidades.
o Otras entradas CWE que están relacionadas con la debilidad Top 25.
o Entradas estándar CAPEC (lista de patrones comunes de ataque junto con un
esquema integral y taxonomía de clasificación) sobre los ataques que pueden
llevarse a cabo con éxito contra la debilidad.
o Enlaces con más detalles, incluyendo ejemplos de código fuente que demuestran la
debilidad, métodos de detección, etc.

TEMA 1 – Ideas clave 20 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» SANS Top 20. Es una lista de vulnerabilidades que requieren solución inmediata.
Es el resultado de un proceso que reunió a docenas de expertos líderes en seguridad.
Incluye instrucciones paso a paso y notas para información adicional útiles para
corregir los defectos de seguridad. Se actualiza la lista y las instrucciones en la medida
que más amenazas sean identificadas.

o Vulnerabilidades en servidores, aplicaciones web, aplicaciones comerciales/open


source.
o No tiene en cuenta las aplicaciones propietarias.

» OWASP Top 10. Su objetivo es crear conciencia sobre la seguridad de las


aplicaciones web mediante la identificación de algunos de los riesgos más críticos que
enfrentan las organizaciones.

o Las 10 vulnerabilidades de seguridad más críticas en aplicaciones web.


o Lista ordenada por criticidad y predominio.
o Representa una lista concisa y enfocada sobre los diez riesgos más críticos sobre
seguridad en aplicaciones.

Consulta en la página 6 del siguiente documento los riesgos de seguridad en aplicaciones


web:
https://www.owasp.org/images/2/2d/OWASP_Top_10_-_2010_FINAL_(spanish).pdf

» WASC Threat Clasification v2.0. Es un esfuerzo de cooperación para aclarar y


organizar las amenazas a la seguridad de un sitio web. Es un proyecto para desarrollar
y promover estándares para la industria y su principal propósito es el crear un
lenguaje consistente y las definiciones de los problemas de seguridad relacionados
con las aplicaciones web.

o Unificación y organización de las amenazas de seguridad Web.


o Describe amenazas, debilidades y ataques.

Escáneres de vulnerabilidades

Este tipo de herramientas analizan los sistemas en busca de vulnerabilidades conocidas.


Disponen de información sobre vulnerabilidades existentes en las versiones de los

TEMA 1 – Ideas clave 21 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

sistemas operativos y aplicaciones almacenadas y actualizadas en una base de datos, que


utiliza para la detección de las mismas.

La herramienta más utilizada es Nessus, inicialmente de código abierto y versión


gratuita, y actualmente en dos versiones, la 4.x en la que el nuevo código es cerrado, y la
versión 2.x (www.nessus.org) que continúa siendo software libre. A raíz de este cambio
se crearon tres proyectos diferentes a partir de la versión libre, Sussen, Porz-Wahn y
OpenVas (inicialmente GNessUs). Actualmente el proyecto Porz-Wahn se unió con
OpenVas (http://www.openvas.org/), la cual continúa actualizando versiones para las
distintas distribuciones de GNU/Linux. Otras herramientas de extendido uso son
Nexpose de Rapid 7 (www.rapid7.com/products/nexpose), ISS Real Secure, Nmap y
Retina.

1.4. Propiedades software seguro

Básicamente se tienen dos conjuntos de propiedades que definen a un software seguro


del que no lo es, las primeras son las esenciales, comunes a la seguridad de cualquier
sistema, cuya ausencia afecta gravemente a la seguridad de una aplicación y un segundo
conjunto, complementarias a las anteriores que no influyen en su seguridad, pero que
ayudan a mejorarla en gran medida.

Las principales propiedades esenciales que distinguen al software de confianza del


que no es, son:

» Integridad. Capacidad que garantiza que el código, activos manejados,


configuraciones y comportamiento no pueda ser o no haya sido modificado o
alterado por personas, entidades o procesos no autorizados tanto durante la fase
de desarrollo como en la fase de operación. Entre las modificaciones que se
pueden realizar tenemos sobreescritura, inclusión de puertas traseras, borrado,
corrupción de datos, etc. Como ejemplo de técnicas y mecanismos que se tienen para
salvaguardar la integridad, tenemos:

o Identificación del modo de trasmisión y procesado de los datos por la aplicación.


o Uso de técnicas de cifrado para asegurar que los componentes y los datos nos son
alterados o corrompidos.
o Estricta gestión de sesiones.

TEMA 1 – Ideas clave 22 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

o Uso de sistemas de monitorización de la integridad


o Uso de firma digital.
o Trasmisión cifrada de los datos.

» Disponibilidad. Capacidad que garantiza que el software es operativo y


accesible por personas, entidades o procesos autorizados de forma que se pueda
acceder a la información y a los recursos o servicios que la manejan, conforme a las
especificaciones de los mismos. Entre las técnicas y mecanismos que se tienen para
salvaguardar la disponibilidad, tenemos por ejemplo:

o Análisis de qué servicios e información es crítica y el modo de tenerlos disponibles.


o Uso de arquitecturas de alta disponibilidad, con diferentes tipos de redundancias.
o Uso de sistemas distribuidos con sistemas de réplica de información entre ellos.
o Uso de sistemas de recuperación a través de imágenes, virtualización, etc.

» Confidencialidad. Capacidad de preservar que cualquiera de sus características,


activos manejados están ocultos a usuarios no autorizados, de forma que se
garantice que solo las personas, entidades o procesos autorizados pueden acceder a la
información.

Entre las técnicas y mecanismos que se tienen para salvaguardar la


confidencialidad, tenemos por ejemplo:

o Clasificación de las aplicaciones y servicios en base a su criticidad.


o Tráfico de relleno.
o Técnicas de control de acceso a los sistemas basado en roles.
o El cifrado de la información y de las comunicaciones.

Figura 13. Propiedades esenciales de la seguridad del software.

TEMA 1 – Ideas clave 23 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Un ejemplo de ataque podría ser un desbordamiento de buffer (buffer overflow)


consiguiendo el control total de la máquina, pudiendo violar las tres propiedades
anteriores al poder robar información del sistema, cuentas de usuario, corromper
ficheros del sistema e incluso apagar la máquina y borrar los ficheros necesarios para
que no vuelva a arrancar.

Estas tres primeras serían las propiedades fundamentales esenciales mínimas que
debería disponer todo software, a las que habría que añadir las siguientes
complementarias:

» Fiabilidad. Capacidad del software de funcionar de la forma esperada en


todas las situaciones a la que estará expuesto en su entorno de
funcionamiento, es decir que la posibilidad de que un agente malicioso pueda
alterar la ejecución o resultado de una manera favorable para el atacante está
significativamente reducida o eliminada.

En este sentido en el documento de referencia (Allen, J. H.; Barnum. S.; Ellison, R. J.;
McGraw, G.; Mead, N. R., 2008), se indica la necesidad de comprobar el
comportamiento del software bajo una gran variedad de condiciones entre las que al
menos deben ser las siguientes:

o Batería de ataques lanzados contra el software.


o Entradas y salidas del software (señales, ficheros de datos, texto, etc.) que puedan
ser comprometidas.
o Interfaces del software a otras entidades que puedan ser comprometidas.
o Ejecución del software en un ambiente hostil donde sea atacado.

» Autenticación. Capacidad que permite a un software garantizar que una


persona, entidad o proceso es quien dice ser o bien que garantiza la fuente
de la que proceden los datos.
» Trazabilidad. Capacidad que garantiza la posibilidad de imputar las acciones
relacionadas en un software a la persona, entidad o proceso que la ha
originado.
» Robustez. Capacidad de resistencia a los ataques realizados por los agentes
maliciosos (malware, hackers, etc.).

TEMA 1 – Ideas clave 24 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Resiliencia. Capacidad del software de aislar, contener y limitar los daños


ocasionados por fallos causados por la explotación de una vulnerabilidad del mismo
y recuperarse reanudando su operación en o por encima de cierto nivel
mínimo predefinido de servicio aceptable en tiempo oportuno.
» Tolerancia. Capacidad del software para «tolerar» los errores y fallos que resultan
de ataques con éxito y seguir funcionando como si los ataques no se hubieran
producido.

Las propiedades que distinguen al software de confianza se ilustran en la figura


siguiente.

Integridad

Confidencialidad Disponibilidad

Resiliencia
SEGURIDAD Fiabilidad
DEL
SOFTWARE
Robustez Autenticación

Trazabilidad Tolerancia

Figura 14. Propiedades seguridad del software.

Existen una serie de factores que influyen en la probabilidad de que un software sea
consistente con las propiedades anteriormente mostradas (Goertzel, K. M., Winograd,
T., 2008), estos incluyen:

» Principios de diseño y buenas prácticas de desarrollo. Las prácticas


utilizadas para desarrollar el software y los principios de diseño que lo rigen. En el
apartado posterior se desarrolla ampliamente este punto.
» Herramientas de desarrollo. El lenguaje de programación, bibliotecas y
herramientas de desarrollo utilizadas para diseñar, implementar y probar el software,
y la forma en que fueron utilizados por los desarrolladores.

TEMA 1 – Ideas clave 25 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Componentes adquiridos. Tanto los componentes de software comercial como


libre en cuanto como fueron evaluados, seleccionados, e integrados.
» Configuraciones desplegadas. Cómo el software se configuró durante la
instalación en su entorno de producción.
» Ambiente de operación. La naturaleza y configuración de las protecciones
proporcionadas por el entorno de ejecución o producción.
» Conocimiento Profesional. El nivel de concienciación y conocimiento de
seguridad que los analistas, diseñadores, desarrolladores, probadores y
mantenedores del software, o su falta del mismo.

1.5. Referencias

Sotirov, A. I. (2002). Automatic vulnerability detection using static source code


analysys.

Graff, M. G., Van Wyk, K. R. (2003). Secure Coding: Principles & Practices. O'Reilly.

Hewlett-Packard Development Company (2011). Top Cyber Security Risks Report.

INCIBE. (2011). Cuaderno de notas del Observatorio ¿Qué son las vulnerabilidades del
software?

MITRE (2012). CVE Introductory Brochure. A brief two-page introduction to the CVE
Initiative.

MITRE. (2012). CWE Introductory Brochure A brief two-page introduction to the CWE
initiative.

MITRE. (2011). CWE/SANS Top 25 Most Dangerous Software Errors.


OWASP TOP 10. (2013). Los diez riesgos más importantes en aplicaciones WEB.
Edición en español.

Goertzel, K. M. (2009). Introduction to Software Security. Edición en español.

TEMA 1 – Ideas clave 26 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Klocwork Inc. (2004). Improving Software By Reducing Coding Defects Investing in


software defect detection and prevention solutions to improve software reliability,
reduce development costs, and optimize revenue opportunities.

SAFECode. (2010). Software Integrity Controls. Assurance-Based approach to


minimizing risks in the software supply chain.

Allen, J. H.; Barnum. S.; Ellison, R. J.; McGraw, G.; Mead, N. R. (2008). Software
Security Engineering: A Guide for Project Managers. Addison Wesley Professional.

Goertzel, K. M., Winograd, T. (2008). Enhancing the Development Life Cycle to Produce
Secure Software, Version 2.0. United States Department of Defense Data and Analysis
Center for Software.

Howard, M., LeBlanc, D. (2003). Writing Secure Code. Microsoft Press.

Howard, M., Lipner, S. (2006). The Security Development Lifecycle: SDL: A Process for
Developing Demonstrably Secure Software. Microsoft Press.

McGraw, G. (2005). Software Security: Building Security In. Addison Wesley


Professional.

Redwine Jr., S. T. (Editor). (2006). Software Assurance: A Guide to the Common Body
of Knowledge to Produce, Acquire, and Sustain Secure Software Version 1.1. US
Department of Homeland Security.

Centro Criptológico Nacional (2013). Guía de Seguridad de la STIC (CCN-STIC-400).


Manual de Seguridad de las Tecnologías de la Información y Comunicaciones.

Komaroff, M., Baldwin, K. (2005). DoD Software Assurance Initiative.

National Aeronautics and Space Administration (NASA) (1992). Software Assurance


Standard, Standard No. NASA-STD-2201-93.

Bermejo, J. R., Díaz, G. Estudio de Técnicas Automáticas de Análisis de


Vulnerabilidades de Seguridad en Aplicaciones Web. UNED.

TEMA 1 – Ideas clave 27 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Real Decreto 3/2010, de 8 de enero, por el que se regula el Esquema Nacional de


Seguridad en el ámbito de la Administración Electrónica.

Rambla, J. L. G., Alonso, J, M. (2009). Esquema Nacional de Seguridad con Microsoft.


Microsoft Ibérica S.R.L.

MITRE. Common Attack Pattern Enumeration and Classification — CAPEC™ A


Community Knowledge Resource for Building Secure Software.

Barnum, S., Sethi, A. (2007). Attack Patterns as a Knowledge Resource for Building
Secure. Software Cigital, Inc.

Barnum, S. (2008). Common Attack Pattern Enumeration and Classification (CAPEC)


Schema Description. Department of Homeland Security EEUU. Software Cigital.

Ortiz, Z., Galindo, F. (2006). Hacia una Taxonomía de Incidentes de Seguridad en


Internet. Ciencias de investigación Academia Desarrollo.

Rald, S. L. N., Pedersen, J. M. (2012). An Updated Taxonomy for Characterizing


Hackers According to Their Threat Properties. Department of Electronic Systems,
Aalborg University, Denmark.

Microsoft Corporation. (2006). Understanding the Security Risk Management


Discipline.

Hewlett-Packard Development Company, L.P. (2015). HP Security Research. Cyber Risk


Report 2015. Recuperado de http://www8.hp.com/us/en/software-solutions/cyber-
risk-report-security-vulnerability/

ALERT LOGIG. (2014). Defense throughout the vulnerability life cycle with alert logic
threat and log manager. Recuperado de
http://resources.computerworld.com/ccd/assets/61660/detail

Software Assurance Pocket Guide Series (2012). Software Assurance in Acquisition and
Contract Language. Acquisition & Outsourcing, Volume I.

ISO/IEC 27034-1, Information technology - Security techniques - Application security.

TEMA 1 – Ideas clave 28 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Lo + recomendado

Lecciones magistrales

Los pilares de la seguridad del software

En esta lección magistral se profundiza en el estudio de la seguridad del software


presentando los tres pilares de la seguridad del software: gestión del riesgo, buenas
prácticas de seguridad y gestión del conocimiento.

La lección magistral está disponible en el aula virtual.

No dejes de leer…

Protection of Information in Computer Systems

El documento del año 1975 que presenta conceptos de seguridad del software que siguen
siendo muy relevantes en la actualidad.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://web.mit.edu/Saltzer/www/publications/protection/

TEMA 1 – Lo + recomendado © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

2011 CWE/SANS Top 25 Most Dangerous Software Errors

El documento presenta una lista de los 25 errores en el software más dañinos, extendidos
y críticos que representan vulnerabilidades fácilmente detectables y explotables que
permiten al atacante tomar control de la máquina.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://cwe.mitre.org/top25/

No dejes de ver…

BSIMM: The Building Security in Maturity Model

En este vídeo se da una visión general de una


importante iniciativa de la seguridad del
software llamada BSIMM y su forma de uso
como una herramienta de medida para su
organización, proveedores y su combinación
con otros métodos de medición de seguridad.

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


https://vimeo.com/99350519

TEMA 1 – Lo + recomendado © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

+ Información

A fondo

Hewlett Packard Development Company, L.P. HP Security Research. Cyber


Risk Report 2015

Informe de año 2015 que proporciona una visión amplia del panorama de las
vulnerabilidades del software, así como una profunda investigación y análisis de los
ataques de y tendencias.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://www8.hp.com/us/en/software-solutions/cyber-risk-report-security-
vulnerability/

Improving Software Security During Development

En este artículo se exploran las bases para la creación de software y sistemas seguros
durante su etapa de desarrollo. La seguridad del software se relaciona directamente con
los procesos de calidad.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://www.sans.org/reading_room/whitepapers/securecode/improving-software-
security-development_384

Cuaderno de notas del Observatorio ¿Qué son las vulnerabilidades del


software?

Artículo que analiza los aspectos básicos de las vulnerabilidades: por qué ocurren y cómo
gestionarlas.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://www.egov.ufsc.br/portal/sites/default/files/vulnerabilidades_notasobs.pdf

TEMA 1 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

CVE Introductory Brochure

Artículo introductorio al formato CVE de gestión de vulnerabilidades de software.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://makingsecuritymeasurable.mitre.org/docs/cve-intro-handout.pdf

CWE Introductory Brochure

Artículo introductorio al formato CWE de gestión de debilidades y vulnerabilidades del


software.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://makingsecuritymeasurable.mitre.org/docs/cwe-intro-handout.pdf

Practical Measurement Framework for Software Assurance and


Information Security

Documento de métricas de medidas de seguridad del software e información que


proporciona un método para medir la eficacia de las medidas de seguridad a nivel
organizacional programa o proyecto.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://www.psmsc.com/Downloads/TechnologyPapers/SwA%20Measurement%2010-
08-08.pdf

TEMA 1 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Enlaces relacionados

Build Security In

El U.S. Department of Homeland Security, DHS, desarrolla un portal de seguridad de


software, junto con el Instituto de Ingeniería de Software de Carnegie Mellon y Cigital.
Este portal ayuda a proporcionar un conjunto común, accesible, bien organizado de
información de prácticas de seguridad de software. El esfuerzo del portal expresamente
apunta al problema, de ampliar y extender el conocimiento de seguridad de software.

Accede a la página desde el aula virtual o a través de la siguiente dirección web:


https://buildsecurityin.us-cert.gov/bsi/home.html

Microsoft Security Developer Center

Sitio web que describe las buenas prácticas de desarrollo seguro de modelo de S-SDLC
de Microsoft y sus herramientas asociadas.

Accede a la página desde el aula virtual o a través de la siguiente dirección web:


https://www.microsoft.com/en-us/sdl/default.aspx

TEMA 1 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Secure Software Inc. Resources.

Sitio web de la empresa HP con recursos y artículos sobre seguridad del software.

Accede a la página desde el aula virtual o a través de la siguiente dirección web:


http://www8.hp.com/us/en/software-solutions/software.html?compURI=1214365

Cigital Inc. Resources

Sitio web de la empresa CIGITAL Inc. con recursos, libros, vídeos y artículos sobre
seguridad del software.

Accede a la página desde el aula virtual o a través de la siguiente dirección web:


http://www.cigital.com/resources

SysAdmin, Audit, Networking, and Security (SANS) Reading Room

Sitio web del Instituto SANS con gran Caridad de artículos, ver las secciones:
Application/Database Sec, Best Practices, Auditing & Assessment, Malicious Code,
Scripting Tips, Securing Code y Threats/Vulnerabilities.

Accede a la página desde el aula virtual o a través de la siguiente dirección web:


http://www.sans.org/reading_room/

TEMA 1 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Bibliografía

McGraw, G. (2003). Building Secure Software: A Difficult But Critical Step in Protecting
Your Business. Cigital, Inc.

Allen, J. H.; Barnum. S.; Ellison, R. J.; McGraw, G.; Mead, N. R. (2008). Software
Security Engineering: A Guide for Project Managers. Addison Wesley Professional.

McGraw, G. (2005). Software Security: Building Security In. Addison Wesley


Professional.

Redwine Jr., S. T. (Editor). (2006). Software Assurance: A Guide to the Common Body
of Knowledge to Produce, Acquire, and Sustain Secure Software Version 1.1. US
Department of Homeland Security.

Krassowski, A. y Meunier, P. (2008). Secure Software Engineering: Designing, Writing,


and Maintaining More Secure Code. Addison-Wesley.

TEMA 1 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Test

1. Indica cuál de las siguientes respuestas no es una causa de aparición de


vulnerabilidades en el software.
A. No seguimiento, por los desarrolladores, de guías de normalizadas de estilo en
la codificación.
B. Desarrollo de las aplicaciones por una asistencia técnica o entidades
subcontratadas.
C. No realización de pruebas seguridad basadas en riesgo.
D. No control de la cadena de suministro del software, lo puede dar lugar a la
introducción de código malicioso en origen.

2. Indica las respuestas no correctas respecto del ataque a las aplicaciones durante las
diferentes fases de su ciclo de vida.
A. Desarrollo. Un desarrollador puede alterar de forma intencionada o no el
software bajo desarrollo.
B. Distribución e instalación. Ocurre cuando el instalador del software bastiona la
plataforma en la que lo instala.
C. Operación. Cualquier software que se ejecuta en una plataforma conectada a la
red tiene sus vulnerabilidades expuestas durante su funcionamiento, excepto si
está protegido por dispositivos de protección de la infraestructura de red.
D. Mantenimiento o sostenimiento. No publicación de parches de las
vulnerabilidades detectadas en el momento oportuno o incluso introducción de
código malicioso por el personal de mantenimiento en las versiones actualizadas
del código

3. Las fuentes de las vulnerabilidades se deben a (indica la incorrecta):


A. Fallos provenientes de la codificación de los diseños del software realizados.
B. Fallos provenientes de la cadena de distribución del software.
C. Los sistemas hardware o software contienen frecuentemente fallos de diseño
que pueden ser utilizados para realizar un ataque.
D. La instalación de software por defecto implica por lo general la instalación de
servicios que no se usan, pero que pueden presentar debilidades que comprometan
la máquina.

TEMA 1 – Test © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

4. Señala la incorrecta. Entre las técnicas y mecanismos que se tienen para salvaguardar
la integridad, tenemos por ejemplo:
A. Identificación del modo de trasmisión y procesado de los datos por la aplicación.
B. Uso de arquitecturas de alta disponibilidad, con diferentes tipos de
redundancias.
C. Uso de firma digital.
D. Estricta gestión de sesiones.

5. Señala la respuesta correcta. ¿Cuál de los siguientes mecanismos de seguridad


protegen de forma más adecuada a las aplicaciones?
A. Cortafuegos de nueva generación.
B. Inclusión de prácticas de seguridad en el SDLC.
C. Sistemas de gestión y correlación de eventos (SIEM).
D. Sistemas de detección de intrusos.

6. Señala la respuesta incorrecta. Se puede definir la seguridad del software como:


A. La confianza que el software, hardware y servicios están libres de intencionadas
o no intencionadas vulnerabilidades y que funcionan conforme a lo especificado y
deseado
B. El nivel de confianza de que el software funciona según lo previsto y está libre
de vulnerabilidades, ya sea intencionada o no diseñada o insertada en el marco del
software.
C. El conjunto de principios de diseño y buenas prácticas a implantar en el SDLC,
para detectar, prevenir y corregir los defectos de seguridad en el desarrollo y
adquisición de aplicaciones, de forma que se obtenga software de confianza y
robusto frente ataques maliciosos, que realice solo las funciones para las que fue
diseñado, que esté libre de vulnerabilidades, ya sean intencionalmente diseñadas
o accidentalmente insertadas durante su ciclo de vida y se asegure su integridad,
disponibilidad y confidencialidad
D. Ninguna de las anteriores.

7. Señala la respuesta correcta. Un fallo de desbordamientos de búfer es:


A. Fallos de implementación.
B. Fallos de diseño.
C. Fallos de implantación.
D. Fallos de configuración

TEMA 1 – Test © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

8. Señala la respuesta correcta. ¿Cuál es el momento de más riesgo en el ciclo de vida de


una vulnerabilidad?
A. Cuando se aplica el parche.
B. Cuando se difunde la existencia del exploit.
C. Actualización: Los sitios no actualizados vuelven a ser víctimas.
D. Verificación inicial de la vulnerabilidad.

9. Señala la respuesta correcta. ¿Cuál es la siguiente propiedad de seguridad: capacidad


que garantiza la posibilidad de imputar las acciones relacionadas en un software a la
persona, entidad o proceso que la ha originado?
A. Robustez.
B. Resiliencia.
C. Autenticación.
D. Trazabilidad.

10. Señala las respuestas correctas. ¿En qué fases modelo de ciclo de vida, según
McGraw, es aplicable el catálogo conocimiento de seguridad exploit?
A. Codificación.
B. Pruebas y resultados.
C. Realimentación de producción.
D. Plan de pruebas.

TEMA 1 – Test © Universidad Internacional de La Rioja (UNIR)


Principios de diseño seguridad del
software
[2.1] ¿Cómo estudiar este tema?

[2.2] Introducción

[2.3] Principios de diseño seguridad del software

[2.4] Tipos de S-SDLC

[2.5] Seguridad del software en las fases del S-SDLC

[2.6] Metodologías y estándares

[2.7] Referencias

TEMA
El problema de la seguridad del software
Introducción al problema de
Esquema

seguridad del software

TEMA 2 – Esquema
Principios de diseño seguridad Tipos de Seguridad en las Metodología y
del software S-SDLC fases del S-SDLC estándares

Separación código, Ciclos de vida Seguridad del software

2
Defensa en
entorno de de software versus aseguramiento
profundidad
Simplicidad diseño ejecución seguro de la calidad
inseguro, registros
eventos seguridad Estándares de calidad y
Mínimo privilegio
seguridad del software
Separación Fallar de forma
privilegios segura
Separación Diseño SW
dominios resistente,
Seguridad por
oscuridad y
defecto
Seguridad en el Software

© Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Ideas clave

2.1. ¿Cómo estudiar este tema?

Para estudiar este tema lee las Ideas clave que te presentamos a continuación.

El objetivo del presente tema es introducir al alumno en las propiedades de un software


seguro, sus principios de diseño, los tipos de ciclo de vida de software seguro (S-SDLC)
y los estándares de seguridad aplicables a los procesos de desarrollo seguro de software.

2.2. Introducción

Existe una gran cantidad de bibliografía relativa a temas de seguridad en los que se suele
comentar los principios de seguridad que han de regir todo diseño. Algunos de ellos están
más enfocados a las configuraciones de los dispositivos de seguridad de red, la mayoría
de ellos se solapan y normalmente coinciden generalmente siendo por tanto análogos.
En este sentido, se selecciona como referencia para la realización de este apartado los
documentos Enhancing the Development Life Cycle to Produce Secure Software y
Writing Secure Code.

La adopción de estos principios de diseño constituye una base fundamental de las


técnicas de programación segura, tanto para la protección de aplicaciones web,
normalmente más expuestas a los ciberataques al estar desplegadas masivamente en
Internet, como otras más tradicionales del tipo cliente-servidor. Las principales prácticas
y principios de diseño tener en cuenta serían:

» Defensa en profundidad.
» Simplicidad del diseño.
» Mínimo privilegio.
» Separación de privilegios.
» Separación de dominios.
» Separación código, ejecutables y datos configuración y programa.
» Entorno de producción o ejecución inseguro.
» Registro de eventos de seguridad.
» Fallar de forma segura.

TEMA 2 – Ideas clave 3 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Diseño de software resistente.


» La seguridad por oscuridad es un error.
» Seguridad por defecto.

2.3. Principios de diseño seguridad del software

Defensa en profundidad

Uno de los principios más importantes de una estrategia defensiva efectiva es la


«Defensa en Profundidad», se define en la guía CCN-STIC-400 [18] como: «Estrategia
de protección consistente en introducir múltiples capas de seguridad, que permitan
reducir la probabilidad de compromiso en caso de que una de las capas falle y en el peor
de los casos minimizar el impacto».

La arquitectura del software y hardware de base que constituirá el entorno de ejecución


donde la aplicación vaya a ser instalada debería contar con una variedad de servicios de
seguridad y protecciones que reduzcan y dificulten la probabilidad de que una acción
maliciosa alcance el software, ya que se minimiza la exposición de las propias
vulnerabilidades al mundo exterior, se reduce la visibilidad externa de los componentes
confiables principales y se aíslan los componentes no confiables de forma que su
ejecución se vea limitada y sus malos comportamientos no afecten o amenacen la
operación confiable de los demás.

El aislamiento significa que el software o componente no confiable dispone de recursos


específicos para su ejecución como memoria, espacio en disco duro, interfaz de red
virtual, etc., en un entorno aislado. Para su implementación se suelen utilizar máquinas
virtuales que además pueden proporcionar otras características que ayudan a mejorar la
fiabilidad, confiabilidad y resistencia como el balanceo de carga, soporte para la
restauración de imágenes, etc.

Objetivo: Introducir múltiples capas de seguridad para reducir la probabilidad de


compromiso del sistema.

Este principio, propone un enfoque defensivo, que implanta protecciones o


mecanismos de seguridad en todos los niveles del sistema o capas del modelo Open
Systems Interconnection (OSI).

TEMA 2 – Ideas clave 4 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Las medidas de seguridad a implementar en cada capa podrán variar en función del
entorno de operación del sistema, sin embargo el principio base o general permanece
inalterable, por ejemplo para las capas siguientes tendríamos:

» Capa de aplicación: Dispositivos de nivel de aplicación como cortafuegos, proxy


reverso, y sistemas de prevención de intrusiones de host que bloqueen las entradas
maliciosas conocidas y problemáticas antes de que llegue al software. Otros
mecanismos son métodos de encriptación, control de acceso, autenticación,
bastionados de aplicaciones, etc.
» Capa de transporte: Mecanismos de cifrado como Socket Secure Layer (SSL) o
Transport Layer Security (TLS).
» Capa de red: Dispositivos de seguridad de red como cortafuegos, sistemas de
protección de intrusiones (IDS/IPS) a nivel de red, sistemas de gestión y correlación
de eventos de infraestructura (SIEM), etc. que protejan y dificulten las acciones
de los ciberatacantes.
» Capa física: Plataformas virtuales «sandboxes» que proporcionan un entorno
aislado de ejecución para los componentes no confiables evitando que sus
malos comportamientos posibles de afectar a los componentes confiables. Así mismo
pueden proporcionar arquitecturas de alta disponibilidad y sistemas de recuperación
completa de las máquinas. Mantenimiento de los equipos de comunicaciones y
proceso de datos en salas construidas en base a requisitos de seguridad estructural
para evitar intrusiones y emanaciones, sistemas de extinción automática de incendios,
sensores de humedad, sistemas de control de accesos, etc.

El principio fundamental detrás de este concepto, es el de dificultar las acciones del


atacante a través de las diferentes medidas de seguridad aplicadas a cada una de las capas
de forma que los diferentes sensores que tenga nuestro sistema detecten las actividades
maliciosas. Cuando una capa se vea comprometida, las medidas de detección, de reacción
y de recuperación nos permitirán reaccionar, disminuyendo la probabilidad de que otras
capas se vean comprometidas, evitando así, que la seguridad del servicio en su conjunto
se vea burlada, disminuyendo por tanto el riesgo.

TEMA 2 – Ideas clave 5 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Otro aspecto importante es la verificación de la cadena de suministros mediante la


comprobación de los hash, código de firma, aplicados al código ejecutable mediante la
validación de la integridad de la misma en el momento de la entrega, la instalación
o en tiempo de ejecución, para determinar:

» Si el código se originó a partir de una fuente de confianza.


» Si la integridad del código de se ha visto comprometida.

Cortafuegos de aplicación
Proxy reverso
Métodos Criptográficos
Datos Aplicación
Control de Acceso Autenticación
Bastionado de las aplicaciones
Datos Presentación Bastionado del sistema operativo

Datos Presentación

Segment Transporte SSL/TLS

Paquetes Red Segmentos de red


Firewall/IDS/IPSEC/VPN

Tramas Enlace

Prevención Intrusiones Seguridad


Bits Físico Física Procedimientos seguridad
Plataforma virtualización

Figura 1. Propiedades seguridad del software.

Prueba de la integridad de contenidos. Por ejemplo, cuando se distribuye un


contenido por la red, y se quiere estar seguro de que lo que le llega al receptor es lo que
se está emitiendo, se proporciona un valor hash del contenido de forma que ese valor
tiene que obtenerse al aplicar la función hash sobre el contenido distribuido asegurando
así la integridad. A esto se le suele llamar checksum criptográfico debido a que es un
checksum que requiere el uso de funciones hash criptográficas para que sea difícil
generar otros ficheros falsos que tengan el mismo valor hash. Otro ejemplo de uso esta
tecnología para verificar la integridad es calcular y guardar el valor hash de archivos para
poder verificar posteriormente que nadie (ej. un virus) los ha modificado.
Fuente: https://es.wikipedia.org/wiki/Funci%C3%B3n_hash

TEMA 2 – Ideas clave 6 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Simplicidad del diseño

La realización de un diseño tan simple como sea posible y la redacción de unas


especificaciones del mismo fácilmente comprensibles y simples, es una forma de obtener
un nivel de seguridad mayor pues disminuirá la probabilidad que el equipo de diseño y
desarrollo incluya debilidades de diseño y errores de programación que resulten en
vulnerabilidades que comprometan la seguridad de la aplicación. Incluso se hará más
fácil el análisis de su descubrimiento y su verificación y validación.

Algunas de las opciones específicas de diseño del software que lo simplifican son [13]:

» Limitar el número de estados posibles en el software.


» Favorecer procesos deterministas sobre los no deterministas.
» Utilice una sola tarea en lugar de realizar múltiples tareas siempre que sea
práctico.
» El uso de técnicas de sondeo en lugar de interrupciones.
» Diseñar los componentes del software con el conjunto mínimo de
características y capacidades que se requieran para realizar sus tareas en el
sistema.
» La descomposición en subsistemas o componentes de un programa debería
adaptarse a su descomposición funcional, permitiendo una asignación uno a
uno de los segmentos de programa a sus fines previstos.
» Desacoplar los componentes y procesos para minimizar las
interdependencias entre ellos, impedirá que un fallo o anomalía en un componente
o proceso afecte a los estados de otros.
» No implementar características o funciones innecesarias. Si el diseño
incluye componentes COTS o del software libre con trozos de código latente o muerto,
funciones innecesarias o no documentadas, el diseño debe incluir contenedores para
aislar los segmentos de código no utilizados para prevenir el acceso a los mismos
durante su ejecución.

Como podemos ver el implementar arquitecturas complejas, cuando se puede


resolver el diseño de forma simple, puede afectar negativamente a la
seguridad del sistema.

Objetivo: Reducir la complejidad del diseño para minimizar el número de


vulnerabilidades explotables por el atacante y debilidades en el sistema.

TEMA 2 – Ideas clave 7 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Mínimo privilegio

De acuerdo con el Software Assurance CBK se define el mínimo privilegio como:

Mínimo privilegio es un principio según el cual se concede a cada entidad (usuario,


proceso o dispositivo) el conjunto más restrictivo de privilegios necesarios para el
desempeño de sus tareas autorizadas. La aplicación de este principio limita el daño
que puede resultar de un accidente, error o el uso no autorizado de un sistema.
También reduce el número de interacciones potenciales entre los
procesos privilegiados o programas, por lo que se minimiza la probabilidad de
ocurrencia de usos maliciosos de privilegios, no deseados o inapropiados.

Una de la principales razones por la que es necesario que una entidad se ejecute con los
mínimos privilegios posibles, es debido a que si un ciberatacante consigue
comprometer una máquina o es capaz de inyectar código malicioso en un proceso del
sistema este se debería ejecutar con los mismos privilegios que tuviera el usuario en la
máquina o el proceso.

Este principio requiere que el diseñador realice una lista de las entidades de software
con los recursos que utiliza y las tareas que debe realizar en el sistema, especificando
para cada una los privilegios reales estrictamente necesarios. Normalmente se
suele asignar un usuario general con conjunto de privilegios que le permitirá realizar
todas las tareas, incluidas las no necesarias. Ejemplos de errores comunes son:

» Aplicación de derechos de administrador.


» Instalación de aplicaciones y servicios con el usuario de administrador.
» Usuarios con derechos de administrador.
» Servicios y procesos con privilegios por tiempo indefinido.

Objetivo: Lo que no está expresamente permitido está prohibido.

Separación de privilegios

Es un principio relacionado con el anterior «mínimo privilegio» que esto implica la


asignación a las diferentes entidades de un rol de las siguientes propiedades:

» Asignación de un subconjunto de funciones o tareas de todas las que ofrece el


sistema.

TEMA 2 – Ideas clave 8 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Acceso a los datos necesarios que debe gestionar para llevar a cabo su función en
base a una serie de roles definidos.

Se evita así que todas las entidades sean capaces de acceder a la totalidad o
llevar a cabo todas las funciones del sistema con privilegios de «superusuario» y
por tanto que ninguna entidad tenga todos los privilegios necesarios para modificar,
sobrescribir, borrar o destruir todos los componentes y recursos de la aplicación. Como
ejemplo tenemos:

» Servidor web: el usuario final solo requiere la capacidad de leer el contenido


publicado e introducir datos en los formularios HTML. El administrador por el
contrario, tiene que ser capaz de leer, escribir y eliminar contenido y modificar el
código de los formularios HTML.

Objetivo: Asignación a las diferentes entidades de un rol que implique el acceso a un


subconjunto de funciones o tareas y a los datos necesarios.

Separación de dominios

Es un principio que en unión con los dos anteriores, «mínimo privilegio» y «separación
de privilegios», que permite minimizar la probabilidad de que actores maliciosos
obtengan fácilmente acceso a las ubicaciones de memoria u objetos de datos del sistema.
Para que el diseño cumpla con este principio deben utilizar de técnicas de
compartimentación de los usuarios, procesos y datos de forma que las entidades:

Solo deben ser capaces de realizar las tareas que son absolutamente necesarias.
Llevarlas a cabo solamente con los datos que tenga permiso de acceso.
Utilizar el espacio de memoria y disco que tenga asignado para la ejecución de esas
funciones.

Objetivo: Minimizar la probabilidad de que actores maliciosos obtengan fácilmente


acceso a las ubicaciones de memoria u objetos de datos del sistema.

El aislar las entidades de confianza en su propia área de ejecución (con recursos


dedicados a la misma) de otras menos confiables (procesadores de texto, software de
descarga, etc.), permite reducir al mínimo su exposición a otras entidades e interfaces
externas susceptibles de ser atacadas por agentes maliciosos.

TEMA 2 – Ideas clave 9 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Las técnicas que tenemos para llevar a cabo lo anterior:

» Sistema operativo confiable.


» Máquinas virtuales. Además pueden proporcionar otras características que ayudan a
mejorar la fiabilidad, confiabilidad y resistencia como el balanceo de carga, soporte
para la restauración de imágenes, etc.
» Funciones sandboxing de lenguajes de programación como Java, Perl, .NET (Code
Access Security), etc.
» Sistemas Unix: chroot jails.
» Trusted processor modules (TPM).

TPM
Es el nombre de una especificación publicada que detalla un criptoprocesador seguro
que puede almacenar claves criptográficas que protejan la información y las
implementaciones de esta especificación, a menudo llamado el «chip TPM» o
«dispositivo de seguridad TPM». Fuente: http://en.wikipedia.org

Separación código, ejecutables y datos configuración y programa

Este principio pretende reducir la probabilidad de que un ciberatacante que


haya accedido a los datos del programa fácilmente pueda localizar y acceder
a los archivos ejecutables y datos de configuración del mismo, lo que le daría
la posibilidad de manipular el funcionamiento del sistema a su interés e incluso el
escalado de privilegios.

La mayoría de las técnicas de separación de los datos de programa, configuración y


archivos ejecutables se realizan en la plataforma de ejecución (procesador más sistema
operativo). A continuación vemos las más principales mostradas (Goertzel, K. M.,
Winograd, T., 2008):

» Utilizar plataformas con arquitectura Harvard.


» Establecer permisos de escritura y lectura de los datos de programa y sus
metadatos al programa que los creó a menos que exista una necesidad explícita
de otros programas o entidades para poder leerlos.
» Los datos de configuración del programa solo deben poder ser leídos y
modificados por el administrador.

TEMA 2 – Ideas clave 10 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Los datos utilizados por un script en un servidor Web deben ser colocados
fuera de árbol de documentos del mismo.
» Prohibir a los programas y scripts escribir archivos en directorios
escribibles como el de UNIX/TMP.
» Almacenar los archivos de datos, configuración y programas ejecutables
en los directorios separados del sistema de archivos.
» Los programas y scripts que están configurados para ejecutarse como servidor Web
de usuario «nobody» (debe suprimirse) deben ser modificados para funcionar bajo
un nombre de usuario específico.
» Cifrar todos los archivos ejecutables e implementar un módulo de
decodificación que se ejecute como parte del inicio del programa para desencriptarlos
al iniciar su funcionamiento.
» Incluir técnicas de cifrado de archivos y firma digital o almacenamiento
en un servidor de datos externos con conexión cifrada (por ejemplo mediante Secure
Sockets Layer ─SSL─ o Transport Layer Security ─TLS─) para aislar los datos de
configuración del software de la manipulación y eliminación, en caso de que las
técnicas de control de acceso al sistema no son lo suficientemente fuertes. Ello
requerirá que el software incluya la lógica de cifrado para descifrar y validar la firma
del archivo de configuración al inicio del programa.
» Implantar clonado de sistemas como medida de recuperación, desde un
servidor remoto (que guardaría las imágenes y los datos de configuración) mediante
una red de comunicaciones fuera de banda específica y cifrada.

Arquitectura Harward
Hace referencia a las arquitecturas de computadoras que utilizaban dispositivos de
almacenamiento físicamente separados para las instrucciones y para los datos (en
oposición a la Arquitectura de von Neumann). Fuente: http://es.wikipedia.org

Objetivo: Reducir la probabilidad de que un ciberatacante que haya accedido a los datos
del programa fácilmente pueda localizar y acceder a los archivos ejecutables y datos de
configuración del programa.

Entorno de producción o ejecución inseguro

Asumir que todos los componentes del entorno de producción y sistemas externos son
inseguros o no confiables, con ello se pretende reducir la exposición de los componentes
del software a agentes potencialmente maliciosos que hayan podido penetrar en el

TEMA 2 – Ideas clave 11 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

perímetro de defensa (los límites dispositivos de protección perimetral) de la


organización y comprometer una máquina desde la que puedan expandirse e iniciar otros
ataques a otras pertenecientes a la red (pivoting).

El software debe ser diseñado con una mínima dependencia de los datos
externos, se debe tener control completo sobre cualquier fuente de entrada de datos,
tanto los proporcionados por la plataforma de ejecución como de sistemas externos,
debiendo validar todos los datos provenientes de las diferentes fuentes del
entorno antes de utilizarlos, pues implican una posibilidad de ataque.

Hay que realizar una descomposición del sistema en sus componentes principales y
realizar una lista de las diferentes fuentes de datos externas, entre las que
podemos tener las siguientes:

» Llamadas a sistema operativo. Se deben evitar realizándolas a través de


middleware o API’s.
» Llamadas a otros programas en la capa de aplicación.
» Llamadas a una capa de middleware intermedia.
» API’s a los recursos del sistema. Las aplicaciones que utilizan las API no deberían
ser utilizadas por usuarios humanos.
» Referencias a objetos del sistema.
» En aplicaciones cliente-servidor, el flujo de datos entre los mismos.
» En aplicaciones Web el flujo de datos ente el cliente y el servidor.

Gran parte de los ataques a los sistemas TIC actualmente se deben a fallos o
carencias en la validación de los datos de entrada, el confiar en la fuente que las
originó hace a la aplicación vulnerable a ataques originados en el cliente al modificar los
datos en el origen o durante su transporte. Los atacantes pueden manipular diferentes
tipos de datos de entrada con el propósito de encontrar vías de compromiso de la
aplicación.

Todos los tipos de entrada deber ser validados y verificados mediante


pruebas específicas. Entre los diferentes tipos de entradas a las aplicaciones tenemos
(Goertzel, K. M., Winograd, T., 2008):

» Parámetros de línea de comandos.


» Variables de entorno.

TEMA 2 – Ideas clave 12 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Localizadores de recursos universales (direcciones URL) e identificadores (URI).


» Referencias a nombres de archivo.
» Subida contenido de archivos.
» Importaciones de archivos planos.
» Cabeceras Hyper Text Transfer Protocol (HTTP).
» Parámetros HTTP GET.
» Campos de formulario (especialmente los ocultos).
» Las listas de selección, listas desplegables.
» Cookies.
» Comunicaciones mediante Java applets.

Los tipo de aplicaciones que más probabilidad presenten de sufrir este tipo de ataques
son las del tipo cliente-servidor, portales web y agentes proxy. Entre los tipos de
ataques que se pueden dar por la carencia de comprobación de los datos de entrada, la
mayoría para aplicaciones Web, tenemos:

» Desbordamientos de búfer (buffer overflow): heap, stack, entero y off-by-one.


» Revelación de información.
» Inyección de comandos.
» Inyección de código SSI inyección SQL, HTTP splitting.
» Contenidos mal formados.
» Servicios web: aparte de los anteriores tenemos, inyección XML, explotación de
interfaces de administración no protegidos.

Para evitar este tipo de vulnerabilidades se deben aplicar una serie de principios de
validación de las entradas, entre los que tenemos (Goertzel, K. M., Winograd, T., 2008):

» Centralizar la lógica de validación de las entradas.


» Asegúrese que la validación de la entrada no puede ser evitada.
» Confiar en «listas blancas» validadas y filtrar las «listas negras».
» Validar todas las entradas de usuario incluidas las realizadas a través de proxies y
agentes que actúen en nombre de los usuarios.
» Rechazar todos los contenidos ejecutables en las entradas provenientes de fuentes no
autorizadas.
» Verificar que los programas que solicitan las llamadas tienen derecho (por la política)
a emitirlas.
» Definir reacciones significativas a errores de validación de entrada.

TEMA 2 – Ideas clave 13 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Validar los datos de salida de la aplicación antes de mostrarlos al usuario o redirigirlos


a otro sistema.

Lista blanca
Lista de aprobación o whitelist en inglés es una lista o registro de entidades que, por una
razón u otra, pueden obtener algún privilegio particular, servicio, movilidad, acceso o
reconocimiento. Por el contrario, la lista negra o blacklisting es la compilación que
identifica a quienes serán denegados, no reconocidos u obstaculizados. Fuente:
http://es.wikipedia.org

Objetivo: Evitar vulnerabilidades aplicando una serie de principios de validación de las


entradas.

Registro de eventos de seguridad

Tradicionalmente los sistemas de auditoría se dedicaban solo a grabar las acciones


realizadas por los usuarios del mismo. Sin embargo actualmente es necesario dotar a las
aplicaciones de la capacidad de generar eventos (logs) de seguridad, para garantizar que
todas las acciones realizadas por un agente malicioso se observan y registran,
contribuyendo a la capacidad de reconocer patrones y aislar o bloquear la fuente del
ataque de modo que se evite su éxito. En definitiva, el dotarle de cierta capacidad de
detección de intrusiones.

Las principales diferencias que distinguen los sistemas con registros de auditoría de
seguridad de registro de los registros de eventos estándar son:

» El tipo de información capturada en el registro de auditoría: eventos de


seguridad.
» Capacidad de gestión de los incidentes relacionados con los eventos de
seguridad.
» Posibilidad de que los eventos de seguridad registrados en la aplicación o sistema,
puedan ser utilizados en procesos reactivos después de la ocurrencia de un
incidente.
» El nivel de protección de integridad.

TEMA 2 – Ideas clave 14 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Objetivo: Generar eventos (logs) de seguridad, para garantizar las acciones realizadas
por un ciberatacante se observan y registran.

Fallar de forma segura

El propósito de este principio es el reducir la probabilidad de que un fallo en el software,


pueda saltarse los mecanismos de seguridad de la aplicación, dejándolo en un estado de
fallo inseguro vulnerable a los ataques. Es imposible implementar una aplicación
perfecta que nunca falle, la solución consiste en saber en todo momento cuál es su estado
y tener implementado un mecanismo en caso que falle.

Algunas de las características específicas del diseño que minimizan la probabilidad de


que el software pase a un estado inseguro son:

» Implementar temporizadores tipo «watchdog».


» Implementar una lógica de control de excepciones.
» El software siempre debe comenzar y terminar su ejecución en un estado seguro.
» Evitar problemas de sincronización y secuenciación.

Objetivo: Reducir la probabilidad de que un fallo en el software, pueda saltarse los


mecanismos de seguridad de la aplicación, dejándolo en un modo de fallo inseguro
vulnerable a los ataques.

Diseño de software resistente

Dos propiedades importantes del software seguro es la robustez y la resiliencia, el


siguiente principio pretende aumentar la resistencia de las aplicaciones reduciendo al
mínimo la cantidad de tiempo que un componente de software defectuoso o
fallido sigue siendo incapaz de protegerse de los ataques. Algunas de las
características de diseño que aumentarán la resistencia del software incluyen [13]:

» Capacidad de autocontrol y de limitar el uso de los recursos.


» Uso de técnicas de monitorización.
» Detección de estados anómalos.
» Proporcionar una realimentación que permita que todos los supuestos y modelos
en los que el programa tome decisiones sean validados antes de ejecutarlas.
» Aprovechar cualquier redundancia y funciones de recuperación.

TEMA 2 – Ideas clave 15 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Uso de plataformas virtuales.


» Uso de técnicas de recuperación.
» Determinar la cantidad de información a proporcionar en los mensajes
de error.

Objetivo: Reducir al mínimo la cantidad de tiempo que el componente de un software


defectuoso o fallido sigue siendo incapaz de protegerse de los ataques.

La seguridad por oscuridad: error

Una de las asunciones que se debe realizar a la hora de diseñar una aplicación, es que el
atacante obtendrá con el tiempo acceso a todos los diseños y todo el código
fuente de la misma. La seguridad por oscuridad es un mecanismo de defensa que
consiste en ocultar información sobre la aplicación de forma que sea difícil
de obtener, pero que en poder de un atacante puede proporcionarle un medio para
comprometerla.

Howard y LeBlanc (2003), no aconsejan que nunca se dependa de la seguridad por


oscuridad solamente indican que es válido usarla como una pequeña parte de una
estrategia general de «defensa en profundidad» para confundir y dificultar las
actividades de ataque de un intruso. A continuación se muestran algunos ejemplos de
seguridad por oscuridad, que pueden constituir un error:

» Guardar información en archivos binarios.


» Capetas ocultas en un servidor web.
» Falsa sensación de seguridad.
» Criptografía privada.
» Cambio del nombre del usuario «administrador».

Objetivo: Concienciarse de que la seguridad por oscuridad es un mecanismo de defensa


que puede proporcionar a un atacante información para comprometer la seguridad de
una aplicación.

Seguridad por defecto

Uno de los principios de seguridad cuyo cumplimiento exige el Real Decreto 3/2010, de
8 de enero, por el que se regula el Esquema Nacional de Seguridad en el ámbito de la

TEMA 2 – Ideas clave 16 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Administración Electrónica, es el de la seguridad por defecto. En su artículo 19 indica


lo siguiente:

Los sistemas deben diseñarse y configurarse de forma que garanticen la seguridad por
defecto:

a. El sistema proporcionará la mínima funcionalidad requerida para que la


organización solo alcance sus objetivos, y no alcance ninguna otra funcionalidad
adicional.
b. Las funciones de operación, administración y registro de actividad serán las
mínimas necesarias, y se asegurará que solo son accesibles por las personas, o
desde emplazamientos o equipos, autorizados, pudiendo exigirse en su caso
restricciones de horario y puntos de acceso facultados.
c. En un sistema de explotación se eliminarán o desactivarán, mediante el control de
la configuración, las funciones que no sean de interés, sean innecesarias e, incluso,
aquellas que sean inadecuadas al fin que se persigue.
d. El uso ordinario del sistema ha de ser sencillo y seguro, de forma que una
utilización insegura requiera de un acto consciente por parte del usuario.

De la lectura del artículo anterior se desprende que el principal objetivo del principio de
seguridad por defecto es el de minimizar la superficie de ataque de cualquier
aplicación o sistema TIC, deshabilitando aquellos servicios y elementos no necesarios y
activando solo los necesarios.

Normalmente cuando se instala o pone en producción una aplicación o servicio, se


activan o instalan servicios que no se usan normalmente que pueden suponer un punto
potencial de entrada para los atacantes. Se debe elegir los componentes que van a ser
utilizados de forma explícita por los usuarios e instalarlos y configurarlos de forma
segura. Hay que minimizar los puntos vulnerables de la aplicación o sistemas pues
amenazan su seguridad global por muy securizado que se tenga el resto, en concreto los
siguientes:

» Entradas y salidas de red.


» Número de puertos abiertos.
» Puntos de entrada a la aplicación, autenticados o no autenticados, locales o remotos y
privilegios administrativos necesarios.
» Número de servicios. Desactivar los instalados por defectos no usados.

TEMA 2 – Ideas clave 17 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Número de servicios con privilegios elevados.


» Número de cuentas de usuario administrador.
» Estado de las listas de control de acceso a directorios y ficheros.
» Control de cuentas de usuario y claves de acceso por defecto a servicios.
» Contenido dinámico de páginas Web.

Varias organizaciones, como el National Institute of Standards and Technology (NIST),


la Agencia de Seguridad Nacional (NSA) y el Centro Criptológico Nacional (CCN), han
publicado guías de seguridad de configuración y scripts para productos COTS populares
y de software libre que incluye la eliminación o restricción de servicios, usuarios,
permisos y software innecesario.

El bastionado de sistemas es un proceso necesario en el marco de cualquier


proyecto que contemple la aplicación de controles de seguridad sobre los
sistemas TIC, tiene como principio implementar todas las medidas de seguridad a nivel
técnico posibles para proteger un sistema sin que pierda la funcionalidad para la que fue
destinado. Habrá casos, en los que surjan conflictos que no se puedan superar, estos
deben ser cuidadosamente documentados para proporcionar una justificación de la
renuncia a los requisitos de configuración de seguridad que impidan el correcto
funcionamiento del software.

Objetivo: Reducir la superficie de ataque de una aplicación o sistema.

Resumen

En el presente apartado se ha realizado un estudio de los diferentes principios de


seguridad a tener en cuenta en el diseño y desarrollo de aplicaciones seguras, que nos
ayudaran a proteger y disponer de aplicaciones seguras con un mínimo de
vulnerabilidades. Como resumen se muestra un gráfico que sintetiza el objetivo de cada
principio.

Principio Objetivo

Defensa en Introducir múltiples capas de seguridad para reducir la


profundidad probabilidad de compromiso del sistema.

Reducir la complejidad del diseño para minimizar el número de


Simplicidad del diseño vulnerabilidades explotables por el atacante y debilidades en el
sistema.
Mínimo privilegio Lo que no está expresamente permitido está prohibido.

TEMA 2 – Ideas clave 18 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Asignación a las diferentes entidades de un rol que implique el


Separación de
acceso a un subconjunto de funciones o tareas y a los datos
privilegios
necesarios.
Minimizar la probabilidad de que actores maliciosos obtengan
Separación de
fácilmente acceso a las ubicaciones de memoria u objetos de
dominios
datos en el sistema.
Separación código, Reducir la probabilidad de que un ciberatacante que haya
ejecutables y datos accedido a los datos del programa fácilmente pueda localizar y
configuración y acceder a los archivos ejecutables y datos de configuración del
programa programa.
Entorno de
Evitar vulnerabilidades aplicando una serie de principios de
producción o
validación de las entradas.
ejecución inseguro
Registro de eventos de Generar eventos (logs) de seguridad, para garantizar las acciones
seguridad realizadas por un ciberatacante se observan y registran
Reducir la probabilidad de que un fallo en el software, pueda
Fallar de forma segura saltarse los mecanismos de seguridad de la aplicación, dejándolo
en un modo de fallo inseguro vulnerable a los ataques.
Reducir al mínimo la cantidad de tiempo que un componente de
Diseño de software
un software defectuoso o fallido sigue siendo incapaz de
resistente
protegerse de los ataques.
Concienciarse de que la seguridad por oscuridad es un
La seguridad por
mecanismo de defensa que puede proporcionar a un atacante
oscuridad: error
información para comprometer la seguridad de una aplicación.

Seguridad por defecto Reducir la superficie de ataque de una aplicación o sistema.

Objetivos principios de seguridad.

2.4. Tipos de S-SDLC

Introducción

Las organizaciones deben insertar buenas prácticas de seguridad en el proceso


de desarrollo de software al objeto de obtener software más seguro o
confiable. Para ello se tienen dos posibilidades, la primera adoptar una metodología
segura de desarrollo que proporcione un marco integrado de mejora de la
seguridad, como los presentadas en este apartado y la segunda la evolución y mejora
de sus actuales prácticas de seguridad.

Estas metodologías no modifican las actividades tradicionales de SDLC, insertan nuevas


actividades con el objetivo de reducir el número de debilidades y vulnerabilidades en el
software, a este nuevo ciclo de vida con buenas prácticas de seguridad
incluidas lo denominaremos S-SDLC.

TEMA 2 – Ideas clave 19 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

En el presente apartado se presentan varios modelos de ciclo de vida S-SDLC con


prácticas de seguridad incluidas, que se pueden aplicar independientemente del tipo de
modelo: ciclo de vida en espiral, extreme programming, etc. Además, algunos métodos
estándar de desarrollo han demostrado que aumentan la probabilidad de que el software
producido por ellos será seguro. Debido a la popularidad actual de los métodos ágiles, es
importante el estudiar los problemas de seguridad que surgen cuando se utiliza este tipo
de ciclos de vida.

Los equipos de desarrollo que utilizan metodologías seguras en el SDLC, casi


inmediatamente perciben una mejora en su capacidad para detectar y
eliminar errores de codificación y debilidades de diseño en el software que
producen, antes de que entren en un proceso de distribución e instalación. Esta mejora
se pondrá de manifiesto conforme el software pase sus controles de seguridad
(revisiones de diseño y código de seguridad, análisis de fallos de inyección, pruebas de
penetración, análisis de vulnerabilidades, etc.).

Los elementos clave de un proceso de S-SDLC, según Goertzel (2009), son:

» Hitos de control en las fases del SDLC.


» Principios y prácticas seguras de software.
» Requisitos adecuados.
» Arquitectura y diseño adecuados.
» Codificación segura.
» Integración de forma segura de los módulos y componentes del software:
» Pruebas de seguridad.
» Despliegue y distribución segura.
» Sostenimiento seguro.
» Herramientas de apoyo al desarrollo.
» Gestión de configuración de sistemas y procesos.
» Conocimientos de seguridad de los desarrolladores.
» Gestión segura del proyecto y compromiso de la alta dirección.

En los siguientes apartados se introduce la metodología S-SDLC McGraw’s Seven


Touchpoints por ser la tomada como base para este tema y se nombran otras existentes
y se referencian otras metodologías actualmente en uso por diferentes organizaciones.

TEMA 2 – Ideas clave 20 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

McGraw’s Seven Touchpoints

Es el modelo base tomado para el desarrollo de este tema, McGraw (2005) propone un
modelo de S-SDLC (cascada o iterativo) en el que define una serie de mejores
prácticas de seguridad a aplicar a los artefactos de cada fase del desarrollo.

En esencia, el proceso se centra en la incorporación de las siguientes prácticas ordenadas


por orden de importancia:

» Revisión de código
» Análisis de riesgo arquitectónico
» Pruebas de penetración
» Pruebas de seguridad basados en riesgo
» Casos de abuso
» Requisitos de seguridad
» Operaciones de seguridad
» Revisión externa

Además de las siete prácticas se identifica una octava, el análisis externo, en el que un
equipo de analistas externos a la organización y por tanto al equipo de desarrollo del
software, realiza revisiones de seguridad independientes, evaluaciones y pruebas del
diseño del software y la implementación. La figura siguiente, muestra el de ciclo de vida
de desarrollo de software seguro S-SDLC en el que se especifican las actividades y
pruebas de seguridad a efectuar en cada fase del mismo.

6. 4. Pruebas 1. 2. 7.
5. Casos 2. Análisis 3. Pruebas
Requisitos basadas Revisión Análisis Operaciones
de abuso de riesgos penetración
seguridad en riesgo código riesgos Seguridad

Requisitos
Arquitectura Plan de Pruebas y Realimentación de
Casos de Codificación producción
Diseño pruebas resultados
abuso

8. Revisión
externa

Figura 2. McGraw’s Seven Touchpoints.

TEMA 2 – Ideas clave 21 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Este orden descrito no se adecuará perfectamente a todas las organizaciones. De hecho,


el orden refleja el trabajo desarrollado en años de experiencia de McGraw al aplicar estas
prácticas en empresas desarrolladoras de software. Por esa razón, la revisión de código
viene antes de análisis de riesgos arquitectónico. Hay que resaltar que estas actividades
hay que repetirlas a lo largo del ciclo de vida lo que supone un ciclo continuo en la
ejecución de las distintas actividades de seguridad:

» Conforme se descubren nuevas amenazas y vulnerabilidades, se tienen nuevos riesgos


que dan lugar a un nuevo caso de abuso y un nuevo análisis de riesgos.
» Cambios en el sistema con nuevos componentes de software ó hardware, implica el
rehacer el análisis de riesgos y revisar el código de los nuevos componentes software.
» Nuevos defectos de implementación que modifican las especificaciones ó del sistema
implican nuevas revisiones de código y as pruebas de seguridad.

Otras metodologías

» Microsoft Trustworthy Computing SDL: http://www.microsoft.com/security/sdl/


» CLASP: Comprehensive Lightweight Application Security Process:
http://www.owasp.org/index.php/Category:OWASP_CLASP_Project
» Team Software Process (TSP): http://www.cert.org/secure-coding/secure.html
» Oracle Software Security Assurance:
http://www.oracle.com/us/support/assurance/index.html
» Appropriate and Effective Guidance in Information Security (AEGIS):
http://www.cs.ox.ac.uk/files/6345/thesis_final.pdf
» Rational Unified Process-Secure (RUPSec):
http://ce.aut.ac.ir/~jaferian/files/publications/WECRUPSec.doc
» Secure Software Development Model (SSDM):
http://www.iaeng.org/.../IMECS2010_pp724-728.pdf
» Waterfall-Based Software Security Engineering Process Model:
http://www.asq.org/pub/sqp/past/vol9_issue1/sqpv9i1schneider.pdf
» Building Security In Maturity Model (BSIMM):
http://www.bsi-mm.com/
» Software Assurance Maturity Model (OPEN SAMM):
http://www.opensamm.org

TEMA 2 – Ideas clave 22 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

2.5. Seguridad del software en las fases del S-SDLC

La seguridad del software es algo más que la eliminación de las vulnerabilidades y la


realización de pruebas de penetración. Un aspecto importante de la misma, es la
adopción por los gerentes de un enfoque sistémico que incorpore los principios de
diseño estudiados en apartados anteriores y unas buenas prácticas de
Seguridad del Software «touchpoint» en su Ciclo de Vida de Desarrollo. Su
objetivo es producir software más seguro y confiable, así como el poder
verificar su seguridad, a este nuevo ciclo de vida le denominaremos ciclo de
vida del software seguro S-SDLC.

Lo anterior exige mejorar el SDLC al tener que incluir y describir con mayor profundidad
técnica y detallada los principios y prácticas de seguridad que los desarrolladores de
software, evaluadores e integradores tienen que adoptar para lograr el doble objetivo de
producir sistemas con software más seguro y poder verificar su seguridad.

Las organizaciones que realizan desarrollos de software, como medida de fomento de la


mejora de seguridad en el software, deberían crear una comunidad de desarrollo seguro,
utilizando tecnologías de colaboración y entornos de desarrollo integrado, con el objetivo
de promover un proceso de mejora continua y fomento del uso de principios
de diseño seguro.

No existe una metodología de ingeniería de seguridad de software que haya probado


unos mejores resultados que otras, todas se basan en la inclusión de prácticas de
seguridad fundamentalmente, por tanto, no importa cuál es el modelo de ciclo de
vida seguido. Lo que sí es importante es que la seguridad sea considerada desde las
primeras etapas del ciclo de vida del software.

TEMA 2 – Ideas clave 23 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

7. Revisión 8.
5. Patrones
código Configuración
de diseño
11. segura
3. Ing. 6. Pruebas 1. Modelado
2. Casos 4. Análisis de Revisión 9. Test
Requisitos basadas en de ataques
de abuso riesgos externa penetración
seguridad riesgo 10.
Operaciones
seguridad

Requisitos Codificación
Arquitectura Pruebas Distribución Operación y
Casos de e
Diseño y despliegue mantenimiento
abuso integración

REALIMENTACIÓN

Figura 3. Mejores prácticas de seguridad del software en el SDLC.

La figura anterior, propone un ciclo de vida de desarrollo de software SDLC en cascada


basado en el modelo de McGraw (2005), para otro tipo como los iterativos sería similar,
donde se especifican las actividades y prácticas de seguridad a efectuar en cada fase del
mismo. En el siguiente apartado se muestran diferentes tipos de S-SDLC adoptados por
diferentes empresas y organizaciones. A continuación se enumeran esas actividades o
mejores prácticas de seguridad del software tomando como referencia el modelo
McGraw (2005)al que se le añaden otras:

» Modelado de ataques.
» Casos de abuso.
» Ingeniería requisitos de seguridad.
» Análisis de riesgo arquitectónico.
» Patrones de diseño.
» Pruebas de seguridad basadas en riesgo.
» Revisión de código.
» Test penetración.
» Configuraciones seguras.
» Operaciones de seguridad.
» Revisión externa.

TEMA 2 – Ideas clave 24 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

En la tabla siguiente se representan las prácticas de seguridad y su relación en cada una


de las fases donde son aplicables.

Relación entre las prácticas de seguridad y las fases del ciclo de vida.

En los siguientes apartados de este tema se desarrollan las prácticas de seguridad


propuestas para el ciclo de vida.

2.6. Metodologías y estándares

Introducción

Las metodologías y estándares, consisten básicamente en guías de comportamiento


específicas destinadas a aplicar una o varias políticas. Su aplicación a la
seguridad del software consiste en el desarrollo de procesos que implementen técnicas
de seguridad en todas las actividades que intervienen en el ciclo de vida de desarrollo de
software. Para conseguir lo anterior, las organizaciones deben implantar un
estándar de aseguramiento de la calidad de software y un estándar de
seguridad.

TEMA 2 – Ideas clave 25 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Las organizaciones relacionadas con normas internacionales sobre seguridad de la


información son:

» International Organization for Standardization (ISO).


» International Electrotechnical Commission (IEC).
» National Institute of Standards and Technology (NIST).

A continuación se realiza una descripción resumida de los estándares más importantes


que las organizaciones pueden adoptar para conseguir los beneficios que suponen tener
procesos implantados de calidad y seguridad del software en todas las actividades del
SDLC, así como una aclaración de las diferencias entre seguridad del software versus
aseguramiento de la calidad.

Seguridad del software versus aseguramiento de la calidad

Antes de comenzar con las actividades y medidas de seguridad a integrar en el SDLC, es


conveniente aclarar las principales diferencias entre aseguramiento de la calidad y
seguridad del software:

» Aseguramiento de la calidad su principal objetivo es hacer que el software


funcione correctamente conforme a las especificaciones del mismo.
» Seguridad del software tiene por objetivo que tanto el software como su entorno
de ejecución presenten el mínimo de vulnerabilidades y por tanto su
superficie de ataque sea la menor posible, de forma sea confiable a pesar
de la presencia de un ambiente externo hostil con ciberataques en curso.

Estas diferencias se pueden caracterizar también en términos de amenazas, las


principales de la calidad son internas no intencionadas debidas a errores o
descuidos, es decir la presencia de defectos en el software que pongan en peligro su
capacidad de funcionar correctamente y de manera previsible.

Por otro lado las amenazas a la seguridad son internas y externas e incluyen una
intención maliciosa materializada en posibles ciberataques que puedan recibir el
software o su entorno de ejecución del software cuando se tiene un comportamiento
impredecible (por cualquier razón).

TEMA 2 – Ideas clave 26 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

En un proceso de desarrollo de software seguro, los profesionales de control de calidad


deben tener siempre en cuenta la seguridad y ser exactos y rigurosos en las
especificaciones, diseño y verificación de la seguridad del software, en base a los riesgos
estimados de forma que el proceso de garantía de calidad incorporare algunas
actividades de su gestión y nuevos procedimientos relacionados con la seguridad.

» Estándares de calidad

o ISO/IEC JTC1 SC7. Ingeniería de software y de sistemas.


o ISO 9126. Calidad del producto.
o ISO 14598. Evaluación de productos de software.
o ISO 12119. Requerimientos de calidad y prueba de COTS.
o ISO 15939. Proceso de medición de software.
o ISO 9000. Familia de normas son normas de calidad establecidas por la ISO.
– UNE-EN ISO 9000. Sistemas de gestión de la calidad. Fundamentos y
vocabulario (ISO 9000:2000).
– UNE-EN 150 9000. Sistemas de gestión de la calidad. Requisitos (ISO
9001:2000).
– UNE-EN 150 9000. Sistemas de gestión de la calidad. Directrices para la mejora
del desempeño (ISO 9004:2000).

» Estándares de seguridad

o ISO / IEC 15026 Systems and software engineering — Systems and software
assurance.
o System Security Engineering Capability Maturity Model (SSE-CMM norma
ISO/IEC 21827
o Norma IEEE 1074-2006, Developing Software Project Life Cycle Processes.
Developing Software Project Life Cycle Processes Norma IEEE 1074-2006.
o ISO / IEC 24772. Proyecto 22, grupo de trabajo para evitar vulnerabilidades en
lenguajes de programación proporcionando una orientación a los programadores
sobre cómo evitar las vulnerabilidades que se pueden introducir en el software al
utilizar ciertas características de un lenguaje de programación seleccionado para el
desarrollo de un proyecto software, sugiriendo alternativas de patrones de
codificación que las eviten. Así mismo ayuda a elegir las herramientas de análisis
estático, detección de vulnerabilidades y orientación de codificación para mejorar
la eficacia en la reducción de vulnerabilidades.

TEMA 2 – Ideas clave 27 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

o ISO/IEC 27034-1, Information technology — Security techniques —


Application security. Norma para ayudar a las organizaciones a integrar la
seguridad en el ciclo de vida de sus aplicaciones.
o ISO/IEC 15408, Evaluation Criteria for IT Security. The Common
Criteria. Los criterios comunes (CC) permiten comparar los resultados entre
evaluaciones de productos independientes en base a un conjunto común de
requisitos funcionales para los productos hardware, software o firmware de las
TIC, estableciendo un nivel de confianza en el grado en el que el producto satisface
la funcionalidad de seguridad en base a la superación de unas pruebas aplicadas.

Los CC contribuyen a aumentar la confianza de los que adquieran productos TIC


que incluyan en funciones de seguridad pues pueden determinar más fácilmente
cuándo un producto cumple una serie de requisitos pues exige a los fabricantes de
los productos certificados publicar una documentación exhaustiva sobre la
seguridad de los productos evaluados por laboratorios independientes.

En lo relativo a la seguridad del software, los niveles EAL más altos poseen un nivel
de garantía de evaluación que captura un conjunto específico de requisitos de
seguridad, de los que es posible deducir algunas propiedades generales que el
software debe exhibir para alcanzarlos:

‒ EAL 5: El sistema debe ser semiformalmente diseñado y probado basado en un


modelo formal y una presentación semiformal de la especificación funcional y
el diseño de alto nivel, de forma que las vulnerabilidades resistan relativamente
a los ataques de penetración. Esta propiedad también se aplica al diseño de
software.
‒ EAL 6: Igual que EAL 5 y además el diseño debe ser semiformalmente
verificado. Como el anterior, este establecimiento también debe aplicarse al
diseño de software.
‒ EAL 7: Igual que EAL 6, más el diseño debe ser verificado oficialmente y
formalmente testeado. Como el anterior, este establecimiento también debe
aplicarse al diseño de software.

2.7. Referencias

Sotirov, A. I. (2002). Automatic vulnerability detection using static source code


analysys.

TEMA 2 – Ideas clave 28 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Graff, M. G., Van Wyk, K. R. (2003). Secure Coding: Principles & Practices. O'Reilly.

Hewlett-Packard Development Company (2011). Top Cyber Security Risks Report.

INCIBE. (2011). Cuaderno de notas del Observatorio ¿Qué son las vulnerabilidades del
software?

MITRE (2012). CVE Introductory Brochure. A brief two-page introduction to the CVE
Initiative.

MITRE. (2012). CWE Introductory Brochure A brief two-page introduction to the CWE
initiative.

MITRE. (2011). CWE/SANS Top 25 Most Dangerous Software Errors.


OWASP TOP 10. (2013). Los diez riesgos más importantes en aplicaciones WEB.
Edición en español.

Goertzel, K. M. (2009). Introduction to Software Security. Edición en español.

Klocwork Inc. (2004). Improving Software By Reducing Coding Defects Investing in


software defect detection and prevention solutions to improve software reliability,
reduce development costs, and optimize revenue opportunities.

SAFECode. (2010). Software Integrity Controls. Assurance-Based approach to


minimizing risks in the software supply chain.

Allen, J. H.; Barnum. S.; Ellison, R. J.; McGraw, G.; Mead, N. R. (2008). Software
Security Engineering: A Guide for Project Managers. Addison Wesley Professional.

Goertzel, K. M., Winograd, T. (2008). Enhancing the Development Life Cycle to Produce
Secure Software, Version 2.0. United States Department of Defense Data and Analysis
Center for Software.

Howard, M., LeBlanc, D. (2003). Writing Secure Code. Microsoft Press.

TEMA 2 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Howard, M., Lipner, S. (2006). The Security Development Lifecycle: SDL: A Process for
Developing Demonstrably Secure Software. Microsoft Press.

McGraw, G. (2005). Software Security: Building Security In. Addison Wesley


Professional.

Redwine Jr., S. T. (Editor). (2006). Software Assurance: A Guide to the Common Body
of Knowledge to Produce, Acquire, and Sustain Secure Software Version 1.1. US
Department of Homeland Security.

Centro Criptológico Nacional (2013). Guía de Seguridad de la STIC (CCN-STIC-400).


Manual de Seguridad de las Tecnologías de la Información y Comunicaciones.

Komaroff, M., Baldwin, K. (2005). DoD Software Assurance Initiative.

National Aeronautics and Space Administration (NASA) (1992). Software Assurance


Standard, Standard No. NASA-STD-2201-93.

Bermejo, J. R., Díaz, G. Estudio de Técnicas Automáticas de Análisis de


Vulnerabilidades de Seguridad en Aplicaciones Web. UNED.

Real Decreto 3/2010, de 8 de enero, por el que se regula el Esquema Nacional de


Seguridad en el ámbito de la Administración Electrónica.

Rambla, J. L. G., Alonso, J, M. (2009). Esquema Nacional de Seguridad con Microsoft.


Microsoft Ibérica S.R.L.

MITRE. Common Attack Pattern Enumeration and Classification — CAPEC™ A


Community Knowledge Resource for Building Secure Software.

Barnum, S., Sethi, A. (2007). Attack Patterns as a Knowledge Resource for Building
Secure. Software Cigital, Inc.

Barnum, S. (2008). Common Attack Pattern Enumeration and Classification (CAPEC)


Schema Description. Department of Homeland Security EEUU. Software Cigital.

TEMA 2 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Ortiz, Z., Galindo, F. (2006). Hacia una Taxonomía de Incidentes de Seguridad en


Internet. Ciencias de investigación Academia Desarrollo.

Rald, S. L. N., Pedersen, J. M. (2012). An Updated Taxonomy for Characterizing


Hackers According to Their Threat Properties. Department of Electronic Systems,
Aalborg University, Denmark.

Microsoft Corporation. (2006). Understanding the Security Risk Management


Discipline.

Hewlett-Packard Development Company, L.P. (2015). HP Security Research. Cyber Risk


Report 2015. Recuperado de http://www8.hp.com/us/en/software-solutions/cyber-
risk-report-security-vulnerability/

ALERT LOGIG. (2014). Defense throughout the vulnerability life cycle with alert logic
threat and log manager. Recuperado de
http://resources.computerworld.com/ccd/assets/61660/detail

Software Assurance Pocket Guide Series (2012). Software Assurance in Acquisition and
Contract Language. Acquisition & Outsourcing, Volume I.

ISO/IEC 27034-1, Information technology - Security techniques - Application security.

TEMA 2 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Lo + recomendado

Lecciones magistrales

Tipos de ciclos de desarrollo de software seguro S-SDLC

En esta lección se presentan varios modelos de ciclo de vida S-SDLC con prácticas de
seguridad incluidas, que se pueden aplicar independientemente del tipo de modelo de,
ciclo de vida en espiral, extreme programming, etc. Además, algunos métodos estándar
de desarrollo se ha demostrado que aumentan la probabilidad de que el software
producido por ellos será seguro y confiable. Así mismo, debido a la popularidad de los
métodos ágiles, es importante el estudiar los problemas de seguridad que surgen cuando
se utilizan este tipo de ciclos de vida.

La lección magistral está disponible en el aula virtual.

TEMA 2 – Lo + recomendado © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

No dejes de ver…

Adding Security to your SDLC

Gartner estima que el 70% de todos los ataques


se han producido en la capa de aplicación en
2013 - convirtiéndose en la superficie principal
de ataque para los hackers. En este vídeo
presenta por qué la capa de aplicación se ha
convertido en el principal objetivo de los
agentes maliciosos, describe el modelo general
S-SDLC e introduce un nuevo enfoque.

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


https://vimeo.com/96026245

Security Design Reviews

La seguridad no es una tarea añadida solo al


final de la fase de implantación, debe abarcar
todas las fases del ciclo de vida del desarrollo
de una aplicación. En este vídeo se presenta
más que suficientes razones de la importancia
de las evaluaciones y revisiones de seguridad
del diseño y las diferentes prácticas de
seguridad de cada una de las fases de SDLC.

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


http://channel9.msdn.com/Blogs/Jossie/Security-Design-Reviews

TEMA 2 – Lo + recomendado © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

+ Información

A fondo

Building Security into the Software Development Life Cycle

Artículo que trata la inclusión de buenas prácticas de seguridad en el ciclo de vida de


desarrollo del software.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://www.coverity.com/library/pdf/coverity-security-wp.pdf

A Plea for Simplicity

Una descripción de principio de diseño de simplicidad.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


https://www.schneier.com/essays/archives/1999/11/a_plea_for_simplicit.html

Enlaces relacionados

The Building Security In Maturity Model

Building Security In Maturity Model (BSIMM) es el resultado de un estudio de iniciativas


de seguridad del software del mundo real, desarrollado a lo largo de varios años.
Presentamos el modelo que se construyó a partir de los datos obtenidos en 67 iniciativas
de seguridad del software.

Accede a la página desde el aula virtual o a través de la siguiente dirección web:


https://www.bsimm.com/

TEMA 2 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Bibliografía

Howard, M., LeBlanc, D. (2003). Writing Secure Code. Microsoft Press.

Howard, M., Lipner, S. (2006). The Security Development Lifecycle: SDL: A Process for
Developing Demonstrably Secure Software. Microsoft Press.

McGraw, G. (2005). Software Security: Building Security In. Addison Wesley


Professional.

McGraw, G. (2003). Building Secure Software: A Difficult But Critical Step in Protecting
Your Business. Cigital, Inc.

Redwine Jr., S. T. (Editor). (2006). Software Assurance: A Guide to the Common Body
of Knowledge to Produce, Acquire, and Sustain Secure Software Version 1.1. US
Department of Homeland Security.

Krassowski, A. y Meunier, P. (2008). Secure Software Engineering: Designing, Writing,


and Maintaining More Secure Code. Addison-Wesley.

TEMA 2 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Test

1. Señala la respuesta correcta. ¿Cuál es el siguiente principio de diseño de seguridad del


Software: Estrategia de protección consistente en introducir múltiples capas de
seguridad, que permitan reducir la probabilidad de compromiso en caso de que una de
las capas falle y en el peor de los casos minimizar el impacto?
A. Simplicidad.
B. Mínimo privilegio.
C. Defensa en profundidad.
D. Ninguna de las anteriores.

2. Señala la respuesta correcta. Indique que medida de seguridad puede ser usada para
implementar el principio de Defensa en Profundidad en la capa física.
A. Mecanismos de cifrado.
B. Plataformas virtuales «sandboxes».
C. Sistemas de gestión y correlación de eventos de infraestructura (SIEM)
D. Cortafuegos, proxy reverso, y sistemas de prevención de intrusiones.

3. Indica la respuesta incorrecta. Algunas de las opciones específicas de diseño del


software que lo simplifican son:
A. Favorecer procesos deterministas sobre los no deterministas.
B. El uso de técnicas de interrupciones en lugar de sondeo.
C. Limitar el número de estados posibles en el software.
D. Desacoplar los componentes y procesos para minimizar las interdependencias
entre ellos

4. Indica la respuesta incorrecta. Separación de privilegios: es un principio que implica


la asignación a las diferentes entidades de un rol, básicamente implica lo siguiente:
A. Acceso a los datos necesarios que debe gestionar para llevar a cabo su función
en base a una serie de roles definidos.
B. Asignación de un subconjunto de funciones o tareas de todas las que ofrece el
sistema.
C. Se evita así que todas las entidades sean capaces de no acceder a la totalidad de
las funciones
D. Ninguna de las anteriores.

TEMA 2 – Test © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

5. Indica la respuesta incorrecta. Normalmente se suele asignar un usuario general con


conjunto de privilegios que le permitirá realizar todas las tareas, incluidas las no
necesarias. Ejemplos de errores comunes son:
A. Usuarios con derechos restringidos.
B. Aplicación de derechos de administrador.
C. Instalación de aplicaciones y servicios con el usuario de administrador.
D Servicios y procesos con privilegios por tiempo indefinido.

6. Indica la respuesta incorrecta. El aislar las entidades de confianza en su área propia


de ejecución (con recursos dedicados a esa área de ejecución) de otras menos confiables
(procesadores de texto, software de descarga, etc.), permite reducir al mínimo su
exposición a otras entidades e interfaces externas susceptibles de ser atacadas por
agentes maliciosos. Las técnicas que tenemos para llevar a cabo lo anterior:
A. Sistemas Unix: chroot jails.
B. Funciones sandboxing de lenguajes de programación como Java, Perl, .NET
(Code Access Security), etc.
C. Trusted processor modules (TPM).
D Sistema operativo virtual.

7. Señala la respuesta incorrecta. Los elementos clave de un proceso de S-SDLC son:


A. Arquitectura y diseño adecuados.
B. Principios y prácticas seguras de software.
C. Requisitos adecuados.
D. Hitos de pago.

8. Indica la respuesta incorrecta. La mayoría de las técnicas de separación de los datos


de programa y configuración y archivos ejecutables se realizan en la plataforma de
ejecución (procesador más sistema operativo). A continuación vemos las más
principales:
A. Permitir a los programas y scripts escribir archivos en directorios escribibles
como el de UNIX/TMP.
B. Establecer permisos de escritura y lectura de los datos de programa y sus
metadatos al programa que los creó a menos que exista una necesidad explícita de
otros programas o entidades para poder leerlos.
C. Los datos utilizados por un script en un servidor Web deben ser colocados fuera
de árbol de documentos del mismo.
D. Utilizar plataformas con arquitectura Harvard.

TEMA 2 – Test © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

9. Señala la práctica de seguridad a la que corresponde la siguiente afirmación. «Son


soluciones generales repetibles a un problema de ingeniería de software recurrente,
destinadas a obtener un software menos vulnerable y un diseño más resistente y
tolerante a los ataques, normalmente se limitan a funciones y controles de seguridad a
nivel del sistema, comunicaciones e información».
A. Test de penetración.
B. Revisión de código.
C. Casos de abuso.
D. Principios de diseño.

10. Señala la respuesta correcta. La seguridad del software es algo más que la
eliminación de las vulnerabilidades y la realización de pruebas de penetración, es una
disciplina. Un aspecto importante de la misma es la adopción de un enfoque sistémico
para:
A. Realizar pruebas de forma correcta.
B. Obtener software de calidad.
C. Incorporar buenas prácticas de seguridad del software «touchpoint» en cada
fase del SDLC y unos hitos de control.
D. Los programadores adquieran conocimientos de seguridad.

TEMA 2 – Test © Universidad Internacional de La Rioja (UNIR)


Seguridad en el ciclo de vida del
software en las fases de requisitos y
diseño
[3.1] ¿Cómo estudiar este tema?

[3.2] Introducción

[3.3] Modelado de ataques

[3.4] Casos de abuso

[3.5] Ingeniería de requisitos de seguridad

[3.6] Análisis de riesgo. Arquitectónico

[3.7] Patrones de diseño

[3.8] Referencias
TEMA
Esquema

Seguridad en el ciclo de vida del software

TEMA 3 – Esquema
Introducción a la seguridad en el
ciclo de vida del software (S-SDLC)

Ingeniería de Análisis de

2
Modelado de Patrones
Casos de abuso requisitos de riesgo.
ataques de diseño
seguridad Arquitectónico

Patrones de Creación de Especificación de Fases del análisis


ataque casos de abuso requisitos de riesgos

Árboles de Ejemplo caso de Metodologías de


ataque uso de seguridad ingeniería de
y caso de abuso requisitos para
software seguro
Seguridad en el Software

© Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Ideas clave

3.1. ¿Cómo estudiar este tema?

Para estudiar este tema lee las Ideas clave que te presentamos a continuación.

El objetivo del presente tema es introducir al alumno en las diferentes prácticas de


seguridad a introducir en el SDLC en las fases de requisitos y diseño, por una
organización al objeto de obtener software más seguro, confiable, que presente un
mínimo de vulnerabilidades y sea resistente a los ataques provenientes del entorno
interior como del exterior.

3.2. Introducción

Como se ha comentado en el tema anterior, se puede definir la seguridad del software


como:

El conjunto de principios de diseño y buenas prácticas a implantar en el SDLC, para


detectar, prevenir y corregir los defectos de seguridad en el desarrollo y adquisición de
aplicaciones, de forma que se obtenga software de confianza y robusto frente
ataques maliciosos, que realice solo las funciones para las que fue diseñado, que
esté libre de vulnerabilidades, ya sean intencionalmente diseñadas o accidentalmente
insertadas durante su ciclo de vida, de forma que se asegure su integridad, disponibilidad
y confidencialidad.

El aumento de los ataques al software vulnerable, ha dejado patente la insuficiencia de


las protecciones a nivel de infraestructura, en este contexto es conveniente el
minimizar al máximo los ataques en la capa de aplicación y por tanto el
número de vulnerabilidades explotables.

TEMA 3 – Ideas clave 3 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Según Gatner dos tercios de las aplicaciones son vulnerables:

Figura 1. Vulnerabilidad aplicaciones. Gatner Inc.

El desarrollo de software seguro y confiable requiere la adopción de un proceso


sistemático o disciplina que aborde la seguridad en cada una de las fases de su ciclo
de vida. Se debe integrar en el mismo dos tipos de actividades de seguridad la primea
es el seguimiento de unos principios de diseño seguro (mínimo privilegio, etc.) y la
segunda la inclusión de una serie de buenas prácticas de seguridad (especificación
requisitos seguridad, casos de abuso, análisis de riesgo, análisis de código, pruebas de
penetración dinámicas, etc.). A este nuevo ciclo de vida con prácticas de
seguridad incluidas lo llamaremos S-SDLC.

Una de las principales ventajas de la adopción de un S-SDLC es el descubrimiento de


errores de codificación y debilidades de diseño en sus etapas tempranas de
su desarrollo, lo que implica, tal y como justificamos en la introducción del primer
tema, un importante ahorro de costes.

Figura 2. Ataques capa aplicación. Fuente: Hoglund. (2004).

TEMA 3 – Ideas clave 4 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Una vez desplegado el software, es fundamental mantener el nivel de seguridad y


confianza, mediante el realización de labores de bastionado del software de base,
gestión de configuración y pruebas de verificación y validación (V&V) como parte de un
proceso de certificación y acreditación que incluya evaluaciones independientes de
terceros.

Poner en funcionamiento prácticas de seguridad del software, que permitan obtener un


software más confiable, requiere hacer algunos cambios en la forma de
construir software en la mayoría de las organizaciones.

3.3. Modelado de ataques

Introducción

El principal objetivo de la seguridad del software es el mantener sus propiedades


de seguridad frente a los ataques realizados por personal malicioso sobre
sus componentes y reducir al mínimo posible sus vulnerabilidades
explotables. Para conseguir que el desarrollo de una aplicación posea las propiedades
y principios de diseño del software seguro presentadas en tema 1, se necesita que el
personal de diseño y desarrollo desarrollen dos perspectivas:

El equipo trabaja para construir un software con las propiedades de


Defensor seguridad necesarias para que sea más resistente a los ataques y
minimizar las debilidades y vulnerabilidad

El equipo se esfuerza por comprender la naturaleza exacta de la amenaza


Atacante a la que el software es probable que se enfrente con el fin de concentrar
los esfuerzos defensivos

Figura 3. Perspectivas de modelado.

La perspectiva del atacante se suele modelar de las siguientes dos formas, que
desarrollamos en párrafos posteriores:

» Patrones de ataque
» Árboles de ataque

TEMA 3 – Ideas clave 5 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

7. Revisión 8.
5. Patrones
código Configuración
de diseño
11. segura
3. Ing. 6. Pruebas 1. Modelado
2. Casos 4. Análisis de Revisión 9. Test
Requisitos basadas en de ataques
de abuso riesgos externa penetración
seguridad riesgo 10.
Operaciones
seguridad

Requisitos Codificación
Arquitectura Pruebas Distribución Operación y
Casos de e
Diseño y despliegue mantenimiento
abuso integración

REALIMENTACIÓN

Figura 4. Modelado de ataques.

El uso combinado de patrones de ataque y árboles de ataque, captura la probabilidad de


cómo los ataques se pueden combinar y secuenciar, esto proporciona una serie
de datos que nos pueden ayudar a diseñar en el software una serie de respuestas
encaminadas a mitigarlos.

Patrones de ataque

Un ataque aprovecha una vulnerabilidad de una aplicación mediante un


exploit, para obtener un beneficio del sistema como escalada de privilegios, robo y
modificación de datos, modificaciones del funcionamiento, denegación de servicio, etc.

Exploit
Del inglés to exploit, explotar o aprovechar. Es una pieza de software, fragmento de
datos o secuencia de comandos y/o acciones, utilizada con el fin de aprovechar una
vulnerabilidad de seguridad de un sistema de información para conseguir un
comportamiento no deseado del mismo. http://es.wikipedia.org

Los patrones de ataque constituyen un mecanismo o medio para capturar y


representar la perspectiva y conocimiento del ciberatacante con el suficiente
detalle acerca de cómo los ataques se llevan a cabo los métodos más frecuentes de
explotación (exploit) y las técnicas usadas para comprometer el software.

TEMA 3 – Ideas clave 6 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

En definitiva constituyen una clasificación de los ataques y una representación


estructurada del pensamiento del atacante, para que el equipo de diseño y
desarrollo obtengan el conocimiento necesario y los pasos a realizar para mitigar con
mayor probabilidad las acciones de los ciberatacantes, reducir su impacto y seleccionar
las políticas de seguridad más convenientes. Derivan del concepto de patrones de diseño
aplicado en un contexto más destructivo que constructivo y están generados a partir de
un análisis en profundidad de determinados ejemplos de exploits del mundo real.

Un catálogo de patrones de ataques, que proporciona un conjunto de definiciones


comunes, una taxonomía de clasificación, un esquema de patrones de ataque y un
conjunto de ellos reales, la constituye la iniciativa del MITRE Common Attack
Pattern Enumeration and Classification (CAPEC).

Actualmente incluye 503 patrones reales de ataque, disponible en:


http://capec.mitre.org.

Dependiendo del nivel de detalle que describe y su nivel de abstracción, los patrones de
ataque constituyen un recurso que proporciona valor al conjunto del SDLC, dado
que puede tener diferentes utilidades en sus diferentes fases. En la tabla siguiente se muestra
un resumen de los usos de los patrones de ataques en las diferentes fases del SDLC.

Fase Utilidad
» Ayuda a identificar requisitos.
Especificación » Ayuda a identificar los riesgos a los que hará frente el software.
de requisitos » Ayuda a definir el comportamiento del sistema para prevenir o reaccionar
ante un tipo específico de ataque probable.
» Proporciona ejemplos de ataques que aprovechan las vulnerabilidades de
Diseño y la arquitectura elegida.
arquitectura » Proporcionan el contexto de las amenazas al que el software se va a
enfrentar, de forma que permite diseñar arquitecturas seguras.
Codificación
» Específica debilidades aprovechadas por los ataques, orientando que
técnicas o prácticas de seguridad de desarrollo evitan estas deficiencias.
» Pueden ser utilizados para orientar las pruebas de seguridad del software
Pruebas en un contexto práctico y realista identificando debilidades concretas para
generar casos de prueba para cada componente.
Operación
» Permitirá la selección de políticas de seguridad y configuraciones acordes
a las amenazas obtenidas de los patrones de ataque.
Aplicación patrones de ataque a las diferentes fases del SDLC.

Un patrón de ataque, como mínimo, debe describir ampliamente el incidente, las


habilidades y recursos necesarios para ejecutarlo con éxito, en qué contextos es aplicable
y proporcionar información suficiente para permitir a los defensores evitar o mitigar

TEMA 3 – Ideas clave 7 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

eficazmente las acciones del atacante. En la tabla siguiente se muestran los ítems de
información de los que consta un patrón de ataque obtenido de CAPEC.

Ítem Descripción
Nombre » Identificador descriptivo del patrón de ataque.

Severidad
» En una escala aproximada típica (muy bajo, bajo, medio, alto, muy
alto) de la gravedad del ataque.
» Descripción detallada del ataque incluyendo la cadena de acciones
Descripción tomadas por el atacante. Descripciones más pormenorizadas podría
incluir árboles de ataque.
» Describe las condiciones que deben existir o funcionalidades y
Prerrequisitos del características que el software de destino debe tener y
ataque comportamiento que debe exhibir para que un ataque de este tipo
tenga éxito.
» Es una escala aproximada (Muy Bajo, Medio Bajo, Alto, Muy Alto).
Probabilidad típica Este campo se utiliza para capturar un valor global promedio típico
del exploit para este tipo de ataque, teniendo en cuenta que no será
completamente exacta para todos.
» Describe el mecanismo de ataque utilizado por este patrón. Con el
fin de ayudar en la normalización y clasificación, este campo
Métodos de ataque comprende una selección de una lista enumerada de definidos
vectores. Este campo puede ayudar a definir la superficie de ataque
requerida por este ataque.

» Contiene ejemplos explicativos o casos demostrativos de este ataque.


Ejemplos Pretende ayudar al lector a comprender la naturaleza, el contexto y
la variabilidad de la agresión en términos más prácticos y concretos.

Conocimiento y » Describe el nivel de habilidad o conocimiento específico requerido


habilidades por un agente malicioso para ejecutar este tipo de ataque. Se codifica
requeridas del con una escala aproximada (bajo, medio, alto), así como un detalle
atacante de contexto.

Recursos
» Este campo describe los recursos (ciclos de CPU, direcciones IP,
herramientas, etc.) requeridos por un atacante para ejecutar con
requeridos
eficacia este tipo de ataque.
» Describe las técnicas normalmente utilizadas para investigar y
Métodos de prueba reconocer un blanco potencial, determinar la vulnerabilidad y
prepararse para este tipo de ataque.

Indicadores de un
» Describe las actividades, eventos, condiciones o comportamientos
que podrían servir como indicadores de que un ataque de este tipo
ataque
es inminente, está en progreso o ha ocurrido.

» Describe acciones o enfoques que pueden potencialmente prevenir o


mitigar el riesgo de este tipo de ataque. Estas soluciones y
Soluciones y mitigaciones están dirigidas a mejorar la resistencia, reduciendo la
mitigaciones probabilidad de éxito del ataque o para mejorar la capacidad de
recuperación del software objetivo, reduciendo el impacto del
ataque si tiene éxito.

TEMA 3 – Ideas clave 8 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Ítem Descripción

Motivación y
» Comprende una selección de una lista enumerada de motivaciones
definidas o consecuencias. Esta información es útil para la
consecuencias del
alineación de patrones de ataque a los modelos de amenaza y para la
ataque
determinación si son relevantes para un contexto dado.

Descripción del
» Describe el contexto en el que este patrón es relevante y aporta más
antecedentes para el ataque. Esta información es útil para una mejor
contexto
comprensión de la naturaleza de este tipo de ataque.
» Describe, lo más exactamente posible, el mecanismo y el formato de
un ataque. Debe tener en cuenta la gramática de un ataque, la
Vector de inyección
sintaxis aceptada por el sistema, la posición de varios campos, y los
rangos de datos que son aceptables.
» Describe los datos de código, configuración u otros a ejecutar o
Payload activar, como parte de un ataque con un vector de inyección de este
tipo.

» Describe el área dentro del software de destino que es capaz de


ejecutar o activar de otro modo la carga útil del vector inyección de
un ataque de este tipo. La zona de activación es donde la intención
Zona de activación
del atacante se pone en acción, puede ser un intérprete de
comandos, un código de máquina activa en un buffer, un navegador
cliente, una llamada API del sistema, etc.
Impacto de » Descripción de los efectos que la activación de la carga útil que un
activación del ataque de este tipo tendría típicamente en la confidencialidad,
payload integridad o disponibilidad del software solicitado.
» Describe el impacto de este patrón de ataque en las características de
seguridad estándar confidencialidad, integridad y disponibilidad.
Impacto CIA Este campo se utiliza para capturar un valor global promedio típico
para este tipo de ataque, teniendo en cuenta de que no será
completamente exacta para todos los ataques.
» Qué vulnerabilidades o debilidades puede el ataque explotar. Se
referencia estándar de la industria CWE. Esta lista debe incluir no
Vulnerabilidades solo a las debilidades que están directamente afectados por el
relacionadas ataque, sino que también aquellas cuya presencia pueda
directamente aumentar la probabilidad de éxito del ataque o el
impacto si tiene éxito.
Requisitos de » Identifica los requisitos de seguridad específicos que son relevantes
seguridad para este tipo de ataques y son lo suficientemente generales como
relevantes para ofrecer oportunidades de reutilización.
Principios de
seguridad
» Identifica los principios de diseño de seguridad que son relevantes
para identificar o mitigar este tipo de ataques.
relacionados

Guía relacionadas
» Identifica las directrices de seguridad existentes que son relevantes
para la identificación o mitigar este tipo de ataque.

» Enumera los recursos de referencia que se utilizaron para elaborar la


Referencias definición de este patrón de ataque y los que podrían ser de utilidad
para ampliar la información sobre este ataque.

Alcance de información de un patrón de ataque.

TEMA 3 – Ideas clave 9 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Árboles de ataque

Un árbol de ataque se puede definir como:

Un método sistemático para caracterizar la seguridad de un sistema, basado en la


combinación y dependencias de las vulnerabilidades del mismo, que un
atacante puede aprovechar para comprometerlo.

En un árbol de ataque, el objetivo del atacante se coloca en la parte superior del


árbol, documentándose las posibles alternativas de ataque en los diferentes recorridos
del árbol, por los nodos de nivel inferior del árbol que contienen objetivos intermedios,
hasta llegar al nivel inferior que contiene los diferentes métodos o técnicas de ataque.
Cada camino a través de un árbol de ataque representa un tipo de ataque único. Para
cada alternativa, se puede añadir recursivamente otras precursoras que alcancen
diversos objetivos parciales que, en conjunto logran el objetivo principal del atacante.

Mediante el examen de diferentes ramas del árbol de ataque, el analista puede


identificar todas las posibles técnicas o métodos que podrían ser utilizados
para comprometer la seguridad del sistema.

Básicamente:

» Captura los pasos realizados en ataques con éxito.


» Captura métodos generales y específicos del sistema de ataque, propiedades del
sistema y otras condiciones previas que hacen, lo hacen posible.
» Se enfoca en las causas de las vulnerabilidades, pero no identifica las contramedidas.
» Representan de forma gráfica y textual de directrices de codificación segura, patrones
de seguridad.

En la representación de la estructura de un árbol de ataque se realiza conforme a


los dos siguientes tipos:

» Textual: sigue una estructura de esquema numérico, el nodo raíz, o la meta,


representada en el primer nivel sin sangría y cada objetivo de nivel inferior se
enumeran con sangría de una unidad por nivel de descomposición.

TEMA 3 – Ideas clave 10 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Ejemplo:

Objetivo: Falsificar una Reserva de vuelos


1. Convencer al empleados de agregar un reserva falsa
1.1 Chantaje empleado
1.2 Amenazar empleado
2. Acceder y modificar la base de datos de vuelos
2.1 Realizar una inyección SQL en la página Web
2.2 Iniciar una sesión en la base de datos
2.2.1 Adivinar la contraseña
2.2.2 Obtener la contraseña rastreando la red (sniff)
2.2.3 Robar la contraseña del servidor
2.2.3.1 Obtener una cuenta del servidor (AND)
2.2.3.1.1 Desbordamiento de búfer
2.2.3.1.2 Obtener acceso cuenta empleado
2.2.3.2 Explotar condición de carrera acceso perfil
protegido

» Grafica o semántica: se construye generalmente con el nodo raíz, o la meta, en la


parte superior, al descender por las ramas del árbol se obtienen subobjetivos hasta
que se llega al nivel inferior donde están los métodos de ataque. Un nodo se
descompone como:

O1
Descomposición «AND»
Un conjunto de objetivos de ataque de nivel inferior, que
tienen que ser alcanzados para que el ataque tenga éxito.
O1.1 O1.2

O1 Descomposición «OR»
Una serie de objetivos de ataque de nivel inferior,
cualquiera de los cuales puede lograrse para que el ataque
O1.1 O1.2 tenga éxito.

Figura 5. Aplicación patrones de ataque a las diferentes fases del SDLC.

TEMA 3 – Ideas clave 11 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Figura 6. Vista conceptual de un árbol de ataque. Adaptada de Redwine, S. T. Jr. (2006).

TEMA 3 – Ideas clave 12 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

3.4. Casos de abuso

Introducción

Los diagramas de casos de uso constituyen unas buenas prácticas para la obtención de
los requisitos funcionales de una aplicación, sin embargo para la obtención de requisitos
de seguridad no lo son, sobre todo los no funcionales o requisitos negativos
referidos a actividades que no debería realizar el sistema. Para solucionar lo anterior se
ha creado un tipo especializado de casos de uso que se utilizan para analizar y especificar
las amenazas de seguridad, caso de abuso, Guttorm, A. y Opdahl, L. (2001) los definen
como:

Un caso de abuso es la inversa de un caso de uso, es decir, una función que el sistema no
debe permitir o una secuencia completa de acciones que resulta en una pérdida para la
organización.

3. Ing. 7. Revisión 8.
Requisitos 5. Patrones
código Configuración
seguridad de diseño
11. segura
6. Pruebas 1. Modelado
2. Casos 4. Análisis de Revisión 9. Test
basadas en de ataques
de abuso riesgos externa penetración
riesgo 10.
Operaciones
seguridad

Requisitos Codificación
Arquitectura Pruebas Distribución Operación y
Casos de e
Diseño y despliegue mantenimiento
abuso integración

REALIMENTACIÓN

Figura 7. Casos de abuso.

Los casos de abuso, o casos de mal uso, son un instrumento que puede ayudar a pensar
de la misma forma que lo hacen los atacantes. Pensando más allá de los aspectos
normativos y funcionales y también estudiando eventos negativos o inesperados, los

TEMA 3 – Ideas clave 13 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

profesionales de seguridad de software entienden mejor cómo crear software seguro,


pues permiten obtener una mejor comprensión de las áreas de riesgo del sistema a través
de (Redwine, 2006):

» Identificación los objetivos de seguridad que debe cumplir el software.


» Identificación de las amenazas de seguridad a ser neutralizadas por el software.
» Identificación de los puntos en el software susceptibles de ser atacados.
» Definición de restricciones, o requisitos negativos, necesarios para alcanzar las
contramedidas necesarias y los objetivos de seguridad.
» Obtener requisitos de seguridad que garanticen que el software aplica las
restricciones necesarias.

Los casos de abuso constituyen un excelente medio de análisis de las amenazas


que debe afrontar el software. Son apropiados para el análisis y especificación de
restricciones, o requisitos negativos, ya que se basan en el uso indebido del sistema.
Establecen la base para otros casos de uso de seguridad que proporcionan los medios
para contrarrestar o mitigar las amenazas capturadas en los mismos y una manera
altamente reutilizable de organizar, analizar y especificar los requisitos de
seguridad de los mismos.

Los casos de abuso describen lo que el software no debe hacer en respuesta al


uso incorrecto o malintencionado del mismo por un agente malicioso. Para cada
caso de uso funcional, el desarrollador debería explorar las formas en que
esa función podría ser deliberadamente mal utilizada. El desarrollador tiene
que identificar todas las posibles relaciones entre casos de uso de seguridad y casos
abuso, para especificar restricciones y requisitos de seguridad para evitar un mal uso o
abuso de las funcionalidades del software. En la figura siguiente se muestra la relación
entre el caso de uso de seguridad y el de abuso asociado (Donald, 2003).

TEMA 3 – Ideas clave 14 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Figura 8. Relación entre el caso de uso de seguridad y el de abuso asociado. Extraída de Donald (2003).

En la siguiente tabla se resume las diferencias entre los casos de uso de seguridad y los
casos de abuso (Donald, 2003):

Característica Casos de Abuso Casos Uso Seguridad


Uso Analiza y especifica las amenazas a Analiza y especifica los
la seguridad requisitos de seguridad
Criterio de éxito Éxito del atacante Éxito de la aplicación
Producido Equipo de seguridad Equipo de seguridad
Usado Equipo de seguridad Equipo de requisitos
Actor externo Atacantes y usuarios Usuarios
Conducido por Análisis de vulnerabilidades de Casos de abuso
activos y amenazas
Diferencias entre los casos de uso de seguridad y los casos de abuso.

Ejemplo caso de uso de seguridad y caso de abuso

Tomando como referencia el artículo de Donald (2003), a continuación presentamos un


ejemplo caso de uso de seguridad y caso de abuso asociados en su versión gráfica, que
ilustra las diferencias entre ambos.

Se presenta un caso de uso tradicional de un cajero automático que puede realizar las
tareas de consulta saldo, depositar, retirar y transferir fondos. Para manejar con
seguridad una de las cuentas, se pueden especificar los casos de uso de seguridad:

» Control de acceso. Identificación, autenticación y autorización.


» Privacidad. Garantizar la privacidad de datos y comunicaciones.

TEMA 3 – Ideas clave 15 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Integridad. Garantizar la integridad de datos y comunicaciones.


» No repudio. Garantizar el no repudio de las transacciones.

Los cuatro casos uso resultantes de especificar los requisitos de seguridad, protegen al
cajero automático y a sus usuarios de tres amenazas potencialmente realizables por un
cibercriminal.

CONTROL DE INGENIERIA
DEPOSITAR ACCESO SOCIAL
RETIRAR
FONDOS (SEGURIDAD) (ABUSO
FONDOS Pirata
informático
ROMPER
PRIVACIDAD
PRIVACIDAD
(SEGURIDAD)
GESTION (ABUSO)
CUENTAS
USUAR
USUARIO
PENETRACION
INTEGRIDAD
(SEGURIDAD) FRAUDE (ABUSO) Cibercriminal

TRANSFERIR CONSULTAR
FONDOS SALDO
NO AGENTES
CASO USO CASOS
REPUDIO MALICIOSOS
SEGURIDAD ABUSO

Figura 9. Ejemplo caso de uso de seguridad y caso de abuso. Extraída de Donald (2003).

En el documento de referencia de Guttorm, A. y Opdahl, L. (2001) se presenta un caso


de abuso para un caso de comercio electrónico, en sus dos versiones, textual considerada
como la más importante y gráfica. Presenta varias relaciones:

» Relación caso abuso → uso seguridad: «incluye» y «extiende».


» Relación caso de uso → abuso: «previene» y «detecta».

TEMA 3 – Ideas clave 16 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Previene Inundar el
Bloquear sistema Detecta
Hojear
Extiende repetidos
catálogo
registros

Registrar Incluye Robar


Cliente cliente información
Incluye tarjeta
Extiende Incluye
Encriptar Previene
Ordenar mensaje Interceptar Cibercriminal
compras Incluye comunicacion

Incluy
Operador Cambiar
contraseña Obtener
Incluye Previene Detecta
contraseña
Extiende
Incluye Monitorizar
el sistema
Establecer
Inicio de
política Incluye
sesión
contraseñas

Figura 10. Ejemplo caso de uso comercio electrónico. Fuente: Guttorm, A. y Opdahl, L. (2001)

3.5. Ingeniería de requisitos de seguridad

Introducción

Gran parte de la mayoría de las vulnerabilidades y debilidades del software tienen su


origen en unos requisitos inadecuados, inexactos e incompletos,
principalmente debido a la falta o debilidad de la especificación de los mismos, que no
determinan las funciones, restricciones y propiedades no funcionales del software que
hacen que este sea previsible, confiable y resistente.

Defectos en los requisitos cuestan 10 a 200 veces más para corregir durante la ejecución,
que si se detectan durante la especificación de los mismos. Además es difícil y costoso
mejorar significativamente la seguridad de una aplicación después de que esté en su
entorno de producción.

La fase de ingeniería de requisitos cubre todas las actividades y tareas que


deben realizarse antes de iniciar el diseño, su principal resultado es la
especificación de los requisitos que definen los aspectos funcionales y no
funcionales del software.

TEMA 3 – Ideas clave 17 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

7. Revisión 8.
5. Patrones
código Configuración
de diseño
11. segura
3. Ing. 6. Pruebas 1. Modelado
2. Casos 4. Análisis de Revisión 9. Test
Requisitos basadas en de ataques
de abuso riesgos externa penetración
seguridad riesgo 10.
Operaciones
seguridad

Requisitos Codificación
Arquitectura Pruebas Distribución Operación y
Casos de e
Diseño y despliegue mantenimiento
abuso integración

REALIMENTACIÓN

Figura 11. Ingeniería de requisitos.


Los requisitos de seguridad deben ser considerados simultáneamente junto con
los demás requisitos, incluidos los relativos a funcionalidad, rendimiento, facilidad
de uso, ya que normalmente los «requisitos de seguridad» a menudo entran en
conflicto con ellos, se hace necesario por tanto:

Integración satisfactoria de la ingeniería de requisitos de seguridad con la ingeniería de


requisitos en su conjunto.

Los requisitos de las funcionalidades o servicios de seguridad del sistema o


el software a menudo se confunden con los requisitos de software seguro:

» Requisitos servicios de seguridad. Incluye la especificación de funciones que


implementan una política de seguridad, como control de acceso, autenticación,
autorización, cifrado y gestión de claves. En la siguiente figura se muestra un alcance
completo de este tipo de requisitos:

TEMA 3 – Ideas clave 18 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Figura 12. Requisitos servicios de seguridad.

Deben especificar:

o Propiedades que el software debe exhibir, ejemplo: el software debe tener


un comportamiento correcto y predecible y disponer de capacidades de
recuperación frente a ciberataques.
o Nivel requerido de seguridad y salvaguardas de riesgo de las funciones de
seguridad.
o Los controles y normas que rigen los procesos de desarrollo,
implementación y operación del software.

» Requisitos de software seguro. Requisitos que afectan directamente a la


probabilidad de que el software sea seguro. Estos abarcan principalmente los
no funcionales, los que garanticen que el sistema seguirá siendo confiable, incluso
cuando esa confianza se vea amenazada.

TEMA 3 – Ideas clave 19 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Figura 13. Vista de alto nivel de las tareas y artefactos involucrados en la fase de requisitos.

Es fundamental que los requisitos de seguridad del software sean:

» Completos.
» Precisos.
» Coherentes.
» Trazables.
» Verificables.

Existen, provenientes de ingeniería de software, una serie de herramientas que permiten


mantener la trazabilidad y gestión de los requisitos de seguridad de sistemas complejos
y críticos. Entre ellas tenemos:

» Praxis High Integrity Systems’ REVEAL.


» Telelogic’s DOORS.
» ChiasTek’s REQTIFY.
» Safeware Engineering’s SpecTRM.

Uno de los problemas típicos relacionados con la ingeniería de software es el análisis


de requisitos o bien no se realiza en absoluto (los requisitos identificados se especifican

TEMA 3 – Ideas clave 20 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

directamente sin ningún análisis o modelado) o se limita a los requisitos funcionales,


haciendo caso omiso de las exigencias de calidad y otras limitaciones, como la
arquitectura, el diseño, implementación y pruebas.

3.6. Análisis de riesgo. Arquitectónico

Introducción

Según estudios y estadísticas disponibles se sabe que aproximadamente un 50 % de los


defectos de seguridad se deben a errores en la fase de diseño denominados «debilidades»
o «flaws» en idioma Ingles. Identificando el riesgo y después con la gestión del
mismo se pueden mitigar gran parte de los problemas de seguridad de un
software.

7. Revisión 8.
5. Patrones
código Configuración
de diseño
11. segura
3. Ing. 6. Pruebas 1. Modelado
2. Casos 4. Análisis de Revisión 9. Test
Requisitos basadas en de ataques
de abuso riesgos externa penetración
seguridad riesgo 10.
Operaciones
seguridad

Requisitos Codificación
Arquitectura Pruebas Distribución Operación y
Casos de e
Diseño y despliegue mantenimiento
abuso integración

REALIMENTACIÓN

Figura 14. Análisis de riesgos.

En la figura anterior, se puede observar que el análisis de riesgos está a caballo entre
la fase análisis de requisitos, donde se obtienen los requisitos de seguridad,
se modelan ataques y realizan casos de abuso, y la fase de la fase de
arquitectura y diseño. Sigue en importancia a la revisión de código, si bien este hecho

TEMA 3 – Ideas clave 21 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

puede variar dependiendo de las características de la organización, de sus tipos de


sistemas, cantidad de software, etc.

En la fase de análisis al obtener los requisitos de seguridad se han obtenido bastantes


conclusiones acerca de los activos del sistema y del impacto que los posibles ataques
pueden causar, pero es en la fase de diseño de la arquitectura del sistema donde se
especifican todos los activos porque se obtienen todos los componentes hardware y
software del sistema, se configura la arquitectura y se deciden las salvaguardas concretas
que van a protegerlo, en función de los requisitos de seguridad y los casos de abuso.

Un análisis de riesgo riguroso implica un exhaustivo entendimiento del impacto sobre el


negocio u objetivos de la organización, que puede requerir un conocimiento de leyes y
regulaciones tanto como del modelo de negocio soportado por el software. También, los
desarrolladores y diseñadores habrán llegado a ciertas suposiciones sobre su sistema y
los riesgos que este afronta.

Un acercamiento a un prototipo de análisis y gestión de riesgo típico implica varias


actividades principales que a menudo incluyen un número de actividades básicas:

» Leer y entender las especificaciones, documentos de arquitectura, y otros documentos


de diseño.
» Discutir sobre el objetivo de análisis con el grupo: brainstorming.
» Determinar los límites del sistema y datos sensibles y críticos.
» Probar el software si ya existe algún prototipo.
» Estudiar el código y otros componentes de software incluyendo el empleo de
herramientas de análisis de código.
» Identificar las amenazas y las fuentes relevantes de ataque. Esta tarea se deriva
fácilmente si se ha hecho previamente la obtención de casos de abuso y los requisitos
de seguridad del sistema.
» Identificar vulnerabilidades posibles, aprovechando el uso de herramientas y
documentación sobre vulnerabilidades comunes.
» Discutir las posibles modificaciones o parches para corregir vulnerabilidades.
» Determinar la probabilidad de riesgo.
» Planificar escenarios de ataque para explotación de las vulnerabilidades.
» Determinar el posible impacto sobre los activos y objetivos de negocio.
» Clasificar los riesgos.
» Desarrollar una estrategia de mitigación.

TEMA 3 – Ideas clave 22 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Recomendar las salvaguardas para mitigar los riesgos.


» Informe de conclusiones.
» Proporcionar la información básica en cuanto a dónde emplear recursos de mitigación
limitados.

Un análisis de riesgos es un proceso sistemático que tiene como propósito estimar la


magnitud y probabilidad de los riesgos a los que podría estar expuesta una organización
y saber qué decisión tomar ante una posible eventualidad. Este proceso aplicado el
desarrollo y diseño del software se denomina «Modelado de Amenazas».
Constituye una herramienta válida para evaluar los riesgos inherentes a una aplicación
durante su desarrollo, principalmente en la etapa de diseño, y que puede ser utilizada
por equipos de desarrollo que no cuenten con expertos en seguridad.

Existen varios métodos o metodologías de Modelado de Amenazas que se


pueden aplicar al desarrollo de software:

Metodologías
1 CORAS (Consultative Objective Risk Analysis System) and SECURIS (Research Council
of Norway-funded Model-Driven Development and Analysis of Secure Information
Systems).
Herramienta
2 CIGITAL's architectural risk analysis process.
3 OCTAVE (Operationally Critical Threat, Asset, and Vulnerability Evaluation). SEI de la
Universidad Carnegie Mellon
4 PTA Technologies Calculative Threat Modeling Methodology (CTMM).
5 Trike. Metodología de evaluación de amenazas.
6 MTAM (Microsoft Threat Analysis and Modeling).
7 PASTA (Process for Attack Simulation and Threat Analysis).
Metodologías de análisis de riesgos.

TEMA 3 – Ideas clave 23 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

3.7. Patrones de diseño

Según se define en el documento de referencias (McGraw, 2005) los patrones de


diseño son:

Una solución general repetible a un problema de ingeniería de software recurrente,


que está expresamente destinado a contribuir al diseño de software menos
vulnerable, más resistente y tolerante a los ataques.

7. Revisión 8.
5. Patrones
código Configuración
de diseño
11. segura
3. Ing. 6. Pruebas 1. Modelado
2. Casos 4. Análisis de Revisión 9. Test
Requisitos basadas en de ataques
de abuso riesgos externa penetración
seguridad riesgo 10.
Operaciones
seguridad

Requisitos Codificación
Arquitectura Pruebas Distribución Operación y
Casos de e
Diseño y despliegue mantenimiento
abuso integración

REALIMENTACIÓN

Figura 15. Patrones de diseño.

El concepto de patrones es más familiar en ingeniería de software, relacionados


principalmente con la arquitectura de los sistemas o soluciones para el diseño de los
mismos. Se han desarrollado patrones de diseño de seguridad para casi todas las
fases del SDLC: requerimientos, análisis, diseño, codificación, etc. El uso adecuado de
estos patrones conduce a la remediación de los principales fallos de seguridad, como por
ejemplo, uno que tuvo un efecto significativo fue un «validador» que construía un
modelo de validación de entrada para defenderse contra los ataques de inyección SQL,
otros ejemplos son los construidos para los lenguajes de programación en C y / o C + +.

A continuación se presentan ejemplos de este tipo de patrones (Redwine, 2006):

TEMA 3 – Ideas clave 24 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Schumacher, Markus, Eduardo Fernandez-Buglioni, Duane Hybertson, Frank


Buschmann, and Peter Sommerlad. Security Patterns: Integrating Security and
Systems Engineering. New York, New York: John Wiley & Sons; 2005.
» Blakley, Bob and Craig Heath, Craig. Technical Guide to Security Design Patterns. San
Francisco, California: The Open Group, 2004 y SecurityPatterns Website.
» Steel, Chris, Ramesh Nagappan, and Ray Lai. Core Security Patterns. Indianapolis,
Indiana: Prentice-Hall Professional, 2005 y Viega, John and Matt Messier. Secure
Programming Cookbook for C and C++. Sebastopol, California: O’Reilly, 2003.
» Kienzle, Darrell M., Matthew C. Elder, David Tyree, and James Edwards-Hewitt.
Security Patterns Repository, Version 1.0, “Security Patterns for Web Application
Development: Final Technical Report”, 4 November 2003 y W. Cunningham,
“Portland pattern repository”, Cunningham & Cunningham, Inc, http://c2.com/ppr/.

3.8. Referencias

Chess, B. y West, J. (2007). Secure Programming with Static Analysis. Addison-Wesley


Software Security Series.

Howard, M. y LeBlanc, D. (2003). Writing Secure Code. Microsoft Press.

Allen, J. H., Barnum, S., Ellison, R. J., McGraw, G., and Mead, N. R. (2008). Software
Security Engineering: A Guide for Project Managers. Addison Wesley Professional.

Goertzel, K. M., and Winograd, T. (2008). Enhancing the Development Life Cycle to
Produce Secure Software, Version 2.0. United States Department of Defense Data and
Analysis Center for Software.

OWASP. (2010). OWASP TOP 10. Los diez riesgos más importantes en aplicaciones
WEB. Edición en español.

Howard, M., and Lipner, S. (2006). The Security Development Lifecycle: SDL: A Process
for Developing Demonstrably Secure Software. Microsoft Press.

McGraw, G. (2005). Software Security: Building Security In. Addison Wesley


Professional.

TEMA 3 – Ideas clave 25 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Redwine, S. T. Jr. (Editor). (2006). Software Assurance: A Guide to the Common Body
of Knowledge to Produce, Acquire, and Sustain Secure Software Version 1.1. US
Department of Homeland Security.

Goertzel, K. M., and Winograd, T. (2008). Enhancing the Development Life Cycle to
Produce Secure Software, Version 2.0. United States Department of Defense Data and
Analysis Center for Software.

Komaroff, M., (ASD/NII) and Baldwin, K. (OSD/AT&L). (2005). DoD Software


Assurance Initiative.

Bermejo, J. R., and Díaz, G. Estudio de Técnicas Automáticas de Análisis de


Vulnerabilidades de Seguridad en Aplicaciones Web. UNED.

Barnum, S., and Sethi, A. (2007). Attack Patterns as a Knowledge Resource for Building
Secure. Software Cigital, Inc.

Barnum, S. (2008). Common Attack Pattern Enumeration and Classification (CAPEC)


Schema Description. Department of Homeland Security EEUU, Software Cigital.

Graff. M. G. Secure Coding. The State of the Practice.

Wyk, G. (2003). Secure Coding: Principles & Practices By M. G. Graff, K. R. van Wyk.
Publisher: O'Reilly.
Hoglund. (2004). Exploiting Software: How to Break Code, By G. Hoglund and G.
McGraw. Addison-Wesley Software Security Series.

Sroka, D. Presentación HP Fortify User Training.

Microsoft Corp. (2003). Application Security Best Practices at Microsoft: The Microsoft
IT Group Shares Its Experiences.

Microsoft Corp (2010). Simplified Implementation of the Microsoft SDL.

Donald, G. (2003). Software Engineering Institute, U.S.A. Security Use Cases. Journal
of Object Technology.

TEMA 3 – Ideas clave 26 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Guttorm Sindre, A. y Opdahl, L. Capturing Security Requirements through Misuse


Cases.

López, S. (2012). Descubriendo el valor de la Seguridad en las Aplicaciones Web con


IBM AppScan. IBM Corporation.

Cunningham, W. Portland pattern repository. Cunningham & Cunningham, Inc.

TEMA 3 – Ideas clave 27 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Lo + recomendado

Lecciones magistrales

Modelado de amenazas

En la presente lección se desarrolla la metodología de amenazas propuesta por


Microsoft: STRIDE, que puede ser ejecutada tanto por expertos como no expertos en
seguridad de la información (diseñadores, desarrolladores, etc.) y se realiza una
introducción a la herramienta que la soporta.

La lección magistral está disponible en el aula virtual.

No dejes de leer…

Microsoft. Simplified Implementation of the Microsoft SDL

En documento describe los conceptos básicos del Microsoft Security Development


Lifecycle (SDL) y las actividades de seguridad individuales en cada una de sus fases.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://www.microsoft.com/es-es/download/details.aspx?id=12379

TEMA 3 – Lo + recomendado 28 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

LingerAttack Modeling for Information Security and Survivability

Esta nota técnica que describe e ilustra un para documentar e identificar patrones de
ataque que ocurren comúnmente al objeto de que los diseñadores de sistemas de
información y analistas pueden utilizarlos para desarrollar sistemas de información más
robustos y confiables.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://resources.sei.cmu.edu/asset_files/TechnicalNote/2001_004_001_13793.pdf

Software Design Misuse and Abuse Cases. Getting Past Positive. Cigital INC

Articulo interesante sobre el diseño de casos de abuso.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


https://www.cigital.com/papers/download/bsi2-misuse.pdf

No dejes de ver…

SDL Tools Overview

Vídeo sobre las diversas herramientas


a utilizar en las diversas fases de
S_SDLC «Microsoft SDL». Doug Cavit,
del equipo de Microsoft SDL
ingeniería, explica por qué los
ejecutivos y gerentes de TI deben
alentar a sus equipos de desarrollo
para descargar las herramientas para implementar un proceso de aseguramiento de
seguridad del software, como el SDL Microsoft.

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


http://technet.microsoft.com/en-us/video/sdl-tools-overview

TEMA 3 – Lo + recomendado © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Trustworthy Computing's

Emil Karafezov presenta las nuevas


características de la herramienta de
modelado de amenazas Microsoft Modeling
Tool 2014.

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


https://www.youtube.com/watch?v=G2reie1skGg

Threat Modeling, by Jim DelGrosso

Vídeo que proporciona una


descripción del proceso de
modelo de amenazas que utiliza
Cigital, mediante un ejemplo de
aplicación del proceso para
identificar fallas potenciales en
un sistema. Objetivos:

» Describir terminología utilizada en el modelado de amenazas


» Describir un proceso de modelado de amenazas de un sistema
» Realizar un modelo de amenazas de algún sistema ficticio

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


https://www.youtube.com/watch?v=We2cy8JwVqc

TEMA 3 – Lo + recomendado © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Introduction. Threat Models

Clase del MIT OpenCourseWare del Professor Zeldovich acerca del modelado de
amenazas.

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


https://www.youtube.com/watch?v=GqmQg-cszw4&feature=youtu.be

No dejes de practicar…

Demostración de pruebas de caja negra

En el siguiente documento se muestra cómo realizar pruebas de caja negra sobre una
aplicación web realizada mediante la aplicación IBM Security AppScan.

El documento está disponible en el aula virtual.

TEMA 3 – Lo + recomendado © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

+ Información

A fondo

Capturing Security Requirements through Misuse Cases

Trabajo que analiza una extensión conceptual de casos de uso, es decir, casos de mal uso,
que describe las acciones que no debería ser posible en un sistema.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://www.nik.no/2001/21-sindre.pdf

Software Assurance in Acquisition: Mitigating Risks to the Enterprise

Esta guía proporciona información sobre cómo incorporar prácticas de aseguramiento


del Software durante todo el proceso de adquisición durante las fases de planificación
de la contratación de la adquisición, supervisión y aceptación, y seguimiento. Se
recomienda leer desde la página 12 a la 49.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


https://www.us-cert.gov/bsi/articles/best-practices/acquisition/a-systemic-approach-
assessing-software-supply-chain-risk

Security Quality Requirements Engineering (SQUARE) Methodology

Documento sobre la metodología de ingeniería de requisitos de seguridad (SQUARE)


para obtener y priorizar los requerimientos de seguridad en los proyectos de desarrollo
de software. Se detalla y explican los pasos de la metodología y los resultados de su
aplicación en estudios de casos recientes.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://www.sei.cmu.edu/reports/05tr009.pdf

TEMA 3 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Attack Patterns as a Knowledge Resource for Building Secure

En este trabajo se analiza el concepto de patrones de ataque, como un mecanismo para


capturar y comunicar la perspectiva del atacante.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://capec.mitre.org/documents/Attack_Patterns-
Knowing_Your_Enemies_in_Order_to_Defeat_Them-Paper.pdf

Common Attack Pattern Enumeration and Classification (CAPEC) Schema


Description

El propósito de este documento es definir un esquema estándar para representar


patrones de ataque y describir de forma detallada el significado y el propósito de cada
elemento de esquema constituyente.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://capec.mitre.org/documents/documentation/CAPEC_Schema_Description_v1.3.pdf

Practical Measurement Framework for Software Assurance and


Information Security

Documento de métricas de medidas de seguridad del software e Información que


proporciona un método para medir la eficacia de las medidas de seguridad a nivel
organizacional programa o proyecto.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://www.psmsc.com/Downloads/TechnologyPapers/SwA%20Measurement%2010-
08-08.pdf

TEMA 3 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Application Security Best Practices at Microsoft

El documento contiene la descripción de los procesos, las políticas y mejores prácticas


que puedan ser de utilidad para las organizaciones crean software seguro.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://download.microsoft.com/download/0/d/3/0d30736a-a537-480c-bfce-
5c884a2fff6c/AppSecurityWhitePaper.doc

Bibliografía

McGraw, G. (2005). Software Design Misuse and Abuse Cases. Getting Past Positive.
Cigital INC.

Chess, B. y West. J. (2007). Secure Programming with Static Analysis. Addison-Wesley


Software Security Series.

Howard, M., LeBlanc, D. (2003). Writing Secure Code. Microsoft Press.

Howard, M., Lipner, S. (2006). The Security Development Lifecycle: SDL: A Process for
Developing Demonstrably Secure Software. Microsoft Press.

McGraw, G. (2005). Software Security: Building Security In. Addison Wesley


Professional.

Redwine Jr., S. T. (Editor). (2006). Software Assurance: A Guide to the Common Body
of Knowledge to Produce, Acquire, and Sustain Secure Software Version 1.1. US
Department of Homeland Security.

Allen, J. H.; Barnum. S.; Ellison, R. J.; McGraw, G.; Mead, N. R. (2008). Software
Security Engineering: A Guide for Project Managers. Addison Wesley Professional.

Krassowski, A. y Meunier, P. (2008). Secure Software Engineering: Designing, Writing,


and Maintaining More Secure Code. Addison-Wesley.

TEMA 3 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Actividades

Trabajo: Metodologías de modelado de amenazas

Para seguir profundizando en el modelado de amenazas se propone realizar este trabajo


que contenga al menos el siguiente contenido:

» Introducción al modelado de amenazas.


» Estudio de metodologías existentes.
» Descripción de una metodología en profundidad.
» Ejercicio práctico de modelado de amenazas, utilizando una herramienta de
modelado como Threat Analysis and Modeling Tool 2014, del siguiente caso que se
describe a continuación (incluir los ficheros generados por la herramienta junto con
el del trabajo en un fichero a subir en la plataforma).

Caso práctico

Con objetivo de afianzar los conocimientos adquiridos sobre el modelado de amenazas,


se pide el definir, modelar y medir las posibles amenazas de una tienda de libros online,
llamada Librería On-Line SA.

Últimamente, ha sufrido un ciberataque que ha comprometido las credenciales de sus


clientes. El incidente ha trascendido en los medios de comunicación, lo que ha producido
una pérdida de cuota de mercado importante, frente a sus competidores.

Con el objetivo de mantener su actual posición en el mercado de venta electrónica de


libros y volver a recurar e incluso superar la que tenía, ha contratado a la empresa
InfoSecurity para llevar a cabo un trabajo de modelado de amenazas a sus sistemas TI
e implementar las salvaguardas que se deriven del mismo en función del nivel de riesgo
y la disponibilidad económica. Se le establece los siguientes requisitos de negocio y
técnicos:

» Habrá tres tipos de usuarios en la aplicación: clientes, administrador TI y agente de


ventas
» Los clientes deben poder buscar productos y gestionar sus pedidos utilizando la tienda
web o llamando a la oficina de ventas.

TEMA 3 – Actividades © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Para que un cliente pueda realizar un pedido el cliente debe, con anterioridad,
registrase para crearle una cuenta.
» El cliente puede pagar con una tarjeta de crédito, débito o mediante trasferencia
bancaria.
» Los clientes deben iniciar sesión antes para poder personalizar sus preferencias.
» Los clientes deben ser capaces de revisar y modificar sus pedidos realizados.
» Los agentes de ventas pueden conceder descuentos a los clientes.
» Los administradores pueden modificar y eliminar clientes y productos e información.
» La tienda web de la librería tendrá que ser accesible desde Intranet e Internet.
» La tienda web deberá diseñarse con una arquitectura distribuida por razones de
escalabilidad.
» El cliente necesitará autenticarse en la tienda web con las credenciales de la cuenta de
usuario, que a su vez se comprobarán contra la base de datos implementada en el
backend de la compañía, a través de una interfaz de servicios web.
» La información de la cuenta del usuario y la información del producto deberán
mantenerse en una base de datos relacional.
» El procesamiento de tarjetas de crédito será subcontratado a un procesador de
terceros.
» Las interacciones de los usuarios con la tienda web se almacenan en un servidor de
log interno de la organización.
» La base de datos deberá copiarse periódicamente en una ubicación de un proveedor
de servicios TI de terceros, para propósitos de recuperación ante desastres.
» El sitio web se diseñará lógicamente como una aplicación cliente/servidor distribuida
conforme a un modelo de tres capas: presentación, proceso y datos.
» Los clientes accederán a la aplicación utilizando navegadores web de escritorio, y
dispositivos móviles.
» El sitio web se desplegará en Internet protegido por una DMZ de dos capas con acceso
tanto para usuarios internos como externos.
» Físicamente, la aplicación estará completamente alojada en un servidor de
aplicaciones (Frontend) alojado en la DMZ, con acceso a un servidor de base de datos
que estará en la red interna de la compañía (Backend).
» Las tecnología utilizada en el desarrollo de la aplicación web es ASP.Net utilizando C
# y la base de datos del backend de la compañía está implementada en base al
producto Microsoft SQL Server.

TEMA 3 – Actividades © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Los objetivos de seguridad establecidos para la tienda web de Librería On-Line SA son
los siguientes objetivos:

OB-1. Recuperar la imagen de la compañía deteriorada tras el ciberincidente ocurrido.


OB-2. Obtener la posición líder de mercado en venta de libros online.
OB-3. Mantener confidencialidad, integridad y disponibilidad de la información
almacenada y trasmitida.
OB-4. Proporcionar un servicio seguro a los clientes existentes y potenciales.
OB-5. Proporcionar un servicio ininterrumpido a los clientes existentes y potenciales.
Se aplicarán técnicas de monitorización, equilibrio de carga, replicación, recuperación
ante desastres y continuidad del negocio y copias de seguridad recuperables
OB-6. Proporcionar una experiencia de usuario mejorada a los clientes existentes y
potenciales.
OB-7. Se establecerán procesos de autenticación, autorización y auditoría.

El sistema estará basado en una típica arquitectura de una aplicación web de tres capas,
donde el cliente es un navegador que accede a los servicios proporcionados por el sitio
web de la librería, que contiene una base de datos de los clientes, cuentas y publicaciones
disponibles, alojada en un servidor de bases de datos y un servidor web que implementa
toda la lógica de negocio.

Tener en cuenta que nos encontramos en la fase análisis de requisitos del SDLC,
identificando requisitos funcionales y de seguridad.

Realización del diagrama DFD de la arquitectura de la aplicación

Para la realización del DFD se utilizara la herramienta Threat Analysis and Modeling
Tool 2016 de la compañía Microsoft, descargable en el siguiente enlace:

Accede a más información a través del aula virtual o desde la siguiente dirección web:
https://www.microsoft.com/en-us/download/details.aspx?id=49168

TEMA 3 – Actividades © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Como ayuda a su manejo, aparte de los manuales que se pueden descargar con
esta herramienta, se aconseja visionar estos dos videos:

» AppSecEU 16 - Matthias Rohr - Practical Threat Modeling with Microsofts Threat


Modeling Tool 2016. https://www.youtube.com/watch?v=C5IPkuDnOGs
» Microsoft SDL Unit04 - Threat Modeling Principles (Level 100).
https://www.youtube.com/watch?v=WGz2JQ1OlGQ

La aplicación permite analizar las amenazas de una aplicación web típica de negocio de
pago electrónico de una librería (textos, libros, revistas, etc.), en formato digital con
opciones de impresión. El sistema está basado en una típica arquitectura de una
aplicación web de tres capas, donde el cliente es un navegador que acceder a los servicios
proporcionados por el sitio web de la librería, que contiene una base de datos de los
clientes, cuentas y publicaciones disponibles, alojada en un servidor uno de bases de
datos (que replica a un hosting externo para tener un backup), un servidor web que
implementa toda la lógica de negocio, una servidor de logs interno como podrían ser un
SIEM y por último un acceso a una pasarela de pagos externa

Tener en cuenta que nos encontramos en la fase análisis de requisitos del SDLC,
identificando requisitos funcionales y de seguridad.

Topología lógica de la aplicación

Os propongo modelar la aplicación mediante el siguiente diagrama DFD que constituye


una representación gráfica que agiliza el proceso de modelado de requerimientos y al
mismo. En la siguiente figura os muestro un modelo básico como ayuda a la realización

TEMA 3 – Actividades © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

del diagrama DFD de la aplicación propuesta. No olvidar configurar las propiedades de


cada elemento del diagrama, por ejemplo, configurar autenticación y autorización en el
servidor web protegerá de posibles amenazas y la herramienta lo tendrá en cuenta a la
hora de calcularlas. Además saldrán amenazas repetidas. Es decir, se tendrán menos
amenazas. Un ejemplo puede ser el siguiente, aunque el alumno lo puede modelar de
forma diferente según considere:

Posible diagrama DFD de la aplicación.

La herramienta Threat Modeling Tool 2016 tiene dos vistas:

» Una de diseño para dibujar el diagrama DFD de la aplicación.


» Una de análisis que calcula las amenazas automáticamente y permite incluir las
salvaguardas manualmente.

TEMA 3 – Actividades © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Selección de vitas

Vistas Threat Analysis and Modeling Tool 2014.

Una vez dibujado el diagrama anterior en la herramienta (u otro que consideréis


adecuado para vuestro diseño) produce un análisis automático por cada elemento de la
lista de componentes definidos en el diseño, mediante el método STRIDE, tomando
como base la siguiente matriz siguiente:

Relación entre las amenazas del método STRIDE y los elementos de un diagrama DFD.

Cuando se selecciona la vista de análisis, la herramienta mostrará las amenazas sugeridas


para el diagrama de flujo de datos dibujado, donde al clicar en cada una de ellas nos
permite introducir las salvaguardas que consideremos y el análisis DREAD del paso de
la metodología.

TEMA 3 – Actividades © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Vista análisis Threat Analysis and Modeling Tool.

Antes es necesario que cargarla plantilla, descargable de la plataforma, «caso1.tb7» (este


archivo se dejará en el foro, se les enviará a sus carpetas de descarga o se descarga desde
el siguiente enlace:

Accede al enlace a través del aula virtual o desde la siguiente dirección web:
ftp://descargasescueladeingenieria@ftp01.unir.net/uploads/05%20Seguridad_del_Sof
tware/caso1.tb7

Y cargarla mediante el menú Aply Template, según la figura:

Aplicación de Plantilla

Aplicación de plantilla.

TEMA 3 – Actividades © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Valorar las amenazas

Una vez que tenemos identificada la lista de amenazas, el siguiente paso consiste en
puntuarlas de acuerdo al riesgo que suponen. Esto nos permitirá priorizar las
actuaciones a efectuar para mitigar el riesgo.

Para ello utilizaremos el método DREAD (Damage, Reproducibility, Exploitability,


Affected, DIscoverability), en castellano: Daño potencial, Reproductividad,
Explotabilidad, Usuarios afectados, Descubribilidad. El riesgo se puede cuantificar como
el resultado de multiplicar la probabilidad de que la amenaza se produzca, por el daño
potencial de esta.

Riesgo = Probabilidad x Impacto potencial= (R+E+DI) x (D+A) = PxI

Cada valor se cuantifica con un valor entre 1 y 3. En la herramienta se incluye este análisis
modificando las pestañas DREAD (Damage, Reproducibility, Exploitability, Affected,
DIscoverability) a valores de high, medium y low. Realizarlo para todas las amenzas.

Damage potential: ¿Cuál es el daño que puede originar la vulnerabilidad si llega a ser explotada?

Reproducibility: ¿Es fácil reproducir las condiciones que propicien el ataque?

Exploitability: ¿Es sencillo llevar a cabo el ataque?

Affected users: ¿Cuantos usuarios se verían afectados?

DIscoverability: ¿Es fácil encontrar la vulnerabilidad?

Significado de cada componente valoración del método DREAD.

Se rellena despues para cada amenaza la siguiente tabla, en la que se incluye un ejemplo:

Probabilidad Impacto P I Riesgo


de Ocurrencia Potencial
(P) (I)
Amenaza R E DI D A (R+E+DI) (D+A) PxI
Inyección de comandos 3 2 2 3 3 7 6 42
SQL

Calculo el riesgo.

TEMA 3 – Actividades © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

El alumno deberá incluir en la memoria esta tabla rellena con al menos 15 de las
amenazas obtenidas de la de la herramienta Threat Analysis and Modeling Tool 2016. Se
valorará que se implemente en idioma español. En la herramienta deberán estar
analizadas todas.

Salvaguardas

Una vez calculado el riesgo con el método DREAD, hay que incluir en la herramienta
manualmente para cada una las salvaguardas que ayuden a mitigarlas. Si se quiere un
catálogo más completo de salvaguardas consultar el Libro II de la Metodología
MAGERIT.

Disponible en:
http://administracionelectronica.gob.es/pae_Home/pae_Documentacion/pae_Metod
olog/pae_Magerit.html#.U2_oe2CKB2E

También se puede utilizar como guía el siguiente diagrama:

Salvaguardadas aplicación web.

TEMA 3 – Actividades © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

También se puede usar la siguiente tabla:

Amenazas Propiedad Salvaguardas


Spoofing identity Autenticación  Procesos de Autenticación, Autorización
(Suplantación de y Auditoría (AAA): hash, firma digital.
Identidad)  Protección de secretos
 No almacenamiento de secretos
 Single Sign On
 IPSEC
Tampering with Data Integridad  Procesos de AAA: hash, firma digital.
(Manipulación de datos)  Códigos de autenticación de mensajes.
 Firmas digitales.
 Protocolos resistentes a la manipulación.
 Listas control de acceso ACL
Repudiation (Repudio) No Repudio  Procesos de Autenticación: hash, firma
digital.
 Procesos de Auditoría.
 Sellado de tiempo.
Information Disclosure Confidencialidad  Procesos de AAA: hash, firma digital.
(Revelación de  Protección de secretos
información)  No almacenamiento de secretos.
 Protocolos seguros.
 Encriptado.
Denial of Service Disponibilidad  Procesos de AAA: hash, firma digital.
(Denegación de servicio)  Listas control de acceso ACL.
 Calidad de servicio.
Elevation of Privilege Autorización  Listas control de acceso ACL.
(Elevación de privilegios)  Control de acceso basado en roles.
 Trabajar con el mínimo privilegio.
 Validación de entradas
Salvaguardas método STRIDE.

Entrega

Incluir el fichero con extensión .tm7 que genera la herramienta y el informe que se puede
generar con la misma.

Extensión aproximada: 15-20 páginas (Georgia 11, interlineado 1,5).

TEMA 3 – Actividades © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Test

1. Señala la respuesta correcta. ¿Qué incluye la seguridad del software?


A. Patrones de codificación.
B. Principios de diseño seguro.
C. Casos de uso.
D. Buenas prácticas de gestión.

2. Señala la respuesta correcta. Los patrones de ataque en la fase de diseño y


arquitectura:
A. Ayuda a definir el comportamiento del sistema para prevenir o reaccionar ante
un tipo específico de ataque probable.
B. Específica debilidades aprovechadas por los ataques, orientando que técnicas o
prácticas de seguridad de desarrollo evitan estas deficiencias.
C. Proporcionan el contexto de las amenazas al que el software se va a enfrentar,
de forma que permite diseñar arquitecturas seguras.
D. Proporciona ejemplos de ataques que no aprovechan las vulnerabilidades de la
arquitectura elegida.

3. Señala la respuesta correcta. Respecto a los usos de los casos de uso de seguridad:
A. Analiza y especifica los requisitos de seguridad.
B. Analiza y especifica las amenazas a la seguridad.
C. Análisis de vulnerabilidades de activos y amenazas.
D. Analiza forense de las actividades maliciosas.

TEMA 3 – Test © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

4. Señala la respuesta incorrecta. Respecto a la ingeniería de requisitos de seguridad:


A. Requisitos de software seguro. Requisitos que afectan directamente a la
probabilidad de que el software sea seguro.
B. Requisitos de software seguro. Incluye la especificación de funciones que
implementan una política de seguridad, como control de acceso, autenticación,
autorización, cifrado y gestión de claves Estas funciones previenen la violación de
las propiedades de seguridad del sistema o de la información que procesa, como el
acceso no autorizado, modificación, denegación de servicio, etc.
C. Los requerimientos no funcionales de seguridad deben especificar: Propiedades
que el software debe exhibir.
D. Los requerimientos no funcionales de seguridad deben especificar: Los
controles y normas que rigen los procesos de desarrollo, implementación y
operación del software.

5. Señala la respuesta correcta. A qué campo de un patrón e ataque definido en CAPEC,


corresponde la siguiente definición: «Describe los datos de código, configuración u otros
a ejecutar o activar, como parte de un ataque con un vector de inyección de este tipo».
A. Zona de activación.
B. Payload.
C. Vector de inyección.
D Indicadores de un ataque.

6. Señala la respuesta incorrecta. Los casos de abuso, o casos de mal uso, son un
instrumento que puede ayudar a pensar de la misma forma que lo hacen los atacantes.
Pensando más allá de los aspectos normativos y funcionales y también estudiando
eventos negativos o inesperados, los profesionales de seguridad de software entienden
mejor cómo crear software seguro, pues permiten obtener una mejor comprensión de
las áreas de riesgo del sistema a través de:
A. Identificación los objetivos de seguridad que debe cumplir el software.
B. Identificación de los puntos seguros del software.
C. Identificación de las amenazas de seguridad a ser neutralizadas por el software.
D Obtener requisitos de seguridad que garanticen que el software aplica las
restricciones necesarias.

TEMA 3 – Test © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

7. Señala la respuesta incorrecta. Es fundamental que los requisitos de seguridad del


software sean:
A. Completos.
B. Precisos.
C. Coherentes.
D. No trazables.

8. Señala la respuesta correcta. Los requerimientos no funcionales de seguridad deben


especificar:
A. Propiedades que el software debe exhibir.
B. Nivel requerido de seguridad y salvaguardas de riesgo de las funciones de
seguridad.
C. Los controles y normas que rigen los procesos de desarrollo, implementación y
operación del software.
D. Todas las anteriores.

9. Señala la respuesta incorrecta. Un acercamiento a un prototipo de análisis y gestión


de riesgo típico implica varias actividades principales que a menudo incluyen un número
de actividades básicas:
A. Discutir sobre el objetivo de análisis con el grupo: brainstorming.
B. Determinar los límites de las amenazas.
C. Probar el software si ya existe algún prototipo.
D. Estudiar el código y otros componentes de software incluyendo el empleo de
herramientas de análisis de código.

10. Señala la respuesta correcta. Una solución general repetible a un problema de


ingeniería de software recurrente, que está expresamente destinado a contribuir al
diseño de software menos vulnerable, más resistente y tolerante a los ataques es:
A. Un caso de uso.
B. Un ejemplo de diseño.
C. Un patrón de diseño.
D. Ninguna de las anteriores.

TEMA 3 – Test © Universidad Internacional de La Rioja (UNIR)


Seguridad en el ciclo de vida del
software en las fases de codificación,
pruebas y operación
[4.1] ¿Cómo estudiar este tema?

[4.2] Introducción

[4.3] Pruebas de seguridad basadas en riesgo

[4.4] Revisión de código

[4.5] Test de penetración

[4.6] Operaciones de seguridad

[4.7] Revisión externa

[4.8] Referencias
TEMA
Seguridad en el ciclo de vida del software

Introducción a la seguridad en el
Esquema

ciclo de vida del software (S-SDLC)

TEMA 4 – Esquema
Pruebas de seguridad Test de Operaciones de Revisión
Revisión de código
basadas en riesgo penetración seguridad externa

Arquitectura de las Consideraciones Distribución

2
herramientas de sobre los test de
Cuestiones sobre la análisis estático de
explotabilidad de las
penetración
código Despliegue
vulnerabilidades
Uso de
Reglas Operaciones
herramientas para
Herramientas de realizar un test de
revisión de código Análisis estático de
código como parte
penetración
del proceso de
Aspectos prácticos revisión de código Herramientas para
de manejo de las
herramientas Ejemplos test de penetración
herramientas de
análisis estático de Recomendaciones
Métricas de análisis código fuente sobre los test de
estático de código
penetración
Aspectos prácticos
de manejo de las
herramientas
Seguridad en el Software

© Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Ideas clave

4.1. ¿Cómo estudiar este tema?

Para estudiar este tema lee las Ideas clave que te presentamos a continuación.

El objetivo del presente tema es introducir al alumno en las diferentes prácticas de


seguridad a introducir en el SDLC en las fases de codificación, pruebas y operación, por
una organización al objeto de obtener software más seguro, confiable, que presente un
mínimo de vulnerabilidades y sea resistente a los ataques provenientes del entorno
interior como del exterior.

4.2. Introducción

Para conseguir software confiable que solo realice las tareas para las que está diseñado
y minimizar al máximo los ataques en la capa de aplicación y por tanto el número de
vulnerabilidades explotables, es necesario seguir un proceso sistemático o disciplina que
aborde la seguridad en todas las etapas del ciclo de vida de desarrollo del software que
incluya una serie de buenas prácticas de seguridad (S-SDLC) como especificación
requisitos seguridad casos de abuso, análisis de riesgo, análisis de código, pruebas de
penetración dinámicas, modelado de amenazas, operaciones de seguridad y revisiones
externas, necesarias para asegurar la confianza y robustez del mismo.

Normalmente, el modelo más propicio para el desarrollo de software en las


organizaciones suele ser una combinación de dos o más modelos de los ciclos de vida
(cascada, espiral, etc.), sin embargo hay que tener en cuenta que lo importante no es
el modelo seguido, si no que la incorporación de buenas prácticas de
seguridad en las diferentes fases del mismo y unos hitos o puntos de control
donde se verifiquen los entregables de cada fase. Entre las razones principales para
añadir prácticas de seguridad en el SDLC tenemos:

» Mayor probabilidad de capturar adecuadamente los requisitos y tomar decisiones de


diseño correctas y no cometer errores involuntarios de codificación.

TEMA 4 – Ideas clave 3 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Dificultad de los agentes maliciosos para explotar vulnerabilidades y debilidades del


software, pues el resultante de un ciclo de vida S-SDLC será más robusto en su
entorno de ejecución y en su interacción con entidades externas.

En la figura siguiente se presenta un diagrama conceptual de dos de las prácticas de


seguridad más importantes, revisión de código y test de penetración realizadas
mediante herramientas de análisis estático y dinámico que escanean el código fuente y
la aplicación en su entorno de ejecución respectivamente, en busca de vulnerabilidades
comunes. Posteriormente se desarrollan en este tema.

Figura 1. Revisión de código y test de penetración.

4.3. Pruebas de seguridad basadas en riesgo

Hasta hace unos pocos años las pruebas de software se desarrollaban en base a la
demostración de sus requisitos, como forma de comprobar el correcto funcionamiento
de sus capacidades e incluso sus funciones y servicios de seguridad, sin embargo no
sirven para determinar cómo se comportará en condiciones anómalas y
hostiles, ni si está libre de vulnerabilidades.

Identificando los riesgos del sistema y diseñando las pruebas en base a ellos, bajo
la perspectiva de un atacante, un probador de seguridad de software puede enfocar
correctamente las áreas de código donde un ataque probablemente pudiera tener éxito.

TEMA 4 – Ideas clave 4 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

7. Revisión 8.
5. Patrones
código Configuración
de diseño
11. segura
3. Ing. 6. Pruebas 1. Modelado
2. Casos 4. Análisis de Revisión 9. Test
Requisitos basadas en de ataques
de abuso riesgos externa penetración
seguridad riesgo 10.
Operaciones
seguridad

Requisitos Codificación
Arquitectura Pruebas Distribución Operación y
Casos de e
Diseño y despliegue mantenimiento
abuso integración

REALIMENTACIÓN

Figura 2. Pruebas seguridad basadas en riesgo.

Aunque los componentes de seguridad, como la criptografía, la autenticación y el


control de acceso, jueguen un papel crítico en la seguridad de software, la seguridad
en sí misma es una característica de la totalidad del sistema, por tanto no se refiere
solamente a los mecanismos y elementos de seguridad. Un desbordamiento de buffer es
un problema de seguridad independientemente de si existe un componente de seguridad
o en un interfaz hombre máquina no crítico. Por esta razón, las pruebas de seguridad
necesariamente deben implicar dos tipos de aproximaciones:

Figura 3. Tipos de pruebas seguridad del software.

TEMA 4 – Ideas clave 5 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Los objetivos de las pruebas de seguridad basadas en el riesgo son los siguientes
(Redwine, 2006):

» Verificar la operación confiable del software bajo condiciones hostiles de ataque.


» Verificar la fiabilidad del software, en términos de comportamiento seguro y cambios
de estado confiables.
» Verificar la falta de defectos y debilidades explotables.
» Verificar la capacidad de supervivencia del software ante la aparición de anomalías,
errores y su manejo de las mismas mediante excepciones que minimicen el alcance e
impacto de los daños que puedan resultar de los ata

Las pruebas de seguridad deberían comenzar a nivel de componente antes de la


integración del sistema. Se deben de utilizar los modelos de ataque, casos de abuso y
análisis de riesgos desarrollados al comienzo del ciclo de vida, para mejorar el plan de
pruebas con casos diseñados desde el punto de vista de los atacantes basados en los
escenarios de abuso. Esto implica tanto pruebas de caja negra como de caja blanca.
Técnicas de test que son particularmente útiles para las pruebas basadas en riesgo
incluyen las mostradas en el siguiente diagrama:

Pruebas basadas
en riesgo

Rev isiones Rev isión de diseño

Caja blanca Análisis estático código

Pru ebas de penetración

Caja negra
Análisis dinámico

Fuzzing Testing

Análisis de código binario

Iny ección de fallos en binario

Escaneo de v ulnerabilidades

Análisis híbrido

Caja gris
Iny ección de fallos en código
fu ente

Figura 4. Tipos de pruebas seguridad basadas en riesgo.

TEMA 4 – Ideas clave 6 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Revisión de diseño. Las vulnerabilidades de nivel de diseño son la categoría de


defectos más difícil de manejar, además son tanto frecuentes como críticos.
Lamentablemente, averiguar si un programa tiene vulnerabilidades de nivel de diseño
requiere conocimiento y experiencia. Ejemplos de problemas de nivel de diseño
incluyen manejo de errores en sistemas orientados a objetos, objetos compartidos,
relaciones de confianza, canales de datos sin protección, mecanismos de control de
acceso incorrectos, carencia de auditorías, registro (logs) y errores en el ordenamiento
de eventos.
» Revisión de código o análisis estático de código. Se considera una de las
prácticas de seguridad más importantes, consiste básicamente en el análisis del
código fuente antes de ser compilado, para detectar errores, construcciones inseguras
de codificación e indicadores de vulnerabilidades o debilidades de seguridad futuras.
» Análisis dinámico (Dynamic Application Security Testing-DAST). Detectan
debilidades y vulnerabilidades de seguridad en aplicaciones Web mientras se están
ejecutando. Emplea técnicas de inyección de fallos en una aplicación, por ejemplo
entrada de datos maliciosos tal y como se representa en la figura siguiente, para
identificar vulnerabilidades comunes, como inyección SQL, cross-site scripting, open
redirect, command injection, path traversal etc. También identifica problemas de
configuración del servidor, autenticación, inicio de sesiones, etc. Lo más eficiente es
la realización de pruebas conjuntas SAST y DAST, pues ayudan a minimizar la
cantidad de falsos positivos. Ejemplos de herramientas:

Aplicación Licencia S.O.


Acunetix WVS. Comercial / Libre Windows
AppScan. Comercial Windows
Burp Suite. Comercial / Libre La mayoría de ellas
GamaScan. Comercial Windows
Tabla 1. Herramientas DAST.

Figura 5. Funcionamiento pruebas Análisis dinámico (DAST). Fuente: López, 2012.

TEMA 4 – Ideas clave 7 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Análisis hibrido o Interactive Application Security Testing (IAST). Otro


tipo de pruebas enfocadas al análisis de aplicaciones tanto Web como de otro tipo, que
implica el uso tanto del código fuente y como del binario ejecutable compilado a partir
de dicho código. Para la realización del análisis, se ejecuta el programa compilado con
un agente dentro del mismo, al tiempo que se «alimentan» las interfaces externas de
la muestra. El revisor sigue y analiza los datos (variables en memoria) que el programa
produce como resultado de su ejecución, de forma que cualquier vulnerabilidad o
anomalía que surja en dicha interfaz se traza simultáneamente con el código fuente
que la genera con mayor eficacia.

Figura 6. Análisis dinámico.

Ejemplo de herramientas:

Herramientas
1 Valgrind. Para todo tipo de aplicaciones
2 INSURE++ herramienta para análisis de errores para todo tipo de aplicaciones
escrita en C, C++.
3 SCA Fortify mas Web Inspect de HP, disponen de un agente para integrar el
resultado de las dos herramientas.
4 IBM Appscan, con el agente GLASS BOX.
5 Acunetix más Acusensor.
6 SEEKER
Tabla 2. Herramientas análisis hibrido.

Las pruebas de seguridad basadas en el riesgo (pruebas de seguridad desde el punto de


vista del atacante) según lo anteriormente expuesto se deberían estructurar en las
siguientes fases:

TEMA 4 – Ideas clave 8 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Descomponer el sistema en sus componentes fundamentales.


» Identificar las interfaces de los componentes.
» Clasificar las interfaces de los componentes por su riesgo potencial.
» Averiguar las estructuras de datos usadas por cada interfaz.
» Encontrar problemas de seguridad inyectando datos maliciosos, apoyándose en el
estado del riesgo ante las posibles amenazas.

En la figura siguiente se muestra las diferentes pruebas a realizar en cada una de las fases
del S-SDLC (Redwine, 2006):

Figura 7. Distribución pruebas de seguridad a lo largo de las fases del S-SDLC.

4.4. Revisión de código.

Introducción

El análisis estático de código fuente, tal y como comenta McGraw (2005), se considera la
actividad más importante de entre las mejores prácticas de seguridad que se
han de realizar en el curso del desarrollo de una aplicación. En los siguientes apartados
se van a analizar los tipos y categorías de herramientas disponibles tanto comerciales
como de open source, para qué lenguajes están disponibles, cómo y cuándo se tienen que

TEMA 4 – Ideas clave 9 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

utilizar y cómo se enmarca el uso de estas herramientas en el proceso de revisión del


código.

7. Revisión 8.
5. Patrones
código Configuración
de diseño
11. segura
3. Ing. 6. Pruebas 1. Modelado
2. Casos 4. Análisis de Revisión 9. Test
Requisitos basadas en de ataques
de abuso riesgos externa penetración
seguridad riesgo 10.
Operaciones
seguridad

Requisitos Codificación
Arquitectura Pruebas Distribución Operación y
Casos de e
Diseño y despliegue mantenimiento
abuso integración

REALIMENTACIÓN

Figura 8. Revisión de código.

Los problemas de seguridad de una aplicación pueden ser resultado de dos tipos de
errores principales:

» Errores simples que comete el programador por confusión, un lapsus


momentáneo, etc.
» Carencias de conocimientos del programador.

Con esto en mente, el análisis estático de código fuente es adecuado para identificar
problemas de seguridad por ciertas razones:

» Las herramientas de análisis estático comprueban el código a fondo y


coherentemente, sin ninguna tendencia. Un análisis valioso debe ser lo más imparcial
posible.
» Examinando el código en sí mismo, las herramientas de análisis estático a menudo
pueden indicar la causa de origen de un problema de seguridad, no solamente uno de
sus síntomas.

TEMA 4 – Ideas clave 10 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» El análisis estático puede encontrar errores tempranamente en el desarrollo, aún


antes de que el programa sea ejecutado por primera vez.
» Cuando un investigador de seguridad descubre una nueva variedad de ataque, las
herramientas de análisis estático, ayudan a comprobar de nuevo una gran cantidad de
código.

La queja más común y contrastada contra las herramientas de análisis estático de


seguridad es que producen demasiado ruido, es decir, falsos positivos: un problema
descubierto en un programa cuando ningún problema en realidad existe. Un
gran número de falsos positivos puede causar verdaderas dificultades.

Los falsos positivos son seguramente indeseables, pero desde una perspectiva de
seguridad, los falsos negativos son mucho peores. Con un falso negativo, un
problema existe en el programa, pero la herramienta no lo detecta. La
penitencia por un falso positivo es la cantidad de tiempo gastada repasando el resultado.
La penitencia por un falso negativo es mucho mayor, pues no solo se paga el precio
asociado por tener una vulnerabilidad en el código, se vive con un sentido falso de
seguridad que se deriva del hecho de que la herramienta hizo parecer que todo era
correcto.

Todas las herramientas de análisis estático de código producen algunos falsos


positivos y falsos negativos, su balance es normalmente indicativo del propósito de la
herramienta de la misma.

» Objetivo descubrir bugs. El coste de omitir un bug dentro de la primera categoría


es, relativamente pequeño hablando en términos de seguridad.
» Objetivo descubrir defectos relevantes de seguridad. La penitencia por bugs
de seguridad pasados por alto es elevada, por lo que este tipo de herramientas, en
general, producen más falsos positivos para reducir al mínimo falsos negativos.

Para que una herramienta de análisis estático descubra un defecto, el defecto debe estar
visible en el código. Esto podría parecer obvio, pero es importante entender que el
análisis de riesgo arquitectónico es un requisito necesario previo al análisis
estático.

TEMA 4 – Ideas clave 11 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Herramientas de revisión de código (Security Review)

Las herramientas de análisis de seguridad estáticas usan muchas de las mismas técnicas
encontradas en otras herramientas, pero su objetivo está más enfocado a
identificar problemas de seguridad por lo que aplican estas técnicas de manera
diferente.

Para una herramienta de comprobación de propiedades, buscando potenciales


vulnerabilidades de desbordamiento de buffer habría que comprobar la propiedad «el
programa no tiene acceso a una dirección fuera de los límites de memoria
asignada». Las herramientas de seguridad generalmente no pueden heredar la
tendencia de las herramientas de bug finding de reducir al mínimo los falsos positivos a
cargo del aumento de falsos negativos. Se inclinan al lado de la precaución e indican las
partes de código que deberían ser sujetas a revisión manual. Esto quiere decir que su
salida todavía requiere (también las herramientas bug finding requieren revisión
posterior) el repaso humano y lo mejor es aplicar su empleo como una parte de un
proceso de revisión de código.

Fortify Software e IBM, fabrican herramientas de análisis estático de código que caen
dentro de esta categoría.

Consulta más información sobre estas herramientas en:


http://www8.hp.com/us/en/software-solutions/software.html?compURI=1214365
http://www-01.ibm.com/software/rational/products/appscan/source/

En la práctica lo importante es que estas herramientas suministran importantes


resultados. El hecho de que sean imperfectas no les impide tener un valor significativo.
Los factores principales prácticos que determinan la utilidad de una herramienta de
análisis estático son:

» La capacidad de la herramienta para comprender el programa que se analiza.


» El equilibrio que la herramienta hace entre la precisión, la profundidad y la
escalabilidad.
» Porcentaje de falsos positivos y falsos negativos de la herramienta.
» El conjunto de errores que la herramienta comprueba.
» Las características de la herramienta para hacerla fácil de usar

TEMA 4 – Ideas clave 12 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Ejemplos de herramientas de análisis estático de código fuente

A continuación se van a enumerar algunas de estas herramientas tanto comerciales como


libres (open source) para lenguajes como C/C++ y java, aunque las herramientas
comerciales soportan varios lenguajes más. Las herramientas libres son en la mayoría de
los casos, proyectos de investigación de universidades. Este apartado se limita a
enumerar algunas de ellas indicando su tipo de licencia y lenguajes que es capaz de
revisar.

Herramienta Licencia Lenguajes


1 SCA de Fortify software de HP, C, C++, Java y
Comercial
otros
2 AppScam de IBM. C, C++, Java y
Comercial
otros
3 Prevent de Coverity, Comercial C, Java y otros
4 K8 Inshight de Klocwork, Comercial C, Java y otros
5 VERACODE SaaS C, Java y otros
6 CXSUITE (CHECKMARX) Comercial C, Java y otros
7 CodeSonar de Grammatech, Comercial C, C++
8 SLAM de Microsoft. Comercial C, C++
9 SATURN de Stanford University. Libre C
10 BOOP (C) de Graz University of
Libre C
technology.
11 Magic de Carnegie Mellon University. Libre C
12 Jtest de Parasoft, Comercial Java
13 FindBugs de Maryland k, Libre Java
14 LAPSE (J2EE) de Stanford University
Libre Java
y UC3M.
15 Java PathFinder. Libre Java
16 Cppcheck Libre C,C++
17 Polyspace de Mathworks. Comercial C , ada
18 Pc-lint de Gimpel Sotfware, Comercial C, C++
Tabla 3. Herramientas de análisis estático de código fuente.

TEMA 4 – Ideas clave 13 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

4.5. Test de penetración

Introducción

Una vez terminada la fase de desarrollo se despliega el sistema, se deben llevar a cabo
muchas de las operaciones o actividades de seguridad relacionadas con la puesta en
marcha de la aplicación para su posterior paso a producción y explotación por
parte de los usuarios. Las actividades de seguridad a realizar en esta fase comprenden la
implementación y comprobación de la eficacia de las salvaguardas, tanto de tipo
software (autenticación p.ej.) como de los dispositivos hardware (firewall p.ej.), que se
derivaron de la actividad de análisis de riesgos realizada en la fase de diseño.

La comprobación de la eficacia de las salvaguardas implementadas se realiza


principalmente mediante los test de penetración, que tiene como principal misión
verificar cómo el software se comporta y resiste ante diferentes tipos de
ataque.

7. Revisión 8.
5. Patrones
código Configuración
de diseño
11. segura
3. Ing. 6. Pruebas 1. Modelado
2. Casos 4. Análisis de Revisión 9. Test
Requisitos basadas en de ataques
de abuso riesgos externa penetración
seguridad riesgo 10.
Operaciones
seguridad

Requisitos Codificación
Arquitectura Pruebas Distribución Operación y
Casos de e
Diseño y despliegue mantenimiento
abuso integración

REALIMENTACIÓN

Figura 9. Test de penetración en el SDLC.

Las pruebas de penetración deben centrarse en aspectos de comportamiento del


software, sus interacciones y vulnerabilidades que no puedan ser detectadas mediante

TEMA 4 – Ideas clave 14 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

otras pruebas realizadas fuera del entorno de producción. Deben tratar de encontrar
problemas de seguridad que puedan originarse en su arquitectura y diseño (frente a
errores de codificación que se manifiestan como vulnerabilidades), ya que este tipo de
problema tiende a ser pasado por alto por otras técnicas de prueba.

El plan de pruebas de penetración deben incluir los «peores» escenarios en los que
se puedan reproducir vectores de ataques e intrusiones que se consideran altamente
perjudiciales, como los escenarios de amenazas internas. El plan de pruebas debe
capturar:

» La política de seguridad del sistema se supone que debe respetar o hacer respetar.
» Amenazas previstas.
» Riesgos de seguridad (conducido por casos de abuso, riesgos arquitectónicos y
modelos de ataque).
» Secuencias de ataques probables que se puedan producir.

Los tipos de pruebas empleadas en esta práctica de seguridad, básicamente incluyen la


realización de un escaneo de vulnerabilidades para poder identificar la posible
brecha de seguridad del sistema para posteriormente intentar comprometerlo mediante
el uso de una herramienta de explotación automática o la ejecución de un exploit,
de forma manual, contra el mismo. En el caso de ser una aplicación web, además hay
que realizar un «análisis dinámico», DAST, para verificar si existen vulnerabilidades
del tipo inyección SQL, cross-site scripting, CSRF, inyección de comandos, path
traversal etc. Básicamente habría que seguir los siguientes pasos de forma cíclica hasta
comprometer el sistema:

» Revisar información obtenida de los casos de abuso, patrones de ataque y el modelado


de amenazas.
» Identificación de vulnerabilidades en el software. Ejecutar la herramienta de escaneo
de vulnerabilidades.
» Buscar exploits en Internet acordes a las vulnerabilidades encontradas.
» Ejecutar los exploits contra la aplicación objetivo, de forma automática o manual.
» Realizar pruebas DAST en caso de que la aplicación esté construida con tecnologías
Web.
» Realizar pruebas de Fuzzing.

TEMA 4 – Ideas clave 15 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

6. Realizar 1. Revisar
información
pruebas Modelo
Fuzzing Amenazas

5.
Realización 2. Identificar
análisis vulnerabilidades
dinámico
(DAST) web

4. Ejecutar
Expolit
(herramienta 3. Buscar
automática o Expolit
manual)
Figura 10. Ejecución pruebas de penetración.

Consideraciones sobre los test de penetración

Una buena parte de los defectos y vulnerabilidades del software directamente no está
relacionada con la funcionalidad de seguridad. Muchas de las cuestiones relacionadas
con la seguridad implican un mal uso de una aplicación, normalmente inesperado y
descubierto por un atacante. Las pruebas de penetración tienen que verificar los
«aspectos negativos» del sistema, es decir se debe probar la seguridad de la
aplicación en base a los riesgos (conducido por casos de abuso, riesgos
arquitectónicos y modelos de ataque) para determinar cómo se comporta ante los
ataques.

Son pruebas de caja negra. En cualquier caso, la prueba de aspectos negativos es un


desafío mucho mayor que la verificación de un aspecto positivo. Un conjunto de pruebas
positivas satisfactoriamente ejecutadas, por lo general da un alto grado de confianza de
que el software realizará funcionalmente su trabajo como se desea. Sin embargo,
enumerar acciones con la intención de producir un fallo y determinar bajo qué
circunstancias este ocurre es más complicado. Es realmente fácil probar si un
componente funciona adecuadamente o no, pero es muy difícil demostrar si
realmente un sistema es seguro a un ataque malévolo.

Si la realización de pruebas para detección de aspectos negativos no revela ningún


defecto, estas únicamente demuestran que ningún defecto ocurre en las condiciones

TEMA 4 – Ideas clave 16 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

particulares de esas pruebas, en ningún caso demuestran que ningún defecto


existe. Cuando se realizan pruebas de penetración que detectan pocas o
ninguna vulnerabilidad de seguridad, quiere decir que la ejecución de esas
pruebas proporciona muy poca seguridad de que una aplicación es inmune
ante ataques. Uno de los problemas principales con el acercamiento más común actual
de este tipo de pruebas es un malentendido de este punto sutil.

Las pruebas de penetración de forma general las más aplicadas de todas las
mejores prácticas de seguridad del software, y suelen ser parte del proceso de
aceptación de final. A causa de restricciones de tiempo, la mayor parte de este tipo de
evaluaciones son realizadas de forma apresurada como un punto de la lista de
comprobación de seguridad al final del ciclo de vida.

Una vez que una aplicación está terminada, está sujeta a las pruebas de penetración
como parte del proceso de aceptación de final. A causa de restricciones de tiempo,
la mayor parte de evaluaciones como estas son realizadas de forma apresurada como un
artículo de lista de comprobación de seguridad al final del ciclo de vida.

Una limitación principal de este acercamiento es que casi siempre


representa una tentativa «demasiado corta y muy tardía» para abordar el
problema de la seguridad al final del ciclo de desarrollo.

Como se ha visto, la seguridad de software es una característica inesperada del sistema,


y el logro de ello implica la aplicación de una serie de touchpoints (mejores prácticas en
todas las fases del ciclo de vida del software. Las organizaciones que fallan en integrar la
seguridad en todas partes del proceso de desarrollo se sorprenden, normalmente de
manera desagradable, de encontrar que su software sufre de defectos sistemáticos tanto
a nivel de diseño como en la puesta en práctica. En una fase tardía del ciclo de vida,
como las pruebas de penetración, los problemas internos del código son
destapados demasiado tarde y las opciones para el remedio conllevan
restricciones tanto de tiempo, como de presupuesto.

La solución de problemas en esta etapa es, la mayoría de las veces, prohibitivamente cara
y casi siempre implica tiritas en vez de curas. Las medidas que se toman después de las
pruebas de penetración tienden a ser en particular reactivas y defensivas, por ejemplo,
ajustando el conjunto de reglas de un firewall.

TEMA 4 – Ideas clave 17 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

El verdadero valor de las pruebas de penetración viene de sondar un sistema en su


ambiente final de operación. El entendimiento del ambiente de ejecución y de
los problemas de configuración es el mejor resultado de cualquier prueba
de penetración. Esto es así, sobre todo, porque estos problemas pueden ser
solucionados en realidad tarde en el ciclo de vida. El saber si realmente un servidor de
aplicaciones Websphere está correctamente instalado y que un cortafuegos funciona
correctamente es tan importante para la seguridad final como lo puede ser la creación de
código seguro. Las pruebas de penetración llegan al corazón del entorno de
ejecución y de los aspectos de configuración rápidamente. (De hecho, su
debilidad está en la incapacidad de seguir más allá de estos aspectos con eficacia.).

El éxito de una prueba de penetración depende de muchos factores, pocos de los cuales
se prestan a la métrica y la estandarización. La primera variable y más obvia es la
habilidad, el conocimiento, y la experiencia del probador. Las pruebas de
penetración de seguridad de software (pruebas de penetración, a veces llamadas de
aplicación) actualmente no siguen un proceso estándar de ninguna clase y por lo tanto
no son en particular cuidadosas con una aplicación constante de conocimiento (pensar
en listas de comprobación). El resultado es que solo los probadores expertos y
experimentados pueden realizar pruebas de penetración satisfactoriamente.

El empleo en esta práctica de seguridad de los requisitos de seguridad, casos de abuso,


el conocimiento de riesgo de seguridad y el modelo de ataque en el diseño de aplicación,
es poco corriente en la práctica. Por consiguiente, las conclusiones de seguridad no
son repetibles a través de equipos diferentes y varían extensamente
dependiendo de la habilidad y la experiencia de los probadores. Además,
cualquier régimen de prueba puede ser estructurado de tal modo que influya en las
conclusiones. Si los parámetros de prueba son determinados por individuos no
motivados (deliberadamente o no) para encontrar problemas de seguridad, es muy
probable que las pruebas de penetración acaben en un ejercicio propio de inutilidad.

La interpretación de resultados es también una actividad importante. Típicamente


los resultados toman la forma de una lista de defectos, bugs, y vulnerabilidades
identificadas durante las pruebas de penetración. Las organizaciones de desarrollo de
software tienden a considerar estos resultados como listas de defectos de seguridad para
consultar y conseguir un sistema seguro. En la práctica, una prueba de penetración
puede identificar solo una pequeña muestra representativa de todos los riesgos de
seguridad posibles en un sistema (sobre todo aquellos problemas que son del entorno de

TEMA 4 – Ideas clave 18 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

ejecución o implican la configuración operacional). Si una organización de


desarrollo de software se centra únicamente en una pequeña y limitada lista de
problemas de seguridad, se terminará por mitigar solo un subconjunto del total de
riesgos de seguridad y posiblemente no aquellos que presentan el mayor riesgo.

Todos estos problemas palidecen en comparación con el problema de que las pruebas de
penetración a menudo son usadas como una excusa para declarar la victoria de seguridad
«y ya está todo hecho». Lamentablemente, las pruebas de penetración realizadas
sin basarse en el análisis de riesgos de seguridad conducen a una falsa
sensación de seguridad.

Una gran ventaja de las pruebas de penetración que bien merece mencionarse, es que se
posicionan como pruebas de tipo de caja negra. Tomando un sistema en su
verdadero ambiente de producción, los analistas de seguridad pueden llegar a descubrir
problemas operacionales y de configuración, normalmente pasados por alto
durante el desarrollo de software.

Herramientas para test de penetración

Uso de herramientas para realizar las pruebas de penetración. Normalmente,


la realización de este tipo de pruebas de caja negra, engloba la realización de otros tipos
de pruebas:

» Escaneo de vulnerabilidades.
» Explotación de vulnerabilidades
» Fuzz testing.
» Análisis dinámico (DAST) para aplicaciones Web.

Con las herramientas de escaneo de vulnerabilidades se encuentran


vulnerabilidades conocidas con poco esfuerzo, que aprovechan las herramientas de
explotación de vulnerabilidades. Las herramientas de análisis dinámico y de
fuzzing pueden observar cómo se ejecuta un sistema, pueden someter los datos
mal formados, malévolos y arbitrarios en los puntos de entrada del sistema
en una tentativa de destapar fallos. Los defectos se reportan al personal de prueba
para su análisis.

TEMA 4 – Ideas clave 19 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Cuando es posible, el empleo de estas herramientas se debe dirigir por los resultados de
análisis de riesgo y los modelos de ataque. El empleo de herramientas tiene dos
ventajas principales.

» Cuando se usan con eficacia, se puede realizar la mayoría del trabajo necesario
para pruebas de penetración de software básicas (en la capa de presentación de un
sistema). Desde luego, un acercamiento conducido por herramientas no puede ser
usado como un reemplazo de la revisión de un analista de seguridad experto (sobre
todo porque las herramientas de hoy son en su naturaleza no aplicables en el nivel de
diseño), pero un acercamiento a base del empleo de herramientas realmente ayuda a
aliviar la carga de trabajo de un revisor y así puede bajar el coste.

» La salida de una herramienta se presta fácilmente a la métrica. Los equipos


de desarrollo de software pueden usar esta métrica para rastrear la tendencia y el
progreso con el tiempo y dirigirse hacia un objetivo de seguridad. Unas métricas
simples, en el uso común de hoy en día, no ofrecen una visión completa del estado de
la seguridad de un sistema. Así es importante acentuar que el certificado de buen
estado de salud de una herramienta de análisis no significa que un sistema esté libre
de defectos.

El valor reside en la siguiente comparación: si la actual ejecución de la herramienta revela


menos defectos que previas ejecuciones, probablemente se ha progresado.

Recomendaciones sobre los test de penetración

» Realizar los test más de una vez.


» Realimentación del resultado de las pruebas de penetración.
» Utilización de pruebas de penetración para evaluar aplicaciones COTS.

TEMA 4 – Ideas clave 20 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

4.6. Operaciones de seguridad

Introducción

El proceso final a llevar a cabo previo al paso a producción de la aplicación segura, son
las actividades centrales de:

» Distribución.
» Despliegue.
» Operaciones.

7. Revisión 8.
5. Patrones
código Configuración
de diseño
11. segura
3. Ing. 6. Pruebas 1. Modelado
2. Casos 4. Análisis de Revisión 9. Test
Requisitos basadas en de ataques
de abuso riesgos externa penetración
seguridad riesgo 10.
Operaciones
seguridad

Requisitos Codificación
Arquitectura Pruebas Distribución Operación y
Casos de e
Diseño y despliegue mantenimiento
abuso integración

REALIMENTACIÓN

Figura 11. Operaciones seguridad.

Distribución

El objetivo de distribución segura es reducir al mínimo las posibilidades de


acceso y manipulación del software durante la transmisión de un proveedor a su
consumidor (envío a través de medios físicos o descarga de red) por los agentes
maliciosos.

TEMA 4 – Ideas clave 21 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

A la hora de realizar la distribución y despliegue del software desarrollado, es


recomendable el realizar las siguientes buenas prácticas:

» Cambio de los valores de configuración predeterminados durante el desarrollo.


» Utilizar mecanismos de distribución estándar como los utilizados en los derechos de
propiedad intelectual.
» Distribuir el software con una configuración por defecto segura y lo más restrictiva
posible.
» Realizar una guía de configuración de seguridad.
» Proporcionar una herramienta de instalación automática.
» Establecer un medio de autenticación para la persona que va a ejecutar la instalación
y configuración.
» Los interfaces de configuración proporcionados por la herramienta o el script de
instalación debe ser seguro.
» Revisión y limpieza de todo el código fuente por el visible usuario (por ejemplo, código
del cliente de aplicaciones web).

Despliegue

Una configuración cuidadosa y la personalización del entorno de despliegue de cualquier


aplicación de software pueden mejorar enormemente su seguridad. El diseño de un
entorno de despliegue adaptado para una aplicación requiere de un proceso:

» Comienza en el nivel de componente de red


» Continúa por el sistema operativo y otro software de base como puede ser un gesto
de base de datos, etc.
» Termina con la propia configuración de seguridad de la aplicación y el sistema.

El software puede haber sido diseñado y desarrollado para ser extremadamente seguro,
pero no lo será si sus parámetros de configuración no se establecen como el
diseñador lo diseñó. De manera similar, los parámetros de configuración de su entorno
de ejecución deben ajustarse de modo que el software no sea innecesariamente expuesto
a amenazas potenciales, a esta tarea se le denomina «bastionado».

TEMA 4 – Ideas clave 22 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Interfaz de usuario
(Autorización, autenticación)

Seguridad de la aplicación
(auditoría, acceso, etc.)
Prácticas de
Red
operación
Gestora bases de datos, (protocolos de
(administración, etc. comunicaciones)
buckup, etc.)

Sistema operativo
(control de acceso
sistema de fichero)

Figura 12. Capas del sistema a proteger

El bastionado del software comprende los procesos y herramientas necesarias para


realizar el control y corrección de los defectos y debilidades de las
configuraciones del software sobre la base de un proceso de control de
configuración. En España el Centro Criptológico Nacional (CCN) y en Estados Unidos el
departamento de Defensa y otros departamentos elaboran directrices de configuración
seguras y listas de control para productos de software comercial, podemos encontrar
algunas en:

» Centro Criptológico Nacional (CCN): https://www.ccn-cert.cni.es/


» NSA guías de configuración de seguridad:
http://www.nsa.gov/ia/mitigation_guidance/security_configuration_guides/index.shtml
» NIST Listas de comprobación de configuración de productos TIC:
http://web.nvd.nist.gov/view/ncp/repository

Operaciones

Muchos desarrolladores de software argumentan que la distribución, despliegue y


operaciones no son parte del proceso de desarrollo de software. Hay que ajustar los
controles de acceso a la red y niveles del sistema operativo, así como diseñar un sistema
de registro de eventos, de monitorización, de backup y recuperación de los sistemas de
ficheros que será lo más eficaz durante operaciones de respuesta ante incidentes. Los
ataques llegarán y estar preparado para defenderse de ellos y para deshacer el daño
ocasionado después de que un ataque ha tenido lugar.

TEMA 4 – Ideas clave 23 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

4.7. Revisión externa

Un análisis externo por personal ajeno al equipo de diseño es bastante eficaz y


fundamental aportando otra visión de la seguridad del sistema y del riesgo y
contribuyendo a una mejora de la seguridad porque seguramente este análisis va
descubrir alguna amenaza y riesgo residual existente. Después, terminado el análisis
externo habrá que revisar el análisis de riesgos y si hay nuevas amenazas y riesgos
gestionarlos para que sean mitigados y si es necesario realizar cambios en la arquitectura
hardware y software, realizar cambios en el código y por tanto repetir la revisión del
mismo, los test de seguridad basados en el riesgo que ha cambiado y volver después del
despliegue de la aplicación a pasar los test de penetración.

Esto conforma un esquema de seguridad en el ciclo de vida de carácter cíclico en el que


es posible que se tengan que realizar varias veces el mismo tipo de actividades
consecuencia de la naturaleza cambiante y de continua evolución de las aplicaciones y
también del carácter cíclico de los distintos ciclos de vida de desarrollo de aplicaciones
donde en muchos casos se van refinando prototipos, que evolucionan hasta conseguir el
sistema final.

4.8. Referencias

Chess, B. y West, J. (2007). Secure Programming with Static Analysis. Addison-Wesley


Software Security Series.

Howard, M. y LeBlanc, D. (2003). Writing Secure Code. Microsoft Press.

Allen, J. H., Barnum, S., Ellison, R. J., McGraw, G., and Mead, N. R. (2008). Software
Security Engineering: A Guide for Project Managers. Addison Wesley Professional.

Goertzel, K. M., and Winograd, T. (2008). Enhancing the Development Life Cycle to
Produce Secure Software, Version 2.0. United States Department of Defense Data and
Analysis Center for Software.

OWASP. (2010). OWASP TOP 10. Los diez riesgos más importantes en aplicaciones
WEB. Edición en español.

TEMA 4 – Ideas clave 24 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Howard, M., and Lipner, S. (2006). The Security Development Lifecycle: SDL: A Process
for Developing Demonstrably Secure Software. Microsoft Press.

McGraw, G. (2005). Software Security: Building Security In. Addison Wesley


Professional.

Redwine, S. T. Jr. (Editor). (2006). Software Assurance: A Guide to the Common Body
of Knowledge to Produce, Acquire, and Sustain Secure Software Version 1.1. US
Department of Homeland Security.

Goertzel, K. M., and Winograd, T. (2008). Enhancing the Development Life Cycle to
Produce Secure Software, Version 2.0. United States Department of Defense Data and
Analysis Center for Software.

Komaroff, M., (ASD/NII) and Baldwin, K. (OSD/AT&L). (2005). DoD Software


Assurance Initiative.

Bermejo, J. R., and Díaz, G. Estudio de Técnicas Automáticas de Análisis de


Vulnerabilidades de Seguridad en Aplicaciones Web. UNED.

Barnum, S., and Sethi, A. (2007). Attack Patterns as a Knowledge Resource for Building
Secure. Software Cigital, Inc.

Barnum, S. (2008). Common Attack Pattern Enumeration and Classification (CAPEC)


Schema Description. Department of Homeland Security EEUU, Software Cigital.

Graff. M. G. Secure Coding. The State of the Practice.

Wyk, G. (2003). Secure Coding: Principles & Practices By M. G. Graff, K. R. van Wyk.
Publisher: O'Reilly.

Hoglund. (2004). Exploiting Software: How to Break Code, By G. Hoglund and G.


McGraw. Addison-Wesley Software Security Series.

Sroka, D. Presentación HP Fortify User Training.

TEMA 4 – Ideas clave 25 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Microsoft Corp. (2003). Application Security Best Practices at Microsoft: The Microsoft
IT Group Shares Its Experiences.

Microsoft Corp (2010). Simplified Implementation of the Microsoft SDL.

Donald, G. (2003). Software Engineering Institute, U.S.A. Security Use Cases. Journal
of Object Technology.

Guttorm Sindre, A. y Opdahl, L. Capturing Security Requirements through Misuse


Cases.

López, S. (2012). Descubriendo el valor de la Seguridad en las Aplicaciones Web con


IBM AppScan. IBM Corporation.

Cunningham, W. Portland pattern repository. Cunningham & Cunningham, Inc.

TEMA 4 – Ideas clave 26 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Lo + recomendado

Lecciones magistrales

Análisis estático de código

En la presente clase magistral se van a analizar los tipos y categorías de herramientas


disponibles tanto comerciales como de open source, para qué lenguajes están
disponibles, cómo y cuándo se tienen que utilizar y cómo se enmarca el uso de estas
herramientas en el proceso de revisión del código.

La lección magistral está disponible en el aula virtual.

No dejes de leer…

A Few Billion Lines of Code Later

Artículo realizado por el equipo de Coverity que describe la experiencia e


implementación de una herramienta de análisis estático comercial.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://cacm.acm.org/magazines/2010/2/69354-a-few-billion-lines-of-code-
later/fulltext

TEMA 4 – Lo + recomendado 27 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Security Controls for Computer Systems

Artículo que introduce la idea de las pruebas de penetración, así como muchas otras
ideas fundacionales de seguridad de los sistemas.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://www.rand.org/pubs/reports/R609-1/index2.html

Vsftpd. Probably the most secure and fastest FTP server for UNIX-like
systems

FTPD seguro, en estos documentos se presenta una descripción del diseño e


implementación de programa vsftpd.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


https://security.appspot.com/vsftpd.html#docs

No dejes de ver…

Dynamic Testing, Why Tools Alone Aren’t Enough

Las herramientas de pruebas dinámicas tradicionales juegan un papel importante en el


aseguramiento del software, pero sí sola no pueden resolver todos los problemas de
seguridad. En este video se presenta por qué es necesario utilizar varias herramientas y
pruebas manuales, así como un enfoque basado en el riesgo en la realización de pruebas
de seguridad del software. El acceso al webinar requiere registro.

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


https://www.cigital.com/resources/videos/on-demand-webinar-451/

TEMA 4 – Lo + recomendado 28 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Lessons from Heartbleed

Vídeo sobre el incidente Heartbleed que afecto a una gran cantidad de servidores con el
software Open SSL instalado. Los autores, expertos en seguridad de aplicaciones,
presentan ideas, lecciones aprendidas y directrices de seguridad que proporcionan a
implementar. El acceso al webinar requiere registro.

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


https://www.arxan.com/resources/lessons-from-heartbleed-strengthening-
application-security-on-busted-technology-architectures-webinar/

Scenario Based Hacking and Penetration Testing

Serie de vídeos que enseñan a realizar pruebas


de penetración, análisis de vulnerabilidades,
etc.

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


http://www.securitytube.net/groups?operation=view&groupId=2

TEMA 4 – Lo + recomendado © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

+ Información

A fondo

All You Ever Wanted to Know About Dynamic Taint Analysis and Forward
Symbolic Execution

Presentación formal y artículos de estos tipos de análisis y sus variaciones.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://users.ece.cmu.edu/~ejschwar/bib/schwartz_2010_dynamic-abstract.html

SPIKE

Página web que muestra cómo utilizar la herramienta de fuzzing de red SPIKE.

Accede a la página desde el aula virtual o a través de la siguiente dirección:


http://resources.infosecinstitute.com/intro-to-fuzzing/

Enlaces relacionados

Metasploit

Metasploit es un proyecto open source de seguridad informática que proporciona


información acerca de vulnerabilidades de seguridad y ayuda en test de penetración y el
desarrollo de firmas para sistemas de detección de intrusos.

Accede a la página desde el aula virtual o a través de la siguiente dirección:


http://www.metasploit.com/

TEMA 4 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Armitage

Sitio web para descargarse este programa que implementa una interfaz gráfica de la
herramienta de penetración Metaexploit. Contiene manuales y vídeos de uso de esta
herramienta.

Accede a la página desde el aula virtual o a través de la siguiente dirección:


http://www.fastandeasyhacking.com/

NMAP

Escáner que proporciona información de puertos abiertos, versiones de sistemas


operativos, etc.

Accede a la página desde el aula virtual o a través de la siguiente dirección:


http://nmap.org/

TEMA 4 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Zap

Escáner de vulnerabilidades de aplicaciones web, desarrollado en el marco del Proyecto


OWASP.

Accede a la página desde el aula virtual o a través de la siguiente dirección:


https://github.com/zaproxy/zaproxy

Burp suite

Escáner de vulnerabilidades de aplicaciones web que dispone de una versión libre y otra
de pago.

Accede a la página desde el aula virtual o a través de la siguiente dirección:


http://portswigger.net/burp/

Kali

Distribución de Linux con las herramientas de prueba de penetración preinstaladas.

Accede a la página desde el aula virtual o a través de la siguiente dirección:


https://www.kali.org/

TEMA 4 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Coverity's free Code Spotter

Herramienta de análisis estático para lenguaje Java.

Accede a la página desde el aula virtual o a través de la siguiente dirección:


http://www.coverity.com/press-releases/coverity-launches-code-spotter-in-free-beta-
version-to-speed-defect-detection-in-java-code/

Coverity Scan initiatives

Herramienta de análisis estático para lenguaje C y C++.

Accede a la página desde el aula virtual o a través de la siguiente dirección:


https://scan.coverity.com/

Joern

Herramienta de análisis estático para lenguaje C y C++.

Accede a la página desde el aula virtual o a través de la siguiente dirección:


http://www.mlsec.org/joern/

TEMA 4 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

FindBugs

Herramienta de análisis estático para lenguaje Java.

Accede a la página desde el aula virtual o a través de la siguiente dirección:


http://findbugs.sourceforge.net/

Bibliografía

Chess, B. y West. J. (2007). Secure Programming with Static Analysis. Addison-Wesley


Software Security Series.

Howard, M., LeBlanc, D. (2003). Writing Secure Code. Microsoft Press.

Howard, M., Lipner, S. (2006). The Security Development Lifecycle: SDL: A Process for
Developing Demonstrably Secure Software. Microsoft Press.

McGraw, G. (2005). Software Security: Building Security In. Addison Wesley


Professional.

Redwine Jr., S. T. (Editor). (2006). Software Assurance: A Guide to the Common Body
of Knowledge to Produce, Acquire, and Sustain Secure Software Version 1.1. US
Department of Homeland Security.

Allen, J. H.; Barnum. S.; Ellison, R. J.; McGraw, G.; Mead, N. R. (2008). Software
Security Engineering: A Guide for Project Managers. Addison Wesley Professional.

Krassowski, A. y Meunier, P. (2008). Secure Software Engineering: Designing, Writing,


and Maintaining More Secure Code. Addison-Wesley.

TEMA 4 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Test

1. Señala la respuesta correcta. Una herramienta de análisis de código reporta que no existen
vulnerabilidades para una aplicación revisada. La aplicación es distribuida y, un mes más
tarde, una inyección SQL es anunciada de forma pública y, posteriormente, explotada. ¿Qué
tipo de limitación de las herramientas de análisis de código se ha expuesto?
A. Un falso positivo.
B. Un falso negativo.
C. Una vulnerabilidad específica de un lenguaje de programación.
D. Ninguna de las anteriores.

2. Señala las respuestas correctas. Un equipo de desarrollo está preocupado por la


amenaza de un escape de información y tiene recursos para llevar a cabo las
verificaciones de seguridad que se listan a continuación. ¿Cuál de las siguientes
aproximaciones recomendarías en este caso?
A. Inyección de fallos en código fuente.
B. Revisión de código.
C. Test de penetración.
D. Ninguna de las anteriores.

3. Señala la respuesta correcta. Un equipo de desarrollo está iniciando un ciclo de


desarrollo de software y planea llevar a cabo test de penetración en algún momento. ¿En
qué etapa del ciclo de desarrollo recomendarías llevar a cabo el test de intrusión?
A. Al finalizar el diseño inicial de la aplicación.
B. Cuándo se consigue ejecutar la aplicación con éxito por primera vez.
C. Cuándo la aplicación está cerca del final del ciclo de desarrollo, en la fase de
operación y mantenimiento.
D. Todas las anteriores.

4. Indicar la respuesta incorrecta. Los factores principales prácticos que determinan la


utilidad de una herramienta de análisis estático son:
A. El equilibrio que la herramienta hace entre la precisión, la profundidad y la
escalabilidad.
B. Porcentaje de falsos positivos (no de negativos) de la herramienta.
C. Las características de la herramienta para hacerla fácil de usar.
D. La capacidad de la herramienta para comprender el programa que se analiza.

TEMA 4 – Test © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

5. Señala la respuesta correcta. Respecto al tipo de análisis Taint Propagation:


A. Análisis de flujo de datos para determinar qué es lo que un atacante puede
controlar, se requiere saber por dónde entra la información en el programa y cómo
se mueve a través de él.
B. Los alias de los punteros son otra clase de problema del flujo de datos. La
finalidad del análisis de alias es determinar qué punteros apuntan a la misma
posición de memoria.
C. Analiza una función individualmente en cuanto a caminos de ejecución y
eliminar caminos falsos, que son caminos por los cuales el código nunca puede
ejecutarse porque son lógicamente incoherentes.
D Para propiedades temporales de seguridad como «la memoria solo debería ser
liberada una vez» y «solo los punteros no nulos deberían ser referenciados» es fácil
representarlas como pequeños autómatas de estado finito.

6. Señala la o las respuestas correctas. Las perspectivas de las pruebas de seguridad


basadas en el riesgo son los siguientes:
A. Perspectiva gerencia.
B. Perspectiva atacante.
C. Perspectiva usuario.
D. Perspectiva defensor

7. Señala la o las respuestas correctas. El principal problema de las herramientas de


análisis estático es:
A. Falsos negativos que produce.
B. Gran cantidad de defectos que encuentra.
C. Reglas de la herramienta.
D. Falsos positivos que produce.

8. Señala la o las respuestas correctas. Las herramientas de análisis estático realizan


varios tipos de análisis.
A. Taint Propagation.
B. Análisis puntual.
C. Model checking.
D. Análisis de flujo de datos.

TEMA 4 – Test © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

9. Señala la o las respuestas correctas. Los test de penetración:


A. En ningún caso demuestran que ningún defecto existe
B. Revisan el código.
C. El entendimiento del ambiente de ejecución y de los problemas de configuración
es el mejor resultado de cualquier prueba de penetración
D. Las conclusiones de seguridad no son repetibles a través de equipos diferentes
y varían extensamente dependiendo de la habilidad y la experiencia de los
probadores.

10. Señala la respuesta correcta. A la hora de realizar la distribución y despliegue del


software desarrollado, es recomendable el realizar las siguientes buenas prácticas:
A. Distribuir el software con una configuración por defecto segura y lo más
restrictiva posible.
B. Proporcionar una herramienta de instalación automática.
C. Cambio los valores de configuración predeterminados durante el desarrollo.
D. Todas las anteriores.

TEMA 4 – Test © Universidad Internacional de La Rioja (UNIR)


Codificación segura aplicaciones I
[5.1] ¿Cómo estudiar este tema?

[5.2] Introducción

[5.3] Prácticas de codificación segura

[5.4] Manipulación y validación de entradas

[5.5] Desbordamiento de memoria

[5.6] Referencias

TEMA
Codificación segura
Esquema

Prácticas de codificación segura Introducción a la codificación segura

TEMA 5 – Esquema
Manejo de la entrada Desbordamiento de
de datos buffer

2
• Validación de toda la entrada
• Descripción del ataque de desbordamiento de buffer
• Validación de todas las fuentes de entrada

• Establecer los límites de confianza


• Reserva dinámica de memoria (heap overflow)
• Realizar fuerte validación de entrada

• No confundir usabilidad por seguridad • Control del tamaño de buffer


• Rechazar directamente datos maliciosos • Strings

• Realizar una buena validación de entrada por defecto


• Comprobar la longitud de la entrada

• Comprobar el tamaño de los campos numéricos


• Prevenir vulnerabilidades de metacaracteres
Seguridad en el Software

© Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Ideas clave

5.1. ¿Cómo estudiar este tema?

Para estudiar este tema lee las Ideas clave que te presentamos a continuación.

El objetivo del presente tema es el estudiar los defectos más comunes que se pueden
cometer al codificar en lenguajes como C y Java en lo relativos a manipulación y
validación de entradas, desbordamiento de memoria. Si se entienden bien los defectos
que se pueden cometer se estará en disposición de poder analizar el código para
encontrarlos y posteriormente corregirlos.

5.2. Introducción

Las principales características que diferencian a un desarrollador que programa teniendo


en cuenta reglas de codificación segura de uno que no, son el conocimiento,
intención y precaución. Un profesional del software que se preocupa por la seguridad
y actúa en conciencia reconoce que las vulnerabilidades y debilidades del software se
pueden originar en cualquier punto del ciclo de desarrollo del software, como la
aplicación de requisitos inadecuados, malas decisiones de diseño e implementación y la
inclusión de involuntarios errores de codificación o de configuración.

El profesional con conocimiento de seguridad de software, es consciente de que una de


las maneras de evitar problemas de seguridad en las aplicaciones es, aparte de requisitos
adecuados y uso de principios de diseño seguro, el seguimiento por los
programadores de prácticas de codificación seguras, que eviten la codificación
errores y debilidades explotables que deriven en vulnerabilidades explotables por los
diferentes tipos de agentes maliciosos.

La responsabilidad de desarrollar software no confiable es atribuible a todas las


partes involucradas en el ciclo de vida de desarrollo y en concreto a los
desarrolladores, que escriben el código, desempeñan un papel vital en el desarrollo de
aplicaciones seguras libres de vulnerabilidades.

TEMA 5 – Ideas clave 3 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

5.3. Prácticas de codificación segura

Para iniciarse en la implementación segura de código, es conveniente empezar con


una serie de recomendaciones generales, a tener en cuenta, como línea a seguir en la
profundización y conocimiento de esta disciplina. En el libro Secure Coding: Principles
& Practices [3] se presenta una serie de recomendaciones que caen en las siguientes
categorías:

» Buenas prácticas:
o Formarse uno mismo.
o Formación continua.
o Manejo de los datos con precaución:
– Comprobar los datos de entrada al sistema.
– Comprobar los límites de las estructuras de datos.
– Comprobar los ficheros de configuración.
– Comprobar los parámetros de los comandos codificados en programas.
– No confiar en URLs.
– Tener cuidado con el contenido WEB.
– Comprobar las variables de entorno.
– Comprobar cookies.
– Inicializar las variables correctamente.
– Identificar las referencias a ficheros correctamente y utilizarlas correctamente.
– Poner especial atención en el almacenamiento de información de carácter
confidencial.
o Rehusar código que no ha sido testeado y probado.
o Insistir en el proceso de revisión de código:
– Efectuar revisiones por parejas de programadores.
– Usar herramientas de seguridad disponibles.
o Usar listas de comprobación.
o Revisar el proceso de mantenimiento:
– Usar estándares.
– Eliminar código obsoleto.
– Probar todos los cambios de código.

TEMA 5 – Ideas clave 4 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Malas prácticas:
o Usar en el código nombres relativos de ficheros.
o Referirse a un fichero con el mismo nombre dos veces en el mismo programa.
o Invocar programas en los que no se confía desde otros en los que se confía.
o Asumir que los usuarios no son maliciosos.
o No utilizar librerías seguras que generan números aleatorios como ramdom.
o Invocar Shell desde líneas de comandos.
o Utilizar direcciones IP, MAC o direcciones de correo para identificar usuarios.
o Utilizar zonas de memoria accesibles por todos los usuarios.
o Almacenar información sensible en una base de datos sin protección.
o Visualizar passwords en las pantallas de los usuarios.
o Distribuir por programa información sensible vía correo electrónico.
o Codificar passwords en la aplicación.
o Almacenar passwords en disco sin cifrar.
o Transmitir passwords sin cifrar.
o Confiar solamente en los mecanismos de protección de ficheros del sistema
operativo, se debe implementar mecanismos adicionales en la aplicación.
o Tomar decisiones de acceso basadas en variables de entorno o parámetros de línea
de comando pasados en tiempo de ejecución.
o Almacenar la aplicación en un sistema de ficheros NFS.
o Confiar en software de terceros en operaciones críticas.

Estos pueden ser solo algunos de los aspectos más generales a tener en cuenta a la hora
de desarrollar y como se verá más adelante, sobre todo a la hora de hablar de defectos de
implementación de código, hay que tener en cuenta los defectos particulares que se
pueden cometer con el lenguaje de programación que se está utilizando, el compilador
que se utiliza, y otro software de terceros que seguramente no se tendrá posibilidad de
verificar, pero que formará parte del sistema, y por tanto podría introducir errores en el
sistema que se está implementando.

» Defectos de implementación. Los defectos de implementación que se pueden


cometer se pueden cometer caen dentro de las siguientes categorías:

TEMA 5 – Ideas clave 5 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Defectos de implementación

Manejo de la entrada de datos

Desbordamiento de buffer

Errores y ex cepciones

Priv acidad y confidencialidad

Programas privilegiados

Errores aplicaciones web

Figura 1. Defectos de implementación.

5.4. Manipulación y validación de entradas

Introducción

Una de las medidas de defensa más importantes que un programador puede llevar a
cabo, es validar todas las entradas que el sistema recibe. Son la fuente de
algunas de las peores vulnerabilidades de las aplicaciones, como son el
desbordamiento de buffer, inyección de SQL y otras.

Los atacantes pueden manipular los diferentes tipos de datos de entrada con el
fin de entregar cargas maliciosas a las aplicaciones. Los tipos de entrada siempre deben
ser probados por un sistema de validación de entrada, para evitar este tipo de
ataques.

Validación de la entrada: conjunto de actividades que aceptan la entrada sin confiar


en ella y comprueban la validez de la misma, limitándola solo a los valores que se sabe
son aceptables.

» Qué validar
o Validar toda la entrada.
o Validar la entrada de todas las fuentes.
o Establecer fronteras de confianza.

TEMA 5 – Ideas clave 6 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Cómo validar
o Usar una fuerte validación de entrada.
o Evitar poner en la lista negra.
o No confundir usabilidad y seguridad.
o No confundir la validación de funcionalidad con la validación de entrada para la
seguridad.
o Rechazar datos maliciosos.
o Hacer una buena validación de entrada por defecto
o Siempre comprobar la longitud de entrada.
o Limitar la entrada numérica.

Validación de toda la entrada

Estas tres palabras serán repetidas durante todo el apartado: validar toda la entrada.
Hay que definir la entrada detalladamente y pensar más allá de los datos que un usuario
puede enviar como entrada. Si una aplicación consiste en más de un proceso, validar la
entrada de cada proceso, incluso si aquella entrada llega de otra parte de la
aplicación. Validar la entrada incluso si llega por una conexión segura, llega de una
fuente confiable o está protegida según permisos de archivo estrictos. Las rutinas de
validación de entrada se pueden dividir en dos grupos principales:

» Comprobaciones de sintaxis que prueban el formato de la entrada y a menudo


puede ser desacoplada de la lógica de aplicación y aplicada cerca del punto donde los
datos entran en el programa.
» Comprobaciones semánticas que determinan si la entrada es apropiada,
considerando la lógica de la aplicación y la función. Comúnmente tienen que
aparecer junto a la lógica de aplicación porque las dos están estrechamente
relacionadas.

Realizar la validación de entrada no solo sobre la entrada de usuario, sino


también sobre datos de cualquier fuente externa al código del sistema que
está siendo desarrollado. Esta lista debería incluir, pero sin limitarse a ella, lo
siguiente:
» Parámetros de línea de comando.
» Archivos de configuración.
» Datos recuperados de una base de datos.
» Subida de archivos.

TEMA 5 – Ideas clave 7 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Variables de entorno.
» Importaciones de archivos planos.
» Servicios de red.
» Valores de registro.
» Propiedades de sistema.
» Archivos temporales.
» Las variables de entorno.
» Localizadores de recursos universales (direcciones URL) e identificadores (URI).
» Referencias de otros nombre de archivo.
» Encabezados Hyper Text Transfer Protocol (HTTP).
» Parámetros HTTP GET.
» Campos de formulario (especialmente los ocultos).
» Las listas de selección, listas desplegables.
» Cookies.
» Comunicaciones Java applets.

A continuación se va a ver un ejemplo de estos tipos de errores o ausencia de validación


en la entrada que conduce una vulnerabilidad conocida como inyección de SQL.

La Versión 2.1.9, Hiberne (Chess y West, 2007), un paquete popular open source,
contiene un ejemplo excelente de qué no hacer con la entrada de línea de
comando. La versión Java de la herramienta SchemaExport de Hibernate acepta un
parámetro de línea de comando llamado " -- delimiter ", que se utilizaba para
separar los comandos SQL en los scripts que generaba. El código se muestra en
la figura 2 de una forma simplificada:

String delimiter;
for (int i=0; i < args.length; i++) {
if ( args[i].startsWith("--delimiter=") ) {
delimiter = args[i].substring(12);
}
}
...
for (int i = 0; i < dropSQL.length; i++) {
try {
String formatted = dropSQL[i];
if (delimiter!=null) formatted += delimiter;
...
fileOutput.write( formatted + "\n" );
}

TEMA 5 – Ideas clave 8 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Figura 2. Ejemplo de no validación de la entrada que puede ocasionar una vulnerabilidad de inyección de
SQL. Fuente: Chess y West (2007).
La opción -- delimiter existe para que un usuario pueda especificar el separador que
debería aparecer entre sentencias SQL. Valores típicos podrían ser un punto y coma o un
retorno de carro. Pero el programa no coloca ninguna restricción contra el valor del
argumento, por tanto a través de un parámetro de línea de comando, se puede escribir
cualquier cadena que se quiera en la sentencia SQL generada, incluyendo órdenes de SQL
adicionales.

Por ejemplo, si una simple SELECT fue generada con -- delimiter ';', esto generaría un
script para ejecutar la sentencia siguiente:

SELECT * FROM items WHERE owner = "admin"

Pero si la misma consulta fue emitida con la opción malévola -- delimiter '; DELETE
FROM items;', generaría una sentencia que limpia a fondo la tabla items con la sentencia
siguiente:

SELECT * FROM items WHERE owner = "admin"; DELETE FROM items

Establecer los límites de confianza

Un límite de confianza se puede pensar como una línea dibujada a través de


un programa, fuera de la cual, no se confía en los datos. Al otro lado de la línea,
los datos se asumen seguros para alguna operación particular. El objetivo de la lógica de
validación es el de permitir a los datos cruzar el límite de confianza, moverse de la zona
no segura a la zona en la que se confía. El modo más fácil de cometer este error es
el de permitir datos confiables y no confiables mezclados en la misma
estructura de datos.

El ejemplo de la figura siguiente, figura 3, demuestra un problema común de frontera de


confianza en Java. Los datos no confiables llegan a una petición HTTP y el programa
almacena los datos en un objeto de sesión HTTP sin realizar primero una validación.
Como el usuario directamente no puede tener acceso al objeto de sesión, los
programadores típicamente creen que pueden confiar en la información almacenada en
el objeto de sesión. Combinando datos validados y no validados en la sesión, este código
viola un límite implícito de confianza.

TEMA 5 – Ideas clave 9 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

status = request.getParameter("status");
if (status != null && status.length() > 0) {
session.setAttribute("USER_STATUS", status);
}

Figura 3. Ejemplo de violación de los límites de confianza. Fuente: Chess y West (2007).

La entrada no validada almacenada en la sesión HTTP del Ejemplo de la figura anterior,


figura 3, se imprime más adelante en la misma página JSP, figura 4. Aunque el valor
viene de un objeto de sesión HTTP, que es de confianza por lo general, el atributo
USER_STATUS nunca fue validado, haciendo de este código vulnerable a un ataque del
tipo crosssite scripting (XSS).

String user_state = "Unknown";


try {
HttpSession user_session = Init.sessions.get(tmpUser.getUser());
user_state = user_session == null ? "Unknown" :
(String)user_session.getAttribute("USER_STATUS");
user_state = user_state == null ? "Available" : user_state;}
... %>
<%=user_state %>

Figura 4. Uso de datos invalidados. Fuente: Chess y West (2007).

Realizar fuerte validación de entrada

Una correcta aproximación a la validación de entrada es comprobar la entrada


frente a una lista de valores correctos conocidos. Una buena validación de
entrada no intenta comprobar valores específicos no válidos. Se considera mejor la
comprobación contra:

Whitelisting: lista de valores conocidos válidos

Cuando el juego de valores de entrada posibles es pequeño, se puede usar la selección


indirecta para conseguir que el whitelist sea imposible de evitar, es la
primera opción cuando se realiza la validación de entrada.

TEMA 5 – Ideas clave 10 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Al final se pone:

Lista negra (Blacklinting): intento de enumerar todas las entradas posibles


inaceptables.

Se puede utilizar algún nivel de indirección en el programa haciendo que el usuario


especifique primero algún subconjunto de datos de entre todos los que el conjunto total
de datos que se pueda dividir, de esta forma si el usuario no sabe alguno de estos
subconjuntos válidos de datos se evita tratar directamente de validar entradas complejas
de datos y solo se valida en principio un índice de los subconjuntos de datos legítimos.

Realizar una buena validación de entrada por defecto

En vez de codificar una nueva solución al problema de validación de entrada cada vez,
diseñar el programa de modo que haya un lugar claro, constante, y obvio
para la validación de entrada. La aplicación debería hacer pasar toda la entrada por
esta lógica de validación y ésta debería rechazar cualquier entrada que no pueda ser
validada.

Esto requiere la creación de una capa de abstracción sobre las bibliotecas del sistema en
la que el programa suele ser introducido. Hacer una buena validación de entrada por
defecto creando una capa de funciones o métodos, se denomina seguridad API. La figura
siguiente, muestra cómo se interpone el API de seguridad entre el programa y las
librerías de sistema.

Lógica de programa

API seguridad

Entrada Librerías de sistema

Figura 5. APIs de seguridad implican un amplio contexto para hacer la validación de entrada.

Comprobar la longitud de la entrada

TEMA 5 – Ideas clave 11 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

La lógica de validación front-end siempre debería comprobar la longitud de


la entrada contra un mínimo y máximo. Las comprobaciones de longitud son por
lo general fáciles de añadir, pues no se requiere mucho conocimiento sobre el significado
de la entrada. Tener cuidado cuando el programa transforma la entrada antes del
tratamiento, pues esta puede hacerse más larga durante el proceso.

if (path != null &&


path.length() > 0 && path.length() <= MAXPATH) {
fileOperation(path);
}

Figura 6. Comprobación de la longitud de un campo. Fuente: Chess y West (2007).

Comprobar el tamaño de los campos numéricos

Comprobar la entrada numérica tanto contra un valor máximo como contra un


valor mínimo como parte de validación de la entrada. Tener cuidado con las operaciones
que podrían ser capaces de llevar un número más allá de su valor máximo o mínimo.

Cuando un atacante aprovecha la capacidad limitada de una variable de tipo entero, el


problema es el desbordamiento de este tipo de datos En C y C ++, el desbordamiento de
número entero típicamente supone parte de la preparación para un ataque de
desbordamiento de buffer. El desbordamiento de número entero en Java no conduce
vulnerabilidades de desbordamiento, pero puede causar un comportamiento indeseable.

El mejor modo de evitar problemas de desbordamiento de un número entero


es comprobar toda la entrada, de este tipo de datos, tanto contra una cota
superior como contra una cota inferior.

Java ofrece varios tamaños diferentes de valores enteros: char (8 bits), short (16 bits), int
(32 bits), y long (64 bits). Sin embargo, no ofrece tipos de entero sin signo, por lo que no
hay ningún modo de evitar comprobar la cota inferior como la superior. En C y C++ leer
campos de entrada usando enteros sin signo, obvia la necesidad de comprobar el límite
inferior, pero hay que tener cuidado porque hay que ser conscientes de que las
operaciones que mezclan enteros con y sin signo pueden acarrear resultados negativos y
convertir resultados con signo en otro sin signo podría producir un resultado inesperado
demasiado grande.

TEMA 5 – Ideas clave 12 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Ejemplo: malloc() acepta un entero y realiza una conversión implícita a entero si signo,
si doAlloc() recibe un número negativo como argumento puede resultar en un
intento de reservar una gran cantidad de memoria.

void* doAlloc(int sz) {


return malloc(sz); /* Implicit conversion here: malloc()
accepts an unsigned argument. */
}

Figura 7. Comprobación de tipos. Fuente: Chess y West (2007).

Prevenir vulnerabilidades de meta-caracteres

Si se permite a los atacantes controlar los comandos que se envían a la base


de datos, sistemas de ficheros, navegador u otros subsistemas se podría para
cambiar la finalidad del mismo. Se pueden tener problemas serios como
consecuencia de ello. Como ejemplos de ellos tenemos los siguientes [23]:

Ataque Implicaciones
SQL Injection Accede/modifica datos en la base de datos
XPath Injection Accede/modifica datos en formato XML
Ejecuta comandos sobre el servidor y accede a datos
SSI Injection
sensibles
LDAP Injection Bypass de autenticación
MX Injection Usa el servidor de correos como una máquina de spam
HTTP Injection Modifica o intoxica el caché de las web
Tabla 1. Defectos de inyección.

» Inyección de SQL

La realización de sentencias SQL donde se combinan palabras clave con datos tiene el
problema de que alguien malintencionadamente pueda alterar las estructuras de
control y por tanto el significado de la sentencia, cuando la intención era solamente
suministrar datos a la sentencia sin alterar las estructuras de control. Un atacante
explota este tipo de vulnerabilidades especificando meta-caracteres que tienen un
significado especial como:
o Simples comillas (‘).
o Dos puntos (..), peligroso en sistema de ficheros.

TEMA 5 – Ideas clave 13 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Para comandos de Shell:


o Punto y coma (;).
o (&&).
o Carácter de nueva línea (/n) para los ficheros de log.
En el ejemplo de la figura siguiente, se muestra este tipo de vulnerabilidad en una
sentencia SQL que se forma concatenando strings de tal forma que se deja abierta a
un ataque conocido como inyección de SQL:

String userName = ctx.getAuthenticatedUserName();


String itemName = request.getParameter("itemName");
String query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ itemName + "'";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);

Figura 8. Ejemplo de bug que deja abierto el código abierto a un ataque de inyección de SQL. Fuente:
Chess y West (2007).

El programador que escribió el código pretendía formar consultas como:

SELECT * FROM itemsWHERE owner = <userName> AND itemname = <itemName>;

Pero un atacante puede asignar al campo itemname la cadena "name' OR 'a'='a" con
lo que la sentencia se convierte en:

SELECT * FROM items WHERE owner = 'wiley' AND itemname = 'name' OR


'a'='a';

La adición de OR 'a'='a' convierte la sentencia pretendida a esta: SELECT * FROM


ítems Esta sentencia extrae todas las filas de la tabla ítems, posibilitando que el
atacante las pueda visualizar. Este es un pequeño ejemplo de lo que un atacante puede
hacer. Muestra que se podrían también borrar todos los datos de la tabla y ejecutar
muchas más sentencias distintas de la pretendida que solo mostrar una fila al usuario.

La forma de ayudar a prevenir este tipo de ataques es utilizar consultas


parametrizadas que fuerzan a la distinción entre estructuras de control
como son las palabras clave de una sentencia SQL de lo que son
puramente datos de entrada por parte del usuario de la aplicación. Los

TEMA 5 – Ideas clave 14 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

programadores pueden explícitamente especificar a la base de datos lo que debe ser


tratado como comando y lo que debe ser tratado como datos.

Debe evitarse formar consultas formadas con sentencias parametrizadas y cadenas


concatenadas:

String item = request.getParamater("item");


String q="SELECT * FROM records WHERE item=" + item;
PreparedStatement stmt = conn.prepareStatement(q);
ResultSet results = stmt.executeQuery();

Figura 9. Ejemplo de consulta SQL construida con el uso de sentencias parametrizadas y concatenadas.
Fuente: Chess y West (2007).

» Manipulación de rutas

Este tipo de error tiene lugar cuando se permite en las entradas de un usuario incluir
meta-caracteres de sistemas de ficheros como:

o slash (/).
o backslash (\).
o punto (.).

donde se espera una ruta relativa un atacante puede convertirla en una ruta absoluta
o recorrer el sistema de ficheros a una posición no planeada subiendo en el árbol de
directorio. Se denomina a un acceso al sistema de ficheros no autorizado
de este tipo manipulación de ruta. El código del ejemplo de la figura siguiente,
muestra la entrada a la aplicación desde una petición HTTP para crear un nombre de
archivo. El programador no ha considerado la posibilidad de que un atacante podría
proporcionar un nombre del archivo como ../../tomcat/conf/server.xml, que hace que
la aplicación suprima uno de sus propios archivos de configuración.

String rName = request.getParameter("reportName");


File rFile = new File("/usr/local/apfr/reports/" + rName);
rFile.delete();

Figura 10. Ejemplo de vulnerabilidad de manipulación de ruta. Fuente: Chess y West (2007).

TEMA 5 – Ideas clave 15 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Las vulnerabilidades de manipulación de ruta son relativamente fáciles de prevenir


con whitelists.

» Inyección de comandos

Si se permite al usuario, especificar comandos de sistema que su programa


ejecuta, los atacantes podrían ser capaces de hacer que el sistema ejecute
comandos maliciosos en su nombre. Se denomina inyección de comandos a la
ejecución de comandos no autorizada.

El código en el ejemplo de la figura siguiente, es para ejecutar un backup de una base


de datos ORACLE en Windows. Se acepta un parámetro que especifica un tipo de
backup con la utilidad rman. Se necesita un acceso privilegiado para poder acceder a
la BD, por tanto la aplicación se ejecuta con un usuario privilegiado. Un atacante
podría pasar como parámetro "&& del c:\\dbms\\*.*“, cualquier comando que se
inyectara se ejecutaría con los privilegios que se tenían para trabajar con la BD.

String btype = request.getParameter("backuptype");


String cmd = new String("cmd.exe /K \"c:\\util\\rmanDB.bat "
+ btype + "&&c:\\utl\\cleanup.bat\"")
Runtime.getRuntime().exec(cmd);

Figura 11. Ejemplo de inyección de comandos. Fuente: Chess y West (2007).

» Falsificación de logs

Los logs son un objetivo para atacantes pues son un recurso valioso para
administradores de sistema y desarrolladores. Si los atacantes pueden falsificar el
valor que es escrito en los log, podrían ser capaces de fabricar eventos en el sistema
mediante la inclusión de entradas corrompidas. Los archivos de log falsificados o de
otro modo, archivos de log corrompidos, pueden usarse para seguir las pistas de
un atacante o implicar a otra parte en la comisión de un acto malicioso.

El ejemplo de la figura siguiente, muestra un trozo de código de una aplicación WEB


que intenta leer un número entero desde un objeto request. Si el valor al ser
comprobado no es entero se escribe el evento de log correspondiente indicando lo
ocurrido.

TEMA 5 – Ideas clave 16 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

String val = request.getParameter("val");


try {
int value = Integer.parseInt(val);
}
catch (NumberFormatException) {
log.info("Failed to parse val = " + val);
}
Figura 12. Ejemplo de falsificación de log. Fuente: Chess y West (2007).

Si un usuario envía a la aplicación «twenty-one» en el parámetro val se registra la


siguiente entrada:

INFO: Failed to parse val=twenty-one

Sin embargo si un atacante envía:

«twenty-one%0a%0aINFO:+User+logged+out%3dbadguy» se registra la siguiente


entrada:

INFO: Failed to parse val=twenty-one INFO: User logged out=badguy

5.5. Desbordamiento de memoria

Introducción

Un desbordamiento de memoria o de buffer ocurre cuando un programa escribe


datos fuera de los límites de la memoria asignada.

Las vulnerabilidades por desbordamiento de buffer por lo general son


explotadas con el objetivo de superponer valores en la memoria en provecho del atacante.
Los errores de desbordamiento buffer están muy extendidos y normalmente dan a un
atacante un control alto del código vulnerable. Se pueden provocar como consecuencia
del manejo incorrecto tanto de cadenas de caracteres como de la manipulación de
números enteros. Este tipo de vulnerabilidades se puede clasificar en los siguientes tipos:

TEMA 5 – Ideas clave 17 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Figura 13. Tipos de vulnerabilidades de Desbordamiento de Buffer.

La mejor forma de prevenir el desbordamiento de buffer es utilizar un lenguaje


de programación que fuerce la comprobación de tipos y de memoria de forma
que su gestión sea segura. C#, Java, Python, Ruby o dialectos de C como CCured y
Cyclone son lenguajes de este tipo. Se usa el término «safe» para referirse a lenguajes
que automáticamente realizan comprobaciones en tiempo de ejecución para impedir a
los programas violar los límites de la memoria asignada.

Los lenguajes seguros deben proporcionar dos propiedades para asegurar que los
programas respetan límites de asignación:

» Seguridad de memoria. Requiere que el programa no leerá o escribirá datos fuera


de los límites de la memoria asignada.
» Seguridad de tipo. En los lenguajes que cumplen esa propiedad, se asigna un tipo
a los objetos, como por ejemplo un tipo int, puntero a int, puntero a función, etc. Esta
propiedad asegura que las operaciones en el objeto son siempre compatibles con su
tipo. Sin esta característica cualquier valor arbitrario podría usarse como una
referencia en la memoria. C y C++ son lenguajes inseguros y ampliamente utilizados
y por tanto el programador es el responsable de prevenir que las operaciones que
manipulan la memoria puedan resultar en desbordamientos de buffer. Un ejemplo
de este tipo de error que se pude cometer en este lenguaje es cuando se declara un
puntero a un número entero (int) y luego se utiliza como un puntero a una función,
tal y como se muestra en ejemplo siguiente:

TEMA 5 – Ideas clave 18 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

int (*cmp)(char*,char*);
int *p = (int*)malloc(sizeof(int));
*p = 1;
cmp = (int (*)(char*,char*))p;
cmp(“hola”,”adios”); // El programa realiza realiza un crash
Figura 14. Error de seguridad de tipos.

Las operaciones que conducen a desbordamientos se reducen a un pequeño conjunto,


por ejemplo Java es un lenguaje esencialmente seguro:

» No tiene explícita manipulación de punteros.


» Límites de arrays, strings son automáticamente comprobados.
» Intentos de referencias a un objeto null son capturados.
» Las operaciones aritméticas están bien definidas.
» Control de acceso a ficheros, sockets mediante: JVM -> Security Manager

No obstante hay que tener en cuenta una serie de consideraciones sobre potenciales
vulnerabilidades de Java:

» Seguridad de tipos. Los campos que son declarados privados o protegidos o que
tienen protección por defecto no deberían ser públicamente accesibles.

public class TowerofLondon { public class GarageSale {


private Treasure public Treasure
theCrownJewels fredsJunk
... ....
} }
Figura 15. Seguridad de tipos en Java. Fuente: Long, 2005.

» Campos públicos. Un campo que es declarado público directamente puede ser


accedido por cualquier parte de un programa Java y puede ser modificado por las
mismas (a no ser que el campo sea declarado como final). Claramente, la
información sensible no debe ser almacenada en un campo público,
porque podría ser comprometido por alguien que podría tener acceso a la JVM que
ejecuta el programa.
» Serialización. Esta facilidad posibilita que el estado del programa sea capturado y
convertido en una byte stream que puede ser restaurado por la operación inversa que
es la deserialización.

TEMA 5 – Ideas clave 19 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» JVM. La JVM en sí misma está escrita en C para una plataforma dada. Esto quiere
decir que la JVM en sí misma puede ser susceptible a problemas de
desbordamiento.

class Echo {
public native void runEcho();
static {
System.loadLibrary("echo");
}
public static void main(String[] args) {
new Echo().runEcho();
}
}

Figura 16. Llamada a un método nativo JNI. Fuente: Chess y West (2007).

El código de la figura siguiente, implementa el método native definido en la clase


Echo. El código es vulnerable a buffer overflow causada por una llamada ilimitada a
gets().

#include <jni.h>
#include "Echo.h" // Echo class compiled with javah
#include <stdio.h>
JNIEXPORT void JNICALL
Java_Echo_runEcho(JNIEnv *env, jobject obj)
{
char buf[64];
gets(buf);
printf(buf);
}

Figura 17. Vulnerabilidad de buffer overflow en un método nativo. Fuente: Chess y West (2007).

TEMA 5 – Ideas clave 20 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Ataque de desbordamiento de buffer basado en el stack

En un ataque clásico por desbordamiento de buffer, el atacante envía los datos que
contienen un segmento de código malévolo a un programa que es vulnerable a este error,
basado en el stack. Además del código malévolo, el atacante incluye la dirección de
memoria del principio del código.

El código malévolo, suele ser un shellcode: conjunto de instrucciones de programación


generalmente en lenguaje ensamblador y trasladadas a opcodes que suelen ser
inyectadas en la pila (o stack) de ejecución de un programa para conseguir que la
máquina en la que reside se ejecute la operación de tipo malicioso. Su nombre
proviene de un exploit que se usaba para obtener una Shell. Deben ser de longitud corta
para poder ser inyectadas dentro de la pila en un espacio reducido y se utilizan para
ejecutar código malévolo aprovechando ciertas vulnerabilidades en el código relativas a
llamadas con desbordamiento de búfer. Principalmente se programa para permitir
ejecutar un intérprete de comandos en el equipo afectado.

En la figura se muestra un ejemplo:

#include <unistd.h>
int main() {
char *scode[2];
scode[0] = "/bin/sh";
scode[1] = NULL;
execve (scode[0], scode, NULL);
}

Figura 18. Shellcode. Fuente http://es.wikipedia.org/wiki/Shellcode

Esta shellcode, que ejecuta la shell /bin/sh, realiza una llamada al sistema execve para
realizar la ejecución de la shell contenida dentro del array scode.

Cuando el desbordamiento de buffer ocurre, el programa escribe los datos del atacante
en el buffer y sigue más allá de los límites del buffer hasta que superponga la
dirección de vuelta de la función con la dirección del principio del código
malicioso. Cuando la función devuelve el control, salta al valor almacenado en su
dirección de retorno.

Normalmente, esto lo devolvería al contexto de la función llamada, pero debido a que la


dirección de retorno ha sido superpuesta, el control salta el buffer y comienza a ejecutar

TEMA 5 – Ideas clave 21 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

el código malicioso del atacante. Para aumentar la probabilidad de adivinar la dirección


correcta del código malicioso, los atacantes típicamente rellenan el principio de su
entrada «con una serie de instrucciones NOP» (ninguna operación).

El código del ejemplo de la figura siguiente, define el problema de función trouble(), que
asigna un buffer char y un int en el stack (pila) y lee una línea de texto de stdin con gets()
en el buffer. Como gets() sigue leyendo la entrada hasta que se encuentra un
carácter de final-de-línea, un atacante puede desbordar el buffer line con
datos maliciosos. En el ejemplo, esta función declara dos variables locales y usa gets()
para leer una línea de texto en el buffer line del stack de 128 octetos.

La pila es un lugar en la memoria de un equipo en el que todas las variables que se


declaran e inicializan antes de pasarlas a tiempo de ejecución se almacenan.

void trouble() {
int a = 32; /*integer*/
char line[128]; /*character array*/
gets(line); /*read a line from stdin*/
}

Figura 19. Empleo incorrecto de gets() que puede incurrir en desbordamiento de buffer. Fuente: Chess y
West (2007).

Otro ejemplo mostrado en la siguiente figura 18, muestra lo que ocurre en un clásico
ataque de buffer overflow.

» El primer marco de stack representa el contenido de la memoria después de llamar a


trouble() pero antes de que sea ejecutada. La variable local line es asignada sobre el
stack que comienza en la dirección 0xNN. La variable local a está justo encima de
line en la memoria; la dirección de vuelta (0x <retorno>) está encima de a. Asumir
que 0x <retorno> apunta a la función que llamó a trouble().
» El segundo marco de stack ilustra un argumento en el cual el trouble() se comporta
normalmente. ¡Se lee la entrada! ¡EJEMPLO BUENO! y retorna. Se puede ver ahora
que line está parcialmente llena con un string de entrada y que otros valores
almacenados sobre el stack son inalterados.
» El tercer marco de stack ilustra un escenario en el cual un atacante explota la
vulnerabilidad de desbordamiento de buffer en trouble() y hace que se ejecute el
código malévolo en vez de retornar normalmente. En este caso, line ha estado llena

TEMA 5 – Ideas clave 22 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

de una serie de NOPs, el código del exploit, y la dirección del principio del buffer,
0xNN.

Uno de los errores de concepto que se tienen sobre las vulnerabilidades de buffer
overflow, es que son solo explotables cuando el buffer está en el stack. Los ataques
basados en el heap pueden sobrescribir datos importantes almacenados en el mismo y
cambiar el flujo del programa. Por ejemplo, se podría sobrescribir el valor de un
puntero a una función, de tal forma que cuando el programa invoque la
función referenciada por el puntero a la función se ejecutará el exploit.

Heap, es la sección de la memoria de un equipo donde todas las variables creadas o


inicializadas en tiempo de ejecución se almacenan.

Figura 20. Ejemplo de ataque de buffer overflow. Fuente: Chess y West (2007).

TEMA 5 – Ideas clave 23 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Ataques relacionados con la reserva dinámica de memoria (heap overflow)

Gran parte de las vulnerabilidades relacionadas con la reserva de memoria dinámica se


corresponden a fallos de programación que encajan en alguna de las siguientes
categorías:

Figura 21. Errores heap overflows.

» Memoria no utilizada, sin desasignar (memory leaks). Favorece de forma


potencial ataques de denegación de servicio. Se produce cuando una aplicación
adquiere la memoria y falla al liberarla de nuevo al sistema operativo. La siguiente
función en «C» deliberadamente pierde memoria al no liberar el puntero a la
memoria asignada, una vez el puntero 'a' está fuera de ámbito, una vez ejecutada la
function_which_allocates () finaliza sin liberar 'a'.

» #include <stdlib.h>
» void function_which_allocates(void) {
» /* reserve en memoria un array de 45 datos tipo floats */
» float * a = malloc(sizeof(float) * 45);
» /* la zona de memora direccionada ppor el punter a 'a' */
» return
» /* al volver a la función main se olvida de liberar la memoria
reservada con la función malloc*/
» }
» int main(void) {
» function_which_allocates();
» /* el puntero “a” ya no exixte por lo que no se puede liberar y por
tanto la memoria seguirá estando asignada*/

Figura 22. Ejemplo memory leaks. Fuente: http://en.wikipedia.org

TEMA 5 – Ideas clave 24 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Uso de memoria después de ser liberada (use after free). Ocurre cuando un
programa continúa usando un puntero que ha sido previamente liberado. Si esa
memoria se vuelve a reservar, un atacante puede lanzar un ataque de buffer overflow.
Catalogado con el CWE-416.

char* ptr = (char*)malloc (SIZE);


...
if (tryOperation() == OPERATION_FAILED) {
free(ptr);
errors++;
}
...
if (errors > 0) {
logError("operation aborted before commit", ptr);
}
Figura 23. Ejemplo use after free. Fuente: Chess y West (2007).

» Acceso a una variable después de liberarla (Dereference After Free). Caso


concreto de use-after-free, que ocurre cuando intentamos acceder a la memoria
dinámica previamente liberada como consecuencia de un free(). En el ejemplo de
abajo [14], el puntero a char buf2R1 es liberado, aunque más adelante se vuelve a
referenciar desde la función strncpy. Como consecuencia, es probable que se
corrompan datos asignados posteriormente en dicha dirección de memoria tras
haber liberado la misma, o que se produzca un crash de la aplicación al intentar
sobreescribir «memoria aleatoria» en la que el proceso no tiene permiso.

Dereference After Free


Acción de acceder a la variable a la que apunta el puntero en cuestión. Ej: int * ptr= &b;
*ptr= 15;

TEMA 5 – Ideas clave 25 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

#include <stdio.h>
#include <unistd.h>
#define BUFSIZER1 512
#define BUFSIZER2 ((BUFSIZER1/2) - 8)
int main(int argc, char **argv) {
char *buf1R1;
char *buf2R1;
char *buf2R2;
char *buf3R2;
buf1R1 = (char *) malloc(BUFSIZER1);
buf2R1 = (char *) malloc(BUFSIZER1);
free(buf2R1); /* libero el puntero*/
buf2R2 = (char *) malloc(BUFSIZER2);
buf3R2 = (char *) malloc(BUFSIZER2);
strncpy(buf2R1, argv[1], BUFSIZER1-1); /* lo vuelvo a utilizar*/
free(buf1R1);
free(buf2R2);
free(buf3R2);
}

Figura 24. Ejemplo dereference free. Fuente: Merino (2011).

» Liberar la memoria más de una vez (double free). Cuando un programa libera
un trozo de memoria más de una vez free(), las estructuras de datos para gestión de
la memoria pueden llegar a corromperse, lo que puede ocasionar que el programa
falle o causar que se llame dos veces a malloc(). Esto último puede dar el control a un
atacante sobre los datos que se escriben en esa memoria doblemente reservada.
Entonces se tiene un programa potencialmente expuesto a ataque de buffer overflow.

int * ab = (int*)malloc (SIZE);


...
if (c == 'EOF') {
free(ab); }
...
free(ab);
Figura 25. Ejemplo double free. Fuente: Merino (2011).

TEMA 5 – Ideas clave 26 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Uso de un puntero con valor NULL (null dereference). El uso de un puntero


con valor null puede ocasionar fallos de segmentación en la gestión de la memoria.

#include <stdlib.h>
int main(int argc, char *argv[]){
int k=0;
int *p=(int *)NULL;
switch(k) {
case 0:
if (*p) k = *p;
default:
break;
}
return 0;
}

Figura 26. Ejemplo null dereference.

Control del tamaño de buffer

Es esencial para evitar los ataques de buffer overflow controlar el tamaño de


los buffers que se utilizan en el programa y no sobrepasar nunca su tamaño en otras
partes del código. Para ello es conveniente almacenar el tamaño de los buffers en
estructuras compuestas de datos como structs o clases en C, C++.

Manipulación de Strings

» Introducción

La estructura de datos de strings de C básica serie de caracteres terminada por el


carácter nulo, es propensa a error y además las funciones de biblioteca para
la manipulación de los mismos solo empeoran el panorama.

En el presente apartado se introduce al alumno en el estudio de los problemas de


seguridades relativas a las funciones de manipulación de strings y las de
segunda generación, más seguras pues limitan el número de datos copiados por
parámetro.

TEMA 5 – Ideas clave 27 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Funciones inherentemente peligrosas

Operaciones con strings de tamaño limitado

Fallos comunes en funciones limitadas

Errores de truncado

Mantenimiento del carácter nulo de terminación

Figura 27. Problemas con funciones que manipulan string.

» Funciones inherentemente peligrosas

Específicamente hay que evitar el uso de funciones como gets(), scanf(), strcpy(), o
sprintf().

o gets(). Esta función lee de la entrada estándar una corriente de bytes y las alacena
el en array apuntado por s hasta que se encuentra el carácter de nueva línea o de
fin de fichero. Puede producir desbordamiento del buffer, que se le pasa como
argumento, si es más pequeño que la fuente de entrada que en esta caso es la
entrada estándar: el teclado. La función getws(), se comporta de la misma forma.

char gets(char *s)

char line[512];
gets(line);

Figura 28. Llamada insegura a gets () similar a la explotada por el gusano Morris. Fuente: Chess y West
(2007).

o scanf(). Función que lee de la entrada estándar los caracteres que corresponden
al formato que se le especifica. Por ejemplo si se especifica %s, se leerán los
caracteres de la entrada en el buffer hasta que llegue un carácter no-ascii, pudiendo
ocasionar un desbordamiento del buffer. También se puede especificar % 255s
limitando a ese número de caracteres los que se pueden leer de la entrada y usarse
la función de un modo más seguro. Funciones de similar comportamiento son
fscanf(), wscanf().

TEMA 5 – Ideas clave 28 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

scanf(const char *FORMAT [, ARG, ...])

char var[128], val[15 * 1024], ..., boundary[128], buffer[15 * 1024];


...
for(;;) {
...
// if the variable is followed by '; filename="name"' it is a file
inChar = getchar();
if (inChar == ';') {
...
// scan in the content type if present, but simply ignore
it
scanf(" Content-Type: %s ", buffer);

Figura 29. Código de w3-msql 2.0.11 vulnerable a un desbordamiento de búfer remoto causada por una
llamada insegura a scanf ().Fuente: Chess y West (2007).

o strcpy(). A diferencia de las funciones anteriores opera en datos ya almacenados


en una variable de programa, lo cual hace que su manejo suponga obviamente
menos riesgo de seguridad. Esta función copia el contenido de un buffer en otro
hasta que se encuentra un carácter nulo en el buffer fuente, por tanto hay que tener
cuidado de que el buffer fuente sea más pequeño que el destino y que esté
terminado por el carácter nulo. Funciones con similar comportamiento son
wcscpy(), lstrcpy().

char strcpy(char *DST, const char *SRC)

char *FixFilename(char *filename, int cd, int *ret) {


...
char fn[128], user[128], *s;
...
s = strrchr(filename,'/');
if(s) {
strcpy(fn,s+1);

Figura 30. Código del programa php.cgi en PHP / FI 2.0beta10 vulnerable a un desbordamiento de búfer
remoto causada por una llamada insegura para strcpy (). Fuente: Chess y West, 2007.

TEMA 5 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

o sprintf(). Para usarla de forma segura hay que comprobar que el buffer de destino
pueda acomodarse a la combinación de todos los argumentos de la fuente de
entrada, controlando los tamaños fuente-destino y las conversiones de
formato que se especifican. Si la longitud del argumento fuente es mayor que
la del destino se producirá un buffer overflow. Funciones de comportamiento
similar son fprintf(), printf(), swprintf().

int sprintf(char *STR, const char *FORMAT [, ARG, ...])

char speed[128];
...
sprintf(speed, "%s/%d", (cp = getenv("TERM")) ? cp : "",
(def_rspeed > 0) ? def_rspeed : 9600);

Figura 31. Código de la Versión 1.0 del daemon de Telnet Kerberos 5 que contiene un desbordamiento
de búfer debido a que la longitud variable de entorno TERM, que nunca se valida. Fuente: Chess y West
(2007).

» Operaciones con strings de tamaño limitado

Muchas de las primeras vulnerabilidades descubiertas en C, C++ eran causa de


operaciones con strings. Cuando se revisó el estándar de C se introdujeron nuevas
funciones equivalentes a las que se han analizado en el apartado anterior con un
parámetro que limita la longitud del buffer de destino de los datos. Conceptualmente
el uso de estas funciones con limitación de buffer destino se realiza reemplazando las
antiguas funciones con las nuevas:

strcpy(buf, src) → strncpy(buf, src, sizeof(buf))

Para asegurarse que ningún desbordamiento de buffer ocurre aquí, una herramienta
tiene que asegurarse solo que dest_size no es más grande que la cantidad de espacio
asignado para dest. El tamaño y el contenido de src no importan. En la mayoría de los
casos, es mucho más fácil comprobar que dest y dest_size están de acuerdo el uno con
el otro.

TEMA 5 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Función no limitada Función limitada equivalente Función limitada equivalente


librería C estándar librería C estándar Windows Safe CRT

char * gets(char char * fgets(char *dst, int char * gets_s(char *s,


*dst) bound, FILE *FP) size_t bound)
errno_t scanf_s(const char
Int scanf(const char
Ninguna *FMT [, ARG, size_t
*FMT [, arg, ...])
bound,...])
Int sprintf(char Int snprintf(char *str, size_t errno_t sprintf_s(char
*str, const char bound, const char *FMT, [, arg, *dst, size_t bound, const
*FMT [, arg, ...]) ...]) char *FMT [, arg, ...]) w
char * strcat(char errno_t strcat_s(char
char * strncat(char *dst, const
*str, const char *dst,size_t bound, const
char *SRC, size_t bound)
*SRC) char *SRC)
char * strcpy(char errno_t strcpy_s(char *dst,
char * strncpy(char *dst, const
*dst, const char size_t bound, const char
char *SRC, size_t bound)
*SRC) *SRC)

Tabla 2. Funciones ilimitadas con sus correspondientes limitadas. Fuente: Chess y West (2007).

El código de la figura siguiente, muestra una vulnerabilidad de desbordamiento de


buffer que es resultado del empleo incorrecto de funciones de manipulación de strings
ilimitadas strcat() y strcpy() en Kerberos 5 Versión 1.0.6, CERT CA-2000-06, [15].
Dependiendo de la longitud de cp y copy, con cualquiera de las llamadas final a
strcat() o a strcpy() podría desbordarse cmdbuf. La vulnerabilidad ocurre en
el código responsable de manipular un string de un comando, que inmediatamente
sugiere que pudiera ser explotable debido a su proximidad a la entrada de usuario. De
hecho, esta vulnerabilidad públicamente ha sido explotada para ejecutar órdenes no
autorizadas sobre sistemas comprometidos.

if (auth_sys == KRB5_RECVAUTH_V4) {
strcat(cmdbuf, "/v4rcp");
} else {
strcat(cmdbuf, "/rcp");
}
if (stat((char *)cmdbuf + offst, &s) >= 0)
strcat(cmdbuf, cp);
else
strcpy(cmdbuf, copy);

Figura 32. Función ilimitada, vulnerabilidad en Kerberos 5. Fuente: Chess y West (2007).

TEMA 5 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Errores de truncado

Incluso cuando se usan correctamente, las funciones de strings limitadas pueden


introducir errores porque truncan los datos que exceden el límite especificado.

El código de la figura siguiente, muestra un error de truncamiento de string que se


convierte en un problema de terminación. El error está relacionado con el empleo de
la función readlink() que no termina con carácter nulo su buffer destino y puede
devolver hasta el número de octetos especificados en su tercer argumento, el código
de la figura cae en la trampa demasiado común de terminar a mano con carácter nulo
la ruta expandida, buf, en este caso, un octeto más allá del final del buffer.

Este error por un byte denominado «off by one» podría ser inconsecuente,
dependiendo de lo que se almacena en la memoria justo más allá del buffer, pues
permanecerá con eficacia terminado por el carácter uno hasta que otra posición de
memoria sea superpuesta. Es decir, strlen(buf) devolverá solo el tamaño real del
buffer más uno, PATH_MAX + 1, en este caso.

Sin embargo, cuando buf posteriormente sea copiado en otro buffer con el valor de
vuelta de readlink() → len como el límite pasado a strncpy(), los datos en buf están
truncados y el buffer de destino se deja sin terminar con el carácter nulo. Este «error
de por uno» probablemente causará un serio desbordamiento de buffer.

char path[PATH_MAX];
char buf[PATH_MAX];
if(S_ISLNK(st.st_mode)) {
len = readlink(link, buf, sizeof(path));
buf[len] = '\0';
}
strncpy(path, buf, len);

Figura 33. Llamada a strncpy() que podría causar error de truncado. Fuente: Chess y West (2007).

Hay que evitar truncar los datos. Si la entrada proporcionada es demasiado grande
para una operación dada, hay que intentar manejar el problema redimensionando
dinámicamente los buffers, o directamente rehusar realizar la operación e indicar al
usuario lo que tiene que ocurrir para que la operación tenga éxito.

TEMA 5 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Mantenimiento del carácter nulo de terminación

En C, los strings dependen de la terminación nula apropiada, sin ello, su tamaño no


puede ser determinado. Los errores de terminación de strings fácilmente pueden
conducir a desbordamientos y errores lógicos. Estos problemas normalmente
se hacen más insidiosos porque ocurren aparentemente de manera no
determinista dependiendo del estado de la memoria cuando el programa se ejecuta.

Considerar el código de la figura siguiente, Como readlink() no termina con carácter


nulo su buffer de salida, strlen() lee la memoria hasta que encuentra un carácter nulo
y por lo que a veces produce valores incorrectos de longitud, dependiendo del
contenido de memoria después de buf.

char buf[MAXPATH];
readlink(path, buf, MAXPATH);
int length = strlen(buf);

Figura 34. String no terminado en carácter nulo producido por readlink(). Fuente: Chess y West (2007).

Los strings incorrectamente terminados, normalmente se introducen en un programa de


varias formas:

o Un pequeño conjunto de funciones, como RegQueryValueEx() y readlink(),


intencionadamente producen strings no terminados.
o Ciertas funciones que copian strings de un buffer a otro, como strncpy(), tienen
que terminar el buffer de destino con un carácter nulo.
o Funciones que leen octetos genéricos de fuera del programa, como fread() y
recvms(), pueden usarse para leer strings. Como estas funciones no distinguen
entre strings y otras estructuras de datos, no garantizan que los strings terminarán
con carácter nulo.

Nunca hay asumir que los datos del mundo exterior están correctamente terminados
con carácter nulo. Si el string no se termina correctamente, la adición de un octeto
nulo en el último octeto del buffer impedirá a otras operaciones como
calcular mal la longitud del string o desbordar el buffer.

TEMA 5 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Errores de formato de cadena (format strings)

Los errores de formato de string ocurren:

Cuando se permite al usuario influir o no definir el argumento del tipo de dato a


mostrar en la entrada estándar, durante la declaración de la función encargada de la
manipulación de strings.

Una función de formato es un tipo especial de función ANSI C, que toma un número
variable de argumentos, de los cuales uno es la llamada cadena de formato. Los
Format String son simples cadenas, caracterizadas por el formato que se les aplica.
Los tipos de formato a aplicar son los siguientes:

Par. Salida Pasado como


%d. Formato de enteros. Valor
%f Formato de punto flotante. Valor
%s Formato cadena. Referencia
%x Formato hexadecimal. Valor
%p Muestra el correspondiente valor del puntero. Referencia
%n En el entero correspondiente a esta especificación de formato se Referencia
almacena el número de caracteres hasta ahora escritos en el búfer.
<n>$ Parámetro de acceso directo Valor

Tabla 3. Parámetros de formato utilizados en lenguaje C.

Vulnerable.c:
#include <stdio.h>
int main(void) {
char texto[30];
scanf(“%29s”, texto);
printf(texto);
return 0;
}

Figura 35. Ejemplo con una vulnerabilidad de formato de string clásica. Fuente: Merino (2011).

Como se muestra en negrita el usuario no ha especificado que la variable «texto» sea


mostrada como de tipo cadena de caracteres (string), al no especificar el tipo de
dato mediante la sintaxis «%s». Este es el motivo por la que el código presentaría

TEMA 5 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

una vulnerabilidad de tipo format string. Las especificaciones de formato más


utilizadas en este tipo de ataque son:
o %x y %s. Para acceder a los contenidos de las direcciones de memoria de la pila.
o %n. Para escribir directamente en de las direcciones de memoria de la pila.

Otro ejemplo real que contiene una vulnerabilidad de formato de string clásica del
demonio de FTP popular wuftpd (que ha sufrido de numerosas vulnerabilidades).

while (fgets(buf, sizeof buf, f)) {


lreply (200, buf);
...
}
void lreply(int n, char *fmt, ...) {
char buf[BUFSIZ];
...
vsnprintf(buf, sizeof buf, fmt, ap);
...
}

Figura 36. Clásica vulnerabilidad de format String en wuftpd 2.6.0. Fuente: Chess y West (2007).

Una de las vulnerabilidades de formato de string más conocidas fue encontrada en la


forma en que la función lreply() es invocada en la Versión 2.6.0, de wuftpd que, de
una forma simplificada, se parece al código de la figura anterior.

En el código vulnerable, un string es leído desde un socket de red y pasado


sin validación como argumento de formato string a la función vsnprintf().
Enviando un comando especial al servidor, un atacante puede remotamente explotar
esta vulnerabilidad para obtener privilegios de root de la máquina.

El problema es que el argumento de formato de string no es requerido si


no se quiere usar y de esta forma los programadores programadores
pueden utilizar por ejemplo printf(str) en lugar de printf,(”%s”,str). Un
atacante podría incluir conversiones de tipo string mientras que el
programador asumía que no contendría nada. En el caso más benigno un
ataque incluiría especificaciones de conversión diseñadas a leer valores del stack y
conseguir acceso a información no autorizada. En casos más serios el atacante
puede usar la directiva %n para escribir varias posiciones de memoria lo
que posibilita todos los ataques más usuales de buffer overflow
modificando la dirección de retorno del stack, modificando el valor del
puntero a una función, etc.

TEMA 5 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

5.6. Referencias

Chess, B. y West, J. (2007). Secure Programming with Static Analysis. Addison-Wesley


Software Security Series.

INCIBE. (2012). Informe de vulnerabilidades, 1er semestre 2012.

Graff, M. G., Van Wyk, K. R. (2003). Secure Coding: Principles & Practices. O'Reilly.

Howard, M. y LeBlanc, D. (2003). Writing Secure Code. Microsoft Press.

Allen, J. H., Barnum, S., Ellison, R. J., McGraw, G., and Mead, N. R. (2008). Software
Security Engineering: A Guide for Project Managers. Addison Wesley Professional.

Goertzel, K. M., and Winograd, T. (2008). Enhancing the Development Life Cycle to
Produce Secure Software, Version 2.0. United States Department of Defense Data and
Analysis Center for Software.

Howard, M., and Lipner, S. (2006). The Security Development Lifecycle: SDL: A Process
for Developing Demonstrably Secure Software. Microsoft Press.

Goertzel, K. M., and Winograd, T. (2008). Enhancing the Development Life Cycle to
Produce Secure Software, Version 2.0. United States Department of Defense Data and
Analysis Center for Software.

Komaroff, M., (ASD/NII) and Baldwin, K. (OSD/AT&L). (2005). DoD Software


Assurance Initiative.

Hoglund. (2004). Exploiting Software: How to Break Code, By G. Hoglund and G.


McGraw. Addison-Wesley Software Security Series.

The SANS Technology Institute. (2006). The Twenty Most Critical Internet Security
Vulnerabilities.

Wagner, D., Foster, J. S., Brewer, E. A. y Aiken, A. (2002). A First Step Towards
Automated Detection of Buffer Overrun Vulnerabilities. Proceedings of the 7th Network
and Distributed System Security Symposium. San Diego, CA.

TEMA 5 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Long, F. Software Vulnerabilities in Java. CERT Technical Note CMU/SEI-2005-TN-


044.

Merino, B. (2011). Software Exploitation. INCIBE.

CERT (2000). Malicious HTML Tags Embedded in Client Web Requests.

Anderson (2001). Security Engineering.

Brown, K. (2004). Windows Vista Technical Articles. Security in Longhorn: Focus on


Least Privilege, DevelopMentor.

Purczynski, W. (2000). Linux Capabilities Vulnerability.


Chen, H., et al. Setuid Demystified. 11th USENIX Security Symposium (San Francisco,
CA, 2002), 171–190.

Provos, N., Friedl, M., and Honeyman, P. (2003). Preventing Privilege Escalation.

Sarmiento, E. (2001). Chapter 4: The Jail Subsystem.

Berkman, A. (2004). ChangePassword 0.8 Runs setuid Shell.

López, S. (2012). Descubriendo el valor de la Seguridad en las Aplicaciones Web con


IBM AppScan. IBM Corporation.

TEMA 5 – Ideas clave © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Lo + recomendado

Lecciones magistrales

Análisis estático de código con HP Fortify

El análisis estático de código fuente se considera la actividad más importante de entre


las mejores prácticas de seguridad que se han de realizar en el curso del desarrollo de
una aplicación. En la siguiente clase magistral se realiza una introducción a una de las
mejores herramientas de análisis estático de código del mercado, Fortify de la compañía
HP.

La lección magistral está disponible en el aula virtual.

No dejes de leer…

Secure Coding in C and C++

Presentación sobre casos prácticos de errores de programación más comunes que se


comente en el lenguaje de programación C y C++.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://resources.sei.cmu.edu/asset_files/BookChapter/2005_009_001_52692.pdf

TEMA 5 – Lo + recomendado © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Common vulnerabilities guide for C programmers

Explica las principales librerías del lenguaje C inseguras y como pueden provocar
ataques de desbordamiento de menor.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


https://security.web.cern.ch/security/recommendations/en/codetools/c.shtml

Memory layout

Explica la distribución de la memoria en programas escritos en lenguaje C.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://www.geeksforgeeks.org/memory-layout-of-c-program/

TEMA 5 – Lo + recomendado © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

No dejes de ver…

Closing Web Application Security Vunerabilities with Fortify

Cómo utilizar Fortify para detectar


vulnerabilidades de seguridad web de tipo
cross site scripting (XSS) e inyección SQL.
Fortify realiza análisis de código fuente y
trabaja en varios lenguajes, incluyendo Java,
NET y PHP.

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


http://www.youtube.com/watch?v=z9vnunUu6Ac

Introduction to Secure Coding for C/C++

Vídeo que trata sobre nueve principios defensivos de


codificación y cómo usar estos principios para prevenir
vulnerabilidades de seguridad comunes. Por último, se
explica en detalle lo que es una vulnerabilidad de
desbordamiento de búfer y cómo funciona.

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


http://www.klocwork.com/elearning/secure-programming-courses/intro-to-secure-
coding-c-cpp/

TEMA 5 – Lo + recomendado © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

+ Información

A fondo

Secure Coding

Guía que presenta prácticas fundamentales de codificación segura y una lista de recursos
con más información para profundizar en las prácticas que propone.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


https://buildsecurityin.us-cert.gov/swa/downloads/Secure_Coding_v1.1.pdf

Defeating Overflow Attacks

Los ataques de desbordamiento de búfer se pueden detectar y prevenir. En este trabajo


se describe qué es un ataque de desbordamiento de búfer y cómo proteger las
aplicaciones de él.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://www.sans.org/reading_room/whitepapers/securecode/defeating-overflow-
attacks_1403

Format Strings Attack

Introducción al error de programación Format String simples cadenas, caracterizadas


por el formato que se les aplica. Si has programado anteriormente en cualquier lenguaje
estarás familiarizado con la función printf().

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://rodin.uca.es/xmlui/bitstream/handle/10498/14119/FormatStringAttack.pdf?se
quence=1

TEMA 5 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Smashing the Stack for Fun and Profit

Artículo de 1996 en el que se describe las formas de realización de ataques de


desbordamiento de memoria basados en la pila.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://insecure.org/stf/smashstack.html

Exploiting Format String Vulnerabilities

Informe en el que se describe con profundidad los ataques de format string.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://crypto.stanford.edu/cs155/papers/formatstring-1.2.pdf

Enlaces relacionados

Secure Coding

Sitio web de Software Engineering Institute de la universidad Carnegie Melon con


numerosos recursos de estándares de programación segura, laboratorio de análisis de
código fuente, metodología TSP-Secure y herramientas y librerías.

Accede a la página desde el aula virtual o a través de la siguiente dirección web:


http://www.cert.org/secure-coding/

TEMA 5 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Bibliografía

Chess, B. y West. J. (2007). Secure Programming with Static Analysis. Addison-Wesley


Software Security Series.

Graff, M. G., Van Wyk, K. R. (2003). Secure Coding: Principles & Practices. O'Reilly.

Hoglund. (2004). Exploiting Software: How to Break Code, By G. Hoglund and G.


McGraw. Addison-Wesley Software Security Series.

Wagner, D., Foster, J. S., Brewer, E. A. y Aiken, A. (2002). A First Step Towards
Automated Detection of Buffer Overrun Vulnerabilities. Proceedings of the 7th Network
and Distributed System Security Symposium. San Diego, CA.

Recursos externos

HPE Security Fortify Static Code Analyzer

HPE Security Fortify Static Code Analyzer permite el análisis de código estático
automatizado para ayudar a los desarrolladores a eliminar las vulnerabilidades y crear
software seguro.

Ayuda a comprobar la seguridad de un software, a reducir costes, a aumentar la


productividad y a implementar las prácticas recomendadas de codificación segura.
Identifica las causas raíz de las vulnerabilidades de la seguridad del software y
correlaciona y prioriza los resultados.

El profesor facilitará el enlace de descarga a través del aula virtual.


Consulta las instrucciones para la instalación de la herramienta.

TEMA 5 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Actividades

Laboratorio #1: Auditoría de código de una aplicación con la


herramienta de HP Fortify

Preparación del laboratorio

Para la realización de este laboratorio deberás ver la lección magistral Análisis estático
de código con HP Fortify. Además te recomendamos que revises el vídeo Closing Web
Application Security Vunerabilities with Fortify.

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


http://www.youtube.com/watch?v=z9vnunUu6Ac

Recuerda que deberás instalar la herramienta HPE Security Fortify Static Code Analyzer,
de la que encontrarás más información en el apartado Recursos externos del tema.

Descripción del laboratorio

Este ejercicio profundiza en el estudio de la práctica de seguridad del software más


importante: revisión estática de código, mediante el uso y manejo de la aplicación de
análisis estático de código Fortify SCA, mediante el análisis de toda una aplicación escrita
en Java. Se describe cómo utilizar el componente de la aplicación Audit Workbench, para
realizar el ciclo de revisión de código de los resultados que Fortify SCA genera.

El método más sencillo para el análisis de una aplicación Java es indicar a Audit
Workbench el directorio de base de los archivos fuente que componen la aplicación. Con
esta información, Fortify SCA identifica automáticamente todos los tipos de fuentes
conocidas de archivos en los directorios especificados, como archivos fuente de Java,
Java Server Pages (JSP), PL / SQL y TSQL archivos, y archivos de configuración XML.
También identifica y utiliza los archivos .jar que encuentra para resolver nombres de
símbolos definidos en el código fuente.

TEMA 5 – Actividades © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Entrega del laboratorio

En este laboratorio deberás auditar la aplicación WEBGOAT y realizar una memoria en


la que se explique la auditoría de 10 de las vulnerabilidades de diferente tipo y de carácter
crítico encontradas por la herramienta. Se debe incluir un estudio detallado del código
(incluir esquemas. gráficos de llamadas, flujos del programa, porciones de código
explicadas, etc.) y documentación de las mismas y una propuesta de posible solución.

Extensión aproximada: 15-20 páginas (Georgia 11, interlineado 1,5).

TEMA 5 – Actividades © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Test

1. Señala la respuesta correcta. En el libro Secure Coding: Principles & Practices se


presenta una serie de recomendaciones de buenas prácticas sobre:
A. Manejo de los datos con precaución.
B. Evitar en la medida de lo posible confiar en software de terceros en operaciones
críticas.
C. No usar listas de comprobación.
D. No usar en el código nombres relativos de ficheros.

2. Señala la o las respuestas correctas. ¿Qué tipo de vulnerabilidad se comete en este


código?
String user_state = "Unknown";
try {
HttpSession user_session = Init.sessions.get(tmpUser.getUser());
user_state = user_session == null ? "Unknown" :
(String)user_session.getAttribute("USER_STATUS");
user_state = user_state == null ? "Available" : user_state;
}
...
%>
<%=user_state %>
A. Integer Overflows.
B. Desbordamiento de buffer.
C. Uso de datos no validados
D. Use after free.

3. Señala la o las correcta. ¿Qué tipo de vulnerabilidad se comete en este código?


char *stringcopy(char *str1, char *str2)
{
while (*str2)
*str1++ = *str2++;
return str2;
}
main(int argc, char **argv)
{
char *buffer = (char *)malloc(16 * sizeof(char));
stringcopy(buffer, argv[1]);
printf("%s\n", buffer);
}
A. Integer Overflows.
B. Desbordamiento de buffer.
C. Format string.
D. Use after free.

TEMA 5 – Test © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

4. Señala la respuesta incorrecta. ¿Qué tipo de vulnerabilidad se comete en este código?


struct hostent *hp;
struct in_addr myaddr;
char* tHost = "trustme.com";
myaddr.s_addr = inet_addr(ip_addr_string);
hp = gethostbyaddr((char *) &myaddr,
sizeof(struct in_addr), AF_INET);
if (hp && !strncmp(hp->h_name, tHost, sizeof(tHost))) {
trusted = true;
} else {
trusted = false;
}
A. Buffer overflow.
B. Validación límites de confianza.
C. Validación de entrada DNS.
D. Memory leaks.

5. Señala la respuesta incorrecta. ¿Es el código es correcto?


if (path != null &&
path.length() > 0 && path.length() <= MAXPATH) {
fileOperation(path);
}
A. Es correcto.
B. Es incorrecto
C. No se puede determinar
D. Ninguna de las anteriores.

TEMA 5 – Test © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

6. Señala la respuesta correcta. La siguiente función acepta como parámetro una cadena
EmployeeNumber y dinámicamente crea una petición SQL utilizando los datos no
confiables. ¿Contiene la siguiente función una vulnerabilidad de Inyección SQL?
public void InsertAccountNumber(String EmployeeNumber)
{
// Create a dynamic SQL statement
String sqlQuery = “SELECT * FROM HrTable WHERE Num = @pENum”;
SqlParameter pENum = new SqlParamater(“@pENum”,SqlDbType.NVarChar,150);
pENum.Value = EmployeeNumber;
SqlComand sqlCmd = new SqlCommand(sqlQuery,
new SqlConnection(connectionString));
sqlCmd.Parameters.Add(pENum);
// Execute the sql command

}
A. La función no contiene una vulnerabilidad de inyección SQL.
B. La función contiene una vulnerabilidad de inyección SQL porque la longitud del
parámetro EmployeeNumber puede exceder el tamaño de 150 caracteres.
C. La función contiene una vulnerabilidad de inyección SQL porqué el parámetro
EmployeeNumber es insertado directamente en la petición SQL.
D. Ninguna de las anteriores

7. Señala la respuesta incorrecta. ¿Qué tipo de vulnerabilidad se comete en este código?


while (fgets(buf, sizeof buf, f)) {
lreply(200, buf);
...
}
void lreply(int n, char *fmt, ...) {
char buf[BUFSIZ];
...
vsnprintf(buf, sizeof buf, fmt, ap);
...
}
A. Integer Overflows.
B. Desbordamiento de buffer.
C. Format string.
D. Use after free.

TEMA 5 – Test © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

8. Señala la respuesta correcta. Una librería que maneja string de forma segura,
intentará asegurar lo siguiente:
A. Las funciones de manejo de cadenas de la biblioteca segura se puede
intercambiar sin modificar nada con las funciones de la biblioteca estándar de
cadena, y viceversa.
B. Que las cadenas han sido validadas correctamente.
C. Que hay espacio suficiente en una cadena de origen y / o destino para realizar
operaciones como concatenación, copia, etc.
D. Ninguna de las anteriores.

9. Señala la respuesta correcta. El siguiente programa es vulnerable a un ataque de


desbordamiento de búfer ¿cuál es el nombre del búfer que pude ser desbordado?

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

#define S 100
#define N 1000

int main(int argc, char *argv[]) {


char out[S];
char buf[N];
char msg[] = " Bienvenido\";
int len = 0;
buf[0] = '\0';
printf(msg);
while (argc) {
sprintf(out, "argument %d is %s\n", argc-1, argv[argc-1]);
argc--;
strncat(buf,out,sizeof(buf)-len-1);
len = strlen(buf);
}
printf("%s",buf);
return 0;
}
A. buf
B. msg
C. out
D. len

TEMA 5 – Test © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

10. Señala la respuesta correcta. ¿Cuándo se da lugar, de forma general, un ataque de


desbordamiento de búfer?
A. Cuando se escribe en la memoria apuntada por un puntero que no ha sido
liberada.
B. Cuando copia un búfer de la pila al heap.
C. Cuando u puntero es usado para acceder a memoria no apuntada por él.
D. Cuando el programa detecta que el búfer está lleno.

TEMA 5 – Test © Universidad Internacional de La Rioja (UNIR)


Codificación segura aplicaciones II
[6.1] ¿Cómo estudiar este tema?

[6.2] Introducción

[6.3] Integers overflows, errores de truncado y problemas con


conversiones de tipo entre números enteros

[6.4] Privacidad y confidencialidad

[6.5] Programas privilegiados

[6.6] Referencias

TEMA
Codificación segura
Esquema

Introducción

TEMA 6 – Esquema
Intergers overflows, Desbordamiento de Privacidad y Programas
errores de truncado y buffer confidencialidad privilegiados
conversiones de tipo
• Principio de mínimos
Manejar errores mediante privilegios
códigos de retorno

2
Intergers overflows • Manejo de los privilegios

Manejo de errores • Restringir los privilegios


Errores de truncado mediante excepciones sobre los sistemas de
ficheros

Registro y depuración • Manejo de excepciones en


programas privilegiados

Desasignar los recursos • Ataque de condiciones de


que no se van a utilizar en carrera en el acceso a
adelante ficheros
• Ficheros temporales
inseguros

• Inyección de comandos
• Descriptores de ficheros
Seguridad en el Software

© Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Ideas clave

6.1. ¿Cómo estudiar este tema?

Para estudiar este tema lee las Ideas clave que te presentamos a continuación.

El objetivo del presente tema es el aprender los defectos más comunes que se pueden
cometer al codificar en lenguajes como C y Java en lo relativo a Integers overflows,
errores de truncado y problemas con conversiones de tipo entre números enteros,
privacidad y confidencialidad, programas privilegiados y errores y excepciones que se
estudiará en la clase magistral. Si se entienden bien los defectos que se pueden cometer
se estará en disposición de poder analizar el código para encontrarlos y posteriormente
corregirlos.

6.2. Introducción

La posibilidad de desarrollar software no confiable es atribuible a todas las partes


involucradas en el ciclo de vida de desarrollo de software y, en concreto, los
desarrolladores de software, que escriben el código, desempeñan un papel vital en el
desarrollo de software seguro libre de vulnerabilidades. La formación en esta materia de
los programadores es muy importante porque si se conoce qué tipo de defectos de
seguridad se pueden cometer en un lenguaje de programación, se pueden evitar muchos
de ellos desde el principio. Además se hacen una serie de recomendaciones a tener en
cuenta a la hora de la implementación, tanto de buenas como de malas prácticas.

El encontrar bugs tempranamente conlleva una reducción del coste económico, en varios
órdenes, con respecto a su descubrimiento en fases posteriores. Este hecho tiene que
incitar a las organizaciones a poner especial interés en esta actividad y encuadrarla en
los procesos y procedimientos de desarrollo.

De todas formas inevitablemente siempre se dejarán defectos en el código una


vez terminada la fase de desarrollo, es por ello por lo que todavía se puede hacer más
por eliminar la mayor parte de defectos posible realizando un análisis de código
fuente durante la codificación y al final de la misma.

TEMA 6 – Ideas clave 3 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

6.3. Integers overflows, errores de truncado y problemas con


conversiones de tipo entre números enteros

Integer overflow

Todos los tipos de representación de números enteros tienen una limitada capacidad
debido a que representan con un limitado número de bits. Esto es un hecho que
normalmente se les olvida a los programadores y pueden ocasionar errores de tipo
integer overflow al intentar almacenar un valor demasiado grande en la
variable asociada que sobrepase esos límites inferior y superior o un valor
grande positivo se convierta en un valor grande negativo y viceversa,
generando un resultado inesperado (valores negativos, valores inferiores, etc.).

En el documento de INCIBE (2012) se indica que:

Este tipo de error puede tener consecuencias graves cuando el valor que genera el
integer overflow es resultado de alguna entrada de usuario (es decir, que puede ser
controlado por el mismo) y cuando, de este valor, se toman decisiones de seguridad,
se toma como base para hacer asignaciones de memoria, índice de un array,
concatenar datos, hacer bucles. etc. Este ha sido el caso de vulnerabilidades como
CVE-2001-014459 en SSH1 y que permitiría a un atacante ejecutar código arbitrario
con los privilegios del servicio ssh; o algunos más recientes como CVE-2011-2371 en
Mozilla Firefox.

El código de la figura siguiente, muestra un ejemplo de integer overflow que se da con


una función que reserva memoria para un string con un tamaño que se lee de un fichero.
Antes de reservar el buffer, varias líneas de código comprueban que el tamaño no es
mayor de 1024 y decrementa su valor en uno para no copiar el carácter de nueva línea
del fichero.

Sin embargo, dependiendo del valor de readamt, decrementar su valor podría causar
resultados erróneos, si se declara sin signo y un atacante ocasiona que getstringsize()
devuelva «0», malloc() será invocada con 4294267295 que es el valor más grande en una
representación de 32-bit y la operación fallará por insuficiencia de memoria.

TEMA 6 – Ideas clave 4 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

unsigned int readamt;


readamt = getstringsize();
if (readamt > 1024)
return -1;
readamt--; // don't allocate space for '\n'
buf = malloc(readamt);
Figura 1. Integer overflow. Fuente: Chess y West (2007).

Otro error de tipo aritmético, es el siguiente:

int ConcatBuffers(char *buf1, char *buf2, size_t len1, size_t len2){


char buf[0xFF];
if((len1 + len2) > 0xFF) return -1;
memcpy(buf, buf1, len1);
memcpy(buf + len1, buf2, len2);

// do stuff with buf


La dos funciones mencpy intentan
realizar una copia > de 255 bytes.
return 0;
}

Figura 2. Error aritmético. Extraída presentación Microsoft «Basic of Secure Development Test»

Errores de truncado

Otro tipo de problemas que se pueden presentar en operaciones con números que
se pueden truncar cuando un tipo de dato entero con gran cantidad de bits
se convierte a otro con menor cantidad de bits, C por ejemplo desecha los bits de
mayor orden, si un entero con signo se convierte desde otro más pequeño en número de
bits, los bits extra se rellenan de tal forma que el número nuevo conserve el mismo signo.

Esto significa que si un número negativo es convertido a un tipo de datos más grande, su
signo será el mismo, pero su valor aumentará considerablemente porque sus bits más
significativos se modificarán. Si un programador no entiende cuándo y cómo las
conversiones tienen lugar pueden tener lugar vulnerabilidades.

TEMA 6 – Ideas clave 5 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Conversiones entre enteros con signo y sin signo

Suponiendo que se tienen cuatro bits para representar enteros con y sin signo se tendría:

Figura 3. Error de truncado que ocurre cuando un entro de 8-bit es truncado a uno de 4 bits y una de
extensión de signo cuando un entero de 4 bit es truncado a un entero con signo de 8 bits. Fuente: Chess y
West (2007).

No pueden representar el mismo número de valores y solo algunos valores pueden ser
convertidos desde un dato de tipo sin signo a otro con signo y viceversa sin cambiar el
significado, mientras otros no. En el caso de valores positivos el problema es que el 50 %
de valores sin signo requieren poner a uno el bit más significativo.

Figura 4. Error que ocurre cuando un entero de 4 bit es truncado de con signo a sin signo y viceversa.
Fuente: Chess y West (2007).

En el código de la figura siguiente, se procesa la entrada de usuario de una serie de strings


de longitud variable almacenadas en una posición simple char*. Los primeros 2 octetos
de entrada dictan el tamaño de la estructura a ser procesada. El programador ha puesto
una cota superior en el tamaño del string: la entrada será procesada solo si len es menor
o igual a 512.

El problema es que len está declarado como tipo short (con signo) entonces la
comprobación contra la longitud de string máxima es una comparación con signo. Más
tarde, len implícitamente se convierte a un número entero sin signo en la llamada a
memcpy(). Si el valor de len es negativo, aparecerá que el string tiene un tamaño
apropiado (se toma la alternativa if), pero la cantidad de memoria copiada por memcpy()
será muy grande (mucho más grande que 512) y el atacante será capaz de desbordar buf
con los datos en strm.

TEMA 6 – Ideas clave 6 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

char* processNext(char* strm) {


char buf[512];
short len = *(short*) strm;
strm += sizeof(len);
if (len <= 512) {
memcpy(buf, strm, len);
process(buf);
return strm + len;
}
else {
return -1;
}
}

Figura 5. Integer overflow causado por conversión signo-sin signo. Fuente: Chess y West (2007).

6.4. Privacidad y confidencialidad

En este apartado se va a analizar cómo hay que manejar las contraseñas, tanto las
que utilizan los usuarios para autenticarse (intbound passwords) como las que utiliza un
programa que actúa como cliente para autenticarse frente a un servicio final (outbound
passwords), como una base de datos o un servidor LDAP. Intbound passwords pueden
ser hashed, sin embargo, outbound passwords deben ser accesibles al programa en texto
claro.

Para profundizar sobre intbound passwords se recomienda la lectura de este libro:


http://www.cl.cam.ac.uk/~rja14/book.html

Mantener las password fuera del código fuente. Cifrar las contraseñas con
algoritmo seguro y almacenarlas fuera del código. La figura siguiente, muestra un trozo
de código que muestra un mal uso de password codificada dentro de código Java.

public class DbUtil {


public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(
"jdbc:mysql://ixne.com/rxsql", "chan", "0uigoT0");
}
}

Figura 6. Password hardcoded. Fuente: Chess y West (2007).

TEMA 6 – Ideas clave 7 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Una buena estrategia consiste en:

» Cifrar las password con una pública implementación de algoritmos


criptográficos robustos y almacenarlas cifradas en un fichero de
configuración. Almacenar la clave necesaria para descifrar la password en un
fichero separado donde la aplicación pueda acceder pero no la mayoría de los
administradores de sistemas.
Usar password robustas. Usar generadores de números aleatorios seguros para
las password de conexiones outbounds. Hay un compromiso entre los conceptos de
robustez y de facilidad, a la hora de elegir un password. Las outbound passwords no
requieren ser recordadas deben ser largas y aleatoriamente generadas usando un
método seguro de generación de números aleatorios.
» Números aleatorios. Si se consigue una buena fuente de generación de números
aleatorios se tiene una buena fuente de secreto. La generación de nuevos secretos es
una parte crítica en el establecimiento de muchas clases de relaciones de confianza.
Los números aleatorios son importantes en la criptografía.

Los computadores son máquinas intrínsecamente deterministas y no son una fuente de


aleatoriedad. Si un programa requiere un volumen grande de valores realmente
arbitrarios, hay que pensar en comprar un generador de números aleatorios
hardware. Los generadores de pseudonúmeros aleatorios caen en dos categorías:

» PRNGS estadísticos, que producen valores que son uniformemente distribuidos a


través de rango especificado, pero son calculados usando algoritmos que crean una
corriente de valores fácil de reproducir y triviales de predecir.
» PRNGS criptográficos, usan algoritmos criptográficos para ampliar la entropía de
una semilla de valor aleatorio en una corriente de valores imprevisibles que, con alta
probabilidad, no puede ser distinguido de un valor realmente arbitrario. Los PRNGS
criptográficos son convenientes cuando la imprevisibilidad es importante, incluyendo
los usos siguientes:

o Criptografía.
o Generación de contraseñas.
o Aleatoria de puertos para seguridad.
o Identificadores externos únicos (identificadores de sesión).
o Códigos de descuento.

TEMA 6 – Ideas clave 8 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Los errores más comunes y más obvios relacionados con números aleatorios ocurren
cuando se usa PRNG estadístico en una situación que exige que los valores sean
sumamente imprevisibles y por tanto producidos por PRNG criptográfico. Otro error
ocurre cuando un PRNG no se crea con entropía insuficiente, causando que la corriente
de números sea predecible.

Números aleatorios en Java. Java tiene métodos de generación de números


aleatorios estadísticos y criptográficos:

» Método estadístico: Random.nextInt().

String generateCouponCode(String couponBase) {


Random ranGen = new Random();
ranGen.setSeed((new Date()).getTime());
return(couponBase + Gen.nextInt(400000000));
}
Figura 7. Función aleatoria no segura. Fuente: Chess y West (2007).

» Clase con métodos criptográficos: Java.security.SecureRandom. El algoritmo


por defecto y las fuentes de entropía usadas por SecureRandom son opciones buenas
para la mayor parte de aplicaciones de software y los usuarios raras veces deberían
tener que proporcionar su propia semilla.

String generateCouponCode(String couponBase) {


SecureRandom secRanGen = new SecureRandom();
return(couponBase + secRanGen.nextInt());
}

Figura 8. Función aleatoria segura. Fuente: Chess y West (2007).

» Números aleatorios en C y C++. C/C++ tienen métodos de generación de


números aleatorios estadísticos y aleatorios:

o Funciones estadísticas: evitar utilizar rand(), srand(), srand48(), drand48(),


lrand48(), random(), srandom().
o Funciones criptográficas: Sobre plataformas de Microsoft, rand_s() (del API
de seguridad de Microsoft CRT) y CryptGenRandom() (de Microsoft CryptoAPI)
proporcionan el acceso a valores criptográficamente fuertes arbitrarios producidos
por el subyacente RtlGenRandom() PRNG. Una precaución: a pesar de la carencia
de pruebas empíricas de lo contrario, la fuerza de los valores arbitrarios que

TEMA 6 – Ideas clave 9 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Microsoft CryptoAPI produce está basada solo en las propias reclamaciones a


Microsoft. La puesta en práctica no ha sido públicamente examinada.

6.5. Programas privilegiados

Introducción

La mayor parte de los programas se ejecutan con un conjunto de privilegios


heredados del usuario con el que se ejecutan. Por ejemplo, un editor de textos
puede mostrar solo los archivos que su usuario tiene el permiso de lectura.

Los programas privilegiados tienen privilegios adicionales que les permiten


realizar operaciones que sus usuarios de otra forma no realizarían.

» Cuando está escrito correctamente, un programa privilegiado concede a


usuarios regulares una cantidad limitada de accesos a algún recurso
compartido, como la memoria física, un dispositivo de hardware, o archivos
especiales como el archivo de contraseñas o la base de datos de correo.
» Cuando está escrito incorrectamente, un programa vulnerable privilegiado deja
a los atacantes campo para actuar. En el peor caso, esto puede permitir un ataque de
escalada de privilegios vertical, en el cual el agente malicioso gana acceso
incontrolado a los privilegios elevados del programa.

Otro tipo común de ataque conocido como «escalada de privilegios horizontal»,


ocurre cuando un atacante engaña a los mecanismos de control de acceso de una
aplicación, para tener acceso a recursos que pertenecen a otro usuario. La figura
siguiente, ilustra la diferencia entre la escalada de privilegio vertical y horizontal.

TEMA 6 – Ideas clave 10 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Administrador

Escalada Privilegios
Alto Privilegio Vertical

Bajo Privilegio Escalada Privilegios


Horizontal

Atacante Usuario

Figura 9. Ataques de elevación de privilegios vertical y horizontal. Fuente: Chess y West (2007).

Principio de mínimos privilegios

Evidentemente es uno de los principales principios de diseño, como ya se comentó en el


tema 2, que a la hora de implementar el código hay que ser lo más consecuente posible
con lo que se especificó durante la fase de análisis de requisitos. La motivación detrás de
este principio está clara: el privilegio es peligroso. Cuantos más privilegios tiene
un programa, mayor daño potencial puede causar.

Un conjunto reducido de acciones posibles disminuye el riesgo potencial de un


programa. La mejor gestión de privilegios, es ninguna gestión de privilegio. El modo más
fácil de prevenir vulnerabilidades relacionadas con el privilegio es diseñar los sistemas
que no requieren componentes privilegiados. Cuando se aplica al código, el principio
de mínimos privilegios implica dos cosas:

Los programas no deberían requerir que sus usuarios tengan privilegios


extraordinarios para realizar tareas ordinarias.
» Los programas privilegiados deberían reducir al mínimo la cantidad de daño que
pueden causar cuando algo va mal.

Dependiendo de la funcionalidad del programa y de sus necesidades de privilegio,


se pueden elevar y bajar sus privilegios en puntos diferentes de su ejecución. Los
programas requieren privilegios para una variedad de motivos:

» Comunicarse directamente al hardware.


» Modificar el comportamiento del OS.
» Enviar a señales a ciertos procesos.

TEMA 6 – Ideas clave 11 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Trabajar con recursos compartidos.

o Apertura de puertos de red con baja numeración.


o Cambio de la configuración global (el registro y/o archivos).

» Protecciones de sistema de archivos principales.


» Instalación de nuevos archivos en directorios de sistema.
» Puesta al día de archivos protegidos.
» Tener acceso a archivos que pertenecen a otros usuarios.

Las transiciones entre estados privilegiados y no privilegiados definen el perfil de


privilegio de un programa. El perfil de privilegio de un programa típicamente puede
ser colocado en una de las cuatro clases siguientes:

» Programas normales que corren con los mismos privilegios que sus usuarios.
Ejemplo: Emacs.
» Programas de sistema que corren con privilegios de root para la duración de su
ejecución. Ejemplo: Init.
» Programas que necesitan privilegios de root para usar un conjunto fijo de
recursos del sistema cuando se ejecutan al principio. Ejemplo: Apache httpd, que
necesita el acceso de root para usar puertos bajos numerados.
» Programas que requieren privilegios de root intermitentemente a lo largo
de su ejecución. Ejemplo: Un demonio de FTP, que usa puertos de baja numeración
intermitentemente en todas partes de su ejecución. En la figura siguiente, se
representa un esquema de los ejemplos mencionados y cuándo necesitarían
privilegios de root.

TEMA 6 – Ideas clave 12 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Figura 10. Ejemplo de utilización de privilegios de root en la ejecución de varios programas. Fuente:
Chess y West (2007).

El concepto de seguridad que la mayoría de la gente debería repetir es «No confiar en


nada». Aunque esto sea un ideal que es imposible de realizar, no hay nada que debería
ser tan perseguido enérgicamente como un programa privilegiado.

Los atacantes usarán para montar ataques de escalada de privilegios:

» Los argumentos al programa.


» El entorno de ejecución del programa.
» Los recursos de que el programa depende (sistema de ficheros).

Manejo de los privilegios

Los errores en la gestión de privilegios son a menudo errores de omisión. En este


apartado, se analiza cómo los programas pueden cambiar sus privilegios y algunos
errores que ocurren en el transcurso de estas operaciones con privilegios. Los privilegios
sobre UNIX y sistemas Linux principalmente son controlados por la clase de ID de
usuario, que gobierna las decisiones de control de acceso.

» Cada proceso UNIX tiene tres IDs de usuario:

o Real user ID correspondiente al usuario que creó el proceso.


o Efffective user ID usado para tomar decisiones de control de acceso.

TEMA 6 – Ideas clave 13 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

o Saved user ID mantiene uid inactivo que es recuperable.

» Cada proceso también tiene tres IDs de grupo:

o The real group ID (real gid, or rgid)


o The effective group ID (effective gid, or egid)
o The saved group ID (saved gid, or sgid)

Como los IDs de grupo tienen impacto en los privilegios y se manejan del mismo modo
que el IDs de usuario, se enfocan como los IDs de usuario y se excluyen los IDs de grupo
de los ejemplos de este apartado en favor de la simplicidad. Además de tres IDs usuario
y de tres IDs de grupo antes mencionado.

Para combatir la difícil naturaleza de la gestión de privilegios, existe un conjunto de


funciones wrapper que proporcionan un interfaz consistente y fácilmente entendible
[19]. Los autores advierten que la mayoría de programas privilegiados realizan tres
operaciones claves sobre sus privilegios:

» Eliminar privilegios con la intención de recuperarlos.


» Eliminar privilegios permanentemente.
» Recuperar privilegios previamente almacenados.

Otra aproximación de gestión de privilegios de acuerdo con el principio mínimos


privilegios es dividir un programa en componentes privilegiados y no
privilegiados. Si las operaciones que requieren privilegios pueden ser categorizadas en
un proceso separado, esta solución puede reducir bastante el trabajo requerido para
asegurar que los privilegios se administran adecuadamente.

Crear dos procesos: uno para realizar la mayor parte del trabajo ejecutándose sin
privilegios, y un segundo que se ejecuta con privilegios y realiza un número limitado de
operaciones. En muchas situaciones tiene la ventaja añadida de que el número de las
líneas de código que se ejecuta con privilegios es mucho más pequeño.

Para un ejemplo de división de privilegios, nos referimos al trabajo de Provos,


Friedl, y Honeyman sobre el proyecto OpenSSH de Privilegios Separados en la
Universidad de Michigan. El equipo dividió OpenSSH en procesos privilegiados y no
privilegiados y el proyecto oficialmente fue adoptado en la distribución OpenBSD.

TEMA 6 – Ideas clave 14 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Restringir privilegios sobre los sistemas de ficheros

Además de la gestión explícita de privilegios y el control de acceso basado en el ID de


Usuario, se puede restringir los privilegios de un programa limitando su visión del
sistema de archivos usando la función de sistema chroot(). Después una correcta
invocación a chroot(), un proceso no puede tener acceso a ningún archivo fuera del árbol
de directorio especificado para esa llamada. Se denomina jaula chroot a tal entorno y
se usa comúnmente para prevenir la posibilidad de que se pueda corromper un proceso
y usarlo para tener acceso a archivos protegidos. Por ejemplo, muchos servidores de
FTP se ejecutan en jaulas chroot para prevenir a un atacante que descubre una nueva
vulnerabilidad en el servidor de ser capaz de descargar otros archivos sobre el sistema.

En sistemas FreeBSD, hay que pensar en usar la utilidad jaula, que pone en práctica
protecciones aún más fuertes que la jaula chroot [21].

El empleo impropio de chroot() puede permitir a atacantes escaparse de la jaula chroot.


Lamentablemente, hay al menos cuatro modos fáciles de causar problemas con chroot().
El código es responsable de leer un nombre de archivo de la red, abre el archivo
correspondiente sobre la máquina local y de enviar el contenido sobre la red, lo cual
podría usarse para implementar el comando FTP GET. Para limitar el daño que un bug
podría causar, el código intenta crear una jaula chroot antes de responder a alguna
solicitud. Esta tentativa de crear una jaula chroot tiene cuatro problemas:

» Llamar a chroot() no afecta a ningún descriptor de archivo que está actualmente


abierto, entonces se puede apuntar a archivos fuera de la jaula chroot. Para ser seguro,
cerrar cada archivo abierto antes de la llamada chroot().
» La llamada a la función chroot(), no cambia el directorio actual de trabajo del proceso,
entonces rutas relativas como ./../../../../etc/passwd todavía pueden referirse a
recursos del sistema de archivos fuera de la jaula chroot después de que se ha llamado
a chroot(). Siempre seguir una llamada a chroot() con la llamada chdir ("/"). Verificar
que cualquier error de manejo de código entre la llamada a chroot() y chdir() no abre
ningún archivo y no devuelve el control a ninguna otra parte del programa que no
sean rutinas de parada. Las funciones chroot() y chdir() deberían estar tan cerca como
sea posible para limitar la exposición a esta vulnerabilidad.
Es también posible y recomendable, crear una jaula apropiada chroot llamando a
chdir() primero. La llamada a chdir() entonces puede tomar un argumento constante
("/"), que es más fácil verificar durante una revisión de código.

TEMA 6 – Ideas clave 15 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

» Una llamada a chroot() puede fallar. Comprobar el valor de retorno de chroot() para
asegurarse del resultado de la llamada.
» Para llamar chroot(), el programa debe ejecutarse con privilegios de root. En cuanto
la operación privilegiada se ha completado, el programa debería eliminar los
privilegios de root y retornar a los privilegios del usuario de invocación. El código en
el ejemplo de la figura 69, sigue ejecutándose como root.

chroot("/var/ftproot");

if (fgets(filename, sizeof(filename), network) != NULL) {


if (filename[strlen(filename) - 1] == '\n') {
filename[strlen(filename) - 1] = '\0';
}
localfile = fopen(filename, "r");
while ((len = fread(buf, 1, sizeof(buf), localfile)) != EOF) {
(void)fwrite(buf, 1, len, network);
}
}

Figura 11. Código de un simple FTP server. Fuente: Chess y West (2007).

Manejo de excepciones en programas privilegiados

Hay que tener en cuenta una serie de directrices generales para manejar eventos
inesperados y excepciones que toman una importancia aún mayor en programas
privilegiados, donde los ataques son más probables y el coste de un exploit consumado
es mayor.

» Comprobar cada condición de error. Muchos bugs al principio misteriosos, son


consecuencia de una llamada de sistema fallida con un valor de retorno ignorado.
» Seguridad sobre robustez: terminación ante errores. No intentar reponerse
de errores inesperados o mal entendidos. Cuando los errores ocurren realmente, la
seguridad prima sobre la robustez. Esto quiere decir que el programa debería o parar
la acción que actualmente realiza o detenerse completamente.
» Inhabilitar señales antes de la elevación de privilegios. De esta forma se evita
tener señales que controlan código que se ejecuta con privilegios. Rehabilitar las
señales después volver a los privilegios estándar que tenía el usuario. Los manejadores
de Señales y los procesos hijos se ejecutan con los mismos privilegios del proceso
padre, por tanto si un proceso se ejecuta con privilegios de root cuando una señal se
activa o un subproceso es ejecutado, el manejador de la señal o el subproceso se

TEMA 6 – Ideas clave 16 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

ejecutará con privilegios de root. El código que maneja las señales nunca debería
requerir privilegios elevados.

Desde luego, un manejador de señales bien escrito debería ser bastante pequeño y
bastante simple, de forma que no pueda causar errores cuando se ejecuta con privilegios:
manejadores de señales que tienen una complejidad mínima son siempre un objetivo que
vale la pena.

Ataques de escalada de privilegios

A veces un ataque contra un programa privilegiado se realiza por un usuario legítimo


del sistema. Normalmente un atacante usa un proceso de tres pasos para obtener
privilegios sobre una máquina.

» Intenta encontrar una debilidad en un servicio de red o en una cuenta de


usuario mal protegida y obtiene acceso a una cuenta con bajos privilegios sobre
la máquina.
» Usa este acceso de bajos privilegios para explotar una vulnerabilidad en
un programa privilegiado y tomar el control de la máquina.

Los ataques de escalada de privilegios pueden tener como objetivo cualquier variedad de
vulnerabilidades de software, en este apartado, se tratan las clases de vulnerabilidades
que son principalmente un riesgo en programas privilegiados:

» Condiciones de carrera de acceso a archivos.


» Permisos de archivo débiles.
» Archivos temporales inseguros.
» Inyección de comandos.
» Mal uso de descriptores de archivo estándar.

Los ataques que aprovechan algunas de estas vulnerabilidades requieren la capacidad de


ejecutar un programa privilegiado directamente y controlar el uid de los programas. Los
otros son igualmente peligrosos para programas que se ejecutan con el usuario root u
otro usuario privilegiado. Todas las vulnerabilidades comparten el hecho de que confían
en la capacidad de un atacante de actuar recíprocamente con un programa privilegiado
a través de su entorno local.

TEMA 6 – Ideas clave 17 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Ataque de condiciones de carrera en el acceso a ficheros

Se encuentran entre un grupo de vulnerabilidades conocidas como time-of-check,


time-of-use (TOCTOU), MITRE clasifica este tipo de vulnerabilidades con el CWE
367. Los errores generados como consecuencia de una condición de carrera
se producen por el cambio que experimenta el estado de un recurso
(ficheros, memoria, registros, etc.) cuando un programa intenta verificar
una propiedad y más tarde toma una decisión suponiendo que la propiedad
no ha cambiado. Los ataques TOCTOU sobre vulnerabilidades del sistema de archivos
generalmente siguen esta secuencia:


Un programa comprueba alguna propiedad de un archivo, refiriéndose al archivo por
su nombre más bien que por el objeto del sistema de fichas subyacente


Un atacante cambia el significado del nombre del archivo que el programa comprobó
de modo que refiera un objeto del sistema de archivos diferente.


El programa más tarde realiza una operación sobre el sistema de archivos que usa el
mismo nombre del archivo y asume que la propiedad previamente comprobada se
mantiene.

Figura 12. Secuencia ataque TOCTOU.

La figura siguiente, muestra el modo que las operaciones en lpr podrían intercalarse con
la ejecución del código de un agente malicioso de un ataque con éxito. Un atacante
invoca lpr con el argumento/tmp/attack y redirecciona el archivo para que apunte al
fichero de sistema/etc/shadow durante el tiempo que pasa entre que es comprobado y
utilizado. En la figura siguiente, se muestra el ejemplo corregido.

for (int i=1; i < argc; i++) {


/* make sure that the user can read the file, then open it */
if (!access(argv[i], O_RDONLY)) {
fd = open(argv[i], O_RDONLY);
}
print(fd);
}

Figura 13. Ejemplo de código con una vulnerabilidad TOCTOU en el acceso a un fichero. Fuente:
Chess y West (2007).

TEMA 6 – Ideas clave 18 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

En la figura siguiente, se muestra un esquema de tiempos con las operaciones que


pueden darse intercaladas de un usuario legítimo y un atacante. El
aprovechamiento de las vulnerabilidades de condiciones de carrera de acceso a un
archivo dependen del hecho de que los sistemas operativos modernos permiten a muchos
programas ejecutarse inmediatamente y no se garantiza que la ejecución de cualquier
programa dado no se intercale con otro. Aunque dos operaciones pudieran parecer
secuenciales en el código original de un programa, cualquier número de instrucciones
puede ser ejecutado entre ellas.

La ventana de vulnerabilidad para tal ataque es el período de tiempo entre cuando una
propiedad es comprobada y cuando se usa el archivo. Los atacantes tienen una variedad
de técnicas para ampliar la longitud de esta ventana para hacer los exploits más fáciles,
como el enviar a una señal al proceso víctima que hace que ceda la CPU a otro proceso.
Incluso con una pequeña ventana, una tentativa de exploit puede repetirse hasta que se
consiga llevar a cabo.

Tiempo Lpr Atacate


Tiempo 1 access(“/tmp/attack”)
Tiempo 2 unlink(“/tmp/attack”)
Tiempo 3 symlink(“/etc/shadow”,“/tmp/attack”)
Tiempo 4 open(“/tmp/attack”)
Tabla 1. Esquema de tiempos de una vulnerabilidad TOCTOU en el acceso a un fichero. Fuente:
Chess y West (2007).

Hay que tener en cuenta que un ataque de condición de carrera todavía puede darse
después de abrir el archivo, si alguna operación posterior depende de una propiedad
comprobada anterior a la apertura del archivo.

Por ejemplo, si la estructura pasada a stat() se obtiene antes de que un archivo sea abierto
y una decisión posterior sobre si hay que operar sobre el archivo está basada en un valor
leído de la estructura de stat, entonces una condición de carrera TOCTOU puede darse
entre la llamada a stat() y la llamada open().

Se pueden evitar muchas vulnerabilidades TOCTOU si las operaciones a realizar


sobre el sistema de ficheros son sobre descriptores de ficheros abiertos. En la figura 143,
se enumeran funciones que utilizan paths como argumentos y descriptores de fichero
equivalentes. Esto es solo una solución parcial porque varias funciones de la biblioteca
de C estándar que interactúan con el sistema de archivos aceptan solo nombres de ruta.

TEMA 6 – Ideas clave 19 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Por suerte, la mayor parte de estas funciones hacen cumplir permisos de acceso al
sistema de archivos cuando se ejecutan, como son link(), mkdir(), mknod(), rename(),
rmdir(), symlink (), unlink(), y utime(). Si se disminuyen los privilegios del usuario actual
antes de la realización de cualquiera de estas operaciones, se asegura la comprobación
de control de acceso al sistema de archivos estándar. Si estas operaciones se
realizan con privilegios debido a los recursos que utilizan, el único modo de conseguir
seguridad es usando permisos de sistema de archivos restrictivos para impedir a los
usuarios cambiar el significado del nombre del archivo simbólico usado.

Funciones que utilizan paths como Funciones que utilizan descriptores de


argumentos fichero equivalentes
Int chmod (const char *filename, mode_t
Int fchmod (int filedes, int mode)
mode)
Int chown (const char *filename, uid_t Int fchown (int filedes, int owner, int
owner, gid_t group) group)
Int chdir (const char *filename) Int fchdir (int filedes)
Int stat (const char *filename, struct stat
Int fstat (int filedes, struct stat *buf)
*buf)
Tabla 2. Funciones que utilizan paths como argumentos y descriptores de fichero equivalentes.
Fuente: Chess y West (2007).

Ficheros temporales inseguros

La biblioteca del lenguaje C estándar contiene muchos mecanismos diferentes para


crear archivos temporales. Algunas funciones intentan crear un único nombre de
archivo simbólico que el programador puede usar para crear un archivo temporal. Otras
funciones van un poco más lejos e intentan abrir un descriptor de archivo, además.

Ambos tipos de funciones son susceptibles a una variedad de vulnerabilidades que


podrían permitir a un atacante inyectar contenido malévolo en un programa, hacer que
el programa realice operaciones malévolas en nombre del atacante, dar acceso al atacante
a información sensible que el programa almacena sobre el sistema de archivos, o permitir
un ataque de denegación de servicio contra el programa.

Las tablas 2 y 3, listan una serie de funciones de la biblioteca de C que intentan generar
un nombre de archivo único para un nuevo archivo temporal. Estas funciones sufren
inherentemente de vulnerabilidad de condición de carrera, TOCTOU, subyacente
en el nombre del archivo escogido. Aunque las funciones garanticen que el nombre del
archivo es único en el tiempo que es seleccionado, no hay ningún mecanismo que impida

TEMA 6 – Ideas clave 20 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

a un atacante crear un archivo con el mismo nombre seleccionado antes de que la


aplicación intente abrir el archivo.

La probabilidad de ataques acertados contra estas funciones aumenta por el hecho de


que usan fuentes muy pobres de aleatoriedad en los nombres que generan, lo cual
hace que un atacante pueda tener éxito. Si un atacante realmente logra crear el archivo
primero, dependiendo de cómo el archivo es abierto, el contenido o los permisos de
acceso del archivo podrían permanecer intactos.

Si el contenido del archivo es malévolo en naturaleza, un atacante podría inyectar datos


peligrosos en la aplicación cuando lee datos del archivo temporal. Si un atacante pre-
crea el archivo con más permisos de acceso de los necesarios, podría más tarde tener
acceso, modificar, o corromper datos que la aplicación almacena en el archivo temporal.
Si el atacante pre-crea el archivo como un enlace a otro archivo importante, la aplicación
podría truncar o escribir datos al archivo y sin ser consciente realizar operaciones
perjudiciales.

Finalmente, en el mejor caso, el archivo puede ser abierto con open() usando O_CREAT
y O_EXCL flags, que fallará si el archivo ya existe y por tanto, prevenir estos tipos de
ataques. Sin embargo, si un atacante con exactitud puede predecir una secuencia de
nombres del archivo temporales, podría ser capaz de impedir al programa abrir el
almacenamiento temporal necesario, causando con eficacia un ataque de denegación de
servicio. Este tipo de ataque es trivial de montar, dada la pequeña cantidad de
aleatoriedad usada en la selección de los nombres del archivo que estas funciones
generan. En Windows, la función GetTempFileName() sufre de las mismas
vulnerabilidades.

TEMA 6 – Ideas clave 21 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Función Descripción

El mktemp () genera un nombre de archivo único por


char* mktemp (char plantilla modificanda [...]. Si tiene éxito, devuelve la plantilla
*template) modificada. Si mktemp () no puede encontrar un nombre de
archivo único, crea una plantilla vacía y la devuelve.

Esta función crea y devuelve un nombre de archivo válido


que no hace referencia a ningún archivo existente. Si el
argumento resultado es un puntero nulo, el valor de retorno
char* tmpnam (char
es un puntero a una cadena interna estática, que puede ser
*result)
modificado por llamadas posteriores. Si no, el resultado debe
ser un puntero a una matriz de al menos L_tmpnam
caracteres, y el resultado se escribe en la misma.

Esta función genera un nombre de archivo temporal único.


Si prefijo no es un puntero nulo, hasta cinco caracteres de
char* tempnam (const
esta cadena usa como prefijo para el nombre de archivo. El
char *dir,
valor de retorno es una nueva cadena generada con malloc
const char *prefix)
(), por lo que debe liberar la memoria que ocups cuando ya
no se necesita.

Tabla 3 Funciones que intentan generar un único fichero temporal. Fuente: Chess y West (2007).

Esta función crea un archivo binario temporal para el modo


FILE* tmpfile (void) de actualización, como si al llamar fopen () con modo wb+.
El archivo se borra automáticamente cuando se cierra o
cuando el programa termina.

El mkstemp () genera un nombre de archivo único y abre el


archivo con open () [con el flag O_EXCL]. Si tiene éxito, se
Int mkstemp (char
modifica la plantilla y devuelve un descriptor para el archivo
*template) abierto en modo lectura y escritura. Si mkstemp () no puede
crear un archivo con un nombre único, devuelve -1. El
archivo se abre en el modo 0600.

Tabla 4. Funciones que intentan generar un único fichero temporal y abrirlo además. Fuente: Chess
y West (2007).

Donde está disponible, mkstemp(), es la mejor opción para crear archivos temporales
entre las funciones ofrecidas por la biblioteca estándar. Pero debido al problema de
permisos de archivo con mkstemp() en viejos sistemas, se debería requerir que todos los
archivos recién creados sean accesibles solo al usuario actual llamando a umask(077)
antes de la creación de cualquier archivo temporal, esto fuerza a todos los archivos recién
creados sean accesibles solo por el usuario que los crea. Como los permisos que asigna
umask() se heredan de un proceso a otro, no confiar en la umask puesta por defecto por
la shell. Un atacante explícitamente puede invocar su programa con una umask
inadecuada y conseguir su objetivo.

TEMA 6 – Ideas clave 22 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Esta solución no aborda el riesgo de un ataque de denegación de servicio montado


por un atacante que puede predecir los valores de los nombres de los archivos que serán
generados. Se tienen dos opciones para crear archivos temporales de forma segura:

» Almacenar los archivos temporales bajo un directorio que no es


públicamente accesible, eliminando así toda la discusión con respecto a ataques.
La figura siguiente, es un ejemplo de código para crear tal directorio.
» Generar los nombres de archivo temporales que sean difíciles de adivinar
usando un generador de números criptográficamente seguros
pseudoaleatorios (PRNG) para crear un elemento aleatorio en cada nombre del
archivo temporal.

Inyección de comandos

Los datos introducidos por un usuario pueden alterar el propósito de un comando,


consulta, etc. a ejecutar en el entorno de la aplicación, base de datos, etc. La secuencia de
actuación de un atacante sería:

» Un atacante modifica el entorno de un programa.


» El programa ejecuta un comando que usa el entorno modificado sin
especificar una ruta absoluta.
» Ejecutando el comando, el programa da privilegios a un atacante o la
capacidad que de otra manera no tendría.

Para entender mejor el impacto potencial del entorno sobre la ejecución de comandos
en un programa, considerar la vulnerabilidad en la utilidad ChangePassword basada en
CGI-Web que permite a los usuarios cambiar sus contraseñas en el sistema
(Berkman, 2004). El proceso de actualización de contraseña incluye ejecutar make en el
directorio /var/yp. Notar que debido a que el programa pone al día registros de
contraseña, debe ser instalado con setuid root. El programa invoca make como sigue:

system("cd /var/yp && make &> /dev/null")

Como el programa no especifica una ruta absoluta para sus variables de entorno antes
de la invocación del comando, un atacante puede aprovecharse del programa
ejecutándolo localmente modificando la variable de entorno $PATH para apuntar su

TEMA 6 – Ideas clave 23 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

código malicioso llamado make y luego ejecutando un script CGI desde un intérprete de
comandos shell, el atacante puede ejecutar código arbitrario con privilegios de root.

En programas seguros privilegiados, $PATH debería contener únicamente directorios de


root, ya que el programa probablemente tendrá que ejecutar utilidades de sistema con
acceso a directorios controlados por el propietario del programa. No incluir el directorio
actual (.) rutas relativas que un atacante podría ser capaz de manipular. En la mayor
parte de entornos, $IFS debería ser puesto a su valor por defecto, \t\n.

Descriptores de ficheros

Los descriptores de archivo estándar stdin (FD 0), stdout (FD 1), y stderr (FD 2) son
típicamente abiertos por el terminal y son usados tanto explícitamente como
implícitamente por funciones como printf(). Algunos programas remiten uno o varios de
estos descriptores a streams de datos diferentes, como un archivo de log, para reutilizar
su comportamiento implícito de forma que sea más adecuado al diseño del programa,
pero la mayor parte los mismos nunca cambia sus valores.

Como con umask y con variables de entorno, un proceso hijo hereda descriptores de
archivo estándar de su padre. Los atacantes pueden aprovechar este hecho para
hacer que un programa vulnerable lea o escriba en archivos del sistema
cuando en realidad se espera interactuar con el terminal.

fd = open("/etc/passwd", O_RDWR);
...
if (!process_ok(argv[1])) {
perror(argv[1]);
}
Figura 15. Código vulnerable a ataques a su descriptor de ficheros estándar. Fuente: Chess y West
(2007).

El ejemplo muestra un programa que como parte de su actividad normal, abre el


archivo/etc/passwd en modo lectura-escritura y después condicionalmente pasa su
primer argumento a stderr() usado por perror(). Se podía creer que estas dos operaciones
no están relacionadas y no tienen ningún impacto la uno sobre la otra, pero el código
realmente contiene un bug.

TEMA 6 – Ideas clave 24 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Un ejemplo de un ataque sobre la vulnerabilidad del ejemplo anterior se puede


ver en la figura siguiente, el código del ejemplo primero cierra stderr (descriptor de
archivo 2) y luego ejecuta el programa vulnerable. Cuando el programa abre/etc/passwd,
open() devolverá el primer descriptor de archivo disponible, que, debido a que el
programa del atacante cerró stderr, será el descriptor de archivo 2.

Ahora, en vez de inofensivamente pasar su primer parámetro al terminal, el programa


escribe la información a /etc/passwd. Aunque esta vulnerabilidad fuera perjudicial
independientemente de la información escrita, este ejemplo es en particular fatal porque
el atacante puede escribir una entrada válida a /etc/passwd. En los sistemas que
almacenan entradas de contraseña en /etc/passwd, se daría acceso con privilegios de
root al atacante sobre el sistema.

int main(int argc, char* argv[]) {


(void)close(2);
execl("victim", "victim", "attacker:<pw>:0:1:Super-User-2:...", NULL);
return 1;
}

Figura 16. Ejemplo de ataque a vulnerabilidad del ejemplo anterior. Fuente: Chess y West (2007).

La solución con vulnerabilidades de descriptor de archivo estándar es franca. Los


programas privilegiados deben asegurar que los tres primeros descriptores de
archivo se abren a archivos seguros conocidos antes del comienzo de su ejecución. Un
programa puede: abrir los tres primeros descriptores de archivo al terminal deseado,
abrir archivos streams (si el programa tiene la intención de usar funciones que
implícitamente dependen de estos valores), o abrir /dev/null tres veces para asegurar
que los tres primeros descriptores de archivo se usan. El ejemplo de la figura 78, ilustra
la segunda opción.

int main(int argc, char* argv[]) {


if (open("/dev/null", O_WRONLY) < 0 ||
open("/dev/null", O_WRONLY) < 0 ||
open("/dev/null", O_WRONLY) < 0) {
exit(-1);
}
...
}

Figura 17. Código que soluciona vulnerabilidades de descriptor de ficheros asegurando el uso de los
tres primeros descriptores de ficheros. Fuente: Chess y West (2007).

TEMA 6 – Ideas clave 25 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

6.6. Referencias

Chess, B. y West, J. (2007). Secure Programming with Static Analysis. Addison-Wesley


Software Security Series.

INCIBE. (2012). Informe de vulnerabilidades, 1er semestre 2012.

Graff, M. G., Van Wyk, K. R. (2003). Secure Coding: Principles & Practices. O'Reilly.

Howard, M. y LeBlanc, D. (2003). Writing Secure Code. Microsoft Press.

Allen, J. H., Barnum, S., Ellison, R. J., McGraw, G., and Mead, N. R. (2008). Software
Security Engineering: A Guide for Project Managers. Addison Wesley Professional.

Goertzel, K. M., and Winograd, T. (2008). Enhancing the Development Life Cycle to
Produce Secure Software, Version 2.0. United States Department of Defense Data and
Analysis Center for Software.

Howard, M., and Lipner, S. (2006). The Security Development Lifecycle: SDL: A Process
for Developing Demonstrably Secure Software. Microsoft Press.

Goertzel, K. M., and Winograd, T. (2008). Enhancing the Development Life Cycle to
Produce Secure Software, Version 2.0. United States Department of Defense Data and
Analysis Center for Software.

Komaroff, M., (ASD/NII) and Baldwin, K. (OSD/AT&L). (2005). DoD Software


Assurance Initiative.

Hoglund. (2004). Exploiting Software: How to Break Code, By G. Hoglund and G.


McGraw. Addison-Wesley Software Security Series.

The SANS Technology Institute. (2006). The Twenty Most Critical Internet Security
Vulnerabilities.

Wagner, D., Foster, J. S., Brewer, E. A. y Aiken, A. (2002). A First Step Towards
Automated Detection of Buffer Overrun Vulnerabilities. Proceedings of the 7th Network
and Distributed System Security Symposium. San Diego, CA.

TEMA 6 – Ideas clave 26 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Long, F. Software Vulnerabilities in Java. CERT Technical Note CMU/SEI-2005-TN-


044.

Merino, B. (2011). Software Exploitation. INCIBE.

CERT (2000). Malicious HTML Tags Embedded in Client Web Requests.

Anderson (2001). Security Engineering.

Brown, K. (2004). Windows Vista Technical Articles. Security in Longhorn: Focus on


Least Privilege, DevelopMentor.

Purczynski, W. (2000). Linux Capabilities Vulnerability.

Chen, H., et al. Setuid Demystified. 11th USENIX Security Symposium (San Francisco,
CA, 2002), 171–190.

Provos, N., Friedl, M., and Honeyman, P. (2003). Preventing Privilege Escalation.

Sarmiento, E. (2001). Chapter 4: The Jail Subsystem.

Berkman, A. (2004). ChangePassword 0.8 Runs setuid Shell.

López, S. (2012). Descubriendo el valor de la Seguridad en las Aplicaciones Web con


IBM AppScan. IBM Corporation.

TEMA 6 – Ideas clave 27 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Lo + recomendado

Lecciones magistrales

Errores y excepciones

Los problemas de seguridad muchas veces comienzan cuando un atacante busca la forma
de violar las expectativas del programador, que muchas veces dan menos importancia a
las condiciones de error y manejo de excepciones y es una de las cosas que tienen en
cuenta los atacantes. En la siguiente lección magistral se realiza una exposición de los
principales errores de programación relativos a los errores y excepciones.

La lección magistral está disponible en el aula virtual.

No dejes de leer…

Basic Integer Overflows

Este artículo presenta una discusión de como un desbordamiento de enteros puede


constituir un vector de ataque.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://phrack.org/issues/60/10.html

TEMA 6 – Lo + recomendado 28 © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

How to Open a File and Not Get Hacked

Presentación de James A. Kupsch y Barton P. Miller sobre los ataque de condiciones de


carrera relativas a la aperturas de archivos.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://research.cs.wisc.edu/mist/presentations/kupsch_miller_secse08.pdf

Software exploitation

Guía de INTECO CERT que aborda diversos aspectos relacionados con la búsqueda y
explotación de vulnerabilidades. El objetivo es concienciar a programadores y
responsables de seguridad sobre la importancia de desarrollar software seguro e
implementar contramedidas con las que mitigar multitud de ataques que hoy en día sigue
siendo la raíz de muchas intrusiones.

Accede a la guía desde el aula virtual o a través de la siguiente dirección web:


https://www.incibe.es/CERT/guias_estudios/guias/guia_software_exploitation

No dejes de ver…

Secure Coding Practices

Vídeo sobre algunas de las mejores


prácticas de desarrollo de aplicaciones
que pueden ayudar a hacer que el
código lo más seguro posible. En
concreto se estudiará acerca de técnicas
de validación de entrada, prevención de
XSS, y tratamiento de errores.

Accede al vídeo desde el aula virtual o a través de la siguiente dirección web:


http://www.professormesser.com/free-comptia-security-training/secure-coding-
concepts/

TEMA 6 – Lo + recomendado © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

+ Información

A fondo

Designing Secure Solutions with .NET

El enfoque adecuado para el diseño de una solución es una que cumpla los objetivos de
negocio y que proteja contra los riesgos identificados con controles que son
transparentes para el usuario. El enfoque parece bastante simple, el desafío es definir lo
que debe ser protegido, cuáles son los riesgos y los tipos de controles necesarios y cómo
ponerlas en práctica de manera rentable.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://www.sans.org/reading_room/whitepapers/securecode/designing-secure-
solutions-dotnet_390

Secure Coding. The State of the Practice

Documento que evalúa las técnicas de software de codificación segura disponibles,


estándares y herramientas y su aplicabilidad potencial en aplicaciones confiables.
Recomienda técnicas aplicables de codificación segura, normas y herramientas para su
uso o modificación potencial de clientes en el desarrollo de dichas aplicaciones.

Accede al artículo desde el aula virtual o a través de la siguiente dirección web:


http://markgraff.com/mg_writings/SC_2001_public.pdf

Bibliografía

Chess, B. y West. J. (2007). Secure Programming with Static Analysis. Addison-Wesley


Software Security Series.

Graff, M. G., Van Wyk, K. R. (2003). Secure Coding: Principles & Practices. O'Reilly.

TEMA 6 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Hoglund. (2004). Exploiting Software: How to Break Code, By G. Hoglund and G.


McGraw. Addison-Wesley Software Security Series.

Howard, M. y LeBlanc, D. (2003). Writing Secure Code. Microsoft Press.

Wagner, D., Foster, J. S., Brewer, E. A. y Aiken, A. (2002). A First Step Towards
Automated Detection of Buffer Overrun Vulnerabilities. Proceedings of the 7th Network
and Distributed System Security Symposium. San Diego, CA.

TEMA 6 – + Información © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

Test

1. Señala la respuesta correcta. ¿Cuándo ocurre un ataque de Integer Overflow?


A. Al realizar una operación de una resta.
B. Un entero es usado como si fuera un puntero.
C. Un entero es usado para acceder a un búfer fuera de sus límites.
D. No hay más espacio en el programa para almacenar un entero.

2. Señala la respuesta correcta. ¿Es el código es correcto?


if (path != null &&
path.length() > 0 && path.length() <= MAXPATH) {
fileOperation(path);
}
A. Es correcto.
B. Es incorrecto.
C. No se puede determinar.
D. Ninguna de las anteriores.

3. Señala la respuesta incorrecta. Los ataques de escalada de privilegios pueden tener


como objetivo cualquier variedad de vulnerabilidades de software, que son
principalmente un riesgo en programas privilegiados:
A. Archivos de sistema.
B. Condiciones de carrera de acceso a archivos.
C. Inyección de comandos.
D. Mal uso de descriptores de archivo estándar.

TEMA 6 – Test © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

4. Señala la respuesta correcta. Se tienen dos opciones para crear archivos temporales
de forma segura:
A. Generar los nombres de archivo temporales que sean fáciles de adivinar usando
un generador de números criptográficamente seguros pseudoaleatorios (PRNG)
para crear un elemento aleatorio en cada nombre del archivo temporal.
B. Almacenar los archivos temporales bajo un directorio que no es públicamente
accesible, eliminando así toda la discusión con respecto a ataques.
C. Almacenar los archivos temporales bajo un directorio que es públicamente
accesible, eliminando así toda la discusión con respecto a ataques.
D. Generar los nombres de archivo temporales que sean difíciles de adivinar
usando un generador de números para crear un elemento en cada nombre del
archivo temporal.

5. Señala la respuesta correcta. Las excepciones tienen dos versiones, la diferencia tiene
que ver con si el compilador usará análisis estático para asegurar que la excepción es
manejada:
A. Cheked y Unchecked.
B. Controladas y no controladas
C. Valores de retorno
D. Ningunas de las anteriores

6. Señala la o las respuestas correctas. ¿Qué tipo de vulnerabilidad se comete en este


código?
u_int nresp;
nresp = packet_get_int();
if (nresp > 0) {
response = xmalloc(nresp*sizeof(char*));
for (i = 0; i < nresp; i++)
response[i] = packet_get_string(NULL);
}
A. Integer Overflows.
B. Desbordamiento de buffer.
C. Format string.
D. Use after free.

7. Señala la respuesta incorrecta. Métodos para detectar y prevenir intergers overflows:


A. Usar tipos sin signo.
B. Verificar el tamaño de los búfer.
C. Restringir la entrada numérica de usuario.
D. Entender las reglas de conversión entre enteros.

TEMA 6 – Test © Universidad Internacional de La Rioja (UNIR)


Seguridad en el Software

8. Señalar la respuesta correcta. Con respecto a los errores y excepciones


A. Si un método declara que lanza una excepción checked, todos los objetos que lo
utilizan deben o manejar la excepción o declarar que lo lanzan también
B. Los compiladores de Java no hacen cumplir las reglas en cuanto a excepciones
checked
C. Todas las excepciones en C++ son checked.
D. Las excepciones checked no tienen que ser declaradas o manejadas.

9. Señala las respuestas correctas. ¿Cuándo un ataque de integer overflow podría


impactar en la seguridad de le memoria?
A. Si el entero es pasado como parámetro a la función prinft().
B. Si el entero es usado como el índice de un array.
C. Si el entero es pasado como parámetro a la función open().
D. Si el entero es pasado como el argumento a malloc().

10. Señala la respuesta correcta. Se tienen dos opciones para crear archivos temporales
de forma segura:
A. Generar los nombres de archivo temporales que sean difíciles de adivinar
usando un generador de números criptográficamente seguros pseudoaleatorios
(PRNG) para crear un elemento aleatorio en cada nombre del archivo temporal.
B. Almacenar los archivos temporales bajo un directorio que es públicamente
accesible, eliminando así toda la discusión con respecto a ataques.
C. Almacenar los archivos no temporales bajo un directorio que es públicamente
accesible, eliminando así toda la discusión con respecto a ataques.
D. Generar los nombres de archivo temporales que sean difíciles de adivinar
usando un generador de números para crear un elemento en cada nombre del
archivo temporal.

TEMA 6 – Test © Universidad Internacional de La Rioja (UNIR)

Potrebbero piacerti anche