Categorías
Hacking y Ciberseguridad Comercial

¿Cómo pueden protegerse los pequeños negocios online en Colombia frente a fraudes digitales, suplantación y ataques en sus páginas web y redes sociales?

En Colombia, el auge del comercio electrónico y las ventas por redes sociales ha impulsado a miles de pequeños negocios a digitalizarse rápidamente. Desde tiendas de ropa hasta ventas de productos artesanales, muchas micro y pequeñas empresas manejan catálogos, pagos y atención al cliente vía páginas web, Facebook, Instagram y WhatsApp.

Sin embargo, esta rápida digitalización trae consigo un incremento exponencial en fraudes digitales, ataques cibernéticos y suplantación de identidad que pueden afectar directamente las ventas y la confianza de los clientes.

¿Cuáles son los fraudes digitales más comunes que afectan a pequeños negocios online en Colombia?

  1. Suplantación de cuentas de WhatsApp Business o perfiles en Instagram
    Los estafadores crean cuentas idénticas a las de la tienda para solicitar pagos anticipados por productos falsos o engañar clientes con ofertas inexistentes.
  2. Phishing y páginas web falsas
    Se crean sitios web que imitan el negocio original para capturar datos bancarios o personales de los clientes.
  3. Ataques a plataformas de pago
    Robos de credenciales o manipulación de pasarelas de pago que generan cobros indebidos o anulaciones fraudulentas.
  4. Robo o filtración de bases de datos de clientes
    Incluye nombres, direcciones, teléfonos y detalles de compra, que luego pueden ser vendidos o usados para campañas de spam y estafas.
  5. Ataques de denegación de servicio (DDoS)
    Que hacen caer el sitio web en momentos claves de ventas, causando pérdidas económicas.
  6. Inserción de código malicioso (malware) en el sitio web
    Que puede redirigir a los visitantes a sitios peligrosos o infectar dispositivos de clientes.

¿Qué pasos debe tomar un pequeño negocio si detecta un fraude digital o ataque en su página web o redes sociales?

  1. Aislar los sistemas afectados y cambiar todas las contraseñas
    Incluye no solo la página web, sino también las cuentas de redes sociales, correo electrónico y plataformas de pago.
  2. Contactar al proveedor de hosting y plataformas sociales
    Para solicitar soporte y bloqueo de cuentas falsas o acceso no autorizado.
  3. Recopilar evidencias
    Capturas de pantalla, correos sospechosos, mensajes de clientes afectados, y registros de acceso para facilitar investigaciones.
  4. Solicitar apoyo profesional en informática forense
    Esto permite identificar la causa, la extensión del daño y las acciones para evitar nuevas brechas.
    Más en https://ihack.red/informatica-forense/
  5. Informar a los clientes con transparencia
    Comunicarles qué sucedió, qué datos pudieron verse comprometidos y qué medidas se están tomando para protegerlos.
  6. Denunciar el incidente ante la Fiscalía
    Para que se inicie un proceso legal contra los responsables.

¿Cómo prevenir fraudes digitales y ataques en pequeños negocios online?

  • Implementar certificados SSL para asegurar la conexión en la página web.
  • Mantener actualizados todos los plugins, temas y sistemas de gestión web.
  • Usar sistemas de pago confiables y verificables.
  • Configurar autenticación de dos factores en todas las cuentas digitales.
  • Capacitar al equipo en identificación de correos y mensajes maliciosos.
  • Realizar respaldos periódicos y seguros de toda la información crítica.
  • Contratar servicios de pentesting para detectar vulnerabilidades en el sitio web y sistemas.
    Consulta https://ihack.red/fortaleza-digital/

¿Qué soluciones ofrece iHack.red para pequeños negocios que venden online?

  1. Auditorías de seguridad completas
    Para identificar brechas en tu infraestructura digital.
  2. Pentesting enfocado en sitios web y plataformas de venta.
  3. Blindaje de WhatsApp Business y redes sociales
    Evitando suplantaciones y clonaciones.
  4. Capacitación en prevención de fraudes digitales para dueños y equipos.
  5. Monitoreo continuo y alertas tempranas para ataques potenciales.
  6. Asistencia en recuperación de cuentas y procesos legales.
  7. Productos físicos de protección, como bolsas anti-interferencia para dispositivos móviles.
    Más información en https://ihack.red/bolsa-de-proteccion-de-senal-fundas-de-faraday/

¿Por qué invertir en ciberseguridad es vital para un pequeño negocio online?

Porque la confianza es la base de la relación con el cliente. Un incidente de seguridad puede:

  • Disminuir la reputación y las ventas.
  • Generar pérdidas económicas directas y multas legales.
  • Crear desconfianza en los canales digitales.
  • Llevar a la suspensión temporal o definitiva del negocio online.

En ciudades como Bogotá, Medellín, Cali y otras capitales regionales, los pequeños negocios que invierten en protección digital han logrado no solo prevenir ataques sino aumentar su competitividad y confianza del cliente.


Si quieres blindar tu pequeño negocio online y proteger tu reputación, iHack.red está listo para ayudarte con estrategias, tecnologías y acompañamiento especializado.

Contáctanos:
👉 https://ihack.red/fortaleza-digital/
👉 https://ihack.red/informatica-forense/

Categorías
Hacking y Ciberseguridad Comercial

¿Cómo protegerse de fraudes digitales en transacciones por banca en línea y aplicaciones móviles en Colombia?

En Colombia, el uso de la banca en línea y las aplicaciones móviles para realizar transacciones financieras ha crecido exponencialmente en los últimos años. Tanto personas naturales como empresas usan estas plataformas para pagos, transferencias y manejo de cuentas bancarias. Sin embargo, este crecimiento también ha traído un aumento en fraudes digitales, ataques y robos de identidad que pueden afectar gravemente las finanzas y la confianza en los servicios digitales.

Los fraudes en banca digital son uno de los delitos cibernéticos que más impacto tienen en usuarios colombianos, especialmente en ciudades como Bogotá, Medellín, Cali y Barranquilla, donde la adopción de tecnología financiera (FinTech) es alta.

¿Cuáles son los fraudes digitales más comunes en banca en línea y apps móviles?

  1. Phishing financiero
    Correos, SMS o mensajes en redes sociales que simulan ser del banco, solicitando datos sensibles o códigos de seguridad.
  2. Sim swapping (clonación de SIM)
    Robo del número telefónico para interceptar códigos de autenticación de doble factor y acceder a cuentas.
  3. Malware y troyanos bancarios
    Software malicioso instalado en dispositivos que registra teclas o intercepta información bancaria.
  4. Ataques de ingeniería social
    Engaños para convencer al usuario de entregar claves, tokens o información confidencial.
  5. Falsos sitios web y apps fraudulentas
    Que imitan a bancos o servicios financieros para robar datos o dinero.
  6. Transferencias no autorizadas
    Mediante el acceso remoto o vulnerabilidades en sistemas.

¿Qué hacer si detectas una transacción sospechosa o un posible fraude?

  1. Contactar inmediatamente a la entidad bancaria
    Para bloquear la cuenta o transacciones y reportar el incidente.
  2. No responder a mensajes sospechosos ni proporcionar datos personales o códigos.
  3. Denunciar ante las autoridades colombianas y la Superintendencia Financiera.
  4. Realizar un análisis forense digital si usas dispositivos o redes empresariales comprometidas.
    Más en https://ihack.red/informatica-forense/
  5. Cambiar todas las contraseñas y activar autenticación multifactor con apps de confianza.

¿Cómo prevenir fraudes en banca en línea y apps móviles?

  • Nunca compartir claves ni códigos de seguridad, ni por teléfono ni por mensajes.
  • Verificar siempre la URL y autenticidad de sitios web y aplicaciones.
  • Instalar aplicaciones oficiales solo desde tiendas autorizadas.
  • Mantener actualizados los dispositivos y apps financieras.
  • Usar redes seguras, evitando Wi-Fi públicas para transacciones.
  • Activar doble factor de autenticación con aplicaciones como Google Authenticator o Authy.
  • Revisar periódicamente los movimientos bancarios para detectar irregularidades.
  • Utilizar bolsas de protección de señal para dispositivos en espacios públicos si se trabaja con información financiera sensible.
    Más en https://ihack.red/bolsa-de-proteccion-de-senal-fundas-de-faraday/
  • Capacitarse y formar al equipo sobre ciberseguridad financiera.

¿Qué servicios ofrece iHack.red para proteger transacciones financieras digitales?

  1. Auditoría de seguridad en dispositivos y redes empresariales.
  2. Simulacros de phishing y campañas de concientización.
  3. Pentesting en apps móviles y plataformas digitales de pago.
    Consulta https://ihack.red/fortaleza-digital/
  4. Consultoría en implementación de autenticación segura y cifrado.
  5. Respuesta inmediata y análisis forense ante incidentes financieros digitales.

¿Por qué es esencial protegerse contra fraudes financieros digitales en Colombia?

