1. 始めに
こんにちは、morioka12 です。
本稿では、バグバウンティなどの脆弱性 調査で行う、JavaScript の静的解析と動的解析についてまとめて紹介します。
免責事項
本稿の内容は、セキュリティに関する知見を広く共有する目的で執筆されており、悪用行為を推奨するものではありません。
想定読者
セキュリティ初学者・学生
特に Web Security の学習をしている方
バグバウンティに興味がある方
(脆弱性 調査をしている方)
( Web アプリケーションの開発者)
検証環境
今回は、ツールの検証環境として、「OWASP Juice Shop 」を活用します。
OWASP Juice Shop は、「OWASP Top 10 」に含まれる脆弱性 を取り入れた「やられアプリ」で、Node.js・Express・Angular などの JavaScript のフレームワーク で書かれています。
静的解析と動的解析
静的解析 (Static Analysis)
動的解析 (Dynamic Analysis)
実際にソースコード が実行されて、その挙動をベースに解析する方法
2. 静的解析 (Static Analysis)
Web アプリケーション上にある JavaScript ファイルを静的解析する場合は、主に以下のような点を確認します。
また、JavaScript ファイルの静的解析は、主に以下のような流れで行います。
対象の Web アプリケーションのドメイン から JavaScript ファイルの URL を収集する
収集した JavaScript ファイルからコードを解析してエンドポイントを列挙する
まだ未発見だったエンドポイントや API 、パラメーターを知れる可能性がある
収集した JavaScript ファイルからコードを解析してシークレットな情報を検出する
ハードコードされている API の認証情報など得れる可能性がある
収集した JavaScript ファイルで使われているライブラリやフレームワーク などを特定して潜在的 な脆弱性 を特定する
実際の Web アプリケーションで有効に活用できるセキュリティ問題を得れる可能性がある
2.1 JavaScript File の URL を収集する
getJS
getJS は、指定したドメイン から JavaScript のファイルの URL を収集することができます。
$ getJS --url https://< Domain> --complete
検証環境に対する実行結果 (クリックで表示)
$ getJS --url http://localhost --complete
http://cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3 .1 .0 /cookieconsent.min.js
http://cdnjs.cloudflare.com/ajax/libs/jquery/2 .2 .4 /jquery.min.js
http://localhost//runtime.js
http://localhost//polyfills.js
http://localhost//vendor.js
http://localhost//main.js
github.com
hakrawler
hakrawler は、クローリングツールで、URL と JavaScript のファイルを収集することができます。
$ echo " https://<Domain> " | hakrawler
検証環境に対する実行結果 (クリックで表示)
$ echo " http://localhost " | hakrawler
http://cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3 .1 .0 /cookieconsent.min.js
http://cdnjs.cloudflare.com/ajax/libs/jquery/2 .2 .4 /jquery.min.js
http://localhost/runtime.js
http://localhost/polyfills.js
http://localhost/vendor.js
http://localhost/main.js
github.com
getallurls (gau)
getallurls (gau) は、 Wayback Machine などから既知の URL を列挙するツールで、その出力結果から JavaScript のファイルのみを抽出して収集することもできます。
$ gau < Domain> | grep " .js$ " | sort -u
github.com
2.2 エンドポイントを列挙する
LinkFinder
LinkFinder は、ドメイン から JavaScript ファイル内にあるエンドポイントを列挙することができます。
$ python3 linkfinder.py -i https://< Domain> -d -o cli
$ python3 linkfinder.py -i https://< Domain> /< Path> /< JS-file> -o cli
検証環境に対する実行結果 (クリックで表示)
$ python3 linkfinder.py -i http://localhost -d -o cli
...
Running against: http://localhost/runtime.js
Running against: http://localhost/polyfills.js
https://github.com/zloirock/core-js/blob/v3.33 .2 /LICENSE
https://github.com/zloirock/core-js
Running against: http://localhost/vendor.js
text/css
http://www.w3.org/2000 /svg
/assets/i18n/
image/png
/engine.io
application/octet-stream
application/pdf
application/msword
image/photoshop
image/x-photoshop
image/psd
application/photoshop
application/psd
zz-application/zz-winassoc-psd
application/x-gtar
application/x-gcompress
application/compress
application/x-tar
application/x-rar-compressed
application/x-zip-compressed
application/zip-compressed
application/x-7z-compressed
application/gzip
application/x-bzip2
/socket.io
text/plain
application/json
https://g.co/ng/security#xss
text/html
M/d/yy
zone.js
http://www.w3.org/1999 /xhtml
http://www.w3.org/1999 /xlink
http://www.w3.org/XML/1998 /namespace
http://www.w3.org/2000 /xmlns/
http://www.w3.org/1998 /MathML/
Running against: http://localhost/main.js
/rest/admin
/application-configuration
/rest/web3
/nftUnlocked
/nftMintListen
/api/Challenges/?key =nftMintChallenge
/submitKey
/walletNFTVerify
/walletExploitAddress
/rest/admin/application-configuration
privacy-security/privacy-policy
https://w.soundcloud.com/player/?url =https%3A//api.soundcloud.com/tracks/771984076 &color =%23ff5500&auto_play =true&hide_related =false&show_comments =true&show_user =true&show_reposts =false&show_teaser =true
/assets/public/images/hackingInstructor.png
https://ponzico.win/ponzico.pdf
https://www.sec.gov/investor/alerts/ia_virtualcurrencies.pdf
assets/public/images/padding/56px.png
/api/Users
/rest/user/authentication-details/
/rest/user/login
/rest/user/change-password?current =
/rest/user/reset-password
/rest/user/whoami
https://www.googleapis.com/oauth2/v1/userinfo?alt =json&access_token =
/rest/saveLoginIp
/rest/deluxe-membership
/login
/api/BasketItems
assets/public/images/products/
/address/select
/rest/track-order
/api/Feedbacks
/rest/captcha
/160
assets/public/images/carousel/1 .jpg
assets/public/images/carousel/2 .jpg
assets/public/images/carousel/3 .jpg
assets/public/images/carousel/4 .jpg
assets/public/images/carousel/5 .png
assets/public/images/carousel/6 .jpg
assets/public/images/carousel/7 .jpg
ftp/legal.md
/api/SecurityAnswers
/api/SecurityQuestions
/rest/user/security-question?email =
/20
/40
/rest/products
/reviews
/api/Products
/api/Quantitys
assets/public/images/products/no-results.png
/search
/2fa/enter
/forgot-password
/register
assets/public/images/padding/19px.png
/api/Complaints
/file-upload
application/pdf
application/xml
text/xml
application/zip
application/x-zip-compressed
multipart/x-zip
/rest/chatbot
/status
/respond
assets/public/images/ChatbotAvatar.png
assets/public/images/uploads/default.svg
/api/Recycles
/api/Addresss
/address/edit/
/delivery-method
/address/create
/api/Challenges
/rest/repeat-notification
/rest/continue-code
/rest/continue-code-findIt
/rest/continue-code-fixIt
/rest/continue-code/apply/
/rest/continue-code-findIt/apply/
/rest/continue-code-fixIt/apply/
/snippets
/snippets/fixes
/snippets/verdict
https://docs.google.com/forms/d/e/1FAIpQLSdaNEuz0dzFA2sexCa0AJ4QOb2OYdEL04eQOLFD2Y4T-BW6ag/viewform?usp =pp_url&entry.384948954 =
https://forms.gle/2Tr5m1pqnnesApxN8
/score-board-preview
assets/public/images/padding/1px.png
http://www.w3.org/2000 /svg
/rest/image-captcha/
/rest/user
/erasure-request
/data-export
https://www.freeprivacypolicy.com/
assets/public/images/padding/81px.png
/rest/wallet/balance
/api/Deliverys
/api/Cards
/16
/10
/wallet
/deluxe-membership
/order-summary
./redirect ?to =https://blockchain.info/address/1AbKfgvw9psQ41NbLi8kufDQTezwG8DRZm
./redirect ?to =https://explorer.dash.org/address/Xr556RzuwX6hg5EGpkybbv5RanJoZN17kW
./redirect ?to =https://etherscan.io/address/0x0f933ab9fcaaa782d0279c300d73750e1311eae6
https://pwning.owasp-juice.shop/part3/donations.html
./redirect ?to =http://shop.spreadshirt.com/juiceshop
./redirect ?to =http://shop.spreadshirt.de/juiceshop
./redirect ?to =https://www.stickeryou.com/products/owasp-juice-shop/794
./redirect ?to =http://leanpub.com/juice-shop
https://opensea.io/collection/juice-shop
/rest/order-history
/orders
https://twitter.com/
/track-result/new
https://twitter.com/intent/tweet?text =
/order-completion
/payment
/#/wallet-web3
/track-result
/rest/memories
multipart/form-data
assets/public/images/JuiceShop_Logo.png
assets/public/images/deluxe/blankBoxes.png
assets/public/images/products/juicy_chatbot.jpg
https://testnets.opensea.io/0x8343d2eb2B13A2495De435a1b15e85b98115Ce05
https://testnets.opensea.io/assets/mumbai/0xf4817631372dca68a25a18eb7a0b36d54f3dbcf7/0
/score-board
address/select
address/saved
address/create
track-result/new
2fa/enter
/application-version
privacy-security/data-export
privacy-security/change-password
privacy-security/two-factor-authentication
privacy-security/last-login-ip
assets/public/images/
/profile
/dataerasure
http://www.w3.org/1999 /html
/accounting
/basket
/order-history
/recycle
/address/saved
/saved-payment-methods
https://owasp.org
https://owasp-juice.shop
/rest/country-mapping
/contact
/complain
/chatbot
/about
/photo-wall
./redirect ?to =https://github.com/juice-shop/juice-shop
./assets/i18n/
image/x-icon
assets/public/favicon_js.ico
text/css
//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3 .1 .0 /cookieconsent.min.css
//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3 .1 .0 /cookieconsent.min.js
//cdnjs.cloudflare.com/ajax/libs/jquery/2 .2 .4 /jquery.min.js
https://www.youtube.com/watch?v =9PnbKL3wuH4
runtime.js
polyfills.js
vendor.js
main.js
github.com
xnLinkFinder
xnLinkFinder は、ドメイン から JavaScript ファイル内にあるエンドポイントやパラメーターを列挙することができます。
$ python3 xnLinkFinder.py -i < Domain> -sp https://< Domain> -sf < Domain> -v
github.com
katana
katana は、クローリングツールで、オプションで JavaScript ファイルの解析と JavaScript ファイル内からエンドポイントをクロールする「-js-crawl
」があり、これを使うことでエンドポイントを列挙することができます。
$ katana -u http://< Domain> -jc
検証環境に対する実行結果 (クリックで表示)
$ katana -u http://localhost -jc
__ __
/ /_____ _/ /____ ____ ___ _
/ ' _/ _ / __/ _ / _ \/ _ /
/_/\_\\_,_/\__/\_,_/_//_/\_,_/
projectdiscovery.io
[INF] Current katana version v1.0.4 (latest)
[INF] Started standard crawling for => http://localhost/
http://localhost/
http://localhost/runtime.js
http://localhost/polyfills.js
http://localhost/main.js
http://localhost/styles.css
http://localhost/rest/country-mapping
http://localhost/redirect?to=https
http://localhost/rest/admin
http://localhost/rest/web3
http://localhost/vendor.js
http://localhost/redirect?to=http
http://localhost/assets/public/images/
http://localhost/rest/admin/application-configuration
http://localhost/api/Cards
http://localhost/address/saved
http://localhost/assets/i18n/
http://localhost/rest/order-history
http://localhost/rest/wallet/balance
http://localhost/snippets/verdict
http://localhost/snippets/fixes
http://localhost/track-result/new
http://localhost/rest/user
http://localhost/rest/image-captcha/
http://localhost/rest/continue-code-findIt/apply/
http://localhost/rest/continue-code-fixIt/apply/
http://localhost/rest/continue-code
http://localhost/rest/repeat-notification
http://localhost/rest/continue-code/apply/
http://localhost/api/Addresss
http://localhost/api/Recycles
http://localhost/address/create
http://localhost/address/edit/
http://localhost/api/Complaints
http://localhost/rest/chatbot
http://localhost/2fa/enter
http://localhost/rest/products
http://localhost/rest/memories
http://localhost/api/SecurityAnswers
http://localhost/rest/user/security-question?email=
http://localhost/rest/track-order
http://localhost/%5C/index.html
http://localhost/application/vnd.ms-word.do
http://localhost/application/vnd.openxmlformats-officedocument.wordprocessingml.do
http://localhost/angular.json
http://localhost/Highlight.js
http://localhost/like/
http://localhost/address/select
http://localhost/assets/public/images/products/
http://localhost/api/BasketItems
http://localhost/rest/deluxe-membership
http://localhost/rest/saveLoginIp
http://localhost/rest/user/whoami
http://localhost/rest/user/reset-password
http://localhost/rest/user/change-password?current=
http://localhost/rest/captcha
http://localhost/api/Deliverys
http://localhost/rest/user/authentication-details/
http://localhost/rest/continue-code-fixIt
http://localhost/rest/continue-code-findIt
http://localhost/api/Users
http://localhost/rest/user/login
http://localhost/Edge/
http://localhost/Trident/
http://localhost/zone.js
http://localhost/Zone.js
http://localhost/api/Quantitys
http://localhost/api/Products
http://localhost/api/SecurityQuestions
http://localhost/api/Challenges
http://localhost/api/Feedbacks
github.com
jsluice
jsluice は、JavaScript ファイルから URL やエンドポイントなどを列挙することができます。
$ jsluice urls https://< Domain> /< Path> /< JS-file> | jq
検証環境に対する実行結果 (クリックで表示)
(出力結果が長いため、Gist に丸ごと添付しました)
$ jsluice urls http://localhost/main.js | jq
{
" url " : " /rest/admin " ,
" queryParams " : [] ,
" bodyParams " : [] ,
" method " : "" ,
" type " : " stringLiteral " ,
" filename " : " http://localhost/main.js "
}
{
" url " : " /application-configuration " ,
" queryParams " : [] ,
" bodyParams " : [] ,
" method " : "" ,
" type " : " stringLiteral " ,
" filename " : " http://localhost/main.js "
}
{
" url " : " /rest/web3 " ,
" queryParams " : [] ,
" bodyParams " : [] ,
" method " : "" ,
" type " : " stringLiteral " ,
" filename " : " http://localhost/main.js "
}
{
" url " : " /nftUnlocked " ,
" queryParams " : [] ,
" bodyParams " : [] ,
" method " : "" ,
" type " : " stringLiteral " ,
" filename " : " http://localhost/main.js "
}
{
" url " : " /nftMintListen " ,
" queryParams " : [] ,
" bodyParams " : [] ,
" method " : "" ,
" type " : " stringLiteral " ,
" filename " : " http://localhost/main.js "
}
{
" url " : " /api/Challenges/?key=nftMintChallenge " ,
" queryParams " : [
" key "
] ,
" bodyParams " : [] ,
" method " : "" ,
" type " : " stringLiteral " ,
" filename " : " http://localhost/main.js "
}
{
" url " : " /submitKey " ,
" queryParams " : [] ,
" bodyParams " : [] ,
" method " : "" ,
" type " : " stringLiteral " ,
" filename " : " http://localhost/main.js "
}
{
" url " : " /walletNFTVerify " ,
" queryParams " : [] ,
" bodyParams " : [] ,
" method " : "" ,
" type " : " stringLiteral " ,
" filename " : " http://localhost/main.js "
}
{
" url " : " /walletExploitAddress " ,
" queryParams " : [] ,
" bodyParams " : [] ,
" method " : "" ,
" type " : " stringLiteral " ,
" filename " : " http://localhost/main.js "
}
{
" url " : " /rest/admin/application-configuration " ,
" queryParams " : [] ,
" bodyParams " : [] ,
" method " : " GET " ,
" type " : " fetch " ,
" filename " : " http://localhost/main.js "
}
...
github.com
endext
endext は、JavaScript ファイルからエンドポイントなどを列挙することができます。
$ go run main.go -l urls-js.txt
検証環境に対する実行結果 (クリックで表示)
urls-js.txt
は、以下のように JavaScript ファイルの URL 一覧が記載されているとします。
(このファイルの生成方法は、「4. その他 > JS Analyze に使える Burp の機能 > Copy URLs」で紹介しています)
$ cat urls-js.txt
http://localhost/103 .js
http://localhost/main.js
http://localhost/polyfills.js
http://localhost/runtime.js
http://localhost/vendor.js
$ go run main.go -l urls-js.txt
______ ________ __
/ ____/___ ____/ / ____/ __/ /_
/ __/ / __ \/ __ / __/ | |/_/ __/
/ /___/ / / / /_/ / /____> < / /_
/_____/_/ /_/\__,_/_____/_/|_|\__/
( * ) EndpointsExtractor Tool By @SirBugs .go Version
( * ) For Extracting all possilbe endpoints from Js files
( * ) Version: 1 .0 .5 ( Updated 3 .Vrs on 7 / 7 / 2023 )
( * ) Contact: Twitter@SirBagoza, GitHub@SirBugs, Medium@bag0zathev2
( * ) Command: go run main.go -l jsurls.txt
( ! ) You can use only -u for single URL or -l for .JS file URLs, Not both
( ! ) This tool has been received the last 3 updates at once
( 1 ) :: rest/admin
( 2 ) :: application-configuration
( 3 ) :: rest/web3
( 4 ) :: nftUnlocked
( 5 ) :: nftMintListen
( 6 ) :: submitKey
( 7 ) :: walletNFTVerify
( 8 ) :: walletExploitAddress
( 9 ) :: rest/admin/application-configuration
( 10 ) :: api/Users
( 11 ) :: rest/user/authentication-details/
( 12 ) :: rest/user/login
( 13 ) :: rest/user/reset-password
( 14 ) :: rest/user/whoami
( 15 ) :: rest/saveLoginIp
( 16 ) :: rest/deluxe-membership
( 17 ) :: login
( 18 ) :: api/BasketItems
( 19 ) :: address/select
( 20 ) :: rest/track-order
( 21 ) :: api/Feedbacks
( 22 ) :: rest/captcha
( 23 ) :: 160
( 24 ) :: api/SecurityAnswers
( 25 ) :: api/SecurityQuestions
( 26 ) :: 20
( 27 ) :: 40
( 28 ) :: rest/products
( 29 ) :: reviews
( 30 ) :: api/Products
( 31 ) :: api/Quantitys
( 32 ) :: search
( 33 ) :: 2fa/enter
( 34 ) :: forgot-password
( 35 ) :: register
( 36 ) :: api/Complaints
( 37 ) :: file-upload
( 38 ) :: rest/chatbot
( 39 ) :: status
( 40 ) :: respond
( 41 ) :: api/Recycles
( 42 ) :: api/Addresss
( 43 ) :: address/edit/
( 44 ) :: delivery-method
( 45 ) :: address/create
( 46 ) :: api/Challenges
( 47 ) :: rest/repeat-notification
( 48 ) :: rest/continue-code
( 49 ) :: rest/continue-code-findIt
( 50 ) :: rest/continue-code-fixIt
( 51 ) :: rest/continue-code/apply/
( 52 ) :: rest/continue-code-findIt/apply/
( 53 ) :: rest/continue-code-fixIt/apply/
( 54 ) :: snippets
( 55 ) :: snippets/fixes
( 56 ) :: snippets/verdict
( 57 ) :: score-board-preview
( 58 ) :: rest/image-captcha/
( 59 ) :: rest/user
( 60 ) :: erasure-request
( 61 ) :: data-export
( 62 ) :: rest/wallet/balance
( 63 ) :: api/Deliverys
( 64 ) :: api/Cards
( 65 ) :: 16
( 66 ) :: 10
( 67 ) :: wallet
( 68 ) :: deluxe-membership
( 69 ) :: order-summary
( 70 ) :: rest/order-history
( 71 ) :: orders
( 72 ) :: track-result/new
( 73 ) :: order-completion
( 74 ) :: payment
( 75 ) :: track-result
( 76 ) :: rest/memories
( 77 ) :: score-board
( 78 ) :: application-version
( 79 ) :: profile
( 80 ) :: dataerasure
( 81 ) :: accounting
( 82 ) :: basket
( 83 ) :: order-history
( 84 ) :: recycle
( 85 ) :: address/saved
( 86 ) :: saved-payment-methods
( 87 ) :: rest/country-mapping
( 88 ) :: contact
( 89 ) :: complain
( 90 ) :: chatbot
( 91 ) :: about
( 92 ) :: photo-wall
( 93 ) :: assets/i18n/
( 94 ) :: engine.io
( 95 ) :: socket.io
github.com
2.3 シークレット情報を検出する
SecretFinder
SecretFinder は、LinkFinder を元に作られたツールで、JavaScript のファイル内にある API Key や Access Token 、認証情報などの機微な情報を検出することができます。
$ python3 SecretFinder.py -i https://< Domain> -e -o cli
github.com
jsluice
jsluice は、JavaScript ファイルからシークレットな情報も検出することができます。
$ jsluice secrets https://< Domain> /< Path> /< JS-file> | jq
github.com
Mantra
Mantra は、JavaScript ファイルや HTML ファイルから API Key を検出することができます。
$ echo " https://<Domain>/<Path>/<JS-file> " | Mantra
github.com
trufflehog
trufflehog は、様々なファイルなどから認証情報を検出することができます。
trufflehog では、事前に JavaScript ファイルをローカルにダウンロードしておく必要があります。
$ trufflehog filesystem < JS-file>
github.com
また、trufflehog はブラウザの拡張機能 が存在するため、これをインストールして有効化しておくと、自動で検出してくれます。
addons.mozilla.org
chrome.google.com
Retire.js
Retire.js は、脆弱性 のある JavaScript のライブラリを検出することができます。
github.com
retire.js はブラウザの拡張機能 が存在するため、これをインストールして有効化しておくと、自動で検出してくれます。
addons.mozilla.org
chrome.google.com
ESLint
ESLint は、JavaScript のファイルに対して静的解析を行うツールで、最新のフレームワーク にもカスタムセキュリティルールで対応して解析することができます。
$ eslint < JS-directory>
また、プラグイン を活用して、様々な観点で静的解析を行うことも可能です。(以下は例)
例) セキュリティのプラグイン を活用して ESLint で静的解析する場合
$ eslint --no-eslintrc -c ~/ESLint/security/.eslintrc.json -f html -o result_eslint-security.html < JS-directory>
github.com
3. 動的解析 (Dynamic Analysis)
Web アプリケーション上にある JavaScript を動的解析する場合は、主にブラウザに搭載されている開発者ツール「DevTools 」を用いて行います。
今回は、Chrome の DevTools を用いて簡単に紹介します。
developer.chrome.com
Debug
DevTools にある「デバッグ 機能」は、特定の条件下で指定した関数にブレークポイント を設定することができます。
ブレークポイント (Breakpoint)とは、プログラムの実行を任意の場所で一時停止して、停止した箇所の変数の状態や関数の呼び出し経路(コールスタック)を確認したり、停止した箇所からコードの実行を一つずつ任意で進めながら、実行の流れを確認したりすることができます。
例えば、「postMessage がワイルドカード (*
)としてターゲットオリジンに使用されている」という条件でブレークポイント を設定します。
その場合は、「debug()
」で以下のようなコードを、DevTools の Console タブから実行します。
debug(postMessage, 'arguments[1] == "*"')
実行後は、Web ページをリロードした際に条件に当てはまる関数が見つかると、自動でブレークポイント が動作して確認することができます。
また、「debug()
」以外にも DOM のイベントにブレークポイント を設定する場合は、「monitorEvents()
」を利用します。
「monitorEvents()
」は、要素とイベントを指定することで、その要素に対するイベントの発生を監視することができます。
monitorEvents(window, 'message')
これらのように、特定のメソッドやイベントなどを動的に追って解析したい場合は、デバッグ 機能を有効的に活用すると良いと思います。
特に、特定の脆弱性 が発生しやすいメソッドやイベント、シンクやソースなどに注目したい場合に有効的な調査することができます。
www.yeswehack.com
www.yeswehack.com
labs.detectify.com
developer.chrome.com
Memory
DevTools にある「メモリ機能」は、ブラウザに読み込まれた Web ページ全体の実行時間やメモリ使用量などの情報を収集することができます。
主に「Heap snapshot」を利用することで、スナップショットを取得して Web アプリケーションの JavaScript ファイル内のエンドポイントやシークレット情報を列挙することができます。
利用方法
DevTools から Memory タブを開く
Select profiling type から「Heap snapshot」を選択して、「Take snapshot」をからスナップショットを取得する
スナップショットが完了したら、検索バー(ctrl+f
)を開く
ここで検索する条件を指定することで、条件のもとにエンドポイントや特定の文字列を列挙することができます。(例: /api
)
Network
DevTools にある「ネットワーク機能」は、ブラウザに読み込まれた Web ページ全体のファイルを収集することができます。
Network タブから、主にフィルターで JavaScript ファイルのみに抽出したり、JavaScript ファイル内にある特定の関数を列挙することもできます。(例: innerHTML
)
Lighthouse
DevTools にある「パフォーマンス測定機能」は、ブラウザに読み込まれた Web ページ全体のセキュリティ問題を検出することができます。
例として、主に以下のような点をベストプラク ティスとして検出してくれます。
Web アプリケーションが HTTPS を使用していない
クロスオリジンの宛先へのリンクが安全でない
非推奨の API が使用されている
フロントエンドの使われている JavaScript のライブラリの一覧
利用方法
DevTools から Lighthouse タブを開く
Device を「Desktop」を選択して、Categoriesを「Best practices」を選択する
「Analyze page load」で測定する
測定が完了したら、読み込まれたページに関する情報が閲覧できる
developer.chrome.com
おすすめ動画
Hacker101 - JavaScript for Hackers (Created by @STOKfredrik)
VIDEO www.youtube.com
Improve Your Hacking Skills Using Devtools | Bug Bounty Tips
VIDEO www.youtube.com
VIDEO www.youtube.com
4. その他
JS Analyze に使える Burp の機能
Copy URLs
Burp Suite を利用して Web アプリケーションをある程度クロールした後に、デフォルトの機能である Proxy タブから JavaScript ファイルの URL を列挙することができます。
Proxy タブの HTTP history タブを開く
Filter setting にある「Filter by file extension」の「Show only」をチェックして、欄に「js
」を指定して、Apply から設定します。
HTTP history タブのリクエス トが JavaScript のファイルのみになった後に、リクエス トを全て選択して、右クリックして「Copy URLs」から URL をコピーします。
コピーした URL リストをローカルのテキストにペーストして保存します。
$ cat urls.txt
http://localhost/103.js
http://localhost/103.js
http://localhost/103.js
http://localhost/main.js
http://localhost/vendor.js
http://localhost/runtime.js
http://localhost/polyfills.js
http://localhost/vendor.js
http://localhost/vendor.js
http://localhost/main.js
http://localhost/main.js
http://localhost/polyfills.js
http://localhost/polyfills.js
http://localhost/runtime.js
http://localhost/runtime.js
http://localhost/vendor.js
http://localhost/main.js
http://localhost/runtime.js
http://localhost/polyfills.js
コピーしたままでは、重複した URL がそのままあるため、sort コマンドで並び替えと重複を排除して、ツールによる静的解析ができる JavaScript ファイルの URL 一覧を作成します。(完成)
$ cat urls.txt | sort -u > urls-js.txt
$ cat urls-js.txt
http://localhost/103 .js
http://localhost/main.js
http://localhost/polyfills.js
http://localhost/runtime.js
http://localhost/vendor.js
DOM Invader
DOM Invader は、Burp の内蔵ブラウザで利用できる機能で、DOM を解析して JavaScript のソースとシンクをツリービューで表示することができます。
また、DOM Based の Reflected XSS や Prototype Pollution などの脆弱性 を検証することもできます。
Proxy タブの Intercept タブを開く
「Open browser」から Burp の内蔵ブラウザを開く
右上のブラウザの拡張機能 にある「DOM Invader」から「DOM Invader is on」を有効にする
Devtools から「DOM Invader タブ」を開いて確認することができる
portswigger.net
portswigger.net
Find scripts (Pro)
Find scripts は、Burp Suite の Professional 版でのみ利用することができる機能で、JavaScript ファイルの全てのスクリプト をエクスポートすることができます。
方法としては、 Target タブにある Site map から特定のドメイン を指定して、Engagement tools にある Find scripts を利用することで、そのドメイン にある全ての JavaScript のファイルを一括でダウンロード(Export)することが可能です。
portswigger.net
[Ex] JS Link Finder (Pro)
JS Link Finder は、Burp Suite の Professional 版でのみ利用することができる拡張機能 で、クロールしたレスポンスから JavaScript ファイルを自動でスキャンして、JavaScript ファイルの URL とエンドポイントを Burp JS LinkFinde タブから表示することができます。
また、Dashboard タブにある Issue activity 欄にも随時検出したエンドポイントを表示してくれます。
portswigger.net
[Ex] JS Miner (Pro)
JS Miner は、Burp Suite の Professional 版でのみ利用することができる拡張機能 で、クロールで見つかった静的ファイルから認証情報やサブドメイン 、エンドポイントなどを自動で検出することができます。
主に JavaScript ファイルや JSON ファイルなどの静的ファイル内を解析して、検出したら Dashboard タブにある Issue activity 欄に随時表示してくれます。
portswigger.net
[Ex] Retire.js (Pro)
Retire.js は、Burp Suite の Professional 版でのみ利用することができる拡張機能 で、クロールで見つかった JavaScript ファイルから使われているライブラリやフレームワーク に存在する潜在的 な脆弱性 を自動で検出することができます。
検出されたら、 Dashboard タブにある Issue activity 欄に随時表示してくれます。
portswigger.net
keyhacks・secrets-patterns-db
keyhacks は、漏洩して取得した API Key が有効なものがどうかを簡単にチェックする方法を示すリポジトリ (ドキュメント)です。
もし、取得した API Key があれば、ここから有効性を確認して、詳細は各 API の公式ドキュメントを確認するようにしてください。
github.com
また、secrets-patterns-db は、API Key やトーク ンなどの機微な情報に関する内容を、正規表現 でまとめたリポジトリ (ドキュメント)です。
これを参考に、jsluice などで独自の Config を作成して、JavaScript のファイルからシークレット情報を検出できるようにすると、良いと思います。
github.com
取得した JavaScript ファイルが難読化(Obfuscation)や軽量化(Minify)されている場合があります。
そのままでは、コードが読みにくい状態のため、js-beautify やオンラインの beautifier.io などを活用すると良いと思います。
github.com
github.com
また、React などで生成されるソースマップファイル(.map
)で、ソースコード の最後の方に「sourceMappingURL」としてファイル名が記載されている場合があります。(以下、例)
//#sourceMappingURL=main.2b0f621f.chunk.js.map
ソースマップファイルを直接ダウンロードしたり、「unwebpack-sourcemap」などを用いることで、簡単にフロントエンドのコードをダウンロードすることができます。
github.com
github.com
github.com
ちなみに、ソースマップファイルを ffuf などを用いてファジングで探す場合もあります。(以下、例)
$ ffuf -w js_files_path.txt -u https://< Domain> /FUZZ -mr " sourceMappingURL "
バグバウンティ入門(始め方)
バグバウンティの始め方については、以下のブログで紹介しているため、よければこちらもご覧ください。
scgajge12.hatenablog.com
参考ドキュメント
kathanp19.medium.com
anithaana3.medium.com
medium.com
infosecwriteups.com
gowthams.gitbook.io
medium.com
bitthebyte.medium.com
book.hacktricks.xyz
5. 終わりに
本稿では、バグバウンティなどの脆弱性 調査で行う、JavaScript の静的解析と動的解析についてまとめて紹介しました。
ぜひ、好みのツールを使って JavaScript ファイルの解析したり、対象の情報収集などをしてみてください。
ここまでお読みいただきありがとうございました。