Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
software
[1.1] ¿Cómo estudiar este tema?
[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
2
Clasificación de vulnerabilidades Complementarias:
Fiabilidad
Escáneres de vulnerabilidades
Autenticación
Trazabilidad
Robustez
Resiliencia
Tolerancia
Seguridad en el Software
Ideas clave
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.
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.
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.
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):
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.
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.
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:
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.
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.
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.
Fallos de implementación
Fallos de diseño
Fallos de configuración
Exploits
Es una instancia particular de un ataque a un sistema informático que aprovecha una
vulnerabilidad específica o un conjunto de ellas.
Gestión de vulnerabilidades
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
CVE-2012-4212
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.
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
» 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.
Escáneres de vulnerabilidades
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:
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:
Integridad
Confidencialidad Disponibilidad
Resiliencia
SEGURIDAD Fiabilidad
DEL
SOFTWARE
Robustez Autenticación
Trazabilidad Tolerancia
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:
1.5. Referencias
Graff, M. G., Van Wyk, K. R. (2003). Secure Coding: Principles & Practices. O'Reilly.
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.
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., Lipner, S. (2006). The Security Development Lifecycle: SDL: A Process for
Developing Demonstrably Secure Software. Microsoft Press.
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.
Barnum, S., Sethi, A. (2007). Attack Patterns as a Knowledge Resource for Building
Secure. Software Cigital, Inc.
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.
Lo + recomendado
Lecciones magistrales
No dejes de leer…
El documento del año 1975 que presenta conceptos de seguridad del software que siguen
siendo muy relevantes en la actualidad.
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.
No dejes de ver…
+ Información
A fondo
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.
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.
Artículo que analiza los aspectos básicos de las vulnerabilidades: por qué ocurren y cómo
gestionarlas.
Enlaces relacionados
Build Security In
Sitio web que describe las buenas prácticas de desarrollo seguro de modelo de S-SDLC
de Microsoft y sus herramientas asociadas.
Sitio web de la empresa HP con recursos y artículos sobre seguridad del software.
Sitio web de la empresa CIGITAL Inc. con recursos, libros, vídeos y artículos sobre
seguridad del software.
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.
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.
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.
Test
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
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.
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.
[2.2] Introducción
[2.7] Referencias
TEMA
El problema de la seguridad del software
Introducción al problema de
Esquema
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
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
Ideas clave
Para estudiar este tema lee las Ideas clave que te presentamos a continuación.
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.
» 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.
Defensa en profundidad
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:
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
Tramas Enlace
Algunas de las opciones específicas de diseño del software que lo simplifican son [13]:
Mínimo privilegio
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:
Separación de privilegios
» 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:
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.
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
» 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.
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
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:
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.
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:
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):
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
Las principales diferencias que distinguen los sistemas con registros de auditoría de
seguridad de registro de los registros de eventos estándar son:
Objetivo: Generar eventos (logs) de seguridad, para garantizar las acciones realizadas
por un ciberatacante se observan y registran.
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.
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
Los sistemas deben diseñarse y configurarse de forma que garanticen la seguridad por
defecto:
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.
Resumen
Principio Objetivo
Introducción
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.
» 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
Otras metodologías
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.
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
» 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.
Relación entre las prácticas de seguridad y las fases del ciclo de vida.
Introducción
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).
» Estándares de calidad
» 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.
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:
2.7. Referencias
Graff, M. G., Van Wyk, K. R. (2003). Secure Coding: Principles & Practices. O'Reilly.
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.
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., Lipner, S. (2006). The Security Development Lifecycle: SDL: A Process for
Developing Demonstrably Secure Software. Microsoft Press.
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.
Barnum, S., Sethi, A. (2007). Attack Patterns as a Knowledge Resource for Building
Secure. Software Cigital, Inc.
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.
Lo + recomendado
Lecciones magistrales
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.
No dejes de ver…
+ Información
A fondo
Enlaces relacionados
Bibliografía
Howard, M., Lipner, S. (2006). The Security Development Lifecycle: SDL: A Process for
Developing Demonstrably Secure Software. Microsoft Press.
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.
Test
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.
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.
[3.2] Introducción
[3.8] Referencias
TEMA
Esquema
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
Ideas clave
Para estudiar este tema lee las Ideas clave que te presentamos a continuación.
3.2. Introducción
Introducción
La perspectiva del atacante se suele modelar de las siguientes dos formas, que
desarrollamos en párrafos posteriores:
» Patrones de ataque
» Árboles 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
Patrones de ataque
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
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.
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.
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.
Í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.
Guía relacionadas
» Identifica las directrices de seguridad existentes que son relevantes
para la identificación o mitigar este tipo de ataque.
Árboles de ataque
Básicamente:
Ejemplo:
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.
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
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
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):
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:
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).
Previene Inundar el
Bloquear sistema Detecta
Hojear
Extiende repetidos
catálogo
registros
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)
Introducción
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.
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
Deben especificar:
Figura 13. Vista de alto nivel de las tareas y artefactos involucrados en la fase de requisitos.
» Completos.
» Precisos.
» Coherentes.
» Trazables.
» Verificables.
Introducción
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
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
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.
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
3.8. Referencias
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.
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.
Barnum, S., and Sethi, A. (2007). Attack Patterns as a Knowledge Resource for Building
Secure. Software Cigital, Inc.
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.
Microsoft Corp. (2003). Application Security Best Practices at Microsoft: The Microsoft
IT Group Shares Its Experiences.
Donald, G. (2003). Software Engineering Institute, U.S.A. Security Use Cases. Journal
of Object Technology.
Lo + recomendado
Lecciones magistrales
Modelado de amenazas
No dejes de leer…
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.
Software Design Misuse and Abuse Cases. Getting Past Positive. Cigital INC
No dejes de ver…
Trustworthy Computing's
Clase del MIT OpenCourseWare del Professor Zeldovich acerca del modelado de
amenazas.
No dejes de practicar…
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.
+ Información
A fondo
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.
Bibliografía
McGraw, G. (2005). Software Design Misuse and Abuse Cases. Getting Past Positive.
Cigital INC.
Howard, M., Lipner, S. (2006). The Security Development Lifecycle: SDL: A Process for
Developing Demonstrably Secure Software. Microsoft Press.
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.
Actividades
Caso práctico
» 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.
Los objetivos de seguridad establecidos para la tienda web de Librería On-Line SA son
los siguientes objetivos:
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.
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
Como ayuda a su manejo, aparte de los manuales que se pueden descargar con
esta herramienta, se aconseja visionar estos dos videos:
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.
Selección de vitas
Relación entre las amenazas del método STRIDE y los elementos de un diagrama DFD.
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
Aplicación de Plantilla
Aplicación de plantilla.
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.
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?
Se rellena despues para cada amenaza la siguiente tabla, en la que se incluye un ejemplo:
Calculo el riesgo.
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
Entrega
Incluir el fichero con extensión .tm7 que genera la herramienta y el informe que se puede
generar con la misma.
Test
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.
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.
[4.2] Introducción
[4.8] Referencias
TEMA
Seguridad en el ciclo de vida del software
Introducción a la seguridad en el
Esquema
TEMA 4 – Esquema
Pruebas de seguridad Test de Operaciones de Revisión
Revisión de código
basadas en riesgo penetración seguridad externa
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
Ideas clave
Para estudiar este tema lee las Ideas clave que te presentamos a continuación.
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.
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.
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
Los objetivos de las pruebas de seguridad basadas en el riesgo son los siguientes
(Redwine, 2006):
Pruebas basadas
en riesgo
Caja negra
Análisis dinámico
Fuzzing Testing
Escaneo de v ulnerabilidades
Análisis híbrido
Caja gris
Iny ección de fallos en código
fu ente
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.
En la figura siguiente se muestra las diferentes pruebas a realizar en cada una de las fases
del S-SDLC (Redwine, 2006):
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
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
Los problemas de seguridad de una aplicación pueden ser resultado de dos tipos de
errores principales:
Con esto en mente, el análisis estático de código fuente es adecuado para identificar
problemas de seguridad por ciertas razones:
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.
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.
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.
Fortify Software e IBM, fabrican herramientas de análisis estático de código que caen
dentro de esta categoría.
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.
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
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.
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.
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.
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.
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.
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.
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.
» Escaneo de vulnerabilidades.
» Explotación de vulnerabilidades
» Fuzz testing.
» Análisis dinámico (DAST) para aplicaciones Web.
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.
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
Distribución
Despliegue
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».
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)
Operaciones
4.8. Referencias
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.
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.
Barnum, S., and Sethi, A. (2007). Attack Patterns as a Knowledge Resource for Building
Secure. Software Cigital, Inc.
Wyk, G. (2003). Secure Coding: Principles & Practices By M. G. Graff, K. R. van Wyk.
Publisher: O'Reilly.
Microsoft Corp. (2003). Application Security Best Practices at Microsoft: The Microsoft
IT Group Shares Its Experiences.
Donald, G. (2003). Software Engineering Institute, U.S.A. Security Use Cases. Journal
of Object Technology.
Lo + recomendado
Lecciones magistrales
No dejes de leer…
Artículo que introduce la idea de las pruebas de penetración, así como muchas otras
ideas fundacionales de seguridad de los sistemas.
Vsftpd. Probably the most secure and fastest FTP server for UNIX-like
systems
No dejes de ver…
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.
+ Información
A fondo
All You Ever Wanted to Know About Dynamic Taint Analysis and Forward
Symbolic Execution
SPIKE
Página web que muestra cómo utilizar la herramienta de fuzzing de red SPIKE.
Enlaces relacionados
Metasploit
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.
NMAP
Zap
Burp suite
Escáner de vulnerabilidades de aplicaciones web que dispone de una versión libre y otra
de pago.
Kali
Joern
FindBugs
Bibliografía
Howard, M., Lipner, S. (2006). The Security Development Lifecycle: SDL: A Process for
Developing Demonstrably Secure Software. Microsoft Press.
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.
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.
[5.2] Introducción
[5.6] Referencias
TEMA
Codificación segura
Esquema
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
Ideas clave
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
» 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.
» 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
Desbordamiento de buffer
Errores y ex cepciones
Programas privilegiados
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.
» Qué validar
o Validar toda la entrada.
o Validar la entrada de todas las fuentes.
o Establecer fronteras de confianza.
» 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.
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:
» 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.
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" );
}
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:
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:
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).
Al final se pone:
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
Figura 5. APIs de seguridad implican un amplio contexto para hacer la validación de entrada.
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.
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.
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.
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).
Pero un atacante puede asignar al campo itemname la cadena "name' OR 'a'='a" con
lo que la sentencia se convierte en:
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.
Figura 10. Ejemplo de vulnerabilidad de manipulación de ruta. Fuente: Chess y West (2007).
» Inyección de comandos
» 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.
Introducción
Los lenguajes seguros deben proporcionar dos propiedades para asegurar que los
programas respetan límites de asignación:
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.
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.
» 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).
#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).
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.
#include <unistd.h>
int main() {
char *scode[2];
scode[0] = "/bin/sh";
scode[1] = NULL;
execve (scode[0], scode, NULL);
}
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.
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.
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.
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.
Figura 20. Ejemplo de ataque de buffer overflow. Fuente: Chess y West (2007).
» #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*/
» 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.
#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);
}
» 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.
#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;
}
Manipulación de Strings
» Introducción
Errores de truncado
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 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().
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).
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.
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().
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).
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.
Tabla 2. Funciones ilimitadas con sus correspondientes limitadas. Fuente: Chess y West (2007).
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).
» Errores de truncado
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.
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).
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.
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:
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).
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).
Figura 36. Clásica vulnerabilidad de format String en wuftpd 2.6.0. Fuente: Chess y West (2007).
5.6. Referencias
Graff, M. G., Van Wyk, K. R. (2003). Secure Coding: Principles & Practices. O'Reilly.
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.
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.
Provos, N., Friedl, M., and Honeyman, P. (2003). Preventing Privilege Escalation.
Lo + recomendado
Lecciones magistrales
No dejes de leer…
Explica las principales librerías del lenguaje C inseguras y como pueden provocar
ataques de desbordamiento de menor.
Memory layout
No dejes de ver…
+ 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.
Enlaces relacionados
Secure Coding
Bibliografía
Graff, M. G., Van Wyk, K. R. (2003). Secure Coding: Principles & Practices. O'Reilly.
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 permite el análisis de código estático
automatizado para ayudar a los desarrolladores a eliminar las vulnerabilidades y crear
software seguro.
Actividades
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.
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.
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.
Test
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
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.
#include <stdio.h>
#include <string.h>
#define S 100
#define N 1000
[6.2] Introducción
[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
• Inyección de comandos
• Descriptores de ficheros
Seguridad en el Software
Ideas clave
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
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.
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.).
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.
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.
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.
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).
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.
Figura 5. Integer overflow causado por conversión signo-sin signo. Fuente: Chess y West (2007).
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.
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.
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.
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.
Introducción
Administrador
Escalada Privilegios
Alto Privilegio Vertical
Atacante Usuario
Figura 9. Ataques de elevación de privilegios vertical y horizontal. Fuente: Chess y West (2007).
» 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.
Figura 10. Ejemplo de utilización de privilegios de root en la ejecución de varios programas. Fuente:
Chess y West (2007).
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.
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.
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].
» 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");
Figura 11. Código de un simple FTP server. Fuente: Chess y West (2007).
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.
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.
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:
1º
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
2º
Un atacante cambia el significado del nombre del archivo que el programa comprobó
de modo que refiera un objeto del sistema de archivos diferente.
3º
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.
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.
Figura 13. Ejemplo de código con una vulnerabilidad TOCTOU en el acceso a un fichero. Fuente:
Chess y West (2007).
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.
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().
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.
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
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.
Función Descripción
Tabla 3 Funciones que intentan generar un único fichero temporal. Fuente: Chess y West (2007).
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.
Inyección de comandos
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:
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
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.
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).
Figura 16. Ejemplo de ataque a vulnerabilidad del ejemplo anterior. Fuente: Chess y West (2007).
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).
6.6. Referencias
Graff, M. G., Van Wyk, K. R. (2003). Secure Coding: Principles & Practices. O'Reilly.
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.
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.
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.
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.
No dejes de leer…
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.
No dejes de ver…
+ Información
A fondo
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.
Bibliografía
Graff, M. G., Van Wyk, K. R. (2003). Secure Coding: Principles & Practices. O'Reilly.
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.
Test
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
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.