◼️ はじめに
CTFのCryptography分野で出てくる画像の「ステガノグラフィ」について,仕組みの解説から実際の抽出までを本記事で書いてみたいと思います.
◼️ ステガノグラフィとは
◻️ ステガノグラフィとは
そもそも,ステガノグラフィとは,ある情報を別の情報の中に埋め込んで隠す技術 のことを指します.
誰もが知っているもので言うと,「縦読み」が相当すると思います.
例えば下のような文章があります.
あたらしい環境になっても
りそうを高く持って
がむしゃらに進んでいこうと思います。
とても貴重な経験ができたこと、
うれしく思っています。
一見普通の文章ですが,行頭の一文字だけを集めて読んでみると「ありがとう」と言う文字が浮かび上がります.
このように,メッセージの中に,別のメッセージを隠すのがステガノグラフィです.
◻️ 画像のステガノグラフィ
今回の本題です.下の画像は一見普通の画像ですが,この画像の中にメッセージが隠されてあります.
画像のステガノグラフィはこのようにに画像ファイルにメッセージを隠して埋め込む技術です.
◼️ 【前提】画像ファイルの基礎
どうやって埋め込まれているかの仕組みの解説の前に,前提となる画像ファイルの基礎について説明します.
◻️ 画像はドットの集合
拡張子がpngなどの画像ファイルは,拡大していくと小さなドットの集合でできていることが確認できると思います.
先ほどの画像を拡大してみます.いっぱい小さいドットが見えてくると思います.
◻️ 色はRGBで作られる
先ほどpng画像ファイルは小さなドットがいっぱい集まってできている話をしました.
では次に,一つ一つのドットの色は,どのように表現されているのでしょうか.
結論から言うと,光の三原色であるRGB(Red, Green, Blue)の3色を混ぜることでドットの全ての色が表現されています.
例えばさっきの画像内のドットの一つを見てみます.
赤枠で囲ったドットを見てみると,このカーキ色はRGBをそれぞれ 112/255, 110/255, 93/255で混ぜて作られる色ということになります.
◻️ 画像ファイルの中身
上で説明したドットの色は画像ファイルではどのように格納されているのでしょうか.
画像ファイルをバイナリエディタで開いてみます.
画像に示すように,画像ファイルの実体は0と1のデータの羅列です.
(※PNG形式などはデータが圧縮されているため,ファイルの中身にそのままRGBの値が並んでいるわけではありませんが,コンピュータが処理する際には以下のようなデータになります)
先ほどのカラーコードは2進数に直すとそれぞれ,
R 112 = 01110000
G 110 = 01101110
B 93 = 01011101
となります.
つまり,コンピュータが画像を画面に表示する時,内部ではこれらの値を並べた「011100000110111001011101」というデータとして扱われていることになります.
そして,この0/1列を,MacBookなどの「画像ビューアー」が解釈・描画することで,「画像」として見ることができています.
◻️ 値を1bit変えてみる!
先ほど色はRGBのカラーコードで決まる話をしました.
ここで1bit色を変えてみたらどうなるでしょうか.
一番下のbitを反転(0↔︎1)させたものを比べてみます.
目のいい人には違いがわかるかもしれませんが,ぱっと見どちらも同じ色に見えると思います.
画像ファイル内ではすごく小さなドットの一つであることを考えると,カラーコードの一番下の値をちょこっと変えたぐらいでは普通の人にはわかりません.
これが,ステガノグラフィーを理解する上で重要なポイントです.
◼️ 文字列の埋め込み方
直前でカラーコードの下位1bitを変えたぐらいでは画像全体に大きな影響を与えないことを確認しました.
この特性を活用し,下位1ビットの値を上手いこと使って文字を埋め込むのが画像のステガノグラフィです.
具体的にどうやって埋め込むかというと,下位1bitの0/1をかき集めてきて,文字コード変換するというものです.
例を下図に示します.
色の情報が0/1列で格納されています.このうち,一番したのbitをかき集めて,(ここでは)8bitのかたまりを作ります.
この8bitを文字コード(ASCIIコード)変換します.すると文字が得られます.
これを多くのビットに対して施していくと画像ファイル内にメッセージも埋め込めるという話です.
このように,下位1bitをかき集めて文字コード変換すると読めるように,最下位ビットを改竄していくのが画像のステガノグラフィです.
◼️ 実践!
説明でわかったけど...実際に文字を埋め込んでみたい!という方向けに,文字埋め込みツール(Gemini使いました)と 埋め込んだ文字を抽出するツール(Cyber Chefを用いた)を作ったので,試してみてください.
◻️ 文字の埋め込み
好きな文字を好きな画像ファイルに埋め込めるようなものです.
使い方はREADMEファイルを参照してください.
◻️ 文字抽出
埋め込まれた文字列を抽出するためのCyber Chefレシピです.
以下,使い方.
-
CyberChefにアクセス
-
RecipeブロックのLoad recipeをクリック
-
Recipe欄に以下のコードを貼付
[ { "op": "Extract RGBA", "args": ["\\n", false] }, { "op": "From Decimal", "args": ["Line feed", false] }, { "op": "To Binary", "args": ["Line feed", 8] }, { "op": "Find / Replace", "args": [{ "option": "Regex", "string": "\\d{7}(\\d)" }, "$1", true, false, true, false] }, { "op": "Find / Replace", "args": [{ "option": "Regex", "string": "\\n" }, "", true, false, true, false] }, { "op": "Find / Replace", "args": [{ "option": "Regex", "string": "(\\d{8})" }, "$1 ", true, false, true, false] }, { "op": "From Charcode", "args": ["Space", 2] } ] -
右下の青文字「LOAD」をクリック
-
Inputブロックに画像ファイルをドラッグ&ドロップ
-
少し待つとOutputブロックに文字列が現れます
うまくいかない時は,Input と Outputブロックの右下の
-
Input character encodingとOutput character encodingがRaw Bytesになっているか -
End of line sequenceがLF(Line Feed)になっているか
確認してみてください.





