30代半ばの事務職員がITエンジニアになった話

おおよそタイトルのとおり、30代半ばにしてITエンジニアのタマゴになってしまった会社員の話

【Webサーバー(IIS)】CookieにSecure属性を設定する

CookieにSecure属性がついていないという
脆弱性の指摘を受けたのでその対策


今回の環境はWebサーバーがIIS
APサーバーがtomcatという構成


tomcat側でもSecure属性の設定は
できるんだけど、サイトの構成上
httpとhttpsが混在している場合、
Cookieの情報を見にいったりしてると
うまく動かないことがあるので


アプリケーションの外側で動いていて
やりとりをオーバーラップしているような
Webサーバー側で設定してあげるのが
正解らしい


というわけで今回はIISへ設定


IISでの設定方法


設定するにはURL書き換えから設定するか
web.configの記載を修正する


GUIが売りのIISの場合、
たいがいのことはアイコンから
設定でき、その操作が
自動的にweb.configに記述されるので
ほとんどの操作はいちいちweb.configを
書き換える必要はないが敢えて


web.configと一言で言っても
IIS全体のマスター?configと
その下位に位置するサイトごとの
web.configが存在し、
通常はサイトごとのほうを編集する
サイト名を右クリックしてフォルダを開く


f:id:ykk333:20190703230931p:plain
IIS フォルダを開く


f:id:ykk333:20190703223920p:plain
IIS フォルダを開く


web.configが見当たらない場合は
なんでもいいので設定をすれば
自動的にweb.configが作成されるらしい


web.configを開いたら

以下の通り設定を記載する

<configuration>
  <system.webServer>
        <rewrite>
            <outboundRules>
                <rule name="cookie secure">
                    <match serverVariable="RESPONSE_SET_COOKIE" pattern=".*" ignoreCase="false" />
                    <action type="Rewrite" value="{R:0}; secure" />
                </rule>
            </outboundRules>
</configuration>


writeはURL書き換え
outboundRulesは出る側の通信のルール
"リクエストのあったすべてのファイルに
対するCookieの末尾にsecureをつけなさい"
という記述


前回の記事でも書いたとおり
セキュリティ上の脆弱性ということで
たびたび指摘される件だけど
これを設定することで完璧!というよりも
やらないよりやったほうがいいよね
くらいのもの


しかしながらセキュリティは高すぎるから
困るということはないものなので
設定しておくにこしたことはない

【セキュリティ】CookieのSecure属性について詳しく調べてみる

CookieにSecure属性がついてないという
ありがたーい脆弱性の指摘を受けた


Secur属性とは何かと言うと、

https通信じゃないとCookieを発行しない

というものらしい
暗号化されていないhttp通信で
Cookieでよく使われるセッションID
なんかが漏えいしたら
セッションを乗っ取られて
やりたい放題されるということかと

http通信下でのCookie secure属性の検証


いろんなサイトを読むと
httpsじゃないとCookieを発行しない
とあるので検証してみる


まずはhttpでsecure属性なし

f:id:ykk333:20190821231228p:plain
http secureなし httpヘッダー

当然Cookie情報が表示される


続いてhttpでsecure属性あり
上記の理論通りなら
Cookie情報が表示されないはず



f:id:ykk333:20190821231652p:plain
http secureあり httpヘッダー

思いっきり表示されてんじゃん…
(secure属性がついていることは確認できる)


待てよ、ブラウザ上は表示されてるけど
通信上ではちゃんと隠されてるのでは?
ということでパケットキャプチャを確認


f:id:ykk333:20190821232211p:plain
http secureあり パケットキャプチャ


ちゃんと表示されている


そりゃそうだ


Apacheの設定(検証にはApacheを使用)
が間違っているのかとかなり当惑したが


調べたところ、
secure属性があると
http通信のときは

Cookieをブラウザに保存しない

という挙動になるらしい


本当にCookieが保存されないのか検証


まずはhttpでsecure属性なしの場合

f:id:ykk333:20190821233204p:plain
http secureなし cookie情報

しっかりCookieがブラウザに保存されてる