Porque las pérdidas económicas directas y la exposición de información sensible pueden impactar no solo a personas sino también a pequeñas, medianas y grandes empresas, afectando su operación y reputación.

En ciudades como Bogotá, Medellín y Cali, la ciberseguridad financiera es una prioridad para garantizar confianza y continuidad en los negocios y servicios personales.


Si deseas proteger tus transacciones financieras y evitar fraudes digitales, iHack.red tiene la experiencia y tecnología para blindar tus operaciones.

Contáctanos:
👉 https://ihack.red/fortaleza-digital/
👉 https://ihack.red/informatica-forense/

Categorías
Hacking y Ciberseguridad Comercial

¿Cómo pueden protegerse los freelancers en Colombia que usan WhatsApp e Instagram para trabajar frente a fraudes digitales y suplantación?

En Colombia, miles de freelancers, diseñadores gráficos, community managers, coaches, terapeutas y pequeños comerciantes usan diariamente WhatsApp e Instagram como canales principales para ofrecer sus servicios y productos. Estas plataformas son accesibles, directas y económicas, pero también son un terreno fértil para ciberdelincuentes que buscan suplantar identidades, robar dinero o información sensible.

La vulnerabilidad no está en la herramienta, sino en la falta de medidas de seguridad y conocimiento sobre los riesgos digitales reales que enfrentan.

¿Por qué los freelancers son blancos fáciles para fraudes digitales?

  • No suelen tener áreas de TI ni asesoría profesional en seguridad.
  • Usan sus celulares personales para todo, sin protección avanzada.
  • Manejan pagos y contratos digitales sin sistemas formales o cifrados.
  • A veces aceptan solicitudes de amistad, mensajes o enlaces sin verificar.
  • Trabajan con clientes nuevos y desconocidos, lo que abre puertas a engaños.
  • No cuentan con respaldo de datos ni planes de contingencia ante ataques.

En ciudades como Bogotá, Medellín, Cali, e incluso en zonas rurales con conectividad, se reportan ataques crecientes como:

  • Suplantación de cuentas de WhatsApp Business para pedir anticipos falsos.
  • Phishing vía Instagram con mensajes que llevan a páginas falsas para robar credenciales.
  • Robo o clonación del número telefónico (SIM swapping).
  • Instalación de malware mediante archivos recibidos de clientes.
  • Extorsión y amenazas tras hackeo de cuentas.

¿Qué hacer si un freelancer descubre que su WhatsApp o Instagram fue hackeado?

  1. No borrar ni modificar nada inmediatamente
    Preservar los mensajes, pruebas de pagos o chats ayuda a rastrear al atacante.
  2. Contactar soporte de la plataforma para reportar el hackeo
    Instagram y WhatsApp tienen procesos para recuperar cuentas, pero pueden ser largos y confusos.
    En iHack.red apoyamos con asesoría para acelerar este proceso.
  3. Denunciar ante las autoridades colombianas
    La Fiscalía tiene unidades especializadas en delitos informáticos, pero requieren evidencia técnica.
  4. Solicitar una investigación forense digital
    Un perito puede identificar cómo entraron, qué información se comprometió y cómo protegerte en el futuro.
    Más en https://ihack.red/informatica-forense/
  5. Avisar a tus clientes y contactos que tu cuenta fue vulnerada
    Para que no caigan en posibles fraudes hechos con tu identidad.

¿Cómo prevenir estos ataques siendo freelancer?

  • Activa la verificación en dos pasos en WhatsApp e Instagram con apps de autenticación, no con SMS.
  • Usa contraseñas fuertes y únicas para todas tus cuentas.
  • No abras enlaces o archivos de remitentes desconocidos o sospechosos.
  • Realiza respaldos periódicos de tus conversaciones y contenidos importantes.
  • Evita usar redes Wi-Fi públicas sin protección (VPN).
  • Utiliza bolsas de protección de señal para tu celular si trabajas en espacios públicos o coworkings.
    https://ihack.red/bolsa-de-proteccion-de-senal-fundas-de-faraday/
  • Mantén actualizado tu sistema operativo y aplicaciones.
  • No compartas datos sensibles ni pagos fuera de plataformas seguras.

¿Qué servicios ofrece iHack.red para freelancers que quieren proteger su negocio digital?

  1. Auditoría de seguridad digital personalizada
    Revisamos tus perfiles, dispositivos y accesos para identificar riesgos.
  2. Pentesting para tus redes sociales y correos
    Simulamos ataques para mostrar vulnerabilidades y te ayudamos a corregirlas.
    Más en https://ihack.red/fortaleza-digital/
  3. Capacitación en prevención de fraudes digitales
    Para que entiendas qué técnicas usan los atacantes y cómo evitar caer.
  4. Respuesta rápida y forense digital ante incidentes
    Te acompañamos en la recuperación y denunciación legal si sufres un ataque.
  5. Protocolos y recomendaciones para proteger tus datos y los de tus clientes.

¿Por qué es importante para un freelancer contar con apoyo profesional en ciberseguridad?

Porque la pérdida o robo de una cuenta puede significar:

  • Pérdida de ingresos al no poder atender clientes.
  • Daño a la reputación profesional.
  • Robo de información confidencial de clientes.
  • Extorsiones o fraudes que comprometen tu negocio.

En Colombia, la ciberseguridad para freelancers es una necesidad urgente y un factor diferencial para competir con confianza.


Si eres freelancer y quieres blindar tu presencia digital, iHack.red tiene las soluciones y experiencia para apoyarte. Contáctanos y protégete con expertos.

👉 https://ihack.red/fortaleza-digital/
👉 https://ihack.red/informatica-forense/

Categorías
Uncategorized

Reversing de programas en Go

En esta ocasión estaremos viendo diferentes herramientas que nos facilitarán la tarea de realizar reversing a programas en Go

¿Por qué es más complicado realizar reversing a programas en GO?

Son varios los factores que dificultan la tarea a los reversers cuando se trata de realizar reversing a los programas en Go como por ejemplo Los programas en GO están enlazados estáticamente (Statically-Linked) es decir que este tendrá incluidos todas las dependencias necesarias para que este funcione. Esto aumenta el tamaño de los mismos, y si abonado a esto no se tienen los símbolos será aún más complicado entender la relación y funcionamiento de las diferentes funciones y podríamos estar analizando código irrelevante para nuestro análisis (código interno de Go). Cuando realizamos reversing a archivos Go sin símbolos no tenemos información tal como los nombres de las variables y funciones con lo que nos dificulta la tarea de entender el propósito de las diferentes funciones y variables además de perdernos fácilmente en las funciones agregadas por Go.

Otra cosa particular de los programas en Go es que las strings no están null terminated en lugar están colocadas pegadas unas con las otras y cuando una función requiere una string se le pasa el puntero y el tamaño de la misma.

En Go Seguir los argumentos y los valores de retorno es más difícil que en programas por ejemplo de c o c++

Realizando pruebas en Go

En esta parte procederemos a compilar un programa en Go y nos dispondremos a analizar el desensamblado con el objetivo de resaltar las diferencias de los programas en Go con otros lenguajes e ilustrar las dificultades que podemos tener a la hora de analizar los mismos

El código que estaremos analizando es el siguiente

package main

import "fmt"

func main() {
    var a int
    var b int
    var res int

    fmt.Println("Ingrese el primer numero : ")
    fmt.Scan(&a)
    fmt.Println("Ingrese el segundo numero : ")
    fmt.Scan(&b)
    res = suma(a, b)
    fmt.Println("La suma es : ", res)
}

func suma(a, b int) int {
    return a + b
}

Como podemos ver es un sencillo programa que pide dos números e imprime el resultado de la suma de los dos números, procedamos a ver el desensamblado del programa compilado con símbolos

Como vemos en la imagen la función carece del prólogo clásico de las funciones en c o c++ en lugar de eso tiene una comparación y un salto a llamar a runtime_morestack. De esta manera inicializan la mayoría de las funciones en GO en caso de ser necesario allocara más stack en runtime. El código que a nosotros nos concierne es el código escrito por el usuario así que esto lo podemos pasar por alto

Llama a runtime_newobject al parecer para allocar espacio para nuestros dos enteros

Luego llama a fmt_Fprintln pero el paso de argumentos no es tan claro como lo es en otros lenguajes. Coloca en una parte del stack “Ingrese el primer numero”, en ebx tiene os_Stdout en rax tiene File io writer. Pero depurando nos damos cuenta que lo que hace es imprimir “ingrese el primer numero”

Luego llama a fmt_Fscan en rax tiene file io reader, en rbx tiene os_Stdin y en determinada posición del stack coloca var_70 que es uno de nuestras variables enteras creadas con runtime_newobject y si depuramos nos damos cuenta que escribe en var_70 el numero leído con fmt_Fscan

Imprime ingrese el segundo numero

Lee nuestro segundo numero y lo almacena en var_78

Los suma

Y por último imprime el resultado de la suma

