PackJ (Pacote pronunciado) é uma ferramenta para ajudar a mitigar ataques da cadeia de suprimentos de software. Ele pode detectar pacotes maliciosos, vulneráveis, abandonados, de erros de digitação e outros pacotes "arriscados" de registros populares de pacotes de código aberto, como NPM, Rubygems e Pypi. Pode ser facilmente personalizado para minimizar o ruído. O PackJ começou como um projeto de pesquisa de doutorado e está sendo desenvolvido atualmente sob várias doações do governo.
Observe o servidor da Web Packj auto-hospedado e várias integrações chegando ainda este mês? Assista a este repositório para se manter atualizado.
Apoiamos vários modelos de implantação:
Use PackJ para auditar dependências em solicitações de tração.
- name : Packj Security Audit
uses : ossillate-inc/[email protected]
with :
# TODO: replace with your dependency files in the repo
DEPENDENCY_FILES : pypi:requirements.txt,npm:package.json,rubygems:Gemfile
REPO_TOKEN : ${{ secrets.GITHUB_TOKEN }}Vista no mercado do Github. Exemplo de execução de relações públicas.
A maneira mais rápida de experimentar/testar packj é usar o Docker. O podman também é suportado para execuções de contêiner (isoladas).
docker run -v /tmp:/tmp/packj -it ossillate/packj:latest --help
Clonar este repo,
git clone https://github.com/ossillate-inc/packj.git && cd packj
Instalar dependências
bundle install && pip3 install -r requirements.txt
Comece com ajuda:
python3 main.py --help
O PackJ pode examinar os pacotes publicados de NPM, PyPI, Rust, PHP e Rubygems Package Registres. O suporte de ferrugem e PHP é WIP. Estamos acrescentando ativamente suporte para registros. Ele também suporta pacotes de NPM e PYPI não publicados (não publicados).
| Registro | Ecossistema | Suportado |
|---|---|---|
| Npm | JavaScript | ✅ |
| Pypi | Python | ✅ |
| Carga | Ferrugem | ✅ |
| Rubygems | Rubi | ✅ |
| Packagist | Php | ✅ |
| Docker | Docker | |
| NUGET | .LÍQUIDO | ✅ |
| Maven | Java | ✅ |
| Cocoapods | Swift |
PackJ oferece as seguintes ferramentas:
O PackJ audita pacotes de software de código aberto para atributos "arriscados" que os tornam vulneráveis a ataques da cadeia de suprimentos. Por exemplo, pacotes com domínios de email vencidos (sem 2FA), grande intervalo de tempo de liberação, APIs sensíveis ou permissões de acesso etc. são sinalizadas como arriscadas.
Auditar o seguinte é suportado:
python3 main.py audit -p pypi:requests rubygems:overcommitpython3 main.py audit -f npm:package.json pypi:requirements.txt Por padrão, audit executa apenas a análise de código estático para detectar código de risco. Você também pode ser o sinalizador PaaS -t ou --trace para executar a análise de código dinâmico, que instalará todos os pacotes solicitados em Strace e monitorar o comportamento do tempo de instalação dos pacotes. Por favor, veja o exemplo de saída abaixo.
$ docker run -v /tmp:/tmp/packj -it ossillate/packj:latest audit --trace -p npm:browserify
[+] Fetching 'browserify' from npm..........PASS [ver 17.0.0]
[+] Checking package description.........PASS [browser-side require() the node way]
[+] Checking release history.............PASS [484 version(s)]
[+] Checking version........................RISK [702 days old]
[+] Checking release time gap............PASS [68 days since last release]
[+] Checking author.........................PASS [[email protected]]
[+] Checking email/domain validity.......RISK [expired author email domain]
[+] Checking readme.........................PASS [26838 bytes]
[+] Checking homepage.......................PASS [https://github.com/browserify/browserify#readme]
[+] Checking downloads......................PASS [2M weekly]
[+] Checking repo URL.......................PASS [https://github.com/browserify/browserify]
[+] Checking repo data...................PASS [stars: 14189, forks: 1244]
[+] Checking if repo is a forked copy....PASS [original, not forked]
[+] Checking repo description............PASS [browser-side require() the node.js way]
[+] Checking repo activity...............PASS [commits: 2290, contributors: 207, tags: 413]
[+] Checking for CVEs.......................PASS [none found]
[+] Checking dependencies...................RISK [48 found]
[+] Downloading package from npm............PASS [163.83 KB]
[+] Analyzing code..........................RISK [needs 3 perm(s): decode,codegen,file]
[+] Checking files/funcs....................PASS [429 files (383 .js), 744 funcs, LoC: 9.7K]
[+] Installing package and tracing code.....PASS [found 5 process,1130 files,22 network syscalls]
=============================================
[+] 5 risk(s) found, package is undesirable!
=> Complete report: /tmp/packj_54rbjhgm/report_npm-browserify-17.0.0_hlr1rhcz.json
{
"undesirable": [
"old package: 702 days old",
"invalid or no author email: expired author email domain",
"generates new code at runtime",
"reads files and dirs",
"forks or exits OS processes",
]
}
AVISO: Como os pacotes podem executar código malicioso durante a instalação, é recomendável usar apenas
-tou--traceao executar dentro de um contêiner do Docker ou em uma máquina virtual.
A auditoria também pode ser realizada em contêineres Docker/Podman. Encontre detalhes sobre atributos arriscados e como usar no Audit ReadMe.
O PackJ oferece uma caixa de areia leve para safe installation de um pacote. Especificamente, impede que pacotes maliciosos exfiltrantes de dados confidenciais, acessando arquivos confidenciais (por exemplo, teclas SSH) e malware persistente.
Sandboxes de scripts de tempo de instalação, incluindo qualquer compliação nativa. Ele usa o STRACE (ou seja, não é necessário VM/contêiner).
Encontre detalhes sobre o mecanismo de sandbox e como usar no Sandbox ReadMe.
$ python3 main.py sandbox gem install overcommit
Fetching: overcommit-0.59.1.gem (100%)
Install hooks by running `overcommit --install` in your Git repository
Successfully installed overcommit-0.59.1
Parsing documentation for overcommit-0.59.1
Installing ri documentation for overcommit-0.59.1
#############################
# Review summarized activity
#############################
[+] Network connections
[+] DNS (1 IPv4 addresses) at port 53 [rule: ALLOW]
[+] rubygems.org (4 IPv6 addresses) at port 443 [rule: IPv6 rules not supported]
[+] rubygems.org (4 IPv4 addresses) at port 443 [rule: ALLOW]
[+] Filesystem changes
/
└── home
└── ubuntu
└── .ruby
├── gems
│ ├── iniparse-1.5.0 [new: DIR, 15 files, 46.6K bytes]
│ ├── rexml-3.2.5 [new: DIR, 77 files, 455.6K bytes]
│ ├── overcommit-0.59.1 [new: DIR, 252 files, 432.7K bytes]
│ └── childprocess-4.1.0 [new: DIR, 57 files, 141.2K bytes]
├── cache
│ ├── iniparse-1.5.0.gem [new: FILE, 16.4K bytes]
│ ├── rexml-3.2.5.gem [new: FILE, 93.2K bytes]
│ ├── childprocess-4.1.0.gem [new: FILE, 34.3K bytes]
│ └── overcommit-0.59.1.gem [new: FILE, 84K bytes]
├── specifications
│ ├── rexml-3.2.5.gemspec [new: FILE, 2.7K bytes]
│ ├── overcommit-0.59.1.gemspec [new: FILE, 1.7K bytes]
│ ├── childprocess-4.1.0.gemspec [new: FILE, 1.8K bytes]
│ └── iniparse-1.5.0.gemspec [new: FILE, 1.3K bytes]
├── bin
│ └── overcommit [new: FILE, 622 bytes]
└── doc
├── iniparse-1.5.0
│ └── ri [new: DIR, 119 files, 131.7K bytes]
├── rexml-3.2.5
│ └── ri [new: DIR, 836 files, 841K bytes]
├── overcommit-0.59.1
│ └── ri [new: DIR, 1046 files, 1.5M bytes]
└── childprocess-4.1.0
└── ri [new: DIR, 272 files, 297.8K bytes]
[C]ommit all changes, [Q|q]uit & discard changes, [L|l]ist details:
O Dr. Packj começou como um projeto de pesquisa de doutorado. É apoiado por vários subsídios do governo.
PackJ começou como um projeto de pesquisa acadêmica. Especificamente, as técnicas de análise de código estático usadas pelo PackJ são baseadas em pesquisas de segurança cibernética de ponta: Projeto Maloss por nosso grupo de pesquisa na Georgia Tech.
PackJ é apoiado por subsídios generosos da NSF, GRA e Alinnovate.
TL; Dr. Os scanners de vulnerabilidade de última geração assumem que o código de código aberto de terceiros é benigno. Portanto, todas essas ferramentas abordam apenas ameaças de bugs de programação acidental no código benigno (também conhecido como CVEs como o LOG4J). Eles não protegem contra os ataques modernos de cadeia de software modernos do tipo Solarwinds de código deliberadamente ruim (também conhecido como malicioso) que é propagado por maus atores usando novas vulnerabilidades no canal de suprimentos, incluindo confusão de dependência, squatting, protesto (sabotagem), sequestro e engenharia social. Um exemplo recente (de dezembro de 22) é o pacote Pytorch que foi comprometido usando a vulnerabilidade de confusão de dependência (sem cve atribuído).
O PackJ não apenas audita CVEs, mas também executa a análise de código dinâmico+estática e dinâmica, bem como verifica os metadados para detectar qualquer comportamento e atributos "arriscados", como desova do shell, uso de chaves ssh, incompatibilidade do código GitHub versus código embalado (proveniência), falta de 2FA e vários outros. Esses atributos inseguros não se qualificam como CVEs, e é por isso que nenhuma das ferramentas existentes pode sinalizar. O PackJ pode sinalizar dependências maliciosas, erradas, abandonadas, vulneráveis e outras inseguras (links fracos) em sua cadeia de suprimentos de software.
O modelo atual de ameaça da cadeia de suprimentos de software assume que o código de código aberto de terceiros é benigno e, portanto, as vulnerabilidades de segurança são rastreadas apenas para bugs de programação acidental (também conhecidos como CVEs). Como tal, todos os scanners de vulnerabilidade de código aberto existentes relatam apenas CVEs conhecidas públicas e ameaças de bugs acidentais no código benigno.
Um exemplo típico de um bug de programação acidental é uma verificação de limites ausentes na entrada do usuário, o que torna o código vulnerável a ataques de transbordamento de buffer. Exemplos populares do mundo real incluem Log4J e Heartbleed. Os invasores precisam desenvolver uma exploração para acionar CVEs (por exemplo, um pacote TCP/IP criado em caso de entradas de coração ou uma entrada numericamente alta para causar transbordamento de buffer). Os CVEs podem ser corrigidos corrigindo ou atualizando para uma versão mais recente da biblioteca (por exemplo, versão mais recente do log4j corrige o CVE).
O cenário moderno da ameaça da cadeia de suprimentos de software mudou após o ataque do Solarwinds. Os maus atores encontraram novas vulnerabilidades, mas desta vez no canal de suprimentos, não código. Essas novas vulnerabilidades, como confusão de dependência, squatting, protesto (sabotagem), seqüestro de contas e engenharia social, estão sendo explorados para propagar malware. Milhares de pacotes comprometidos de NPM/PYPI/Ruby foram relatados.
Em contraste com o CVS, o malware é deliberadamente ruim (também conhecido como malicioso). Além disso, o próprio malware é uma exploração e não pode ser corrigido ou corrigido, atualizando para uma versão mais recente. Por exemplo, o ataque de confusão de dependência foi intencionalmente malicioso; Ele não explorou nenhum bug de programação acidental no código. Da mesma forma, um autor do pacote popular que sabote seu próprio código para protestar contra a guerra é muito intencional e não explora nenhum CVS. O squatting de digitação é outro vetor de ataque que os maus atores usam para propagar malware em registros populares de pacotes de código aberto: ele explora erros de digitação e inexperiência de desenvolvedores, não bugs de programação acidental ou CVEs no código.
Os scanners existentes não conseguem detectar esses ataques modernos de cadeia de software modernos do tipo Solarwinds do código deliberadamente vulnerável (malicioso). Essas ferramentas simplesmente digitalizam o código-fonte em busca de dependências de fonte aberta, compilam uma lista de todas as dependências usadas e procuram cada <tecência-name, versões de dependência> Up em um banco de dados (por exemplo, NVD) para relatar versões de pacotes afetadas (por exemplo, versão vulnerável do log4j, versão LIBSSL afetada por batidas carameladas).
O PackJ não apenas audita CVEs, mas também executa a análise de código dinâmico+estática e dinâmica, bem como verifica os metadados para detectar qualquer comportamento e atributos "arriscados", como desova do shell, uso de chaves ssh, incompatibilidade do código GitHub versus código embalado (proveniência), falta de 2FA e vários outros. Esses atributos inseguros não se qualificam como CVEs, e é por isso que nenhuma das ferramentas existentes pode sinalizar. O PackJ pode sinalizar dependências maliciosas, erradas, abandonadas, vulneráveis e outras inseguras (links fracos) em sua cadeia de suprimentos de software. Por favor, leia mais no Audit ReadMe
O PackJ pode ser facilmente personalizado (ruído zero) para o seu modelo de ameaça. Basta adicionar um arquivo .packj.yaml no diretor superior do seu repositório/projeto e reduzir a fadiga de alerta, comentando atributos indesejados.
Encontramos mais de 40 e 20 pacotes maliciosos em Pypi e Rubygems, respectivamente usando esta ferramenta. Vários deles foram derrubados. Consulte um exemplo abaixo:
$ python3 main.py audit pypi:krisqian
[+] Fetching 'krisqian' from pypi...OK [ver 0.0.7]
[+] Checking version...OK [256 days old]
[+] Checking release history...OK [7 version(s)]
[+] Checking release time gap...OK [1 days since last release]
[+] Checking author...OK [[email protected]]
[+] Checking email/domain validity...OK [[email protected]]
[+] Checking readme...ALERT [no readme]
[+] Checking homepage...OK [https://www.bilibili.com/bangumi/media/md140632]
[+] Checking downloads...OK [13 weekly]
[+] Checking repo_url URL...OK [None]
[+] Checking for CVEs...OK [none found]
[+] Checking dependencies...OK [none found]
[+] Downloading package 'KrisQian' (ver 0.0.7) from pypi...OK [1.94 KB]
[+] Analyzing code...ALERT [needs 3 perms: process,network,file]
[+] Checking files/funcs...OK [9 files (2 .py), 6 funcs, LoC: 184]
=============================================
[+] 6 risk(s) found, package is undesirable!
{
"undesirable": [
"no readme",
"only 45 weekly downloads",
"no source repo found",
"generates new code at runtime",
"fetches data over the network: ['KrisQian-0.0.7/setup.py:40', 'KrisQian-0.0.7/setup.py:50']",
"reads files and dirs: ['KrisQian-0.0.7/setup.py:59', 'KrisQian-0.0.7/setup.py:70']"
]
}
=> Complete report: pypi-KrisQian-0.0.7.json
=> View pre-vetted package report at https://packj.dev/package/PyPi/KrisQian/0.0.7
PackJ sinalizou Krisqian (v0.0.7) como suspeito devido à ausência de repositório de origem e uso de APIs sensíveis (rede, geração de código) durante o tempo de instalação do pacote (em setup.py). Decidimos dar uma olhada mais profunda e achamos o pacote malicioso. Encontre nossa análise detalhada em https://packj.dev/malware/krisqian.
Mais exemplos de malware que encontramos estão listados em https://packj.dev/malware, entre em contato conosco em [email protected] para obter uma lista completa.
Para saber mais sobre a ferramenta PackJ ou ataques da cadeia de suprimentos de software de fonte aberta, consulte nosso
Assistir ? Este repositório para se manter atualizado.
Tem um recurso ou solicitação de suporte? Visite nossa página de discussão do github ou junte -se à nossa comunidade Discord para discussão e solicitações.
A PackJ foi desenvolvida por pesquisadores de segurança cibernética da Ossillate Inc. e colaboradores externos para ajudar os desenvolvedores a mitigar os riscos de ataques da cadeia de suprimentos ao adquirir dependências de software de código aberto de terceiros não confiáveis. Agradecemos a nossos desenvolvedores e colaboradores. Mostre seu apreço, dando -nos um se você gosta do nosso trabalho.
Congratulamo -nos com contribuições de código em braços abertos. Consulte Diretrizes Contribuindo.MD. Encontrou um bug? Por favor, abra um problema. Consulte nossas diretrizes de segurança.md para relatar um problema de segurança.
Atualmente, o PackJ pode examinar os pacotes NPM, PYPI e Rubygems para atributos "arriscados". Estamos adicionando suporte à ferrugem.
O PackJ usa análise de código estático, rastreamento dinâmico e análise de metadados para auditoria abrangente. A análise estática por si só não é suficiente para sinalizar malware sofisticado que pode se esconder melhor usando a ofuscação de código. A análise dinâmica é realizada instalando o pacote em strace e monitorando seu comportamento de tempo de execução. Por favor, leia mais no Audit ReadMe.
Este é um comportamento malicioso muito comum. O PackJ detecta a ofuscação de código, bem como a desova dos comandos do shell (chamada do sistema EXEC). Por exemplo, o PackJ pode sinalizar o uso da API getattr() e eval() pois indicam "geração de código de tempo de execução"; Um desenvolvedor pode ir e dar uma olhada mais profunda então. Veja main.py para obter detalhes.