Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
macos_app_structure — Mergulho educacional aprofundado em app bundles do macOS, arquivos plist e comportamento do processo launchd, com notas de segurança ofensiva sobre empacotar payloads como arquivos .app e evadir o monitoramento da árvore de processos. | Kitploit
Ferramentas/GitHubGitHub/yo-yo-yo-jbo/macos_app_structure
Mecanismos de PersistênciaEvasão de IDS/IPSAprendizado e EducaçãoRed TeamingDesenvolvimento de Payloads
GitHubyo-yo-yo-jbo/macos_app_structure

macos_app_structure

Mergulho educacional aprofundado em app bundles do macOS, arquivos plist e comportamento do processo launchd, com notas de segurança ofensiva sobre empacotar payloads como arquivos .app e evadir o monitoramento da árvore de processos.

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar
Ver Repositório
472há 1 mêsRevisado pelo Kitploit

Introdução ao macOS - Estrutura de Apps no macOS

Fazer a transição do Linux ou Windows para o macOS pode parecer andar por uma terra estranha e desconhecida. Como o Linux é open-source e o Windows é bem documentado e muito popular (e o macOS não é exatamente nenhum dos dois), o macOS pode ser desafiador às vezes. Neste post, pretendo discutir algumas das primeiras coisas que você pode notar no macOS - Apps, Apps em todos os lugares!

Apps vs. processos (tarefas?)

Para quem vem de um ambiente Windows ou Linux, o conceito de Apps pode parecer estranho. Todos sabemos que threads são "unidades de execução" e que processos são contêineres para threads com seu próprio espaço de endereçamento -- o que há mais além disso? Bem, processos raramente são distribuídos em arquivos únicos. Tanto no Windows quanto no Linux, há muitas coisas das quais o código pode precisar para funcionar. Algumas delas são:

  • Módulos carregáveis (.dll, .so). Por exemplo, a biblioteca de runtime C (msvcr<version>.dll no Windows, libc-<version>.so) e outras dependências.
  • Recursos. Por exemplo, no Windows, os executáveis vêm em um formato chamado PE, que possui diretórios - um deles é o diretório de recursos (até certo ponto documentado aqui) que pode conter recursos (imagens, strings e outros). Recursos também podem ser carregados do disco dinamicamente, é claro.
  • Assinaturas digitais. Elas são menos comuns no Linux (embora existam de alguma forma - por exemplo, em Pacotes Debian), mas são importantes. No Windows, podem existir no próprio arquivo PE (leia aqui) ou em arquivos de catálogo (ou seja, externamente).
  • Configuração. No Linux, são arquivos (como seus confiáveis arquivos .bashrc), e no Windows se dividem entre arquivos (ex.: xml, ini, json) e o Registro do Windows.
  • Outros executáveis.

Bem, o macOS dá grande ênfase a Application Bundles. A ideia é empacotar (quase) tudo o que é necessário para o programa rodar em uma estrutura de diretórios - incluindo recursos, informações de localização, etc. Claro, nem tudo pode ser empacotado de forma organizada (como a biblioteca de runtime C, por exemplo) - mas ainda assim significa que as coisas ficam empacotadas de forma organizada - sem necessidade de navegar em um Registro enorme ou ler páginas de manual para localizações obscuras de arquivos de configuração. Application bundles são apenas diretórios que terminam com .app - embora a interface oculte a extensão .app (e o fato de ser um diretório). Da perspectiva de um atacante, isso é interessante - já que um Application Bundle pode ter ícones arbitrários e esconde a extensão .app - a entrega de malware pode ser alcançada enganando um usuário desprevenido para clicar em tal app. Por exemplo, pense em um arquivo Resume.app com um ícone de PDF.

A estrutura de diretórios de um Application Bundle pode ser facilmente examinada, obviamente pela App Calculator embutida:

root@kitploit:~
jbo@McJbo ~ % cd /System/Applications/Calculator.app
jbo@McJbo Calculator.app % ll
total 0
drwxr-xr-x   3 root  wheel    96 Mar 17 21:34 .
drwxr-xr-x  43 root  wheel  1376 Mar 17 21:34 ..
drwxr-xr-x   9 root  wheel   288 Mar 17 21:34 Contents
jbo@McJbo Calculator.app % cd Contents
jbo@McJbo Contents % ll
total 16
drwxr-xr-x    9 root  wheel   288 Mar 17 21:34 .
drwxr-xr-x    3 root  wheel    96 Mar 17 21:34 ..
-rw-r--r--    1 root  wheel  2147 Mar 17 21:34 Info.plist
drwxr-xr-x    3 root  wheel    96 Mar 17 21:34 MacOS
-rw-r--r--  204 root  wheel     8 Mar 17 21:34 PkgInfo
drwxr-xr-x    4 root  wheel   128 Mar 17 21:34 PlugIns
drwxr-xr-x   54 root  wheel  1728 Mar 17 21:34 Resources
drwxr-xr-x    3 root  wheel    96 Mar 17 21:34 _CodeSignature
-rw-r--r--    1 root  wheel   461 Mar 17 21:34 version.plist
jbo@McJbo Contents % cd MacOS
jbo@McJbo MacOS % ll
total 344
drwxr-xr-x  3 root  wheel      96 Mar 17 21:34 .
drwxr-xr-x  9 root  wheel     288 Mar 17 21:34 ..
-rwxr-xr-x  1 root  wheel  540912 Mar 17 21:34 Calculator
jbo@McJbo MacOS %