Como nos hemos dado cuenta en este ejemplo es que muchas veces seguir las variables, argumentos y valores de retorno en go puede llegar a ser más complicado que en otros lenguajes, pero podemos ayudarnos de la documentación de go la cual es bastante completa y asistirnos de la depuración

Análisis de programas en Go sin símbolos

En esta parte procederemos a compilar el ejemplo anterior pero esta vez sin símbolos y veremos una herramienta que nos ayudara en el análisis de programas Go cuando estos carecen de símbolos.

Abramos el ejemplo en ida

Como podemos ver en la imagen tenemos 1128 funciones y ninguna tiene nombre o alguna pista si es interna de go o creada por el usuario. Si empezamos a realizar el reversing así va a ser demasiado tedioso.

Gracias a AlphaGolang de sentinel labs esto no tiene que ser así. AlphaGolang es una serie de scripts para idapython que te permiten entre otras cosas recuperar la información de los símbolos, veamos esta serie de scripts en acción

  1. Recrear la tabla pcln

La tabla pcln es una tabla que contiene información sobre las funciones del programa incluyendo los nombres. El primer script lo que hace es recrear dicha tabla

Aquí tenemos los segmentos del programa ejemplo antes de ejecutar el primer script

Ejecutamos el primer script

Y este es el resultado el script crea un segmento que contiene la información de esta tabla

2. Descubrimiento de funciones y renombrado

El siguiente script lo que hace es renombrar las funciones del programa

Estas son las funciones antes de ejecutar el segundo script

Y este es el resultado luego de ejecutar el script. Como vemos ha renombrado la gran mayoría de funciones ahorrándonos un gran trabajo sin embargo no todas fueron renombradas

3. El tercer script organiza las funciones en carpetas, pero por una razón la cual desconozco no funciona en mi maquina

4. El cuarto script arreglas las referencias a las strings

5. El quinto y ultimo script comenta en todas las llamadas a newobject el tipo de objeto

Conclusión

La ingeniería inversa de programas en go puede llegar a tener una mayor dificultad que la ingeniería inversa a otros lenguajes, pero existen Scripts y herramientas que hacen que el proceso de reversing sea mas llevadero

Categorías
Uncategorized

Reversing

Hola amigos en esta ocasión estaremos hablando de la ingeniería inversa, aprenderemos que es, resolveremos las dudas más comunes y aprenderemos que es lo necesario para iniciarse en este arte

¿Qué es el reversing?

El reversing o la ingeniería inversa es el proceso de tomar un producto final y obtener información sobre su funcionamiento y\o como fue realizado, existen varios tipos de reversing como, por ejemplo, reversing de hardware, software, mecánico etc. en este artículo nos enfocaremos en la ingeniería inversa de software

¿Para qué se usa el reversing?

El reversing de software se utiliza en muchas áreas diversas, como por ejemplo en análisis de malware, para conocer el funcionamiento y las acciones llevadas a cabo por el mismo con el objetivo de crear las medidas de protección necesarias. También es utilizado en el área de detección de vulnerabilidades, en esta se utiliza la ingeniería inversa para identificar el código con fallas de seguridad y crear exploits que aprovechan esas vulnerabilidades descubiertas. Otros usos que se le pueden dar al reversing son, recuperar código perdido, extender funcionalidades, descifrar algoritmos criptográficos, descifrar protocolos, y también es utilizado en el cracking de software para retirar las medidas de protección del software, y retirar las limitaciones

¿Es el reversing Legal?

El reversing es legal si el producto sometido a ingeniería inversa fue obtenido de manera legal y se es el propietario del mismo, aunque esto puede variar dependiendo de la legislación del país. también es legal realizar ingeniería inversa de malware.

Realizar reversing a determinado software con el objetivo de quitarle las medidas de seguridad y limitaciones para poder usarlo “Full”, es ilegal, a esto se le conoce como cracking

¿Cómo iniciarse en reversing?

Para iniciarse en reversing es muy útil tener una base de programación, aunque esto no debe ser impedimento para empezar, se puede aprender los conceptos de programación conforme se avanza, es necesario conocer las instrucciones más comunes del código ensamblador para la arquitectura objetivo, si se realiza reversing de códigos interpretados es necesario conocer esos lenguajes. Algo muy importante es la práctica, para practicar de manera legal se pueden utilizar crackmes que son programas destinados para aprender técnicas de ingeniería inversa, existen muchos crackmes y de muchos niveles desde principiante hasta algunos muy avanzados.

También existen cursos y comunidades como Crackslatinos que es una gran comunidad donde siempre están dispuestos a darte una mano

¿Cuáles son las herramientas?

A la hora de realizar reversing nos podemos ayudar de muchas herramientas que nos asistirán en el proceso de ingeniería inversa, entre esas herramientas tenemos Desensambladores, decompiladores, debuggers, editores hexadecimales, y otras herramientas útiles que nos asisten en la labor

Desensambladores

Los desensambladores son programas que se encargan de traducir el código maquina a código ensamblador

Debuggers

Los debuggers o depuradores son programas en los cuales podemos ver paso a paso las instrucciones del programa (muchas veces en ensamblador), podemos parar en cualquier punto del programa, editar el flujo de ejecución del programa, editar las instrucciones entre un abanico de posibilidades, sin duda una de las herramientas esenciales a la hora de hacer reversing

Decompiladores

Los decompiladores son herramientas que a partir de un código compilado realizan el proceso de convertir el código maquina a seudocódigo C, este proceso no es perfecto y nunca se recupera el código original sino una aproximación

Editores Hexadecimales

Los editores hexadecimales son programas que nos permiten editar archivos binarios

Detectores de packers

Este tipo de herramientas nos muestran si el programa se encuentra protegido por un packer y que packer información que será de mucha utilidad

Algunas herramientas frecuentemente utilizadas

En este apartado veremos una lista de herramientas frecuentemente utilizadas y su objetivo

IDA

The interactive disassembler es una herramienta super completa para realizar tanto análisis estático como dinámico, esta cuenta con desensamblador, decompilador, debugger, sumado a la capacidad de renombrar variables, crear estructuras crear scripts para automatizar procesos y muchas otras cosas que nos facilitan el análisis. Esta herramienta cuenta tanto con versión gratuita (IDA freeware), como versión de pago

x64dbg

x64dbg es un debugger que soporta debugging tanto de x64 con x32, esta herramienta soporta también un lenguaje de scripting similar al ensamblador

Process Explorer

Esta herramienta que hace parte de sysinternal suite es una herramienta que nos permite ver los procesos en ejecución e información adicional como los handles, las dlls procesos hijos entre otra información

Process Monitor

Esta herramienta también de sysinternal suite nos permite monitorizar las acciones realizadas por un proceso como por ejemplo esta herramienta registrará si el proceso manipula el registro, si crea o modifica archivos entre otras acciones, esta cuenta con una serie de filtros que nos ayudan a encontrar más fácilmente información especifica

WireShark

Esta herramienta la cual es un packet analyzer nos permite capturar los paquetes enviados y recibidos y nos permite filtrar y ver la información de cada paquete

HxD

HxD es un editor hexadecimal bastante usado este nos permite modificar archivos binarios

CFF explorer

Esta herramienta nos permite ver y editar el contenido de archivos portable ejecutable, que es el formato de archivo de los ejecutables de Microsoft Windows

RegShot

Esta herramienta te permite tomar un snapshot del estado actual del registro y uno después de haber ejecutado el software analizado con el objetivo de ver qué cambios sufrió el registro

Palabras Finales

La ingeniería inversa de software es un área que requiere practica y dedicación para dominarla. Pero una vez aprendidas las bases el proceso es más llevadero

Categorías
Uncategorized

Introducción a ensamblador

Cuando nosotros escribimos nuestro código fuente en un lenguaje de alto nivel este al ser compilado es traducido a código maquina el cual es ejecutado por el procesador. Cuando realizamos ingeniería inversa tomamos un ejecutable ya compilado y realizamos el desensamblado del mismo para proceder con el análisis.

¿Qué es desensamblar?

Desensamblar es el proceso de traducir el código de máquina de un programa en lenguaje ensamblador. Es decir, el proceso de convertir el código de máquina en una representación legible por humanos, que es más fácil de entender y analizar que el código de máquina.
Un desensamblador toma el archivo ejecutable del programa y lo analiza para identificar las instrucciones de código de máquina y su correspondiente representación en lenguaje ensamblador. El resultado es un archivo de texto legible por humanos que muestra el código ensamblador del programa.
Es importante destacar que el proceso de desensamblar no siempre produce un código ensamblador idéntico al código fuente original, ya que el código de máquina puede ser optimizado y reordenado por el compilador durante la compilación. Por lo tanto, el código ensamblador producido por el desensamblador puede requerir cierta interpretación y análisis para comprender completamente su funcionamiento.

¿Qué es el lenguaje ensamblador?