続いてhttpでsecure属性ありの場合

f:id:ykk333:20190821233323p:plain
http secureあり cookie情報

Cookieが保存されていないことを確認


つまり正確に言うと

http通信でsecure属性があると
secure属性つきでcookieは発行されるが
ブラウザには保存されない

ということになる

考察、というか疑問


で、これの悪用のしかたはというと


・偽サイトを用意して脆弱性のある
サイトへのリンクを踏ませて
Cookieを搾取


・アクセスポイントを偽造するなどして
流れてくるCookieを搾取


…つまり通信上のCookieを盗聴してる
わけだから、被害者のブラウザに
Cookieが保存されようがされまいが
どっちでもよくて
Secure属性がついてたとしても
盗聴されるのは上記の通り


Secureどうこうよりも
通信が暗号化されているかどうかの
ほうが重要で、
・httpでのアクセスを受け付けない
・サイト内にhttp・httpsを混在させず
すべてhttpsに統一
といったことのほうが大事なんだと思う


それでもブラウザにCookieが保存されるか
されないかの違いはあるので
設定しておいたほうがいいんじゃない?
くらいのものだと認識している


大いに勘違いしているかもしれないので
間違っていたら誰か指摘してください[]

【Webサーバー(IIS)】httpヘッダーにServerのバージョンが表示されてしまう脆弱性と対策

httpヘッダーにServerバージョン情報が
表示されてしまうという脆弱性
指摘を受けた


今回はIISで動いているWebサーバーが
該当したためIISでの対策メモ
もちろんApacheやnginxでも
それぞれ対策方法があるはず

バージョンが表示されてしまう状況の再現と対策 その1


まずは普通にIEやらChromeやらEdgeで
該当のサイトにアクセスして
F12 開発用Windowを開く
ネットワークの応答ヘッダーあたりに
Serverのバージョンが表示されている

f:id:ykk333:20190724223721p:plain
ServerVersionの表示


バージョン情報を出さないようにするには
IISマネージャ
URL書き換え
規則の追加
送信規制の空の規則


f:id:ykk333:20190724224836p:plain
URL書き換え


一致するスコープ サーバー変数
変数名 RESPONSE_SERVER
変数値 パターンに一致する
使用 正規表現
パターン  .*

と設定


f:id:ykk333:20190724225056p:plain
URL書き換え


バージョンが表示されてしまう状況の再現と対策 その2


通常のアクセスだけなら上記で
対応できるのだが、
意図的に400 Bad Requestを起こすと
ヘッダーにServer情報が表示されてしまう

(一例)
curl -I -H "Host:" http://exsample.com
HTTP/1.1 400 Bad Request
Contetnt-Length:
Content-Type: text /html;
Server: Microsoft-HTTPAPI/X.XX
Date: Mon, XX XX 2019


これは通常のアクセスであれば
IIS自身が返すServerヘッダーなので
上記の設定で対応可能だが
イレギュラーなものは
Http通信を管理するドライバーである
http.sysが返すSeverヘッダー
となるため


これを表示させないようにするには
レジストリの変更が必要

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP

DisableServerHeader


という値を設置し
値のデータを 1 に設定


httpサービスの再起動

net stop http /y
net start w3svc


Serverヘッダーに限らず
httpヘッダーにバージョン情報を
細かにのせてしまうと
脆弱性のあるバージョンだった場合
攻撃されやすくなるということらしい


そもそもバージョンを表示させている
こと自体、なんにも対策がされていない
ことが見て取れるため攻撃対象に
なりやすい、と
なるほど、確かに言われればその通り


にしても、
だったらそんなもんIISやらApache
デフォルトで表示しないように
なってればいいんじゃないかと
思うのは自分だけではあるまい

【Webサーバー(IIS)】httpヘッダーにASP.NETのバージョンが表示されてしまう脆弱性と対策

httpヘッダーにASP.NETバージョン情報が
表示されてしまうという脆弱性
指摘を受けた


実は詳しくは理解してないけど
.NETはJavaなんかと
同列のプログラムの
フレームワークだと認識している


