現在様々なアプリケーションが提供されていますが、その一つ一つが複雑なプログラミング言語から制作されているものがほとんどです。また管理や開発の過程で、開発者はセキュリティ対策のために多くの努力が必要とされています。
そのような中でリバースエンジニアリングなど攻撃についての情報がインターネット上で簡単に得ることができたり、色々な攻撃用のツールが低価格や時には無料で入手できる時代になってきています。そこで攻撃者からアプリケーションや独自のプログラムを守るために有効なのが「難読化」です。
今回は、「難読化」とは何なのか?そして難読化の典型的な例などについてご説明いたします。
難読化とは?
プログラマーがソースコードなどを意図的に読みにくく記述することで、可読性を著しく下げたり、解析し辛くする技術を「難読化」と呼びます。プログラムやアルゴリズムを隠したり不明瞭にすることにより、攻撃者にソフトウェアプログラムをリバースエンジニアリングされることを防止できます。それらを行うことで企業秘密などの知的財産権の侵害や不正アクセスによる情報漏えいなどから保護します。
難読化はコードの動き自体には影響を与えません。しかしプログラムの構造自体は複雑にはなりますが、あくまでも読みづらくするだけで解読が完全不可能になるというわけではありません。時間をかければ解析も可能なので過信は禁物だと思ってよいでしょう。
例えば、以下のようなソースコードがあるとします 。
int i;
void write_char(char ch)
{
printf("%c", ch);
}
int main()
{
for (i = 0; i < 15; i++) {
write_char("hello, world!\n"[i]);
}
return 0;
}
難読化すると以下のようにパッと見だけでは分かりづらくなります。
int i;main(){for(i=0;i["]<i;++i){--i;}"]; data
read('-'-'-',i+++"hell\
o,world!\n",'/'/'/'));}read(j,i,p){
write(j/p+p,i---j,i/i);}
コードの難読化には様々な技術があり、それぞれ相互に補完し合って層状のセキュリティを構築することがきます。これはJavaScriptコードなどの中間レベルの命令の形式を作成する言語、またはC#やVB.NET、Managed C ++、F#などの.NET言語に最も効果的とされています。
AWSを利用する上での重要となるセキュリティの考え方と実際に運用する際に必要となるベストプラクティス、また、AWSのセキュリティサービスをどう活用すればいいのかについてご紹介したセミナーの講演資料です。
難読化の基本 5つのテクニック
難読化技術の典型的な例として以下のようなものがあげられます。
1. Renaming(名称の変更)
ほとんどの.NET言語(C#など)、iOS、JavaScript、Androidの難読化ツールで使用されている基本的な変換方法です。新しい名称は”a”、”b”、”c”などの英単語や数字、識別不可能な文字などを利用することが可能です。名称を変更することでメソッドと変数の名前が変更されます。
2. String Encryption(文字列の暗号化)
実行可能な文字列を暗号化によって隠すことでリバースエンジニアリングなどの攻撃を防ぎ、必要な場合にのみ元の値に復元することができます。暗号化については後ほど改めてご説明いたします。
3. Control Flow Obfuscation(制御フローの難読化)
制御フローの難読化は逆コンパイラを混乱させ中断させるために、偽の条件文やその他の紛らわしい構造体を追加します。有効な実行可能ロジックを生成する条件処理や分岐処理、および反復処理などの構造を合成し、逆コンパイラが試みられた時に解析困難なコードが生成されます。
4. Instruction Pattern Transformation(命令パターンの変換)
コンパイラによって作成された命令を変更します。変更後も適切な命令ではありますが、JavaScriptやC#のような高レベルの言語では正しくマッッピングされない可能性があります。
5. iterative code obfuscation(反復符号難読化)
1 つ以上の難読化アルゴリズムをコードに繰り返し適用することで、前の難読化アルゴリズムが次の難読化アルゴリズムを生成し、コードに階層性のセキュリティを追加する技術です。
難読化のメリットとデメリット
難読化することによる効果については前述した通り、アプリケーションのコードの確認や分析することをより困難にさせる技術で攻撃者からのリバースエンジニアリングや改ざんの予防に繋がります。
また難読化を行うことでデータの読み込み速度やローディングの速度、キャッシュ速度の向上などセキュリティ対策以外のパフォーマンス面のメリットも多く期待されます。
それに対しデメリットとして挙げられるのは、プログラミング自体が複雑になるために作業者側の管理作業も複雑化する点です。その分専門的な知識も必要となってきます。そのような技術的デメリットをカバーすることができれば、リスクヘッジのためにも行っておいて損はないかと考えられます。
難読化と暗号化の違いとは?【おまけ】
難読化とよく似た言葉に「暗号化」という用語があります。技術者の方なら既にご存知の情報かとは思いますが、お恥ずかしながら筆者自身は明確な違いが分からなかったので簡単にご紹介させていただきます。
「難読化」とは、攻撃者に対してコードなどを複雑化し、攻撃者から読みにくくすることです。攻略の時間稼ぎが主な目的とされています。
それに対し、「暗号化」とはデータ自体を読めなくすることを指します。鍵を持っている人のみが暗号化されたデータを複合することで解読することができます。インターネットを通じてデータのやり取りをしていると、攻撃者によってデータの中身が見られたり、データの改ざんやなりすましなど多くの危険があります。そこで第三者が見ても内容を理解できないようにするための方法として暗号化が使われています。
今回は、難読化の基本についてご説明させていただきました。サイバー攻撃者の技術も年々高度化してきているので、そのためにも早めのセキュリティ対策を行うことが重要になってくるのかもしれません。
AWSのセキュリティ対策にオススメ!
コストパフォーマンスよく実現する方法
・with コロナ期における企業システムの直近の脅威について
・NHNテコラスで推奨しているセキュリティ対策
・中小企業のお客様におすすめできるサービス