El ensamblador (también conocido como «Assembly» en inglés) es un lenguaje de programación de bajo nivel utilizado para escribir programas que operan directamente en la arquitectura de una computadora. El ensamblador utiliza una sintaxis que está muy cerca del lenguaje de máquina, lo que permite al programador escribir instrucciones que se traducen directamente en códigos de máquina ejecutables por el procesador.

Antes de ver las instrucciones en ensamblador debemos conocer lo que son los registros, Los registros del procesador son pequeñas áreas de almacenamiento en la CPU que se utilizan para realizar operaciones aritméticas y lógicas, y para almacenar temporalmente datos y direcciones de memoria.
Existen varios registros entre los cuales destacamos: registros de propósito general, registros de coma flotante y registros de propósito especifico.

Registros de propósito General (GPR)

Los registros de propósito general son utilizados para almacenar temporalmente datos y direcciones de memoria. Algunos de estos cumplen propósitos específicos en determinadas instrucciones.
Entre los registros de propósito general para la arquitectura de 64 bits tenemos los registros RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP y los registros desde el R8 al R15

Registros de punto Flotante

Los registros de punto flotante son utilizados para realizar operaciones matemáticas con números de punto flotante en la arquitectura de 64 bits tenemos los registros de la serie XMM, YMM y ZMM

Registros de Propósito Especifico

Entre los registros de propósito especifico tenemos los registros RFLAGS y RIP. El registro RIP es utilizado para contener la dirección de la próxima instrucción que se va a ejecutar y el registro RFLAGS es utilizado para contener el estado de la CPU y contiene diferentes banderas que indican el resultado de las operaciones entre otras cosas

Si por ejemplo el resultado de una resta nos da cero el registro RFLAGS colocara la bandera que indica que el resultado es cero (Zero Flag) a 1 indicando que el resultado de la operación anterior fue cero. O si por ejemplo el resultado de la resta da un numero negativo la bandera del registro RFLAGS que indica que el resultado es un numero negativo (Sign Flag) será colocada a 1 en caso contrario es decir el resultado dio un numero positivo la bandera que indica que el resultado es negativo será colocada a 0

Instrucciones en ensamblador

Las instrucciones del lenguaje ensamblador son el conjunto de instrucciones que son interpretadas directamente por el procesador estas las podemos clasificar en, instrucciones de movimiento de datos, instrucciones de comparación, instrucciones aritméticas, instrucciones de control de flujo, instrucciones de llamada y retorno, instrucciones de manejo de pila, instrucciones lógicas y de desplazamiento de bits

instrucciones de movimiento de datos

Las instrucciones de movimiento de datos nos permiten mover desde la fuente al destino estas pueden ser de movimiento incondicional o movimiento condicional

Instrucciones de movimiento incondicional

Las instrucciones de movimiento incondicional son instrucciones que se encargan de mover datos desde la fuente al destino incondicionalmente es decir que no tienen en cuenta los FLAGS o banderas antes de mover entre estas instrucciones tenemos LEA, MOV y XCHG

MOV

La instrucción MOV nos permite mover datos desde fuente a destino en caso de que la fuente se encuentre entre corchetes (por ejemplo, modo de direccionamiento indirecto) se calculará la dirección y se moverá el contenido de la dirección a la fuente

sintaxis

mov destino, origen

ejemplo

mov eax, 1 ; mueve el valor 1 al registro EAX
mov ebx, eax ; mueve el valor de EAX a EBX
mov [memoria], eax ; mueve el valor de EAX a la dirección de memoria indicada
mov al, [ebx] ; mueve el byte almacenado en la dirección apuntada por EBX al registro AL
mov dword ptr [eax], 0 ; mueve el valor 0 a la dirección de memoria indicada por el registro EAX

LEA

La instrucción Lea (Load effective Address) es una instrucción utilizada para calcular la dirección efectiva, esta instrucción va a calcular la dirección del segundo operando (el operando fuente) y lo va a almacenar en el primer operando (destino) es decir calculará la dirección contenida entre corchetes y moverá la dirección no el contenido de la dirección

sintaxis

lea registro, dirección_de_memoria

ejemplo

lea ebx, [memoria] ; carga la dirección de memoria en EBX
lea eax, [ebx+4] ; carga la dirección de memoria desplazada por 4 bytes de la dirección almacenada en EBX en EAX
lea edx, [ebx+eax*2] ; carga la dirección de memoria desplazada por el doble del valor almacenado en EAX desde la dirección almacenada en EBX en EDX

XCHG

Exchange Esta instrucción intercambia los contenidos de registros/memoria con registros

sintaxis

xchg destino, origen

ejemplo

xchg eax, ebx ; intercambia el contenido de los registros EAX y EBX

MOVSX

La instrucción MOVSX (move sign extended) es una instrucción que mueve desde una fuente más pequeña a un destino más grande y el espacio sobrante lo rellena con el bit de signo de la fuente

sintaxis

movsx registro_destino, origen

ejemplo

movsx eax, byte ptr [memoria] ; mueve el byte almacenado en la dirección de memoria indicada a EAX y lo extiende a 32 bits
movsx ebx, word ptr [memoria] ; mueve la palabra almacenada en la dirección de memoria indicada a EBX y lo extiende a 32 bits
movsx edx, al ; extiende el valor del registro AL (8 bits) a 32 bits y lo mueve a EDX 

MOVZX

La instrucción MOVZX (move zero extended) es una instrucción que mueve desde una fuente más pequeña (la cual puede ser un Word o byte) a un destino más grande y el espacio sobrante lo rellena con ceros

sintaxis

movzx registro_destino, origen

ejemplo

movzx eax, byte ptr [memoria] ; mueve el byte almacenado en la dirección de memoria indicada a EAX y lo extiende a 32 bits con ceros
movzx ebx, word ptr [memoria] ; mueve la palabra almacenada en la dirección de memoria indicada a EBX y lo extiende a 32 bits con ceros
movzx edx, al ; extiende el valor del registro AL (8 bits) a 32 bits con ceros y lo mueve a EDX

Instrucciones de movimiento condicional

Las instrucciones de movimiento condicional son instrucciones que verifican las banderas de estado o flags antes de mover en caso de que la condición necesaria para el movimiento no se cumpla es decir las banderas que esta verifica no están seteadas el movimiento no se realizará

instrucciones de comparación

las instrucciones de comparación realizan la comparación de dos operandos sin modificar ninguno de ellos, pero actualizando las banderas de estado dependiendo del resultado de la comparación
entre las instrucciones de comparación tenemos TEST y CMP

TEST

La instrucción test realiza la operación AND entre el primer y segundo operando sin alterar ninguno, pero modificando las banderas de estado dependiendo del resultado de la operación AND

sintaxis

test destino, origen

ejemplo

test eax, ebx ; realiza la operación AND lógica entre EAX y EBX y establece las banderas según el resultado
test al, 0xFF ; realiza la operación AND lógica entre el registro AL y el valor hexadecimal 0xFF, estableciendo las banderas según el resultado
test [memoria], 0x10 ; realiza la operación AND lógica entre el valor almacenado en la dirección de memoria indicada y el valor hexadecimal 0x10, estableciendo las banderas según el resultado

CMP

La instrucción CMP (Compare) realiza una resta entre el primer y segundo operando (operando1-operando2) actualiza las banderas de estado y no modifica ninguno de los operandos

sintaxis

cmp operando1, operando2

ejemplo

cmp eax, ebx ; compara los valores de los registros EAX y EBX y establece las banderas según el resultado
cmp al, 0xFF ; compara el valor del registro AL con el valor hexadecimal 0xFF y establece las banderas según el resultado
cmp [memoria], ebx ; compara el valor almacenado en la dirección de memoria indicada con el valor del registro EBX y establece las banderas según el resultado

instrucciones aritméticas

las instrucciones aritméticas como su nombre lo indica nos permiten realizar operaciones aritméticas tales como la suma, resta, multiplicación o división

ADD

La instrucción ADD suma el operando fuente más el operando de destino y el resultado de la suma queda almacenado en el operando de destino

sintaxis

add destino, origen

ejemplo

add eax, ebx ; suma el valor del registro EBX al valor del registro EAX y almacena el resultado en EAX
add [memoria], eax ; suma el valor del registro EAX al valor almacenado en la dirección de memoria indicada y almacena el resultado en esa dirección de memoria
add al, 0x10 ; suma el valor hexadecimal 0x10 al valor del registro AL y almacena el resultado en AL

SUB

La instrucción SUB le resta al operando de destino la fuente (destino-fuente) y el resultado de la resta es almacenado en el operando de destino

sintaxis

sub destino, origen

ejemplo

sub eax, ebx ; resta el valor del registro EBX del valor del registro EAX y almacena el resultado en EAX
sub [memoria], eax ; resta el valor del registro EAX del valor almacenado en la dirección de memoria indicada y almacena el resultado en esa dirección de memoria
sub al, 0x10 ; resta el valor hexadecimal 0x10 del valor del registro AL y almacena el resultado en AL

MUL

