MacDropAnyがAdWareを食わしている

ここ数日、Safari Technology Preview 15でlinkをclickしたり、Web pageのlinkではない文字列をdragすると、広告屋のページが開くことがあり不審に思っていたので、Malwarebytes Anti-Malware for Macを走らせてみたところ

2016-10-26 22:58:37 : —– Scan Started —–
2016-10-26 22:58:37 : Scanning with signatures version 136 (2016-10-25)
2016-10-26 22:58:45 : OSX.Genieo : ~/Library/LaunchAgents/com.zibity.MacDropAnyDonationProcessor.plist
2016-10-26 22:58:59 : *** Scan time: 0d 00:00:21 ***
2016-10-26 22:58:59 : —— Scan Ended ——

という悲しいお知らせが表示された。なお、file pathはlogin directoryを除いた相対表記に変更してある。
“com.zibity.MacDropAnyDonationProcessor.plist”という文字列からして、Dropboxの同期対象をsymbolic linkで追加してくれるMacDropAny(http://www.zibity.com/macdropany.html)をinstallしてあるので、これがdropした可能性が大きい。また、”DonationProcessor”と表記されているあたりで、上記のSafariでの操作をhijackして広告屋にredirectすることにより、「広告を表示させることによって強制的に寄付という名の広告料を受け取る」ことを行っていることが見て取れる。悪質な開発者であると断定するするので丸っと公開してやる。

では、まず、~/Library/LaunchAgents/com.zibity.MacDropAnyDonationProcessor.plistの中身はこうだ。なお、plistはxml fileなので可読性を良くするために適宜改行と行頭に半角空白を加えているとともに、file pathはlogin directoryを除いた相対表記に変更してある。なにやらうまくコード表記されないので画像もどうぞ。

<br /><br /><br /><br />        Label
            com.zibity.MacDropAnyDonationRequester
        Program
            ~/Library/Application Support/MacDropAny/MacDropAny Donation Requester.app/Contents/MacOS/applet
        StartInterval
            259200


~/Library/LaunchAgents/に置かれている,plistファイルなので、loginと同時に自動的に読み込まれ、~/Library/Application Support/MacDropAny/MacDropAny Donation Requester.app/Contents/MacOS/appletが、72時間ごとに起動される。

次に、~/Library/Application Support/MacDropAny/MacDropAny Donation Requester.appのパッケージ構成は次のとおりだ。なお、Resource folderの.proj folderはmacOSではlocalizeに用いられるものなので詳細は記さない。

  • Contents
    • _CodeSignature
      • CodeResources (下記参照)
    • info.plist (下記参照)
    • MacOS
      • applet (binary)
    • pkginfo (“APPLaplt”と記述されているのみ)
    • Resources
      • applet.icns
      • applet.rsrc
      • description.rtfd (空)
      • de.lproj
      • en.lproj
      • fr.lproj
      • it.lproj
      • nl.lproj
      • Scripts
        • main.scpt (下記参照)

CodeResources

<?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>files</key>
    <dict>
        <key>Resources/Scripts/main.scpt</key>
        <data>
        t1vr09u6MwRkJSnoMAoXm6NxQ/Q=
        </data>
        <key>Resources/applet.rsrc</key>
        <data>
        bx4YSVoGGSR3MIxNN6tq8RiOG9I=
        </data>
        <key>Resources/de.lproj/Localizable.strings</key>
        <dict>
            <key>hash</key>
            <data>
            jYOl1+BlMB4AQBrJ6Ohvzfrql/Y=
            </data>
            <key>optional</key>
            <true/>
        </dict>
        <key>Resources/description.rtfd/TXT.rtf</key>
        <data>
        L2Vi5Bzmo8FKkjho0hL/lWoeFiE=
        </data>
        <key>Resources/en.lproj/Localizable.strings</key>
        <dict>
            <key>hash</key>
            <data>
            d6/iVZK19zEsJ6QTiWUPi0+VmzU=
            </data>
            <key>optional</key>
            <true/>
        </dict>
        <key>Resources/fr.lproj/Localizable.strings</key>
        <dict>
            <key>hash</key>
            <data>
            WcJVLlyQKGEH9GkHWD32Yewd/5g=
            </data>
            <key>optional</key>
            <true/>
        </dict>
        <key>Resources/it.lproj/Localizable.strings</key>
        <dict>
            <key>hash</key>
            <data>
            usT3OZ5fhy7Xunm58EZS4GObBwY=
            </data>
            <key>optional</key>
            <true/>
        </dict>
        <key>Resources/nl.lproj/Localizable.strings</key>
        <dict>
            <key>hash</key>
            <data>
            sigXl0hoKzX85lbitk6ad4/ikTU=
            </data>
            <key>optional</key>
            <true/>
        </dict>
    </dict>
    <key>files2</key>
    <dict>
        <key>Resources/Scripts/main.scpt</key>
        <data>
        t1vr09u6MwRkJSnoMAoXm6NxQ/Q=
        </data>
        <key>Resources/applet.rsrc</key>
        <data>
        bx4YSVoGGSR3MIxNN6tq8RiOG9I=
        </data>
        <key>Resources/de.lproj/Localizable.strings</key>
        <dict>
            <key>hash</key>
            <data>
            jYOl1+BlMB4AQBrJ6Ohvzfrql/Y=
            </data>
            <key>optional</key>
            <true/>
        </dict>
        <key>Resources/description.rtfd/TXT.rtf</key>
        <data>
        L2Vi5Bzmo8FKkjho0hL/lWoeFiE=
        </data>
        <key>Resources/en.lproj/Localizable.strings</key>
        <dict>
            <key>hash</key>
            <data>
            d6/iVZK19zEsJ6QTiWUPi0+VmzU=
            </data>
            <key>optional</key>
            <true/>
        </dict>
        <key>Resources/fr.lproj/Localizable.strings</key>
        <dict>
            <key>hash</key>
            <data>
            WcJVLlyQKGEH9GkHWD32Yewd/5g=
            </data>
            <key>optional</key>
            <true/>
        </dict>
        <key>Resources/it.lproj/Localizable.strings</key>
        <dict>
            <key>hash</key>
            <data>
            usT3OZ5fhy7Xunm58EZS4GObBwY=
            </data>
            <key>optional</key>
            <true/>
        </dict>
        <key>Resources/nl.lproj/Localizable.strings</key>
        <dict>
            <key>hash</key>
            <data>
            sigXl0hoKzX85lbitk6ad4/ikTU=
            </data>
            <key>optional</key>
            <true/>
        </dict>
    </dict>
    <key>rules</key>
    <dict>
        <key>^Resources/</key>
        <true/>
        <key>^Resources/.*\.lproj/</key>
        <dict>
            <key>optional</key>
            <true/>
            <key>weight</key>
            <real>1000</real>
        </dict>
        <key>^Resources/.*\.lproj/locversion.plist$</key>
        <dict>
            <key>omit</key>
            <true/>
            <key>weight</key>
            <real>1100</real>
        </dict>
        <key>^version.plist$</key>
        <true/>
    </dict>
    <key>rules2</key>
    <dict>
        <key>.*\.dSYM($|/)</key>
        <dict>
            <key>weight</key>
            <real>11</real>
        </dict>
        <key>^(.*/)?\.DS_Store$</key>
        <dict>
            <key>omit</key>
            <true/>
            <key>weight</key>
            <real>2000</real>
        </dict>
        <key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
        <dict>
            <key>nested</key>
            <true/>
            <key>weight</key>
            <real>10</real>
        </dict>
        <key>^.*</key>
        <true/>
        <key>^Info\.plist$</key>
        <dict>
            <key>omit</key>
            <true/>
            <key>weight</key>
            <real>20</real>
        </dict>
        <key>^PkgInfo$</key>
        <dict>
            <key>omit</key>
            <true/>
            <key>weight</key>
            <real>20</real>
        </dict>
        <key>^Resources/</key>
        <dict>
            <key>weight</key>
            <real>20</real>
        </dict>
        <key>^Resources/.*\.lproj/</key>
        <dict>
            <key>optional</key>
            <true/>
            <key>weight</key>
            <real>1000</real>
        </dict>
        <key>^Resources/.*\.lproj/locversion.plist$</key>
        <dict>
            <key>omit</key>
            <true/>
            <key>weight</key>
            <real>1100</real>
        </dict>
        <key>^[^/]+$</key>
        <dict>
            <key>nested</key>
            <true/>
            <key>weight</key>
            <real>10</real>
        </dict>
        <key>^embedded\.provisionprofile$</key>
        <dict>
            <key>weight</key>
            <real>20</real>
        </dict>
        <key>^version\.plist$</key>
        <dict>
            <key>weight</key>
            <real>20</real>
        </dict>
    </dict>
</dict>
</plist>

Info.plist

<?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>CFBundleAllowMixedLocalizations</key>
    <true/>
    <key>CFBundleDevelopmentRegion</key>
    <string>English</string>
    <key>CFBundleExecutable</key>
    <string>applet</string>
    <key>CFBundleIconFile</key>
    <string>applet</string>
    <key>CFBundleIdentifier</key>
    <string>com.zibity.MacDropAnyDonationRequester</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>MacDropAny Donation Requester</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleSignature</key>
    <string>aplt</string>
    <key>LSMinimumSystemVersionByArchitecture</key>
    <dict>
        <key>x86_64</key>
        <string>10.6</string>
    </dict>
    <key>LSRequiresCarbon</key>
    <true/>
    <key>LSUIElement</key>
    <true/>
    <key>WindowState</key>
    <dict>
        <key>bundleDividerCollapsed</key>
        <false/>
        <key>bundlePositionOfDivider</key>
        <real>981</real>
        <key>dividerCollapsed</key>
        <false/>
        <key>eventLogLevel</key>
        <integer>2</integer>
        <key>name</key>
        <string>ScriptWindowState</string>
        <key>positionOfDivider</key>
        <real>436</real>
        <key>savedFrame</key>
        <string>0 90 1280 687 0 0 1280 777 </string>
        <key>selectedTab</key>
        <string>log</string>
    </dict>
</dict>
</plist>

main.scpt

## Begin Donate Script ##
set runcount to 0
try
    if (do shell script "ls ~/Library/Preferences") contains "com.zibity.donate" then set runcount to ((do shell script "defaults read com.zibity.donate runcount") as number)
end try

try
    if runcount is not greater than 1000 then
        try
            set ButtonReturned to (button returned of (display alert (localized string "MacDropAny: Would you like to donate?") message (localized string "Hello! It's Sebastian here, MacDropAny's ") & (round (((current date) - (date "1997年7月14日月曜日 0:00:00")) / 31536000) rounding down) & (localized string "Message text2") buttons {(localized string "No, thanks"), (localized string "Maybe later"), (localized string "Donate Now")} default button 3 cancel button 2)) as text
        on error number ErrNum
            if ErrNum is -128 then set ButtonReturned to (localized string "Maybe later")
        end try
        if ButtonReturned is (localized string "Donate Now") then
            open location "http://donate.zibity.com"
            resignDonationRequester()
        else if ButtonReturned is (localized string "No, thanks") then
            resignDonationRequester()
        end if
    else
        resignDonationRequester()
    end if
end try

on resignDonationRequester()
    do shell script "defaults write com.zibity.donate runcount 1407"
    try
        do shell script "rm -rf ~/Library/Application\\ Support/MacDropAny"
    end try
    try
        do shell script "rm -f ~/Library/LaunchAgents/com.zibity.MacDropAnyDonationProcessor.plist"
    end try
    try
        do shell script "launchctl remove com.zibity.MacDropAnyDonationRequester"
    end try
end resignDonationRequester

肝は”main.scpt”の14行から18行だ。MacDropAnyを起動すると寄付のお願いダイアログが表示され、このダイアログには”Donate Now”と”No, thanks”のボタンがある。前者をclickすると寄付をするためのWeb pageが表示されて終わったように見せかけるが、後者をclickしたときと同様に”resignDonationRequester”に移動し、なんと”defaults write com.zibity.donate runcount 1407″がdefaultとして書き込まれる。”default read com.zibity.donate”で確認すると次の結果が表示された。

{
runcount = 0;
}

しかも、”resignDonationRequester”でAdWareを削除する記述をしているが、上記のように丸っと残っており動作していない。

これらのことから、MacDropAnyが突っ込んだAdWare OSX.Genieoを削除するためには、AppCleanerでfileとfolderを削除した上で、”defaults delete com.zibity.donate”および”launchctl remove com.zibity.MacDropAnyDonationRequester”をTerminal.appで行う必要がある。

“~/Library/LaunchAgents/com.zibity.macdropupdate2.plist”が残存していたのでこれも削除すること。(2016.10.28追記)

広告
MacDropAnyがAdWareを食わしている