たとえばJavaで書かれたアプリは
Apacheを使おうがIISを使おうが動くけど、
.Net系は同じMicrosoft製の
WindowsServerとIISの組み合わせ
じゃないと動かない?


ゆえに今回のケースはIISでしか
発生しないと思われる


バージョンが表示されてしまう状況の再現


状況次第とは思うけど
今回のケースでは
どうにかして

500 Internal Server Error

をだすと


f:id:ykk333:20190702232159p:plain
ASP.Net version情報

応答ヘッダー部分に
X-ASPNet-Version: 4.XXXX
とバージョン情報が表示されるというもの


ちなみに関係ないけど
phpで500エラーを意図的にだすには
以下のようにするらしい

<?php
header('HTTP/1.1 500 Internal Server Error');
?>

バージョンが表示されないようにするための対策


バージョンというかそもそも
X-ASPNet-Version:
という項目自体を出さなくする


必須で表示しなければいけない
項目は決まっているので
アプリ側が許せば
それ以外の項目は基本的に
表示・非表示の制御は
できる、、、
のかもしれない(自信なし)


設定するにはweb.configの
記載を修正する


GUIが売りのIISの場合、
たいがいのことはアイコンから
設定でき、その操作が
自動的にweb.configに記述される


しかし、マニアックなこととなると
web.configを直接編集しないと
いけないらしい


web.configと一言で言っても
IIS全体のマスター?configと
その下位に位置するサイトごとの
web.configが存在し、
通常はサイトごとのほうを編集する
サイト名を右クリックしてフォルダを開く


f:id:ykk333:20190703230931p:plain
IIS フォルダを開く


f:id:ykk333:20190703223920p:plain
IIS フォルダを開く


当初、フォルダのなかにweb.configが
見当たらずかなり悩んだが
なんでもいいので設定をすれば
自動的にweb.configが作成されるらしい


web.configを開いたら
configurationの中のsystem.webの中に
以下の通りX-ASPNet-Versionを無効化する
設定を記載する

<configuration>
  <system.web>
    <httpRuntime enableVersionHeader="false" />
  </system.web>
</configuration>


httpヘッダーには実は非常に多くの
情報が含まれていて、デフォルトの
まま表示させてしまうと
攻撃者にとって有用な情報が
多々あるというのが最近
身をもって分かってきた


一般ピーポーには
バージョンが分かったくらいでは
どうしようもないけど
玄人にしたらよい手掛かりになって
しまうのだろう


インターネットに公開している
Webサーバーを持っている限り
気をつけるに越したことはない

【Squid】リバースプロキシサーバー・SSLアクセラレータのdefaultsiteの挙動について

Squidとは


そういえば、プロキシサーバーや
リバースプロキシってなに?
って聞かれるとイマイチ
はっきり答えられない


意外といろんな仕事をしているので
一概にこれと言えないからなのかも
しれない


例えば
サーバーが複数台あったとして
今どき通信は暗号化されてて当たり前
普通にするとすべてのサーバーに
SSL証明書が必要だけど
いちばん手前にリバースプロキシ
サーバーを置いて、こいつにだけ
SSL証明書を持たせる


いったん通信をすべてリバプロで
受けて各サーバーに振り分け、と
そうすればSSL証明書
ひとつで済むという話


このSSLアクセラレータという機能が
今回携わった案件
と言ってもリバプロとサーバーが
1対1で、それ意味あるの?
と言えなくもない状態だけど


で、このプロキシやリバースプロキシ
のなかではかなりの確率で
Squidというサービスが仕事をしている

Squid.confの設定


Squidの設定は基本的にConfigファイルを
いじることで行う
もしかしたら使いやすいコンソールなぞ
存在するのだろうか


端的に言うと、リバースプロキシとしての
機能は以下の2行に凝縮されている
と言っても過言ではないと思う

https_port 192.168.0.1:443 accel cert=certificate.pem key=key.pem defaultsite=192.168.0.2 protocol=http
cache_peer 192.168.0.2 parent 80 0 no-query originserver
192.168.0.1の443ポート(https)に対してリクエストがきたら
certとkeyの証明書を使ってhttps通信をしたうえで
192.168.0.2に対して80ポート(http)で転送しなさい