Esta instrucción realiza la multiplicación sin signo del operando con el registro RAX y el resultado de la multiplicación es almacenado en RDX:RAX (la parte alta en RDX y la parte baja en RAX)

sintaxis

mul operando

ejemplo

mul eax ; multiplica el valor del registro EAX por el valor del registro EAX y almacena los 32 bits más significativos del resultado en EDX y los 32 bits menos significativos en EAX
mul ebx ; multiplica el valor del registro EBX por el valor del registro EAX y almacena los 32 bits más significativos del resultado en EDX y los 32 bits menos significativos en EAX
mul dword [memoria] ; multiplica el valor almacenado en la dirección de memoria indicada por el valor del registro EAX y almacena los 32 bits más significativos del resultado en EDX y los 32 bits menos significativos en EAX

IMUL

La instrucción IMUL realiza la multiplicación de números con signo y esta puede tener uno dos o tres operandos cuando esta tiene un operando se comporta similar a MUL pero en este caso multiplicando con signo el registro RAX por el operando y el resultado se almacena en el registro RDX:RAX. Con dos operandos multiplica la fuente por el destino y el resultado se almacena en la fuente. Con tres operandos multiplica el segundo operando con el tercer operando el cual debe ser una constante y el resultado lo almacena en el primer operando

sintaxis

imul operando
imul destino, operando
imul destino, operando, const

ejemplo

imul eax, ebx ; multiplica el valor del registro EBX por el valor del registro EAX y almacena el resultado en EAX
imul ecx, dword [memoria] ; multiplica el valor almacenado en la dirección de memoria indicada por el valor del registro ECX y almacena el resultado en ECX
imul rax, rbx ; multiplica el valor del registro RBX por el valor del registro RAX y almacena el resultado en RAX

DIV

Esta instrucción realiza la división de números sin signo de los registros RDX:RAX (dividendo) entre el operando (divisor), el resultado es almacenado en el registro RAX y el residuo en el registro RDX

sintaxis

div operando

ejemplo

div ebx ; divide el valor del registro EDX:EAX (valor de 64 bits) por el valor del registro EBX y almacena el cociente en EAX y el resto en EDX
div dword [memoria] ; divide el valor almacenado en la dirección de memoria indicada por el valor del registro EAX y almacena el cociente en EAX y el resto en EDX

IDIV

Esta instrucción realiza la división con signo de los registros RDX:RAX (dividendo) entre el operando (divisor), el resultado es almacenado en el registro RAX y el residuo en el registro RDX

sintaxis

idiv operando

ejemplo

idiv ebx ; divide el valor del registro EDX:EAX (valor de 64 bits) por el valor del registro EBX y almacena el cociente en EAX y el resto en EDX
idiv dword [memoria] ; divide el valor almacenado en la dirección de memoria indicada por el valor del registro EAX y almacena el cociente en EAX y el resto en EDX

instrucciones de control de flujo

estas instrucciones nos permiten alterar el flujo del programa entre estas instrucciones tenemos las instrucciones de salto incondicional y salto condicional

instrucciones de salto incondicional

JMP

La instrucción JMP salta a la dirección de memoria especificada por el operando incondicionalmente es decir salta sin tener en cuenta las banderas o FLAGS

sintaxis

jmp destino

ejemplo

etiqueta:
; instrucciones
jmp etiqueta ; salta de vuelta a la etiqueta
; más instrucciones

Instrucciones de salto condicional

Las instrucciones de salto condicional verifican determinadas banderas y si la condición se satisface es decir las banderas que chequea están seteadas salta a la dirección indicada por el operando, en caso contrario (la condición no se satisface) la instrucción no salta

instrucciones de llamada y retorno

las instrucciones de llamada y retorno nos permiten entrar y retornar de las funciones

CALL

La instrucción CALL salta a la dirección apuntada por el operando, pero antes coloca en el stack la dirección de retorno es decir la dirección siguiente a donde fue ejecutada

sintaxis

call subrutina

ejemplo

subrutina:
    ; instrucciones
    ret ; retorna de la subrutina

call subrutina ; llama a la subrutina indicada y salta a la dirección de memoria donde comienza la subrutina

RET

La instrucción RET saltará a la dirección de retorno es decir la dirección colocada en el stack por la instrucción CALL

sintaxis

ret

ejemplo

subrutina:
    ; instrucciones
    ret ; retorna de la subrutina

call subrutina ; llama a la subrutina indicada y salta a la dirección de memoria donde comienza la subrutina 

instrucciones de manejo de pila

las instrucciones de manejo de pila nos permiten colocar y retirar valores de la pila o stack

PUSH

La instrucción PUSH coloca valores en el stack

sintaxis

push operando

ejemplo

push eax ; coloca el valor del registro eax en la pila
push 10 ; coloca el valor 10 en la pila
push dword [memoria] ; coloca el valor almacenado en la dirección de memoria "memoria" en la pila

POP

La instrucción POP retira valores del stack

sintaxis

pop destino

ejemplo

pop eax ; saca el valor de la cima de la pila y lo coloca en el registro eax
pop dword [memoria] ; saca el valor de la cima de la pila y lo coloca en la dirección de memoria "memoria"

instrucciones lógicas

Las instrucciones Lógicas nos permiten realizar operaciones lógicas entre las cuales tenemos AND, OR, NOT, XOR

AND

La instrucción AND nos permite realizar la operación lógica AND entre el operando destino y fuente y el resultado de esta operación es almacenado en el operando de destino

sintaxis

and destino, origen

ejemplo

and eax, ebx ; realiza la operación lógica "AND" entre los valores de los registros eax y ebx, y almacena el resultado en eax
and dword [memoria], 0xFF ; realiza la operación lógica "AND" entre el valor almacenado en la dirección de memoria "memoria" y la constante 0xFF, y almacena el resultado en la misma dirección de memoria

OR

La instrucción OR nos permite realizar la operación lógica OR entre el operando destino y fuente y el resultado de esta operación es almacenado en el operando de destino

sintaxis

or destino, origen

ejemplo

or eax, ebx ; realiza la operación lógica "OR" entre los valores de los registros eax y ebx, y almacena el resultado en eax
or dword [memoria], 0x7F ; realiza la operación lógica "OR" entre el valor almacenado en la dirección de memoria "memoria" y la constante 0x7F, y almacena el resultado en la misma dirección de memoria

NOT

Esta instrucción realiza la negación del operando

sintaxis

not destino

ejemplo

not eax ; realiza la operación lógica "NOT" en el valor del registro eax, y almacena el resultado en eax
not byte [memoria] ; realiza la operación lógica "NOT" en el valor almacenado en la dirección de memoria "memoria", y almacena el resultado en la misma dirección de memoria

XOR

La instrucción XOR nos permite realizar la operación lógica XOR entre el operando destino y fuente y el resultado de esta operación es almacenado en el operando de destino. Un uso frecuente de esta operación es colocar un registro a cero.

sintaxis

xor destino, origen

ejemplo

xor eax, eax ; coloca el registro eax a cero
xor eax, ebx ; realiza la operación lógica "XOR" entre los valores de los registros eax y ebx, y almacena el resultado en eax
xor byte [memoria], 0xff ; realiza la operación lógica "XOR" entre el valor almacenado en la dirección de memoria "memoria" y el valor 0xff, y almacena el resultado en la misma dirección de memoria

instrucciones de desplazamiento de bits

Las instrucciones de desplazamiento de bits como su nombre lo indica son utilizadas para desplazar bits, un uso muy frecuente es para manejar valores de campos de bits o para multiplicar o dividir entre potencias de 2

SHL y SAL

Las instrucciones SHL (Shift logical Left) y SAL (Shift artitmenical Left) desplazan os bits hacia la izquierda el número de veces indicado por la fuente, rellenando los nuevos lugares con ceros

sintaxis

shl destino, fuente
sal destino, fuente

ejemplo

mov eax, 0x00000001 ; mueve el valor hexadecimal 0x00000001 al registro eax
shl eax, 1 ; desplaza los bits en eax un bit a la izquierda
mov ebx, 0xffff0000 ; mueve el valor hexadecimal 0xffff0000 al registro ebx
sal ebx, 4 ; desplaza los bits en ebx cuatro bits a la izquierda, realizando un desplazamiento aritmético

desplazar hacia la izquierda equivale a multiplicar por una potencia de dos

SHR

La instrucción SHR (Shift logical Right) desplaza los bits hacia la derecha el número de veces indicado por la fuente, rellenando los nuevos lugares con ceros

sintaxis

shr destino, fuente

ejemplo

mov eax, 0x12345678 ; coloca el valor 0x12345678 en eax
shr eax, 4 ; desplaza 4 bits a la derecha

SAR

La instrucción SAR (Shift Aritmetical Right) desplaza los bits hacia la derecha el número de veces indicado por la fuente y rellena los nuevos lugares con el bit de signo que tenía el destino

sintaxis

sar destino, fuente

ejemplo

