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

ハニポで収集したマルウェアで使用されているpackerを調べてみた。

Security Python

はじめに

ハニーポット dionaeaで収集した209の検体がどんなpackerを用いてるのか調べた。
運用中のdionaeaに対し、nmap -sSした結果は以下のとおり。

Starting Nmap 6.46 ( http://nmap.org ) at 2015-02-03 01:12 JST
Nmap scan report for <ipアドレス>
Host is up (0.098s latency).
Not shown: 987 closed ports
PORT     STATE    SERVICE
21/tcp   open     ftp
22/tcp   open     ssh
25/tcp   filtered smtp
42/tcp   open     nameserver
80/tcp   open     http
135/tcp  open     msrpc
139/tcp  filtered netbios-ssn
443/tcp  open     https
445/tcp  filtered microsoft-ds
1433/tcp open     ms-sql-s
3306/tcp open     mysql
5060/tcp open     sip
5061/tcp open     sip-tls

Nmap done: 1 IP address (1 host up) scanned in 14.50 seconds

調査方法

VMremnux上でPEファイルを読み込むためのPythonライブラリであるpefileのラッパーのpackeridを用いた。

packeridはPEiDのシグネイチャを用いてpacker判定を行っているが標準のシグネイチャは貧弱なので公開されている以下のシグネイチャを用いた。

https://raw.githubusercontent.com/cuckoobox/cuckoo/master/data/peutils/UserDB.TXT
http://www.sysreveal.com/peidt-userdb-3/

アナライジング•マルウェアで紹介されていたpanda securityのuserdb.txtは死んでしまったようで使えなかった。
http://research.pandasecurity.com/blogs/images/userdb.txt

上の2つのシグネイチャを用いたpackeridの結果はそれぞれ異なるので、pythonで結果を読み取って出力した。

packerid

packeridはPEファイルだと認識できないときや、引数が複数の場合にファイル名をつけて結果を出力するが、それだと結果を収集する際に少々不便なのでそれらを出力しないようコードを書き換えてmypackeridとして使用した。

sed -e 's/file, ":  ### ERROR ###"/"### ERROR ###"/g' -e 's/file, ": ",  matches/matches/g' /usr/local/bin/packerid > /usr/local/bin/mypackerid
mypackerid * --database='/media/sf_malware/userdb.txt'> ../result1.txt
mypackerid * --database='/media/sf_malware/userdb2.txt'> ../result2.txt

あとから考えれば、cut -f2使ったほうが楽だった。

Pythonスクリプト

# coding: UTF-8

from collections import defaultdict

count = defaultdict(int)

with open('result1.txt') as f1, open('result2.txt') as f2:
    for line1, line2 in zip(f1.readlines(), f2.readlines()):
        replaced_line1 = line.replace('\n', '')
        replaced_line2 = line2.replace('\n', '')

        if replaced_line != 'None':
            count[replaced_line1] += 1

        elif replaced_line2 != 'None':
            count[replaced_line2] += 1

        else:
            count[replaced_line1] += 1

print count

結果

上のPythonスクリプトの結果は以下のようになった。

defaultdict(<type 'int'>, 
{"['Armadillo v1.xx - v2.xx']": 82,
"['UPX v0.89.6 - v1.02 / v1.05 - v1.22 DLL']": 12,
'None': 108, 
'### ERROR ###': 7})

Armadilloでpackされてるものが82個、UPXでpackされているものが12個、packされてないものが108個、そもそもPEファイルでないものが7個という結果になった。色んな種類のpackerでpackされていると思っていたのでこの結果は予想外であった。

また、win向けのPEファイルばかりあったので、こういう正体不明な奴にポートスキャンしてOS特定までする攻撃者は少ないのかなあと思った。

もっと検体を集めてから再度調べたい。