Como você pode ver, Calculator.app é um diretório. Dentro dele há um único item - outro diretório chamado Contents. Dentro de Contents há vários itens:

  • Info.plist - contém metadados sobre a App. Mais sobre isso depois.
  • MacOS - contém o executável principal da App (como pode ser visto na terceira listagem de diretórios).
  • PkgInfo - não obrigatório. Um arquivo binário que contém informações do pacote.
  • PlugIns - não obrigatório. Um diretório que pode conter plugins para a App. A Calculator tem dois - um para "Basic and Scientific" e outro para "Hexadecimal" (eu realmente não sei por que fizeram essa separação, nem me importo).
  • Resources - não obrigatório. Como o nome sugere, contém recursos. Você pode encontrar vários itens lá, incluindo um arquivo .icns com ícones, bem como diretórios com o sufixo .lprroj relacionados à localização.
  • _CodeSignature - não obrigatório. Como o nome sugere - contém informações de assinatura de código.
  • version.plist - não obrigatório, contém informações de versão.

Observe que são muito poucos os itens oficialmente necessários. Na verdade, podemos criar nossa primeira App sem nem compilar nada! Mas primeiro precisamos discutir o arquivo Info.plist.

Arquivos de lista de propriedades

Quanto mais você olha para o macOS, mais encontra esses arquivos estranhos. Eles nada mais são do que arquivos de configuração glorificados. Eles sempre terão a extensão .plist, que é apenas uma forma abreviada de se referir ao seu nome formal: arquivos Property list. Infelizmente, existem 3 formatos plist diferentes mantidos pela Apple:

  • Um formato xml, legível por humanos.
  • Um formato json, não muito usado.
  • Um formato binário, que normalmente pode ser identificado pelo texto bplist como magic number.

Felizmente, existe um utilitário chamado plutil que suporta todos os formatos. Para exibir um arquivo plist, basta usar plutil -p. Por exemplo:

root@kitploit:~
jbo@McJbo Contents % plutil -p Info.plist | head -n 20
{
  "BuildMachineOSBuild" => "22A380007"
  "CFBundleDevelopmentRegion" => "English"
  "CFBundleExecutable" => "Calculator"
  "CFBundleGetInfoString" => "10.14, Copyright © 2000-2018, Apple Inc."
  "CFBundleHelpBookFolder" => "Calculator.help"
  "CFBundleHelpBookName" => "com.apple.Calculator.help"
  "CFBundleIconFile" => "AppIcon"
  "CFBundleIconName" => "AppIcon"
  "CFBundleIdentifier" => "com.apple.calculator"
  "CFBundleInfoDictionaryVersion" => "6.0"
  "CFBundleName" => "Calculator"
  "CFBundlePackageType" => "APPL"
  "CFBundleShortVersionString" => "10.16"
  "CFBundleSignature" => "????"
  "CFBundleSupportedPlatforms" => [
    0 => "MacOSX"
  ]
  "CFBundleVersion" => "223"
  "CTIgnoreUserFonts" => 1
jbo@McJbo Contents %

Há também funcionalidades de conversão embutidas no plutil - não vamos demonstrá-las agora. A Apple documenta vários requisitos no Info.plist de uma App, mas são muito poucos os campos realmente obrigatórios. Aqui estão alguns campos interessantes:

  • CFBundleExecutable - o nome do executável principal, esperado no diretório MacOS.
  • CFBundleIconFile - o nome do arquivo de ícone. Não obrigatório.
  • CFBundleIdentifier - um identificador para o App Bundle. A Apple recomenda usar a notação DNS reversa (ex.: com.apple.calculator).
  • CFBundleName - o nome do bundle.

Com isso em mente, podemos criar nossa primeira app incrível, sem nem programar! Dê uma olhada:

root@kitploit:~
#!/bin/zsh

# Create Bundle structure
mkdir -p ./MyApp.app/Contents/MacOS

# Create main executable file - a shell script in our case
cat <<EOF > ./MyApp.app/Contents/MacOS/MyApp
#!/bin/zsh
osascript -e 'tell app "Finder" to display dialog "Hello from MyApp!"'
EOF
chmod +x ./MyApp.app/Contents/MacOS/MyApp

# Create the Info.plist file
cat <<EOF > ./MyApp.app/Contents/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleExecutable</key>
	<string>MyApp</string>
	<key>CFBundleIdentifier</key>
	<string>com.myapp</string>
	<key>CFBundleName</key>
	<string>MyApp</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
</dict>
</plist>
EOF

Isso criará uma nova app chamada MyApp - clicar nela simplesmente executará o script zsh (chamado MyApp). Note que ela usa osascript, que é um interpretador de AppleScript e uma verdadeira caixa de Pandora, mas apenas mostrará um diálogo que diz Hello from MyApp!. Você poderia escrever código arbitrário nesse arquivo de shell zsh, obviamente. Versões mais novas do macOS podem exibir um prompt pedindo para permitir que o zsh chame o osascript - vamos discutir por que isso acontece em um post futuro, mas note que não perguntará após a primeira aprovação.

Abrindo uma App

Abrir uma App significa que um processo ainda é criado - obviamente aquele apontado por CFBundleExecutable. Sob qual processo ele roda? Vejamos:

root@kitploit:~
jbo@McJbo ~ % open -a Calculator
jbo@McJbo ~ % ps -A -j | grep Calculator | grep -v grep
jbo              12067     1 12067      0    1 S      ??    0:00.41 /System/Applications/Calculator.app/Contents/MacOS/Calculator
jbo@McJbo ~ %

O comando open é equivalente a dar um duplo clique na App Calculator - é bastante fascinante e vamos discuti-lo em breve. Agora que a Calculator está rodando, usamos ps para mostrar os processos em execução. Como esperado, /System/Applications/Calculator.app/Contents/MacOS/Calculator é o processo que roda, e ele tem um PID de 12067. No entanto, seu ID de processo pai é 1!

O ID de processo 1 no macOS é /sbin/launchd. Ele é o "gerente de daemons/agentes por usuário e em todo o sistema". Você pode imaginá-lo como services.exe (se veio de um ambiente Windows) ou systemd (se está familiarizado com Linux). Além de gerenciar serviços (que são chamados de Launch Agents e Launch Daemons no macOS), ele também é o pai de todas as Applications, o que é uma das razões pelas quais obter uma árvore de processos significativa no macOS é desafiador.

Curiosamente, você ainda pode rodar a App Calculator apenas como um processo invocando /System/Applications/Calculator.app/Contents/MacOS/Calculator diretamente, mas ela não será filha do launchd:

root@kitploit:~
jbo@McJbo ~ % /System/Applications/Calculator.app/Contents/MacOS/Calculator &
[1] 12502
jbo@McJbo ~ % 2023-04-04 15:54:22.987 Calculator[12502:1297087] XType: XTFontStaticRegistry is enabled by Info.plist.

jbo@McJbo ~ % ps -A -j | grep Calculator | grep -v grep
jbo              12502   951 12502      0    1 SN   s000    0:00.31 /System/Applications/Calculator.app/Contents/MacOS/Calculator
jbo@McJbo ~ % echo $$
951
jbo@McJbo ~ %

De fato, a Calculator roda sem problemas, mas agora é um processo filho do nosso terminal. Uma coisa a notar no comportamento que vimos é que atacantes podem usá-lo para fins diferentes. Por exemplo, atacantes podem facilmente sair da árvore de processos para evadir ferramentas de segurança, além de abusar de vulnerabilidades de lógica (leia meu artigo sobre a vulnerabilidade de escape do Sandbox do macOS se tiver tempo).

Há outras responsabilidades interessantes para o launchd (leia sobre LaunchAgents e LaunchDaemons), mas não vamos discuti-las por enquanto.

Mais sobre bundles

Aqui mostrei um tipo de bundle, mas há muitos outros (não é uma lista completa):

  • .app - já vimos este; são Application Bundles que são contêineres para Apps.
  • .framework - contém Frameworks, que são bundles carregáveis. Sim, no macOS você pode chamar dlopen em um arquivo carregável (.dylib) ou pode carregar um bundle de framework inteiro (com recursos, código, etc.).
  • .kext - contém kernel extensions, que são bundles carregáveis, mas para o kernel do macOS. Em versões recentes do sistema operacional, a Apple realmente se esforça para reduzir o número de extensões de kernel.
  • .plugin - como o nome sugere, um contêiner para plugins.

Resumo

Este é o primeiro de uma série de posts curtos com o objetivo de ajudar as pessoas a fazer a transição para a pesquisa no macOS.
A primeira coisa que notei, do ponto de vista da segurança ofensiva, foi como é fácil empacotar payloads em uma estrutura de app agradável.
As coisas não são tão simples, porém - nos próximos posts descobriremos que obter execução de código não é tão trivial devido aos muitos recursos de segurança do macOS.

Fique ligado!

Jonathan Bar Or (https://jonathanbaror.com)

Baixar ferramenta