今月はセキュリティテストについて説明する「テスターカレンダー」という記事でサイクルを続けます。 多くの人はどこから始めればよいか分からず、困難を恐れます。 KonturのWebアプリケーションセキュリティテスターであるIvan Rumakは、脆弱性を発見する基本を共有しました。 初心者はこの記事で基本的な知識を見つけ、経験豊富なテスターはCSRFに対する保護のバイパスに関するセクションが役立つことに気付くでしょう。
昨年、IvanはMail.ru脆弱性検索プログラムで4位になり 、 Hack The World 2017コンテストのトップ100に入りました。
2月に、私は仲間のテスターに脆弱性を探し、セキュリティバグのリリースをチェックするように教えることにしました。 トレーニング計画から、記事の非常に基本的な部分を取り上げました。開始する場所、HTTPとは何か、また、1つの脆弱性-保護の検索、保護、バイパスの方法について完全な分析を行いました。

どこから始めますか?
この問題は多くの初心者が直面しています。 誰かが最初にWebアプリケーションセキュリティコミュニティであるOWASPにアクセスします。 OWASPで学んだ最も有用なことは、 Webアプリケーションの最も危険で一般的な脆弱性のリストです 。 意味のあるトレーニングは、私がそれらのそれぞれを詳細に研究し始め、不慣れな単語をすべてグーグルで調べ始めたときに始まりました。 HTTPプロトコルデバイスの知識がなくても、最も一般的なクライアントの脆弱性(CSRF、XSS)を調査することは非常に難しいことが明らかになりました。
そのため、このプロトコルのデバイス、データ転送フォーマット、およびBurp設定を他のテスターに正確に教え始めました。 これは、ブラウザがすべてのHTTP要求を渡すデバッグプロキシです。 そこで、編集、分析、スキャン、再送信ができます。
別の優れた情報源は、他のハッカーからの公開レポートを読んで再生することです。
http://h1.nobbd.de/など、セキュリティバグに関する開示されたメッセージを集約するサイトがあります。 そこで、脆弱性とは何か、それらがどのように発見され、修復されるかがわかります。 実際の経験を積むには、自分でバグを再現することが重要です。 これを行うには、プラットフォームを使用して、 DVWAなどの脆弱性検索を実行できます。
HTTPについて
ユーザーのウェブアプリケーションとのやり取りがどのように機能するかを知ることは非常に重要です。 したがって、クライアントがWebサーバーと対話するためのHTTPプロトコルについて説明します。 その中で私たちは興味があります:
方法 開始するには、GETとPOSTを区別するだけで十分です。 クエリの最初の行に示されます。
GET-サイトからコンテンツを取得します。
GET / HTTP/1.1 Host: example.com
POST-そこに送るもの。
POST /endpoint HTTP/1.1 Host: example.com User-Agent: Apache-HttpClient/4.5.5 (Java/1.8.0_161) Content-Type: application/x-www-form-urlencoded param1=value1¶m2=value2
URI :ファイルまたはエンドポイントへのパス。リクエストの最初の行のスラッシュの後に示されます。
ヘッダー-ヘッダー :ユーザーエージェント、コンテンツタイプ、ホストなど 任意の名前と値を持つ標準(Accept、User-Agentなど)とカスタム(X-Auth-Token:123など)があります。
コンテンツタイプについて
Content-Typeは、パラメーターが本文で渡されるリクエストに対して指定する必要があります。 このヘッダーは、リクエストのコンテンツがどの形式で送信されるかをWebサーバーに伝えます。 キー3のコンテンツタイプ:
-アプリケーション/ json
Content-Type: application/json {"param1":"value1","param2":"value2"}
-アプリケーション/ x-www-form-urlencoded
Content-Type: application/x-www-form-urlencoded param1=value1¶m2=value2
-テキスト/プレーン
Content-Type: text/plain anytext{"param":123}><<>><xml>
サーバーに渡されるパラメーター。 名前と値が含まれています。 URIの後にParam = value&param2 = value2&param3 = value3で記述されるか、Content-Typeで指定された形式で本文に記述されます。
クッキー ユーザーを承認する最も一般的な方法。 ユーザーがサービスにログインすると、一意のキーが与えられます。一意のキーはブラウザーに保存され、このキーを使用してすべてのHTTP要求がこのサービスに送信されます。 クライアントAがクライアントBにアクセスできないように、ユーザーを識別するために使用されます。
ユーザーがUIのボタン(「保存」など)を押すと、メソッド、URI、パラメーター、およびCookieを含むそのようなHTTP要求をWebサーバーに送信します。 ブラウザ(Chrome F12->ネットワーク)で調査のために送信したリクエストをキャッチし、 Restlet ClientなどのAPIを介してクライアントを送信できます。 または、デバッグプロキシ( Burp 、Fiddler)を使用します。
HTTPプロトコルデバイスを知っていれば、特定の脆弱性の調査を開始できます。 例として、私はCSRFの脆弱性を引用します-初心者がそれから始めると便利です。
CSRFの脆弱性について
CSRF(クロスサイトリクエストフォージェリ)-脆弱なリソースにユーザーに任意のHTTPリクエストを送信させる機能。 CSRFの脆弱性は「クライアント側」です。その助けにより、他のユーザーのみを攻撃できますが、サーバーと内部インフラストラクチャは攻撃できません。
リクエストの送信元を確認しないサービスは、ウェブサイトまたは外部ドメインからの脅威にさらされています。 そのようなリクエストは、onload属性を介してformタグを使用して送信されます-つまり ページ上の要素がロードされるとすぐに送信されます。
<form>
。 htmlページのこのタグは、GETまたはPOST要求を任意のリソースに送信します。
例:
<form name=form1 action=”https://example.com/sendmoney” method=”POST”> <input type=hidden name=”amount” value=”9999”> </form>
属性:
name=”form1”
-フォーム名
action=”https://example.com/test”
リクエストの送信先
method=”POST”, method=”GET”
-使用するメソッド
enctype=”application/x-www-form-urlencoded”
-リクエストを送信するContent-Type この属性を指定しない場合、デフォルトでapplication / x-www-form-urlencodedになります。
<input>
タグを使用して、パラメーターを指定します。
その属性:
type=”hidden”
-タイプ、hiddenを使用する方がほとんど常に良いです。 ファイルをアップロードする必要がある場合、要求を次の形式で送信するボタンが必要な場合はtype=”file”
使用しtype=”file”
: type=”submit”
name=”sendmoney”
-パラメーター名
value=”9999”
-パラメーター値
ページの例:
<html><body> <form name=form1 action=”https://example.com/changepassword” method=”POST”> <input type=hidden name=”newpassword” value=”123456”></form> <body onload=”document.form1.submit()”> <!-- form1 --> </body></html>
このようなページにアクセスすると、ユーザーは知らないうちに次のようなものを送信します。
POST /changepassword HTTP/1.1 Host: example.com Content-Length: 18 Origin: https://evil.com Content-Type: application/x-www-form-urlencoded Accept: text/html, */* Cookie: auth.cookie.from.example.com=verysecret User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36 Referer: https://evil.com newpassword=123456
HTTPリクエストの送信元のサーバーにチェックがない場合、通常どおりに処理されます。 つまり evil.comのユーザーはcookie auth.cookie.from.example.com = verysecretを使用してHTTPリクエストを送信します。これはブラウザーによって置き換えられ、現在のセッションのコンテキストでexample.comはパスワードを123456に変更します。
HTMLページからリクエストを送信するには微妙な点があります。
1)formタグを介したリクエストの送信は、標準ヘッダーによってのみ制限されます。 アプリケーションのセッショントークンがCookieではなく、たとえば、承認などの各リクエストの承認ヘッダーを介して送信される場合、CSRFは適用できません。
GET /userdata HTTP/1.1 Host: example.com Accept: text/html, */* Authorization: APIKEY123123123123123123 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36 Referer: https://evil.com
2)偽のPOSTリクエストのContent-Typeは、application / x-www-form-urlencoded、multipart / form-dataまたはtext / plainのみです。 繰り返しますが、formタグの制限によるものです。
3)formタグを使用すると、GET / POSTリクエストのみを送信できます。 PUT / PATCH / DELETE / MKCOLおよびその他はスキップされません。
CSRFの検索方法
アプリケーションで作業するときにサーバーに送られる要求を監視します。 変更リクエストを選択し、csrftest.htmlファイルからformタグを介して送信してみてください。

サーバーが通常どおりcsrftest.htmlからのそのようなリクエストを受け入れ、何かを変更した場合、バグを開始できます。
作業手順:
- アプリケーションをクリックして、ブラウザコンソールまたはデバッグプロキシでリクエストをキャッチします。
- GETリクエストによって何かが変更された場合は、<img src =”パラメータを使用してすべての方法で”>としてhtmlページから繰り返してみてください。
- 変更がPOST要求によって発生し、CSRFに対する保護がない場合は、formタグで繰り返します。
- 保護されている場合は、回避してみてください。
CSRF保護
formタグを介してクロスドメインリクエストを送信する不本意なユーザーから身を守るには、そのようなリクエストが外部のサイトから送信されないようにしてください。
フォームからのリクエストがサイトから送信されたことを確認する方法は?
1)サイトで行われた各リクエストは、CookieおよびCSRFTokenカスタムヘッダーで一意のトークンを送信します。 要求を受信したら、この要求で何かを変更する前に、ヘッダー値がCookieに保存されている値と一致するかどうかを確認します。
POST /changepassword HTTP/1.1 Host: example.com CSRFToken: dadfaae9-c625-4bdf-8804-c7977d96954f Cookie: session=123123123123; CSRFToken=dadfaae9-c625-4bdf-8804-c7977d96954f Content-Type: application/x-www-form-urlencoded Content-Length: 61 newpass=123456
この保護の欠点は、GET要求の場合、このヘッダーがほとんどの場合オプションであることです。 何かを変更するエンドポイント(例:/ changepass)のアプリケーションで、POST本体からURLにパラメーターを転送し、GETのようなリクエストを作成できます(ところで、HEADとOPTIONSもこのように機能します)、リクエストは機能します本格的なPOSTとして、次のようにこの保護を回避できます。
<img src=”https://example.com/changepass?newpassword=123456”>

2)最後のアイテムと同じ、Cookieのトークンのみがパラメーターのトークンと比較されます。
POST /changepassword HTTP/1.1 Host: example.com Cookie: session=123123123123; CSRFToken=dadfaae9-c625-4bdf-8804-c7977d96954f Content-Type: application/x-www-form-urlencoded Content-Length: 61 newpass=123456&CSRFToken=dadfaae9-c625-4bdf-8804-c7977d96954f
このエンドポイントへのリクエストがURLのパラメーターを使用してGETとして行われる場合でも、攻撃者の他のユーザーのcsrftokenパラメーターは不明であり、この攻撃を抑制することは必須です。
トークンが2つの部分から生成されている場合、静的(たとえば、ユーザーのIDからのハッシュ)および動的(トークンが受信された日付からのハッシュ)に対処することができます。 その後、静的部分のみでトークンを送信できます。 または、トークンをまったく使用せずにリクエストを送信すると、Facebookにはそのようなバグがありました( https://amolnaik4.blogspot.ru/2012/08/facebook-csrf-worth-usd-5000.html )。
3)各リクエストのContent-Typeは、formタグでサポートされているものと異なる必要があります(urlencoded、text / plain、multipart / form-data)。
これは、Cookie、カスタムヘッダー、およびURLのパラメーターの両方でユーザー認証が可能な場合、CSRFからAPIを保護するための良い方法です。
サイトのルートに不適切に設定されたcrossdomain.xmlがある場合、Flashを介して、ユーザーに任意のContent-Typeでリクエストを送信させることができます。 詳細なFlash記事はこちらです。
4)同じサイトCookie。 Cookieフラグ。httponlyでの認証中に設定され、ブラウザがこれらのCookieが属していない左側のサイトからCookieを送信することを許可しません。 クールですが、すべてのブラウザがこのフラグをサポートしているわけではありません。 Originのチェックについても同じことです。クールで動作しますが、すべてのブラウザがクロスドメインリクエストに対してOriginを正しく送信するとは限りません。
今すぐチェック:
-アプリケーションでは、POSTリクエストにCSRFに対する保護があります。
-保護がカスタムヘッダーのトークンとCookieのトークンに基づいて構築されている場合、POSTとして送信される機密アクション(パスワードの変更、組織での追加ユーザーの作成、送金)は、URLのパラメーターを使用してGETに変換できませんボディおよびシステムの変更(200 OK、201 CREATED ...)。 PUT / PATCHをPOSTまたはGETに変換することに似ています。
-機密性の高いアクションが「Content-Type:application / json」で送信され、CSRFに対する保護がこの上にのみ構築されている場合、application / x-www-form-urlencoded、multipart / form-data、text /の形式で本文を含むリクエストを送信してみてくださいプレーン。 成功した場合は、インターネット上の左側のサイトから<form>
を使用して繰り返します。
-サイトのルートディレクトリには、不適切に設定されたcrossdomain.xmlはありません。これは、Flashを使用したクロスドメインリクエスト用のファイルです。 (example.com/crossdomain.xml)。 「悪い」とは、クロスドメインリクエストを任意のサイトから自分のサイトに送信できる場合であり、crossdomain.xmlでどのドメインとどのリクエストを実行できるかが明示的に記述されています。
まとめ
これで、セキュリティテストの基本事項と、トピックを深くするための情報を入手できる場所がわかったので、CSRFでプロジェクトを確認し、HTTPを理解できます。
次は? 新しいタイプの脆弱性を学び、プロジェクトでそれらを探し、それらを排除します。 一緒になって、インターネットをより安全にします!
便利なリンク
カレンダー記事のリスト:
別のアプローチを試してください
合理的なペアテスト
フィードバック:発生方法
テストを最適化する
本を読む
分析テスト
テスターはバグをキャッチし、Canerを読み、移動を整理する必要があります。
ロードサービス
QAサービスメトリック
セキュリティをテストする
顧客を知る
バックログを取る