AWS WAFv2のマネージドルールを使ってRFIから保護する

AWS WAFv2のマネージドルールを使ってRFI (Remote File Inclusion)を防げるか確認しました。結果的にCommonRuleSetで保護できることを確認しました。検証にはDVWAを使いました。脆弱性の学習やツールのテストに利用できるWebアプリケーションです。
2019.12.10

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWS WAFv2のマネージドルールを使ってRFI (Remote File Inclusion)を防げるか確認しました。結果的にCommonRuleSetで保護できることを確認しました。検証にはDVWAを使いました。脆弱性の学習やツールのテストに利用できるWebアプリケーションです。

外部ファイルの準備

DVWAに実行させるリモートファイルを用意します。mt_rand(1, 100)で1から100のランダムな数字を表示する内容です。これをS3にWeb Hostingしておきます。

<html>
<head>
<title>Random</title>
  <style>
       #section1 {height: 0%; text-align:center; display:table; width:100%;}
   </style>
</head>
<body>
<?php
echo '<div class="section" id="section1">';
echo '<h1>' . mt_rand(1, 100) . '</h1>'; 
echo '</div>'; 
?>
</body>
</html>

バケットポリシーを設定し、DVWAと自分のいる場所から接続可能にしておきます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObjectDeny",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::bucketname",
                "arn:aws:s3:::bucketname/*"
            ],
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "IPAddress1/32",
                        "IPAddress2/32"
                    ]
                }
            }
        },
        {
            "Sid": "PublicReadGetObjectAllow",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::bucketname",
                "arn:aws:s3:::bucketname/*"
            ],
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "IPAddress1/32",
                        "IPAddress2/32"
                    ]
                }
            }
        }
    ]
}

DVWAのRFI脆弱性

File Inclusionを選択すると、以下のようなページが表示されます。

DVWAのSecurity LevelをLowにします。File InclusionページのURL中にあるpageを「page=https://外部ファイル.php」のように変更すると、1から100の間のランダムな数字が表示されます。S3にあるリモートファイルを読み込み、数字が表示された結果です。この程度であれば実害はありませんが、悪意のあるファイルを読み込んでしまうと困ったことになります。

ソースコードを見てみます。Security LevelがLowの場合、以下のようにユーザーが入力したpageをそのまま受け取ります。

$file = $_GET[ 'page' ];

mediumの場合は、"http://"などを取り除いています。「page=https://外部ファイル.php」は成立しません。

$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\"" ), "", $file );

AWS WAFv2による保護

「AWS-AWSManagedRulesCommonRuleSet」を設定したところ、「page=https://外部ファイル.php」の通信をブロックできました。AWS WAFの設定方法はこちらのブログをご覧ください。

サンプルログを見ると、「GenericRFI_QUERYARGUMENTS」のルールでブロックしたことがわかります。RFIとQUERYARGUMENTSとのことで名前からもドンピシャなルールだとわかります。

さいごに

DVWAとAWS WAFv2を利用し、RFI (Remote File Inclusion)脆弱性の攻撃をブロックできることを確認しました。S3にランダムな数字を表示するPHPファイルをホスティングし、DVWAにpageクエリストリングを設定した状態でアクセスすると、サーバーにS3のリモートファイルが読み込まれ、DVWAにランダムな数字が表示されました。AWS WAFv2では「AWS-AWSManagedRulesCommonRuleSet」ルールの「GenericRFI_QUERYARGUMENTS」でRFI攻撃を遮断できることを確認しました。RFIは紹介した方法以外でも成立する可能性があるため、RFI脆弱性が発生しないようにアプリケーションを作りつつ、脆弱性診断を行うなど他の対策もしっかりと行うと抜け漏れの少ない安全なシステムになるかと思います。