Hace un par de meses terminé el Curso de Especialización "Inteligencia Artificial para Expertos en Ciberseguridad" (que ahora tiene una segunda edición programada), liderado por Chema Alonso y Pablo García Bringas en la Universidad de Deusto. Durante las presentaciones virtuales de los trabajos finales, Chema nos ofreció la posibilidad de escribir un artículo explicando el proyecto, para incluirlo en su blog y compartir nuestro aprendizaje. Aquí está el mío.
En mi trabajo final me centré en la optimización de configuraciones de seguridad con IA. Concretamente, en el uso de modelos de lenguaje grandes (LLMs) para mejorar la seguridad del código y los ficheros de configuración. La idea fue crear un flujo de trabajo sencillo en Visual Studio Code que permitiera usar LLMs funcionando en local mediante Ollama.
Asistentes de código basados en IA
Las herramientas de completado de código, como Intellisense de Microsoft y otras similares, existen desde hace tiempo en los entornos de desarrollo (IDEs) como Visual Studio y Eclipse. Inicialmente, permitían un gran ahorro de tiempo al equipo de desarrollo al sugerir, según se va escribiendo, nombres de procedimientos y funciones de objetos, parámetros de los métodos, etcétera.
La incorporación de alguna característica de IA a estas herramientas trajo algunas mejoras, como permitir generar líneas completas en función del contexto. Así surgió IntelliCode como evolución de Intellisense, siguiendo con el ejemplo de Microsoft. Además, basándose en repositorios de código abierto de GitHub, coloca los elementos más probables (métodos, parámetros, etc.) en la parte superior de las sugerencias de Intellisense.
La evolución actual ha llevado a estas herramientas a incluir funcionalidades de chat basadas en modelos de lenguaje grandes como GPT de OpenAI. Esto permite, entre otras cosas, dar al asistente una descripción de un problema en lenguaje natural y obtener la solución en un lenguaje de programación concreto. Un ejemplo de este tipo de herramientas es GitHub Copilot.
Aunque OpenAI dispone de algunos modelos open source, este no es el caso de la familia de modelos GPT en que se basa Copilot, que son de naturaleza cerrada. Además, al ser Copilot un servicio en la nube, esto implica que nuestro código puede escapar de nuestro control, al incluirse como contexto de nuestros prompts. Esto puede hacer que el uso de Copilot no sea adecuado en ciertos proyectos donde la privacidad es primordial.
La idea del trabajo fue entonces buscar una alternativa Open Source y gratuita a GitHub Copilot (que es, por el momento, un servicio de pago).
Ollama y LLMs en local
Figura 1: Cómo utilizar GenAI para la detección de
bugs en ficheros Web.config usando Ollama
En mi trabajo final me centré en la optimización de configuraciones de seguridad con IA. Concretamente, en el uso de modelos de lenguaje grandes (LLMs) para mejorar la seguridad del código y los ficheros de configuración. La idea fue crear un flujo de trabajo sencillo en Visual Studio Code que permitiera usar LLMs funcionando en local mediante Ollama.
Asistentes de código basados en IA
Las herramientas de completado de código, como Intellisense de Microsoft y otras similares, existen desde hace tiempo en los entornos de desarrollo (IDEs) como Visual Studio y Eclipse. Inicialmente, permitían un gran ahorro de tiempo al equipo de desarrollo al sugerir, según se va escribiendo, nombres de procedimientos y funciones de objetos, parámetros de los métodos, etcétera.
La incorporación de alguna característica de IA a estas herramientas trajo algunas mejoras, como permitir generar líneas completas en función del contexto. Así surgió IntelliCode como evolución de Intellisense, siguiendo con el ejemplo de Microsoft. Además, basándose en repositorios de código abierto de GitHub, coloca los elementos más probables (métodos, parámetros, etc.) en la parte superior de las sugerencias de Intellisense.
La evolución actual ha llevado a estas herramientas a incluir funcionalidades de chat basadas en modelos de lenguaje grandes como GPT de OpenAI. Esto permite, entre otras cosas, dar al asistente una descripción de un problema en lenguaje natural y obtener la solución en un lenguaje de programación concreto. Un ejemplo de este tipo de herramientas es GitHub Copilot.
Aunque OpenAI dispone de algunos modelos open source, este no es el caso de la familia de modelos GPT en que se basa Copilot, que son de naturaleza cerrada. Además, al ser Copilot un servicio en la nube, esto implica que nuestro código puede escapar de nuestro control, al incluirse como contexto de nuestros prompts. Esto puede hacer que el uso de Copilot no sea adecuado en ciertos proyectos donde la privacidad es primordial.
La idea del trabajo fue entonces buscar una alternativa Open Source y gratuita a GitHub Copilot (que es, por el momento, un servicio de pago).
Ollama y LLMs en local
Ollama es un proyecto Open Source que ofrece una plataforma para ejecutar modelos de lenguaje grandes (LLMs) en local de forma sencilla. Al ejecutar un modelo en local evitamos que el código que estamos desarrollando abandone nuestro equipo, mejorando así la privacidad. Está disponible para varias plataformas (macOS, Windows, GNU/Linux y Docker) y es la primera pieza del trabajo.
Ollama soporta una gran variedad de modelos. Para el proyecto elegí uno de los modelos Open Source más populares, Llama 3 de Meta. Está disponible en las versiones de 8.000 y 70.000 millones de parámetros (8B y 70B). Desde que presenté el proyecto ha salido la versión de Llama 3.1, que añade un modelo de 405.000 millones de parámetros (405B). Para este artículo se ha utilizado esta versión 3.1 más reciente, en su versión 8B.
En su carta Open Source AI Is the Path Forward, Mark Zuckerberg detalla algunos de los motivos por los que los modelos Open Source son buenos para un equipo de desarrollo. Uno de estos puntos es, precisamente, el caso de las empresas que manejan información sensible que no pueden enviar a los modelos en la nube y cerrados.
La segunda pieza del proyecto fue utilizar este modelo, sin ningún tipo de ajuste fino o Fine-Tuning y ponerlo a prueba para analizar la seguridad del código y los ficheros de configuración, como se ha descrito al principio.
Instalación de Ollama
La instalación de Ollama es muy sencilla, en este caso se ha descargado para macOS. En la imagen se muestran los tres pasos de la instalación. En la primera pantalla se muestra la bienvenida; la segunda permite instalar la línea de comandos; y la última muestra un ejemplo para descargar el modelo Llama 3 desde una línea de comandos.
Figura 2: Proceso de instalación de Ollama
Instalación del modelo Llama 3.1
En el caso del modelo Llama 3.1, el comando a ejecutar para instalarlo desde la terminal de macOS es: ollama run llama3.1. El modelo descargado es el de 8.000 millones de parámetros (8B) y ocupa 4,7 GB.
Figura 3: Instalación del modelo Llama 3.1
Primer uso de Ollama con el modelo en local
Una forma sencilla de empezar a usar el modelo recién instalado en Ollama es instalar una interfaz web que nos permita realizar consultas, al estilo ChatGPT. Para ello existen proyectos como Open WebUI. La forma más sencilla de instalarlo es mediante Docker y entonces disponemos de una aplicación web servida en local con la que podemos interactuar con el modelo:
Figura 4: Consulta al modelo con Open WebUI
Como se observa en la imagen, es una interfaz que nos resulta muy familiar si ya hemos utilizado ChatGPT. En este ejemplo, se ha arrastrado un fichero Web.config de configuración de IIS y se le ha preguntado al modelo si es seguro. En el proyecto se han utilizado prompts en inglés. Aunque el modelo Llama 3.1 es multi-idioma, la mayoría de los datos de entrenamiento están en inglés y en las pruebas se consiguieron los mejores resultados en ese idioma.
A pesar de su sencillez, este enfoque de trabajo desde la interfaz web es limitado. Implica que tenemos que ir cambiando de contexto entre la aplicación donde desarrollamos, por ejemplo, Visual Studio Code y el chat en el navegador. Si el modelo nos sugiere cambios en el fichero, debemos volver al IDE para aplicarlos manualmente.
Si queremos un flujo de trabajo similar al uso de GitHub Copilot, integrado en una herramienta de desarrollo, debemos incorporar una pieza más a las que ya tenemos.
Extensiones para Visual Studio Code
Existen una serie de extensiones para Visual Studio Code (y otros IDEs) que permiten utilizar los asistentes de código basados en IA. Una de ellas es Continue, una extensión Open Source para Visual Studio Code y JetBrains que ofrece funciones como autocompletar líneas enteras y secciones de código, chat con el LLM sobre funciones y ficheros de nuestro proyecto, generación de código a partir de lenguaje natural, etcétera. Si utilizamos Visual Studio Code, se puede descargar e instalar la extensión desde el marketplace de Visual Studio Code. Una vez instalada la extensión, la configuración es sencilla.
En primer lugar, se configura el proveedor de modelos LLM, como muestra la imagen anterior. Como puede verse, hay varios disponibles. Si disponemos de claves de API, se pueden utilizar modelos comerciales, como los de OpenAI. En este caso elegimos Ollama para usar los modelos locales.
En el siguiente paso, mostrado en la imagen, se elige el modelo concreto. La extensión ofrece varios modelos configurados por defecto. En nuestro ejemplo hemos elegido "Autodetect" para indicar que se rellene el desplegable de modelos (que se observa vacío en la parte inferior izquierda) con los modelos ya disponibles en Ollama. Habíamos descargado ya el modelo Llama 3.1 de Meta cuando instalamos Ollama.
Uso de la extensión Continue
Con la extensión ya configurada, si ahora nos colocamos en la pestaña de Continue tenemos disponible el chat contra el modelo Llama 3.1 en local, que hemos seleccionado en el desplegable inferior donde aparecen los modelos instalados en Ollama.
En la imagen puede verse uno de los usos de esta extensión, la generación de código a partir del lenguaje natural. En el ejemplo, hemos pedido al modelo que genere una función en Python para calcular la secuencia Fibonacci para un número dado. Llama ha generado la función, incluyendo ejemplos de la salida para diversos valores.
Ahora que todas las piezas el proyecto están encajadas, ha llegado el momento de poner a prueba el modelo en local para el propósito inicial de mejorar la seguridad de ficheros de código con configuración de entornos .NET con Web.config. De todo esto, puedes ver la charla de "Some dirty, quick and well-known tricks to hack your bad .NET WebApps".
Extensiones para Visual Studio Code
Existen una serie de extensiones para Visual Studio Code (y otros IDEs) que permiten utilizar los asistentes de código basados en IA. Una de ellas es Continue, una extensión Open Source para Visual Studio Code y JetBrains que ofrece funciones como autocompletar líneas enteras y secciones de código, chat con el LLM sobre funciones y ficheros de nuestro proyecto, generación de código a partir de lenguaje natural, etcétera. Si utilizamos Visual Studio Code, se puede descargar e instalar la extensión desde el marketplace de Visual Studio Code. Una vez instalada la extensión, la configuración es sencilla.
Figura 5: Configuración del proveedor de modelos en Continue
En primer lugar, se configura el proveedor de modelos LLM, como muestra la imagen anterior. Como puede verse, hay varios disponibles. Si disponemos de claves de API, se pueden utilizar modelos comerciales, como los de OpenAI. En este caso elegimos Ollama para usar los modelos locales.
Figura 6: Configuración del modelo en Continue
En el siguiente paso, mostrado en la imagen, se elige el modelo concreto. La extensión ofrece varios modelos configurados por defecto. En nuestro ejemplo hemos elegido "Autodetect" para indicar que se rellene el desplegable de modelos (que se observa vacío en la parte inferior izquierda) con los modelos ya disponibles en Ollama. Habíamos descargado ya el modelo Llama 3.1 de Meta cuando instalamos Ollama.
Uso de la extensión Continue
Con la extensión ya configurada, si ahora nos colocamos en la pestaña de Continue tenemos disponible el chat contra el modelo Llama 3.1 en local, que hemos seleccionado en el desplegable inferior donde aparecen los modelos instalados en Ollama.
Figura 7: Uso de Continue para generación de código
En la imagen puede verse uno de los usos de esta extensión, la generación de código a partir del lenguaje natural. En el ejemplo, hemos pedido al modelo que genere una función en Python para calcular la secuencia Fibonacci para un número dado. Llama ha generado la función, incluyendo ejemplos de la salida para diversos valores.
Figura 8: Libro de Python para Pentesters 2ª Edición en 0xWord
por Daniel Echeverri Montoya a.k.a. Adastra
Figura 9: "Some dirty, quick and well-known tricks to hack your bad .NET WebApps".
Para el primer ejemplo, se ha utilizado un fichero Web.config de configuración de IIS. Para generar un fichero vulnerable se utilizó GPT-4o de OpenAI, con el siguiente prompt:
"Eres un ingeniero de ciberseguridad que está probando una nueva forma de detectar vulnerabilidades en ficheros de configuración de IIS. Genera un fichero de configuración Web.config que incluya las vulnerabilidades más importantes en este tipo de ficheros."
Tras generar el fichero Web.config, se incluyó en un proyecto ASP.NET real para ver que era correcto y que la aplicación funcionaba.
Figura 10: Fichero Web.config vulnerable generado por ChatGPT-4o
En la imagen se muestra el fichero de configuración generado y se ven algunas de las nueve vulnerabilidades introducidas. En la siguiente imagen hemos abierto en Visual Studio Code el fichero Web.config (mitad izquierda), que aparece junto con la la pestaña de la extensión Continue, que contiene el chat con el modelo LLM en local (mitad derecha).
Figura 11: Análisis de la seguridad del fichero de configuración con Continue
con bugs de Debug Mode Enabled y con CustomErrors Enabled
Para incorporar nuestro fichero Web.config como contexto a la ventana del chat, seleccionamos todo el contenido (con Cmd+A en macOS o Ctrl+A en Windows) y lo incorporamos al chat con (Cmd+L o Ctrl+L). A continuación del fichero adjunto, introducimos el prompt para el modelo.
En el curso aprendimos que, cuanto más detallado es el prompt, mejor es la respuesta y menor la probabilidad de que el modelo "alucine". Tras probar varios prompts para analizar la seguridad del fichero con el modelo Llama local, se llegó a éste:
You are a cybersecurity expert with access to vulnerability databases and cybersecurity guidelines and best practices. You have deep knowledge of programming code, as well as software and hardware configuration files, like the one attached here.
Analyze this attached file to identify potential security issues. For each issue, provide a brief explanation suitable for a technical audience and propose a change to the file that will eliminate or mitigate the vulnerability.
Ensure that your proposed changes include inline code in the response.
Primero se le da al modelo un rol: un experto en ciberseguridad con acceso a bases de datos de vulnerabilidades, guías de ciberseguridad y mejores prácticas y un profundo conocimiento del código y de los ficheros de configuración. A continuación, se le indica qué resultado esperamos obtener: un análisis de los riesgos de seguridad del fichero con una explicación técnica y una propuesta que elimine o mitigue la vulnerabilidad. Por último, se pide que la salida incluya las mejoras en forma de código en línea. Esta última petición será muy interesante, como se verá a continuación.
En el siguiente vídeo se ve que el modelo nos ha respondido, analizando las vulnerabilidades del fichero. La primera indica que el modo de depuración está habilitado, lo que puede exponer información sensible a un atacante. La recomendación es desactivarlo, poniendo a false el atributo debug. Al haber solicitado el cambio propuesto como texto en línea, la extensión permite aplicarlo directamente al código. Si colocamos el ratón en el texto en línea, aparecerán varios iconos. Pulsando el primero (Apply to current file) la herramienta aplica el cambio en la línea adecuada.
Figura 12: Demostración de aceptación de recomendación
Hay que tener en cuenta que en el vídeo se han recortado algunos momentos para reducir su peso, en realidad tarda algo más que lo que se muestra.
Slash Commands
Una vez que hemos encontrado un prompt que nos ha dado buenos resultados, conviene encontrar una forma de no tener que copiarlo y pegarlo en el chat cada vez que queremos analizar un fichero. Continue dispone de los comandos slash, es decir, los que comienzan por /. Un ejemplo es el comando /comment, que se utiliza para que el LLM comente el código seleccionado.
Lo bueno es que podemos crear nuestros propios Slash Commands. Para ello, pulsamos sobre el icono de la tuerca que aparece en la barra inferior de la ventana de la extensión Continue. Se nos abrirá el fichero config.json de la configuración de la extensión. Es un fichero JSON sencillo y podemos añadir nuestros comandos en la sección customCommands, por ejemplo:
"customCommands": [{"name": "secure","prompt": "{{{ input }}}\n\nYou are a cybersecurity expert with access to vulnerability databases and cybersecurity guidelines and best practices. You have deep knowledge of programming code, as well as software and hardware configuration files, like the one attached here.\n\nAnalyze this attached file to identify potential security issues. For each issue, provide a brief explanation suitable for a technical audience and propose a change to the file that will eliminate or mitigate the vulnerability.\n\nEnsure that your proposed changes include inline code in the response.","description": "Evaluar la seguridad"}]
Ahora, procedemos de la misma manera que antes, seleccionando todo el fichero Web.config y añadiéndolo al chat de Continue. Pero simplemente escribimos /secure en el chat, en lugar del prompt completo:
Figura 13: Uso de slash command /Secure en Continue
Corrección masiva con el modo edición
Antes hemos visto cómo se puede corregir directamente el código original a partir de las recomendaciones proporcionadas por el modelo, pulsando el icono de aplicar cambios que aparecía en la línea de la corrección. Si queremos aplicar varios cambios a la vez, en lugar de ir aplicando uno por uno, podemos utilizar el modo edición de la extensión Continue.
Como antes, pulsamos Cmd+A o Ctrl+A para seleccionar todo el contenido. Ahora, en lugar de incorporarlo al chat como hicimos al principio, pulsamos Cmd+I o Ctrl+I para acceder al modo edición. En la parte superior de Visual Studio Code aparece una caja de texto donde podemos introducir un Slash Command, ya sea uno de los propios de la extensión o uno definido por nosotros.
En el vídeo se muestra cómo Continue aplica todos los cambios propuestos por el modelo. Una vez aplicados, los podemos revisar uno a uno e ir aceptándolos o rechazándolos de forma individual. Si estamos seguros de que todos los cambios propuestos son adecuados, se pueden aceptar todos en bloque.
Como antes, el vídeo tiene cortes y el proceso tarda algo más de lo mostrado. Aunque no veamos en la ventana de chat cómo se reciben los tokens según se va produciendo la inferencia, este proceso debe ocurrir igualmente. Por eso, hasta que no se recibe la respuesta completa del LLM, no se observarán cambios en el fichero de configuración.
Como antes, pulsamos Cmd+A o Ctrl+A para seleccionar todo el contenido. Ahora, en lugar de incorporarlo al chat como hicimos al principio, pulsamos Cmd+I o Ctrl+I para acceder al modo edición. En la parte superior de Visual Studio Code aparece una caja de texto donde podemos introducir un Slash Command, ya sea uno de los propios de la extensión o uno definido por nosotros.
Figura 14: Ejemplo de Slash Command
En el vídeo se muestra cómo Continue aplica todos los cambios propuestos por el modelo. Una vez aplicados, los podemos revisar uno a uno e ir aceptándolos o rechazándolos de forma individual. Si estamos seguros de que todos los cambios propuestos son adecuados, se pueden aceptar todos en bloque.
Como antes, el vídeo tiene cortes y el proceso tarda algo más de lo mostrado. Aunque no veamos en la ventana de chat cómo se reciben los tokens según se va produciendo la inferencia, este proceso debe ocurrir igualmente. Por eso, hasta que no se recibe la respuesta completa del LLM, no se observarán cambios en el fichero de configuración.
Consideraciones finales
A modo de referencia, para el trabajo se utilizó un Mac mini de 2023 con chip Apple M2 y 16 GB de memoria, con un Neural Engine de 16 núcleos. En las pruebas, esta configuración pudo ejecutar con soltura modelos de entre 7.000 y 13.000 millones de parámetros.
El uso de modelos de lenguaje grandes como asistentes al desarrollo de código tiene un gran potencial. A medida que el nuevo hardware que se lance incluye aceleración por hardware para mejorar el rendimiento de las tareas de IA, va a ser cada vez más viable el uso de LLMs en local, ya sean genéricos o para tareas específicas. Las ventajas en cuanto a privacidad que ofrece este enfoque suponen una alternativa viable a los modelos cerrados y en la nube.
Saludos,
Autor: Fernando Gutiérrez Calderón
No hay comentarios:
Publicar un comentario