で、defaultsiteがどういう意味かと言うと

httpリクエストにHostがない場合にはホスト名は192.168.0.2にしなさい

という意味

具体的には192.168.0.2サーバーの
環境変数Server_nameにdefaultsiteの
値を代入している


つまり、前回・前々回の記事にも
からむけど、リダイレクト先には

https://[Server_name]/xxx

を返すので
ローカルIPが漏えいする原因となる


転送先の192.168.0.2サーバーの
Apache.confに強制的に
Server_nameの値を入れ込んで
みたところ、やはり通信上
手前にあるSquidが優先されるらしく
対策はdefaultsiteの値をホスト名と
しておくしかないらしい

defaultsiteについてまだまだいろいろ


さて、Squidhttpsで通信を受けて
httpで転送しました、
が、転送先(192.168.0.2)からSquid
対する通信をhttpsにする機能は
持ち合わせていない(たぶん)


https(443)の通信しか許可していない
というケースは多いはずだから
このままだとhttpが蹴られてエラーが
発生するのがお約束のコース


なので、どこかでhttpsSquidに返す
ような仕掛けを作ってあげることが必要


今回の案件ではこともあろうに
クラッチ開発したアプリ側に
この仕掛けを作ってあった


Server_nameが192.168.0.xxx
(ぜんぜん関係ないアドレスだけど
Squid.confのdefaultsiteと一致)
だったらhttpsで返すという設定…


ちゃんと動いている間はよかったけど
リバースプロキシを入れ替えた際に
問題が発生、アプリ様がhttps
返さなくなる…


なのでアプリ側の設定はとりあえず
たぶんずっと無視してApacheの機能で代用


状況証拠から推察するに
Squid2(2.6)からSquid3(3.5)に
バージョンが上がった際に、
転送先のServe_nameを
Squid.confのdefaultsiteに
書き換えるという挙動が
変更になったと思われる


確認できる限り、
Squid3.5ではServer_nameは
元のまま書き換わっていない


これを示している文献は
見つかっていないが
Squid自体がもともと
http1.0での通信をベースに
作られているということを
鑑みると一定の信憑性はあるかと


この調査だけで2~3ヶ月かかり
自宅のLinuxにもSquidを導入したりで
えらく大変だった、けど
得るものも多かったかもしれない
意図せずして自宅にWebサーバーを
構築できる日も近いかもしれない

【Webサーバー(Apache)】ローカルIPアドレスが漏えいしてしまうという脆弱性と対策について

ローカルIPがばれてしまう脆弱性への対策 Apache


インターネットに公開している
Webサーバーについて
脆弱性の診断を受けたところ、
特定の条件下でローカルIPが露呈
されてしまう脆弱性が発見される


IISのサーバーだけでなくApache
サーバーでも発見された


ちなみにIISApacheとnginxの
シェアはほとんど同じくらいらしい


ということはおのずと
対策についてもそれぞれ
覚えないといけなそうだが
これもいい機会と思っておこう


Apacheにおいての対策は
Sever_nameを指定しておくこと

httpリクエストとServer_nameの関係


Server_nameとは
Apache内で使われている環境変数のこと
一見自身のサーバー名が格納されるように
見える

http(またはhttps)://exsample.com でアクセス
 ↓
Server_name : exsample.com


として返してくれる
実はこれ

> HEAD /xxxx HTTP/1.1
> Host: exsample.com
> User-Agent: xxxx
> Accept: */*


こんなかんじで送信した
httpリクエストのHost部分を参照している


つまり
IP直打ちでアクセスすると

http://12.34.56.78 でアクセス
(※グローバルアドレス)
 ↓
Server_name : 12.34.56.78


IPで返してくることになる
ここでhttp1.0・Hostなしで
リクエストを送信すると

> HEAD /xxxx HTTP/1.0
> Host: 
> User-Agent: xxxx
> Accept: */*


Sever_nameはどうなるかと言うと

Server_name : 192.168.1.100


