
Apple MacOS Screen Sharing: Leitura/escrita arbitrária de arquivos -> RCE
Pela primeira vez em um bom tempo, temos um RCE no MacOS.
Descoberto originalmente por @osxreverser, e posteriormente expandido por bynar.io. Veja https://blog.calif.io/p/no-country-for-old-passwords para mais informações.
Isso é derivado principalmente do trabalho de @panchocosil (bem, Claude...), que publicou um PoC somente leitura. O repositório de @HORKimhab parece ser um tanto duvidoso, especialmente porque get-svn.sh parece uma tentativa de ataque à cadeia de suprimentos posterior.
De qualquer forma, consegui fazer a escrita funcionar e, a partir disso, obter RCE.
usage: exploit.py [-h] [-w LOCAL] [-m MODE] [-p PORT] [-u USER] [-r RETRIES] [-t TIMEOUT] [-o FILE] ip [path]
-o para gravar o arquivo lido em um arquivo local. Útil para binários-w para gravar um arquivo local em [path].De certa forma, possível. No MacOS, executar a leitura em um diretório (em vez de um arquivo) despeja o conteúdo bruto do diretório (todos os arquivos nele). Portanto, não conseguir listar arquivos não é um problema.
Então, primeiro um pouco de reconhecimento. python3 exploit.py <ip_addr> /Library/Preferences/com.apple.loginwindow.plist fornece o nome de usuário dos usuários conectados. Depois, você pode ler /User/<username>/.ssh/ e torcer para que o ssh também esteja habilitado (normalmente quando o VNC está, o SSH também está).
Como a leitura vem de root e ignora o TCC (pelo que entendi), você pode simplesmente despejar os históricos dos navegadores e (talvez?) cookies. Geralmente isso é suficiente.
Em todos os casos, você pode gravar em /Library/LaunchDaemons/ e esperar uma reinicialização. Você então terá persistência. Mas, claro, somos impacientes, então há maneiras melhores.
Muitas vezes haverá registros existentes que você pode sobrescrever. Por exemplo, /Library/PrivilegedHelperTools/com.microsoft.autoupdate.helper, us.zoom.ZoomDaemon e com.microsoft.teams.TeamsUpdaterDaemon são comumente encontrados instalados.
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AbandonProcessGroup</key>
<true/>
<key>Label</key>
<string>com.microsoft.EdgeUpdater.wake.system</string>
<key>LimitLoadToSessionType</key>
<string>System</string>
<key>ProgramArguments</key>
<array>
<string>/Library/Application Support/Microsoft/EdgeUpdater/Current/EdgeUpdater.app/Contents/MacOS/EdgeUpdater</string>
<string>--wake-all</string>
<string>--enable-logging</string>
<string>--vmodule=*/components/update_client/*=2,*/chrome/updater/*=2</string>
<string>--system</string>
</array>
<key>StartInterval</key>
<integer>3600</integer>
</dict>
</plist>
Olhando para isso, podemos ver que o binário em /Library/Application Support/Microsoft/EdgeUpdater/Current/EdgeUpdater.app/Contents/MacOS/EdgeUpdater é executado em um intervalo definido.
Podemos então substituir esse binário e, mesmo sem precisar lidar com o launchctl, temos RCE!
Divertido.