AR ホームベーカリー

オイラのアウトプット用ホームベーカリー!

ELF ファイルを解析する

「謎のコマンドがサーバーのリソースを食い尽くしている!」

と騒いでいる人が社内にいて、マトモに話を聞けるのがリリース担当の僕しかいない状態なので、リリース作業をしつつ謎を調査していた。

macOS 環境で調査しています、対象の環境は Linux

ELF ファイルとは

qiita.com

結局コンパイルされたバイナリっぽい。

謎の ELF ファイルを調査する

less で開くと先頭あたりに ELF と書いてあるので概ね ELF ファイルと判別がつくけど、ここは古典的に file コマンドを投げてみる。

❯ file backup
backup: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, no section header

ちゃんと ELF ファイルとして認識されていた。

次にこいつを readelf コマンドで読んでみる。

インストールは以下。

❯ brew install binutils

確認すると以下のようになる。

❯ readelf -a backup
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0xea4d70
  Start of program headers:          64 (bytes into file)
  Start of section headers:          0 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         3
  Size of section headers:           0 (bytes)
  Number of section headers:         0
  Section header string table index: 0

...

読めた。 しかし何がなんだかわからないので、 ghidra を使って逆コンパイル (ディスアセンブリ) して実際のコードを確認してみる。

ghidraRun

インストールは以下。

❯ brew install --cask ghidra

実行には JDK 21 以降が必要。

僕は jenv を使っているので /opt/homebrew/Cellar/openjdk/23.0.2/libexec/openjdk.jdk/Contents/Home というけったいなパスになっているが、 JDK21 以降であればなんでもいいので用意してください。

❯ ghidraRun
WARNING: JAVA_HOME environment specifies non-existing directory: Using system JDK, no JAVA_HOME set!
******************************************************************
JDK 21+ (64-bit) could not be found and must be manually chosen!
******************************************************************
Enter path to JDK home directory: /opt/homebrew/Cellar/openjdk/23.0.2/libexec/openjdk.jdk/Contents/Home
Saved changes to /Users/donbulinux/Library/ghidra/ghidra_11.4_PUBLIC/java_home.save

Project

説明書いてある所によっては、起動したらいきなり import file で対象の ELF ファイルを読み込める、とのことだったけど、現代では普通に無理なので、以下の手順で新しいプロジェクトを作成する。

  1. File > New Project
  2. Non-Shared Project
  3. Next >>
  4. Project Directory
  5. どこか作業ディレクトリを作成して指定する
  6. 僕は /Users/donbulinux/Workspace/ghidra/test のように ghidra ディレクトリ以下にプロジェクト名でディレクトリを切っている
  7. Project Name
  8. なんか適当に名前を決める、 test とかでもぜんぜん構わない
  9. Finish

Import File

  1. File > Import File
  2. Select File To Import
  3. ファイルの Import 諸元が出てくるのでそのまま OK
  4. Summary が出てくるので OK

Analyze

インポートした ELF ファイルがプロジェクトツリーに表示されるので、ダブルクリックすると解析が始まる。

基本的に OK か Analyze を押せば解析してくれる。

macOS 環境だと以下のようにセキュリティとプライバシーでブロックされるので、画面がでるたびに「このまま開く」を押して、パスワード認証なり許可を与えてから、システム設定 > セキュリティとプライバシーを表示して実行がブロックされていたら許可を与える、などを繰り返す。

許可許可許可ァ!

解析できると Decompile 画面に以下のような感じでコードが表示されてくる。

解析した所

これは悲しいことに /* WARNING: Control flow encountered bad instruction data */ となっていて、解析を阻止するように小賢しいアレソレが入っている様子だった。

結局これなに

バイナリ解析するのも大変だしでWebサーバーのログ確認してもらったら脆弱性利用してマイニング用のファイル送り込まれたのでは? とのことだった。

め、めんどくせぇ〜!

素性

md5 と sha256 で確認した結果を malware bazeer で検索したけどヒットしなかったので、まあデータ抜くとか悪意のある系ではなく、本当に小銭稼ぎ系だったんだろうなあ、という感じでした。 やれやれ。

ファイル削除して一応ウィルススキャンを全体にキメておわり。

参考

kashiwaba-yuki.com