IPアドレスのフィルタリング対策について

ipv3 未分類

フィッシングサイトのフィルタリング設定をすり抜けるために、わざとIPアドレスを8進数や16進数にエンコードしてすり抜けるという手法が報告されていたので、実験してみました。
 フィッシングサイトは、ウィルス対策ソフトなどがURLのフィルタリングを行って、一般のユーザが接続しないようにする対策を講じています。
 このフィルタリングをかいくぐるために、URLではなくあえて特殊なエンコードを用いたIPアドレスを使って接続させる方法が報告されています。

●フィルタリングの仕組み
 ユーザがサイトのURLリンクすると、
  http://ayasiisaito**.jp , 100.202.10.**
   └>ウィルス対策サイト等の有害データベースにURLやIPが載っているか照合する
      該当あり → エラーメッセージを表示して接続させない
      該当なし → そのままHPを表示する
 という仕組みでフィルタリングを行っています。

●問題点
 一つのフィッシングサイトに接続する表記が無数に存在することになり、
   ・データベースが膨大になる
   ・照合に時間がかかる
   ・表記方法によってはフィルタリングをすり抜ける
 という問題が考えられます。

実験環境

メイン機 windows 11 Home 10.0.22621
VMWare上にubuntu 22.04.3 (IP 192.168.12.128)
 公開フォルダ /var/www/html 上に次のHTMLを配置しています

<html>
<body><h1>HELLO HTML!</h1></body>
</html>

接続試験(curlを使って接続確認を行う)

windowsのコマンドプロンプトから次のコマンドを入力し、VM上のHTMLを読み込みます。

c:\>curl 192.168.19.128

次の結果を得ることができ、正常につながっていることが確認できました。

<html>
<body><h1>HELLO HTML!</h1>
</body>
</html>

実験1 IPアドレスを8進数で記入する

windowsのコマンドプロンプトから次のコマンドを入力します。

C:\>curl 192.168.019.128
curl: (6) Could not resolve host: 192.168.019.128
C:\>curl 192.168.023.128
<html>
<body><h1>HELLO HTML!</h1>
</body>
</html>

19を019と表記すると、接続できなくなりますが、
 10進数 19 → 8進数 23
として、8進数で指定すると、接続することができます。
 このことから、頭に0がついている数字は8進数とみなしているようです。
 8進数と10進数を混在させた表記でも正常に接続できました。

C:\>curl 0300.0250.023.0200
C:¥>curl 192.0250.19.0200
C:¥>curl 192.168.19.0200
C:\>curl 192.0250.023.0200
//いずれの入力でも結果は同じ
<html>
<body><h1>HELLO HTML!</h1></body>
</html>

実験2 IPアドレスを16進数で記入する

16進数は数字の頭に「0x」をつけます。
次のコマンドを入力したところ、一部のURLを16進数で指定しても接続することを確認できました。

C:\>curl 192.168.0x19.128
curl: (28) Failed to connect to 192.168.25.128 port 80 after 21035 ms: Couldn't connect to server
C:\>curl 192.168.0x13.128
<html>
<body><h1>HELLO HTML!</h1></body>
</html>

16進数、10進数、8進数混在のURLが動くのか試したところ、

C:\>curl 0xc0.0xa8.0x13.0x80
C:\>curl 0xc0.0250.023.128
C:\>curl 192.0xA8.023.0200
//いずれの入力でも結果は同じ
<html>
<body><h1>HELLO HTML!</h1></body>
</html>

という結果になり、混在していても接続が可能でした。

実験3 IPアドレスを2進数で表記する

続いて、2進数ではどうかと思い、次のコマンドを試しましたがエラーになりました。

C:\>curl 192.168.0b00010011.128
curl: (6) Could not resolve host: 192.168.0b00010011.128

C:\>curl 192.168.0b00110001.128
curl: (6) Could not resolve host: 192.168.0b00110001.128

もしやリトルエンディアンかと思い、両方試していますが、リゾルベのエラーになっており、2進数のIPアドレスは解決できない仕様となっているようです。

実験4 IPアドレスのオクテット結合について

IPv4アドレスなのに、第3オクテットまでしかないものや、第一オクテットまでしか表記されていないものもあったので、次の実験をしました。

C:\>curl 192.168.4992
<html>
<body><h1>HELLO HTML!</h1></body>
</html>

計算式は次の通りです
 (第三オクテット×256)+第四オクテット
 19×256+128 = 4992
ということは、第一オクテットだけのIPアドレスも作れそうですね。

C:\>curl 3232240512
<html>
<body><h1>HELLO HTML!</h1></body>
</html>

予想通り第一オクテットだけのIPアドレスを作ることができました。
計算式は次の通りです。
(第一オクテット×16777216)+(第二オクテット×65536)+(第三オクテット×256)+第四オクテット
(192×16777216)+(168×65536)+(19×256)+第四オクテット=3232240512

ということは、16進数化してもつながりそうですね。

C:\>curl 0xC0A81380
<html>
<body><h1>HELLO HTML!</h1></body>
</html>

やっぱりつながりました。
第一と第二、第三と第四を結合すれば、IPV6風「http://0xabcd.0x23de/」のIPアドレスも作れると思い、次のコマンドで実験しましたが、失敗でした。

C:\>curl 49320.4992
curl: (6) Could not resolve host: 49320.4992
C:\>curl 0xC0A8.0x1380
curl: (6) Could not resolve host: 0xC0A8.0x1380

結合するには最下位のオクテットから順に結合する必要があるみたいです。

ならば、次のIPアドレスならいけるか!

C:\>curl 0xc0.0xa8.0x1380
<html>
<body><h1>HELLO HTML!</h1></body>
</html>

いけました! 新規格IPv3風ですw

まとめ

このようにIPアドレス一つで無数の表記方法があるのに驚きました。
しかし、表記方法は無数でも最終的に接続するIPアドレスは1つだけなので、IPデコードを行って、結合したIPアドレスでフィルタリングをかければいいだけの話だと思うのですが、なにかできない理由かあるのでしょうか。