mov eax, 0xFFFF0000 ; coloca el valor 0xFFFF0000 en eax
sar eax, 16 ; desplaza 16 bits a la derecha

desplazar hacia la derecha equivale a dividir entre una potencia de dos

ROR y ROL

Las instrucciones ROR (Rotate right) y ROL (Rotate left) realizan una rotación de bits a la derecha e izquierda respectivamente

sintaxis

ror destino, fuente
rol destino, fuente

ejemplo

mov eax, 0x0F0F0F0F ; coloca el valor 0x0F0F0F0F en eax
ror eax, 8 ; rota los bits de eax 8 posiciones a la derecha
mov eax, 0x0F0F0F0F ; coloca el valor 0x0F0F0F0F en eax
rol eax, 8 ; rota los bits de eax 8 posiciones a la izquierda
Categorías
Uncategorized

GPT Custom knowledge con LangChain

Sean todos bienvenidos una vez más a este espacio, en esta ocasión estaremos explorando LangChain y estaremos viendo algunos conceptos y un ejemplo practico de su uso

¿Qué es LangChain?

LangChain es un open source framework para construir aplicaciones con LLM (Large languge models), esta permite enlazar LLM con otras fuentes de datos y permite al Modelo interactuar con su entorno

Ventajas de usar LangChain

LangChain ofrece varios componentes tales como, prompt template, models, chains, indexes, agents, que permiten generar aplicaciones mas complejas con LLM de una manera más fácil a continuación conoceremos algunos de estos componentes.

Models

Los modelos nos permiten conectar con Modelos como por ejemplo GPT4. hay dos tipos de modelos los cuales son Language models (Modelos de lenguaje) y Text Embedding Models

Language models (Modelos de lenguaje)

Los modelos de lenguaje nos permiten interactuar con modelos de lenguaje, así como su nombre indica, estos están subdivididos en dos subtipos LLM los cuales toman texto y retornan texto y ChatModels los cuales toman mensajes de chat y retornan mensajes de chat

Text Embedding Models

Esta clase de modelos toma texto como entrada y retorna un Embedding, la cual es una representación numérica de dicho texto

Prompts

Prompt se refiere al texto o a la entrada de nuestro modelo LangChain esta entrada puede ser construida por varios componentes LangChain ofrece PromptTemplate que son los responsables de construir las prompt estos permiten entre otras cosas crear prompts con determinado formato

from langchain.prompts import PromptTemplate, ChatPromptTemplate
string_prompt = PromptTemplate.from_template("tell me a joke about {subject}")
chat_prompt = ChatPromptTemplate.from_template("tell me a joke about {subject}")
string_prompt_value = string_prompt.format_prompt(subject="soccer")
chat_prompt_value = chat_prompt.format_prompt(subject="soccer")

Indexes

El uso más común que se le da a los indexes es extraer información relevante para los LLM los principales indexes están centrados alrededor de vector databases. LangChain cuenta con funcionalidades tales como Document loaders que permiten la carga de documentos, Text splitters que permiten dividir estos documentos en trozos más pequeños, vector stores el cual almacena documentos y sus embeddings asociados y retrievers que obtienen información relevante la cual puede ser combinada con LLM

Chains

Las cadenas nos permiten combinar múltiples componentes para crear aplicaciones. Tenemos cadenas que nos permiten por ejemplo responder preguntas, hacer resúmenes entre otras además podemos crear nuestras propias cadenas

Agents

Los agentes permiten a los LLM interactuar con su entorno por ejemplo podemos crear un agente que le permita al modelo realizar búsquedas por internet

Ejemplo de uso LangChain

A continuación, vamos a hacer un ejemplo de cómo podemos utilizar LangChain de manera práctica, lo que estaremos haciendo es tomar un documento PDF el cual va a ser la fuente de conocimientos externa, y procederemos a hacer preguntas a la IA y le estaremos pasando el documento como contexto

explicación de nuestro Código

El primer paso es importar todas las librerías necesarias

# -*- coding: utf-8 -*-
from transformers import GPT2TokenizerFast
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.chains.question_answering import load_qa_chain
from langchain.llms import OpenAI
import textract

Luego de importar las librerías tomamos nuestro PDF y le extraemos el texto con la función process

# convertimos el pdf a texto
doc = textract.process(r'C:\Users\HP\Desktop\chat_GPT\datos\Virus_Informaticos.pdf')

para que esta función funcione correctamente en nuestro Windows debemos tener instalado poppler y la ruta del mismo agregado al Path.

Lo siguiente que hacemos es guardar el texto que extraemos del PDF en un documento de texto y lo leemos

# guardamos el texto y reabrimos
with open('texto.txt', 'w',  encoding="utf-8") as f:
    f.write(doc.decode('utf-8'))

with open('texto.txt', 'r', encoding="utf-8") as f:
    text = f.read()

luego creamos una función para contar los tokens esta función la pasaremos como argumento a nuestro text splitter que será el encargado de dividir nuestro texto en trozos

# creamos una funcion para contar los tokens
tokenizer = GPT2TokenizerFast.from_pretrained("gpt2")

def count_tokens(text: str) -> int:
    return len(tokenizer.encode(text))

y dividimos el texto en trozos o chunks

# dividimos el texto en chunks
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size = 512,
    chunk_overlap  = 24,
    length_function = count_tokens,
)

chunks = text_splitter.create_documents([text])

después de esto creamos nuestra base de datos de vectores, para hacer esto primero obtenemos nuestro modelo para crear los embeddings y creamos la base de datos pasándole los chunks y el modelo de embedding a FAISS.from_documents

# obtenemos el embedding model
embeddings = OpenAIEmbeddings()

# creamos la database de vectores
db = FAISS.from_documents(chunks, embeddings)

luego de esto lo que hacemos es pedirle al usuario que realice una pregunta y obtenemos los fragmentos relacionados con la pregunta que hizo el usuario gracias a un similarity search

# realizamos la busqueda por similaridad
query = input("realiza tu pregunta: ")
docs = db.similarity_search(query)

por último, creamos nuestra cadena Question answering que nos permite hacer preguntas y obtener respuestas, esta cadena la obtenemos con la función load_qa_chain que recibe como argumentos el modelo y el tipo de cadena, en este caso el tipo de cadena es stuff, este tipo de cadenas se recibe nuestros docs obtenidos con el similarity search como contexto

# creamos un QA chain que nos permite hacer preguntas en base a nuestros documentos
chain = load_qa_chain(OpenAI(temperature=0), chain_type="stuff")

print(chain.run(input_documents=docs, question=query))

al ejecutar nuestro código podemos ver la respuesta que nos da el modelo

Esta información es basada en nuestro documento PDF

Conclusión

Hemos visto como usar LangChain y lo poderoso que es este framework, LangChain tiene funcionalidades ya definidas y la posibilidad de implementar o agregarle nuevas funcionalidades lo que lo hace ideal para crear aplicaciones con LLM

Categorías
Uncategorized

Debugging

¿Qué es el debugging?

Debugging o depuración es el proceso de encontrar bugs o errores en el programa, en este identificamos y aislamos las causas del error. Este puede llevase a cabo de diferentes maneras entre las cuales tenemos software testing, revisión del código o mediante herramientas como debuggers

¿Qué es un debugger?

Un debugger es una herramienta que nos permite depurar un programa en estos podemos ver instrucción por instrucción, alterar el flujo de ejecución, ver los valores de las distintas variables y editarlos, colocar puntos de interrupción o breakpoints. Los depuradores nos permiten ver cómo se comporta el programa mientras es ejecutado

Conociendo las partes de un debugger

En esta parte procederemos a conocer las diferentes partes que puede tener un debugger tomando como ejemplo un debugger muy utilizado llamado x64dbg, el objetivo de esta parte es familiarizarse no solo con este depurador sino entender las diferentes partes para tener un conocimiento general que nos puede servir para cualquier depurador. Algo a tener en cuenta es que algunas de las cosas incluidas en un depurador quizás no estén incluidas en otro, pero hay elementos que son comunes de depurador a depurador

Este es nuestro depurador, lo primero que haremos será cargar un archivo ejecutable para depurarlo, para hacer esto presionamos archivo->abrir

Entre las otras opciones que tenemos están vincular que nos permite depurar un proceso que se encuentra corriendo actualmente, cambiar el comando empleado que nos permite pasarle argumentos al proceso

Una vez cargado nuestro programa en el depurador este para por defecto en el breakpoint del sistema y nos rellenara las diferentes partes con distinta información que procederemos a aclararlos a continuación

Desensamblado

En esta parte se nos muestra el código ensamblador de nuestro ejecutable, en esta parte podemos ver las instrucciones que el programa va ejecutando, podemos colocar breakpoints en la dirección que queramos y también podemos alterar el flujo de ejecución del mismo

Registros

En esta parte podemos ver y modificar los valores de los diferentes registros incluyendo las banderas de estado

Variables Locales

En esta parte nos muestra las variables locales de la función que estamos depurando actualmente y también nos da la opción de seleccionar la convención de llamada de la función

