シェルコード
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2015/10/10 16:23 UTC 版)
符号化
多くのプロセスでは注入できるデータには制限(フィルター)があるため、シェルコードはその制限内で書く必要があり、それにはコードを小さくすること、ヌル文字を途中に含めないこと、英数字のみにすることなどが含まれる。このような制限に対処する方法はいくつかある。
- 設計と実装の最適化により、シェルコードを大きさを減らす。
- シェルコードで使えるバイトの範囲の制限に対応するため、実装を修正する。
- 通常なら注入できないバイトのパターンを生成するため、自己書き換えコードを使う。
命令コードをネットワーク経由でそのまま送信するとセキュリティソフトによって検出されるため、自己解凍コードやポリモルフィックコードで符号化されることが多い。
符号化方法
ブラウザを対象として利用する場合、シェルコードはパーセントエンコーディング、"\uXXXX"エンコード、HTMLでの文字エンコードを使ってJavaScriptの文字列として符号化される。例えば、IA-32アーキテクチャで2個のNOP命令を符号化することでどう見えるかを示す。まず符号化しない状態では、次のようになる。
90 NOP 90 NOP
これはパーセントエンコーディングで符号化した文字列とした場合、次のようになる(unescape()はデコード関数)。
unescape("%u9090");
"\uXXXX"エンコードで文字列とした場合、次のようになる。
"\u9090";
そして、HTMLでの文字エンコードで文字列とした場合、
"邐"
あるいは
"邐"
となる。
ヌル文字排除
一般にシェルコードはヌル文字を終端とする文字列として対象プロセスに注入されるため、ヌル文字(一般に0x00)をその途中で使うことはできない。途中にヌル文字があると、そこまでしか文字列としてコピーされない。従ってヌル文字に相当するコードがシェルコードの途中にある場合、シェルコードは最後まで実行されない。
途中にヌルバイトを含むシェルコードからヌルを含まないシェルコードを生成するには、同じ効果を持つ別の命令列に置き換える。例えば、IA-32アーキテクチャで以下の命令があるとする。
B8 01000000 MOV EAX,1 // Set the register EAX to 0x000000001
即値の1が符号拡張されるため、ヌルバイトが命令に含まれている。
33C0 XOR EAX,EAX // Set the register EAX to 0x000000000 40 INC EAX // Increase EAX to 0x00000001
この命令列は先の命令と同じ効果があるが、バイト数が少なくなるだけでなく、ヌルバイトも含まない。
英数字または印字可能文字
ある状況では、印字可能な文字(制御文字以外)や英数字だけしか注入できない場合がある。そのような状況ではシェルコードを書くのに使える命令の種類は大きく制限される。そのための技法は Phrack 57号で Rix が発表しており[2]、それによれば任意のコードを英数字のみのコードに変換することができる。よく使われる技法は自己書き換えコードで、デコーダ部分は制限されたコードのみで動作するよう書く必要がある。シェルコード本体も例えば英数字のみのコードに符号化しておき、デコーダがそれを注入後に書き換え、その後実行する。
Unicode
最近のプログラムでは、文字列にUnicodeを使っている。多くの場合、ASCII文字列は処理前にUnicodeに変換される。UTF-16なら各文字に2バイトを使用する(一部は4バイト)。ASCII文字列をUTF-16に変換すると、元の文字列の各バイトの後ろにゼロバイトが挿入される。Phrack 61号で Obscou が示したとおり[3]、この変換後も正しく動作するシェルコードを書くことは可能である。任意のシェルコードをUTF-16化したときに動作するよう自動変換するプログラムが存在している。これも、自己書き換えコードを基本としている。
|
- ^ Sockets, Shellcode, Porting, & Coding: Reverse Engineering Exploits and Tool Coding for Security Professionals. by James C. Foster and Stuart McClure (April 12, 2005). ISBN 1-59749-005-9
- ^ “Writing ia32 alphanumeric shellcodes”. Phrack (2001年11月8日). 2008年2月29日閲覧。
- ^ “Building IA32 'Unicode-Proof' Shellcodes”. Phrack (2003年8月13日). 2008年2月29日閲覧。
- ^ “Architecture Spanning Shellcode”. Phrack (2001年8月11日). 2008年2月29日閲覧。
- シェルコードのページへのリンク