5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Goの構造体をGhidraで逆アセンブルして静的解析する

Last updated at Posted at 2023-12-05

お詫び

執筆中インフルエンザにり患してダウンしていたため、書ききれませんでした。

アドカレ中には書き切りますので温かい目で見守っていただけますと幸いです。

はじめに

普段はVR企業でバックエンドエンジニアをやっています。

弊社では今までバックエンドのAPIを主にRuby/Railsで実装していたのですが、最近ではGoで実装することが増えてきております。

そこで今回はGoの内部実装の理解を進めるため、サイバーセキュリティでは有名なGhidraでGoの実行ファイルを逆アセンブルしてみます。

Ghidraとは

Ghidra

リバースエンジニアリングツールです。

アメリカのNSA(国家安全保障局)が開発したもので、2019年にOSSとして公開されました。

開発自体は2000年前半から始まっていて、十数年の時を経て誰でも利用できるようになりました。

今回はこのGhidra最新バージョン 10.4 にてGoバージョン対応が入り、1.171.20 がサポートされるようになりました。

そこで今回はGoの 1.20 で構造体を表現したソースコードをコンパイルしてバイナリコード(=実行ファイル)を作成したのち、リバースエンジニアリングで元の構造体に復元できるか見てみたいと思います。

なぜ逆アセンブル、デコンパイルするのか

以前私がCTFに参加していたときの記事があります。

このCTFというのは簡単に言えばハッキングコンテストで、いろいろなセキュリティのジャンルの問題を解いて点数を競う競技です。

このジャンルには reversing というものもあり、問題として実行ファイルが与えられて、表層解析や静的解析、動的解析などの手法を駆使して、必要な情報を奪取します。

そしてその中でも静的解析に利用されるのが逆アセンブルやデコンパイルという方法になります。

つまり0と1で表現されているだけの実行ファイルからそれがどのようなことをするものなのか分析できるようになることを目的とします。

実行ファイルならそのまま実行すればいいじゃないかと思うかもしれませんが、そのファイルに悪意のあるコードが含まれている場合、実行環境がウイルス等に汚染される可能性があります。

例えば作成元が不明な実行ファイルや、インターネットで不特定多数の人が入手できる実行ファイルなどは当然のこと、実行ファイルである以上、リスクはつきものです。

そのため、事前にどういうファイルなのかをファイルを実行することなく調査、解析できることにはとても意義があります。

なぜGoなのか

Goはクロスプラットフォーム対応で、各種OSの実行ファイルを同じソースファイルから作成することができます。

マルウェア開発者は少ない労力で各プラットフォーム向けの実行ファイルを作成することができるのでGoによるマルウェアが増えてきています。

そのためバイナリ解析者はGoによるマルウェア解析ができることが今後より期待されます。

Goの実行ファイルの特徴

- String reference to "Go Build ID:"
- Tons of references to "vendor/golang.org" in strings
- PDB path references to "/go/src/"
- Symbol table names starting with "main.", "runtime.", "os."
- URLs referencing "go.org" or "golang.org"
- OSX binaries referencing Go Github repository
- Has section names like .gosymtab, .gopcnltab, .go.buildinfo

事前準備

では早速バイナリ解析をするための準備を始めます。

Ghidraのホスト環境

  • Windows 11 Pro
    • バージョン:21H2
    • OSビルド:22000.2538
    • プロセッサ:Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz 2.11 GHz
    • 実装RAM:16.0 GB (15.7 GB 使用可能)
    • システムの種類:64 ビット オペレーティング システム、x64 ベース プロセッサ

Go build環境

  • Linux(WSL2)
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.3 LTS"
  • Go
$ go version
go version go1.21.1 linux/amd64

OpenJDKインストール

リンク先のバージョンは 17 ですが、たぶん最新でもいいと思います。

image.png

JAVA_HOMEPath にzipを展開したフォルダのルートとbinフォルダを指定します。

image.png

image.png

Ghidraインストール

以下からzipをダウンロードして展開します。

ghidraRun.bat を実行します。

image.png

goの実行ファイルをインポートする

今回利用するGoの実行ファイルは以下となります(事前にbuildしています)。

$ file hello_world
hello_world: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=njE5p-SYvX81Coej0Ddq/MXkw_O-x2LoHvERX2vcL/b60xbcwo3xlyP-JDfLsN/8OUi4FSpBEys1yPjYGKa, with debug_info, not stripped

重要なのは静的リンクであり、ストリップされていないという部分です。

静的リンクとはライブラリが外部リンクではなくファイル内にハードコードされているという意味で、実際に呼ばれるライブラリの関数名が明示的に書かれていないため解析の難易度を高めます。

ストリップとは解析のヒントにつながるシンボル情報が残っているかどうかを指していて、 not stripped はシンボル情報が残っている状態を意味しています。

シンボル情報はあればあるほど解析の難易度は下がります。

ちなみに unpacked っぽそうです。

実行ファイルは linuxでの実行ファイルである ELF という形式になっています。

CPUアーキテクチャは 64-bit です。

image.png

少し遠回りになりますが、まずはGhidraに何も設定をしていない状態でGoの実行ファイルをインポートします。

警告が出ますが、アクセスを許可します。

image.png

image.png

image.png

image.png

image.png

image.png

----- Loading /C:/Users/USER/Downloads/hello_world -----
Skipping section [.gosymtab] with invalid size 0x0
Unsupported symbol name has been escaped: "type:.eq.struct { runtime.gList; runtime.n int32 }"
Error creating symbol: type:.eq.struct { runtime.gList; runtime.n int32 } - Symbol name contains invalid characters: type:.eq.struct { runtime.gList; runtime.n int32 }
Unsupported symbol name has been escaped: "type:.eq.sync/atomic.Pointer[interface {}]"
Error creating symbol: type:.eq.sync/atomic.Pointer[interface {}] - Symbol name contains invalid characters: type:.eq.sync/atomic.Pointer[interface {}]

ここでAdditional Informationのセクションを見ると、一部のシンボルが取得できないとあるので、より情報を得るために gotools をインポートします。

gotools をインポートする

逆アセンブルする

main.main を見つける

.gopclntab で関数名を解決できるようにする

参考にした

Go Basics

Ghidra

Reversing Tips

Assembly Language

OSS(ghidra Extensions)

Books

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?