
CVE-2017-14948(D-Link 880 ファームウェア向け)
この小さな記事では、D-Link製品で見つけたバグについて説明します。D-Linkは幅広い製品を提供しており、多くの異なるルーターモデルが異なるファームウェアバージョンを搭載しています。この文書では、次のファームウェアバージョンを取り上げます: DIR-880L, DIR-868L, DIR-890L, DIR-885L, DIR-895L。 前置きはこれくらいにして、さっそく始めましょう。
D-Linkルーターを所有していなかったため、ファームウェアへの無料アクセスが提供されていたので、静的解析のみに頼ってバグを見つけることにしました。注意: このセクションではファームウェアDIR-880Lを参照しますが、他のファームウェアも同様の構造を持っています。
DIR-880Lファームウェアをダウンロードして展開した後、そのファームウェアには完全なsquashFSファイルシステムが含まれており、約2160のファイルが含まれていることがわかりました。それぞれを個別に検討したくなかったので、ユーザー入力を処理するファイルを探し始めました。
設定ファイルを解析し、HTTPの既知のヘッダーを探した後、最終的に3つのバイナリに焦点を絞り、さらに1つに絞り込みました: fileaccess.cgi です。
以下は脆弱な関数の逆アセンブリです:
signed int __fastcall content_type(char *a1)
{
char *dest; // [sp+4h] [bp-10h]@1
const char *haystack; // [sp+Ch] [bp-8h]@1
char *haystacka; // [sp+Ch] [bp-8h]@3
dest = a1;
haystack = getenv("CONTENT_TYPE");
if ( !haystack )
return -22;
haystacka = strstr(haystack, "boundary=");
if ( !haystacka )
return -22;
strcpy(dest, haystacka + 9);
return 0;
}
上記のコードでは、変数'CONTENT_TYPE'(変数haystackが指す)の内容はユーザーが制御できます(HTTPリクエストのヘッダーを通じて)。その内容は、キーワード'boundary'の後、バッファdestにコピーされますが、haystackaの長さがチェックされていません。呼び出し元の関数(アドレス0x1CE6C)を見ると、destのサイズは256バイトであると推測できます。攻撃者はCONTENT_TYPEの内容を制御できるため、'boundary='に続けて少なくとも257文字を送信して、バッファオーバーフローを引き起こす可能性があります。
同じファームウェアサンプルで、HTTPクッキーに関するさらに2つの同様のバグが見つかりました。 そのうちの1つを以下に示します:
v10 = getenv("HTTP_COOKIE");
if ( v10 )
{
strcpy((char *)&v5, &v10[v11]);
v17 = strlen((const char *)&v5);
}
ここで、変数v10はユーザークッキーを指しており、最大4kバイトまで可能です(RFC2109による)。しかし、変数v5は1024バイトの大きさです(関数のスタックフレームから推測できます)。これにより、バッファオーバーフローが発生する可能性があります。
これらのバグはD-Linkに報告され、確認されました。
これらのファームウェアサンプルはDIR-880Lと同様の構造を持ち、同じHTTPフィールドに関連する同じバグがあります。