Aclaraciones

En esta parte se nos mostraran aclaraciones como por ejemplo el contenido de un puntero

Volcado de memoria

En esta parte tenemos el volcado de memoria es decir el contenido de la memoria, esta parte la usamos cuando queremos ver el contenido de cierta zona de memoria

Stack

En esta parte tenemos el contenido del stack, que como sabemos es la zona destinada para guardar nuestras variables locales, argumentos, registros salvados entre otra información

En la pestaña breakpoints tenemos todos los breakpoints o puntos de interrupción que hemos colocado, por defecto el depurador nos coloca un breakpoint en el entry point del programa y nos aclara que parará una sola vez

En la pestaña mapa de memoria podemos ver las diferentes secciones del ejecutable, su dirección de inicio y final, así como también las secciones de las diferentes dlls, memoria reservada dinámicamente y los permisos de estas

En la pestaña pila de llamadas tenemos la pila de llamadas es decir las funciones que han sido llamadas para llegar a la función actual, de primero tenemos la función actual y bajando tenemos los callers

Una vez familiarizados con el debugger procederemos a aprender a como depurar nuestros programas, para esto debemos aprender a como tracear, también debemos aprender a colocar puntos de interrupción y los diferentes puntos de interrupción que tenemos a nuestra disposición, además debemos aprender a buscar referencias y otra información que nos puede ser de utilidad.

Con el objetivo de ilustrar esto procederemos a realizar el análisis del crackme de cruehead, en este articulo no veremos la solución del mismo solo lo tomaremos como ejemplo para aprender a usar nuestro depurador

El primer paso será abrir nuestro crackme en el depurador y una vez abierto nos parará por defecto en el breakpoint del sistema

si queremos cambiar este comportamiento lo podemos hacer en opciones->preferencias y en la pestaña eventos podemos seleccionar solamente el breakpoint en el punto de entrada o entry point, esto hará que el programa pare en el entry point

Resaltado en la imagen superior tenemos los comandos que nos permiten, reiniciar el programa, detenerlo, correrlo, pausarlo y tracearlo, procederemos a explicar cada uno a continuación

Reiniciar

Reinicia el proceso que está siendo depurado actualmente

Detener

Detiene el proceso que está siendo depurado actualmente

Ejecutar

Ejecuta el programa hasta que este finaliza o encuentra un breakpoint

Pausar

Pausa la ejecución del programa

Step into

Ejecuta la instrucción entrando a cada uno de los calls

Step over

Ejecuta la instrucción sin entrar a los calls, los calls se ejecutan por completo, pero no se muestra el código dentro de estos

Trace Into y Trace Over

Inicializar el traceado que lo que hace es ejecutar las instrucciones recordándolas y se detiene cuando se cumple determinada condición

Ejecutar hasta el retorno

Ejecuta el contenido de la función actual hasta que llega al fin de esta (el retorno)

Ejecutar hasta el código de usuario

Ejecuta todo el código del sistema y se detiene cuando llega nuevamente al código de usuario

Breakpoints

Los breakpoints o puntos de interrupción los utilizamos cuando queremos parar en determinada instrucción o código que nos interesa, existen varios tipos de breakpoints como lo son de memoria, de hardware y software

Memory Breakpoints

Los breakpoints de memoria nos permiten detener la ejecución del programa cuando se accede a determinada zona de memoria estos pueden parar en acceso ya sea para lectura o escritura, solo en lectura, solo en escritura o en ejecución

Hardware Breakpoints

Los hardware breakpoints son llevados a cabo mediante registros de depuración en el procesador podemos colocar un máximo de 4 breakpoints de este tipo y las condiciones de estos pueden ser de en acceso, en lectura, escritura o ejecución

Software Breakpoints

Este tipo de breakpoint lo colocamos cuando queremos parar en determinada instrucción, cuando colocamos este tipo de breakpoint el depurador cambia la instrucción por un int3 que hace que el programa se detenga ahí pero estos pueden llegar a ser detectados por el programa fácilmente, los breakpoints de software paran en ejecución pero x64dbg soporta breakpoints por software condicionales un ejemplo de esto puede ser parar si determinado registro tiene determinado valor como por ejemplo eax==0x1234

Retomando a el ejemplo del crackme lo primero que hacemos será correr el mismo en el debugger e intentar buscar referencias a cadenas que puedan ser de nuestro interés o también podemos parar en el momento en que se lee nuestro username y serial

Una vez abierto presionamos register

nos abre esta ventanita que nos pide nombre de usuario y serial coloquemos username y 12345

Nos abre esta ventanita que nos indica que fue invalido, tratemos de ver si encontramos referencias a esta string en el debugger y analizar el código en busca de la comparación que decide cuando mostrar o no esta ventanita

Presionamos en el área del desensamblado clic derecho buscar en->módulo actual->referencias a cadena

Vemos que tuvimos suerte y encontramos dos referencias a la cadena “no luck there, mate!” coloquemos un breakpoint en ambas direcciones

Ahí colocamos nuestros breakpoints en las dos referencias, y nos damos cuenta que en una de las referencias esta muy cerca una referencia a la cadena que puede ser nuestro chico bueno, nos ayudamos con un plugin llamado xAnalyzer, una vez instalado el plugin de a cuerdo a las instrucciones de github

Damos clic derecho xAnalyzer analyze module

Este plugin hace un gran trabajo resaltándonos el inicio de las funciones ciclos y demás, vemos que nuestra referencia a nuestra string “no luck there, mate!” es usada por un mensaje box en una función que empieza en 0x401362 y si nos fijamos en la otra referencia

Está dentro de otra función que empieza en 0x40137e esta función hace determinadas comparaciones y ciclos y si no le gusta nos manda al chico malo, ahora busquemos referencias a el código que llama a estas funciones, lo primero que haremos es en el inicio de cada una de estas funciones (me refiero a las funciones que llaman a nuestra cadena)

Posicionados en la dirección que queremos encontrar referencias damos clic derecho->encontrar referencias a-> dirección seleccionada

Nos dirigimos a la dirección y colocamos un breakpoint

Una vez hecho esto con las dos referencias reiniciamos nuestro programa

Colocamos un username y un serial y al dar ok se detiene en nuestro breakpoint

Una vez detenidos podemos ver que va a pasar nuestro username y nuestro serial a dos funciones, la función en la que le pasa el username es la función que realizaba unas comparaciones y bucles y si algo no le gustaba nos mostraba el mensaje de chico malo, al salir de estas funciones en la dirección 0x401241 realiza una comparación que si eax es igual a ebx llama a la función 0x40134d que si nos fijamos cual es

Nos damos cuenta que es la función que nos manda el cartel de felicitaciones, así que lo que haremos es forzar el salto para que siempre nos mande al cartel de felicitaciones a esto se le conoce como parchear

Posicionados sobre el salto decisivo damos clic derecho->ensamblar o presionamos espacio

Cambiaremos el je (salta si es igual) por un jmp (salta siempre)

Nos quedará así ahora presionamos aceptar, ahora para que los cambios se guarden presionamos clic derecho->parches

En la ventana que se nos abre le damos a aplicar el parche

Nos abrirá el explorador de archivos

Guardamos la versión modificada con un nombre cualquiera y procedemos a probarla

Abrimos la versión modificada y colocamos un username y serial cualquiera

Y vemos que al presionar ok ¡nos muestra el mensaje de felicitaciones!

Esto concluye nuestro articulo de hoy en el cual en el nos familiarizamos con el depurador y hemos aprendido como depurar un programa e incluso a modificarlo

Categorías
Uncategorized

Bot Telegram Con ChatGPT

Bienvenidos una vez mas a este espacio, en esta ocasión estaremos creando un Bot de telegram al cual le estaremos integrando chatgpt.

Este será un sencillo ejemplo de cómo integrar el api de OpenAI con el api de Telegram

Como primer paso debemos crear un api key de OpenAI para poder interactuar con la misma, para hacer esto nos dirigimos a https://platform.openai.com/account/api-keys y creamos nuestra key presionando el botón

Le asignamos un nombre y presionamos créate secret key

Una vez presionado el botón OpenAI nos advierte que debemos guardar la key en un lugar seguro y por razones de seguridad no seremos capaces de ver la key nuevamente así que debemos copiar la key y guardarla tal como nos recomienda OpenAI

Una vez creada nuestra key de OpenAI nos dirigimos a Bot Father y creamos nuestro Bot siguiendo las instrucciones y guardamos el token de nuestro Bot

Una vez hecho esto ya estamos listos para empezar con nuestro Bot

Lo primero que debemos hacer es importar los módulos necesarios para nuestro código

import json
from aiogram import Bot, Dispatcher, executor, types
import openai

el modulo json lo utilizamos para leer el contenido del archivo de configuración, el modulo aiogram es utilizado para interactuar con el api de Telegram y el modulo openai es utilizado para interactuar con el api de OpenAI