"Hostを読んで格納したいけど
空白だからローカルIPを返しとけ"
という挙動になるらしい


これがローカルIPが漏えいしてしまう理屈


Server_nameの設定


なので対策のひとつとしては
http1.0でのリクエストが来ようが
Server_nameをあらかじめ固定しておき
常に一定の値を返すこと


Apacheのconfigファイルで
変数を強制的に指定

SetEnv Server_name  exsample.com

または

SetEnvif _ .* Server_name=exsample.com
※条件つき書式
 と言ってもどんな条件でも
 Sever_nameをexsample.comにしろ
 というだけの意味


configファイルは
旧来のApacheだと

httpd.conf

というファイル名
Ubuntuに導入したApache
(Apache2?)
従来httpd.confでまとめられていた
configがばらけている様子

envvars

というファイルを編集するっぽい

【Webサーバー(IIS)】ローカルIPアドレスが漏えいしてしまうという脆弱性と対策について

ローカルIPがばれてしまう脆弱性への対策 IIS


インターネットに公開している
Webサーバー(IIS)について
脆弱性の診断を受けたところ、
特定の条件下でローカルIPが露呈
されてしまう脆弱性が発見される


IISにおいての対策は
結論から言うと
バインドの設定で
ホスト名を指定すること


とはいうものの
ここまでたどり着くのは
紆余曲折あったわけで…


バインドの設定

まず試したのは
実はバインドの設定

インターネットインフォメーションサービス(IIS)マネージャー
 ↓
サイト
 ↓
(サイト名 exsample.com)
 ↓
バインド
 ↓
ホスト名 に(exsample.com)をいれる

f:id:ykk333:20190620220121p:plain
IISオプション

こうするとかならず
http(またはhttps);//exsample.com
でないとアクセスできなくなる
グローバルIPでもアクセスできない


ここに問題があった


どういうわけか
同じサイトなのに
ホスト名を2つつけて
別サイトにアクセスしているかの
ような意味の分からない運用を
していたため


http://exsample.com
はつながるけど
http://test.com
はつながらない
という不具合が発生
(中身は同じサイト)


そもそもサイトにアクセスする
ときのURLをしばるだけで
対策に効果があるのか?
ということでいったんボツ


リダイレクトの設定


脆弱性が発見されたのは
実在するフォルダに対して
http://exsample.com/folder
と末尾に" / "をつけないと
そのフォルダにリダイレクト
されてしまうために起こる
というもの


なので
http://exsample.com/folder/
にアクセスされたときに
トップページにリダイレクト
されるようにしてしまおうと
考えた


まずはIISにリダイレクトが表示
されていない場合、

f:id:ykk333:20190620222135p:plain
IISリダイレクト

こんなところに設定があった

インターネットインフォメーションサービス(IIS)マネージャー
 ↓
サイト
 ↓
(サイト名  exsample.com)
 ↓
HTTPリダイレクト
 ↓
このリダイレクト先に要求をリダイレクト
にトップページのURLを入力

f:id:ykk333:20190620222437p:plain
IISリダイレクト


一見うまくいったように見えた
が、肝心のトップページから
ログインする際にリダイレクトが
発生するため、
ログイン→リダイレクト→
トップページ(ログイン画面)
のループという
お粗末な状況が発生


この案もボツ


http1.0 の無効化


http1.0でリクエストを
送信した場合に脆弱性
あるので、そもそも
http1.0を禁止してしまえば
いいのでは、という発想


どんな影響があるかわからない
ので普通に考えて却下

再度、バインドの設定


試行錯誤した結果、
バインドの設定で
ホスト名を追加すれば
同じ中身でも
違うURLを設定できる
とのこと
まさしく運用どおり


さらに
そのホスト名でしか
アクセスを受け付けない


ということは
ホスト名が不明の場合
つまりhttp1.0リクエストで
Hostヘッダーがない場合も
つながらないということ

これだ!

f:id:ykk333:20190620222730p:plain
IISバインド

というわけで
ローカルIPアドレス
表示されてしまうという
脆弱性に対して
対策ができましたとさ