bashのアップデート

上記アップデート前

$ env x='() { :;}; echo vulnerable' bash -c 'echo this is a test; echo \"$x\"'
vulnerable
this is a test
""
  • 環境変数xに設定した'() { :;}; echo vulnerable'のecho vulnerableの部分が実行されているのだ。
  • そして、設定したはずの環境変数xは空っぽ...。

上記アップデート後

$ env x='() { :;}; echo vulnerable' bash -c 'echo this is a test; echo \"$x\"'
this is a test
"() { :;}; echo vulnerable"

直った!

Snow Leopardをどうするか

  • 残念ながら、Snow Leopardbashのアップデートは提供されていない...。
  • そうか、影響しないのかと試してみると、思い切り影響している!
$ env x='() { :;}; echo vulnerable' bash -c 'echo this is a test; echo \"$x\"'
vulnerable
this is a test
""
  • という訳で、とりあえず一番バージョンの近いLion用のbashアップデートをダウンロードしてみた。
  • 実行してみると、「このアップデートには10.7が必要です」と警告されて、インストールできない...。
  • もはや、Snow Leopardはサポート対象外になったのか...。
  • 諦めようと思ったのだけど、そう言えばpkgutilなんてコマンドがあったような気がした。
  • pkgutilと入力して、実行してみると、ヘルプが表示された!
$ pkgutil
Usage: pkgutil [OPTIONS] [COMMANDS] ...

Options:
  --help                 Show this usage guide
  --verbose, -v          Show contextual information and format for easy reading
  --force, -f            Perform all operations without asking for confirmation
  --volume PATH          Perform all operations on the specified volume
  --edit-pkg PKGID       Adjust properties of package PKGID using --learn PATH
  --only-files           List only files (not directories) in --files listing
  --only-dirs            List only directories (not files) in --files listing
  --regexp               Try all PKGID arguments as regular expressions

Database Commands:
  --pkgutil-version      Show pkgutil version.
  --pkgs, --packages     List all currently installed package IDs on --volume
  --pkgs-plist           List all package IDs on --volume in plist format
  --pkgs=REGEXP          List package IDs on --volume that match REGEXP
  --groups               List all GROUPIDs on --volume
  --groups-plist         List all GROUPIDs on --volume in plist format
  --group-pkgs GROUPID   List all PKGIDs in GROUPID
  --files PKGID          List files installed by the specified package
  --lsbom PKGID          List files in the same format as 'lsbom -s'
  --pkg-groups PKGID     List all GROUPIDs that PKGID is a member of
  --export-plist PKGID   Print all info about PKGID in plist format
  --verify PKGID         Verify file permissions of the specified package
  --repair PKGID         Repair file permissions of the specified package
  --pkg-info PKGID       Show metadata about PKGID
  --pkg-info-plist PKGID Show metadata about PKGID in plist format
  --file-info PATH       Show metadata known about PATH
  --file-info-plist PATH Show metadata known about PATH in plist format
  --forget PKGID         Discard receipt data for the specified package
  --unlink PKGID         Delete the files installed by the specified package
  --learn PATH           Update --edit-pkg PKGID with actual metadata from PATH

File Commands:
  --expand PKG DIR       Expand the flat package PKG to DIR
  --flatten DIR PKG      Flatten the files at DIR as PKG
  --bom PATH             Extract any Bom files from the pkg at PATH into /tmp
  --payload-files PATH   List the paths archived within the (m)pkg at PATH
  • ざっと眺めてみると、--expand PKG DIRが使えそうな、そんな気がする。
$ cd ~/Desktop
$ pkgutil --expand "/Volumes/OS X bash update/BashUpdateLion.pkg" bash_upate
  • すると、デスクトップにbash_upateが出現し、その中に3つのファイルが見える。
$ ls
BashUpdateLion.pkg/    Distribution*    Resources/
  • しばらくすると、Distributionは実行ファイルなのだけど、その実体はxmlに包まれたスクリプトであることに気付いた。
  • そして、その中に見える10.7の文字は、インストーラーがチェックしているOSXのバージョン番号であると予想できる。
  • 10.7がLion以降をチェックするのなら、そこをすべて10.6に置き換えてしまうとSnow Leopardでもインストールできるのではないか?
  • 至極自然な予想であり、それは確信となりつつあり、そう思い始めたらもう止められない。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<installer-gui-script minSpecVersion="1">
    <options hostArchitectures="i386" customize="never"/>
    <title>SU_TITLE</title>
    <script>
</script>
    <volume-check script="VolumeCheck()"/>
    <installation-check script="InstallationCheck()"/>
    <script>
function InstallationCheck(prefix) {
	if (system.compareVersions(system.version.ProductVersion, '10.7') &lt; 0 || system.compareVersions(system.version.ProductVersion, '10.8') >= 0) {
		my.result.message = system.localizedStringWithFormat('ERROR_0', '10.7');
		my.result.type = 'Fatal';
		return false;
	}
	return true;
}
function VolumeCheck(prefix) {
	if (system.env.OS_INSTALL == 1) return true;
	var hasOS = system.files.fileExistsAtPath(my.target.mountpoint + "/System/Library/CoreServices/SystemVersion.plist");
	if (!hasOS || system.compareVersions(my.target.systemVersion.ProductVersion, '10.7') &lt; 0 || system.compareVersions(my.target.systemVersion.ProductVersion, '10.8') >= 0) {
		my.result.message = system.localizedStringWithFormat('ERROR_0', '10.7');
		my.result.type = 'Fatal';
		return false;
	}
	if (!hasOS || system.compareVersions(my.target.systemVersion.ProductVersion, '10.7.5') &lt; 0) {
		my.result.message = system.localizedStringWithFormat('ERROR_2', '10.7.5');
		my.result.type = 'Fatal';
		return false;
	}
	return true;
}
</script>
    <license file="License.rtf"/>
    <readme file="SUDescription.html"/>
    <choices-outline>
        <line choice="manual"/>
    </choices-outline>
    <choice id="manual" title="SU_TITLE">
        <pkg-ref id="BashUpdateLion" auth="Root">#BashUpdateLion.pkg</pkg-ref>
    </choice>

	<pkg-ref id='BashUpdateLion' installKBytes='3906' version='1.0.1.1306847324'/>

	<pkg-ref id='BashUpdateLion' installKBytes='3906' version='1.0.1.1306847324'/>
</installer-gui-script>
  • テキストエディタで開いて、10.7を10.6に一括置き換え。
    • ちなみに、10.7.5の部分は10.6.5となった。
  • この修正を反映して、元のpkgファイルに戻すことができれば、インストールできるかもしれない。
  • pkgutilのヘルプを見ると、--expand PKG DIRの下には、--flatten DIR PKGがある。
  • 引数の部分がPKG DIRの逆順 DIR PKGという並びになっていることから、pkgファイルに復元できそうな予感がする。
$ pkgutil --flatten bash_update BashUpdate.pkg
  • すると、見事にデスクトップにBashUpdate.pkgが出現した。
  • 念のためOSX環境全体をバックアップしてから、ダブルクリックで実行してみると...

見事にインストーラーが起動して、正常にインストールできてしまった!(気がする)

$ env x='() { :;}; echo vulnerable' bash -c 'echo this is a test; echo \"$x\"'
this is a test
"() { :;}; echo vulnerable"

直った!

      • 但し、Snow Leopard用ではないので、どこかに何らかの問題が出るかもしれない。