yo he creado un archivo de configuración json en el cual almaceno la key de OpenAI y el token de nuestro Bot, esto puede hacerse de esta forma o también puede hacerse almacenando las keys en variables de entorno

Lo siguiente que debemos hacer es leer nuestras keys del archivo de configuración json esto lo hacemos abriendo nuestro archivo con open y json.load() y almacenamos nuestras keys en las variables telegram_token y opeanai_key

# leemos las keys
with open("config.json") as cfg:
  data=json.load(cfg)
  telegram_token=data["telegram_token"]
  openai_key=data["openai_key"]

lo siguiente que hacemos es asignar nuestra key de OpenAI y creamos la instancia del Bot

# Asignamos la key OpenAi
openai.api_key= openai_key

# Creamos La instancia del bot
bot=Bot(token=telegram_token)

Lo siguiente es instanciar nuestro dispatcher el cual es un componente de la biblioteca aiogram que es utilizado para manejar y enrutar mensajes entrantes en un Bot de Telegram. este recibe los mensajes y los dirige a las funciones de manejo adecuadas para su procesamiento.

El dispatcher se encarga de registrar y administrar los controladores de mensajes para diferentes tipos de eventos, tales como mensajes de texto, comandos, actualizaciones de chat entre otros. Puede asociar funciones especificas a estos eventos y ejecutarlas cuando se produzcan

Algunas funciones importantes del Dispatcher incluyen:

register_message_handler(): Permite registrar una función para manejar mensajes de texto entrantes. Se puede especificar opcionalmente una condición para filtrar los mensajes basados en su contenido o atributos.

register_callback_query_handler(): Permite registrar una función para manejar consultas de botones en línea. Estas consultas se generan cuando un usuario interactúa con un botón en línea adjunto a un mensaje.

register_inline_handler(): Permite registrar una función para manejar consultas en línea. Estas consultas se generan cuando un usuario escribe el nombre del Bot seguido de un comando o consulta especial en el campo de entrada de un chat.

register_errors_handler(): Permite registrar una función para manejar errores que ocurren durante la ejecución del Bot. Esto puede ser útil para manejar excepciones y tomar medidas adecuadas en caso de errores.

En este caso nosotros estaremos usando el decorador message_handler para asociar funciones a mensajes.

@disp.message_handler(commands=["start", "help"])
async def bienvenido(message: types.Message):
  await message.reply("bienvenido a este bot, preguntame lo que quieras!")

lo que hemos hecho en el código de arriba es crear una función decorada llamada bienvenido la cual se ejecutará cuando se reciba un mensaje que contenga alguno de los comandos especificados en la lista (start o help), esta responderá con el mensaje “bienvenido a este Bot, preguntame lo que quieras!»

Luego creamos otra función la cual manejara cualquier otro mensaje que no sea un comando

@disp.message_handler()
async def chat(message: types.Message):
  response = openai.Completion.create(
    model="text-davinci-003",
    prompt=message.text,
    temperature=0,
    max_tokens=100,
    top_p=1,
    frequency_penalty=0.0,
    presence_penalty=0.0
  )
  await message.reply(response.choices[0].text)


esta función utiliza el api de OpenAI para generar una respuesta al mensaje recibido utilizando el modelo text-davinci-003 la respuesta generada se envía como respuesta al mensaje enviado

por último, iniciamos nuestro dispatcher con executor.start_polling(disp)

if __name__ == "__main__":
  executor.start_polling(disp)

al ejecutar nuestro código e interactuar con nuestro Bot de telegram

Vemos que nuestro Bot interactúa con nosotros correctamente

Conclusión

En esta ocasión hemos aprendido como crear nuestros bots de telegram y como interactuar con ellos utilizando el api de OpenAI, también hemos visto como utilizar aiogram para crear nuestros bots de una forma más fácil

Categorías
Inteligencia Artificial y Ciberseguridad

Wiz Research descubre base de datos expuesta de DeepSeek

Una base de datos accesible públicamente perteneciente a DeepSeek permitió el control total sobre las operaciones de la base de datos, incluyendo el acceso a datos internos. La exposición incluyó más de un millón de registros con información altamente sensible.


31 de enero de 2025
Lectura de 3 minutos

base de datos expuesta de DeepSeek, iHack

Wiz Research ha identificado una base de datos ClickHouse expuesta

El equipo de Wiz Research identificó una base de datos ClickHouse de DeepSeek accesible públicamente, lo que permitía el control total sobre las operaciones de la base de datos y el acceso a datos internos.

La exposición incluía más de un millón de registros, con información como historial de chats, claves secretas, detalles del backend y otros datos altamente sensibles.

Tras descubrir el problema, el equipo de Wiz Research notificó de inmediato a DeepSeek, que procedió a asegurar la base de datos rápidamente.

En esta publicación, detallaremos nuestro descubrimiento y analizaremos las implicaciones para la industria.


Resumen ejecutivo

DeepSeek, una startup china de inteligencia artificial, ha ganado atención en los medios gracias a sus innovadores modelos de IA, en particular el modelo de razonamiento DeepSeek-R1. Este modelo rivaliza con OpenAI o1 en rendimiento, destacando por su eficiencia y menor costo.

Dado el crecimiento de DeepSeek en la industria de la IA, el equipo de Wiz Research decidió evaluar su postura de seguridad externa.

Hallazgo clave: En pocos minutos, identificamos una base de datos ClickHouse completamente abierta y sin autenticación, accesible en:

  • oauth2callback.deepseek.com:9000
  • dev.deepseek.com:9000

Datos expuestos:

  • Historial de chats
  • Datos internos del backend
  • Claves API
  • Registros operativos

Riesgo crítico: La base de datos permitía acceso sin autenticación, lo que facilitaba el control total sobre los datos y la posibilidad de escalamiento de privilegios dentro del entorno de DeepSeek.

control sobre datos, deepseck, ihack
deepseck clickHouse, ihack

Análisis detallado de la exposición

El equipo de Wiz Research comenzó su evaluación con un mapeo de los dominios públicos de DeepSeek, identificando alrededor de 30 subdominios expuestos.

Sin embargo, al explorar puertos más allá de los estándares HTTP (80/443), encontramos puertos abiertos inusuales (8123 y 9000) en los siguientes hosts:

  • http://oauth2callback.deepseek.com:8123
  • http://dev.deepseek.com:8123
  • http://oauth2callback.deepseek.com:9000
  • http://dev.deepseek.com:9000

Resultado: Estos puertos llevaban a una base de datos ClickHouse accesible sin autenticación, lo que planteaba un grave riesgo de seguridad.

Método de acceso:
Aprovechando la interfaz HTTP de ClickHouse, accedimos a la ruta /play, lo que permitía ejecutar consultas SQL directamente desde un navegador.

Con una simple consulta SHOW TABLES;, obtuvimos una lista completa de bases de datos disponibles.


Datos expuestos en la tabla «log_stream»

Entre todas las bases de datos, una en particular llamó la atención: log_stream, que contenía más de un millón de registros sensibles.

Columnas clave:

  • timestamp: Registros desde el 6 de enero de 2025.
  • span_name: Referencias a los endpoints internos de la API de DeepSeek.
  • string.values: Registros en texto plano, incluyendo historial de chats, claves API y metadatos operativos.
  • _service: Indica qué servicio de DeepSeek generó los registros.
  • _source: Expone el origen de las solicitudes, revelando historial de chats, claves API, estructuras de directorios y metadatos del chatbot.

Riesgo crítico:

  • Un atacante podía extraer mensajes de chat en texto plano.
  • Posible exfiltración de contraseñas y archivos locales mediante consultas avanzadas como SELECT * FROM file('filename'), dependiendo de la configuración de ClickHouse.

Nota: No ejecutamos consultas intrusivas más allá de la enumeración inicial para mantener prácticas de investigación ética.


Lecciones clave y riesgos para la industria

La rápida adopción de IA sin medidas de seguridad adecuadas es un riesgo creciente.
Este incidente demuestra que los mayores peligros en seguridad de IA provienen de exposiciones accidentales, no necesariamente de amenazas avanzadas.

Riesgos clave:

  • Muchas startups de IA priorizan la innovación sin proteger adecuadamente sus infraestructuras.
  • Bases de datos expuestas pueden revelar información confidencial sin necesidad de un ataque sofisticado.
  • Las medidas de seguridad en IA deben fortalecerse de inmediato.

Recomendaciones:

  • Implementar autenticación en todas las bases de datos accesibles en línea.
  • Auditar regularmente la seguridad de la infraestructura.
  • Involucrar equipos de seguridad en el desarrollo de IA para evitar exposiciones accidentales.

Conclusión

La inteligencia artificial está creciendo a un ritmo sin precedentes, pero la seguridad no ha seguido el mismo ritmo.

El caso de DeepSeek demuestra que muchas startups de IA han evolucionado sin implementar protocolos de seguridad adecuados.

La industria debe adoptar medidas de seguridad tan estrictas como las aplicadas en servicios de computación en la nube.

Fuente original: Wiz Research