2019年3月12日 星期二

A Wormable XSS on HackMD!



在 Web Security 中,我喜歡伺服器端的漏洞更勝於客戶端的漏洞!(當然可以直接拿 shell 的客戶端洞不在此限XD) 因為可以直接控制別人的伺服器對我來說更有趣! 正因如此,我以往的文章對於 XSS 及 CSRF 等相關弱點也較少著墨(仔細翻一下也只有 2018 å¹´ Google CTF 那篇XD),剛好這次的漏洞小小有趣,秉持著教育及炫耀(?)的心態就來發個文了XD

最近需要自架共筆伺服器,調查了一些市面上支援 Markdown 的共筆平台,最後還是選擇了國產的 HackMD! 當然,對於自己要使用的軟體都會習慣性的檢視一下安全性,否則怎麼敢放心使用? 因此花了約半天對 HackMD 進行了一次原始碼檢測(Code Review)!

HackMD 是一款由台灣人自行研發的線上 Markdown 共筆系統,除了在台灣資訊圈流行外,也被許多台灣研討會如 COSCUP, g0v 或 HITCON 等當成官方的共筆存放地點,甚至還是 Ethereum 的協作平台! 除了雲端使用及企業方案外,整份原始碼也很佛心的開放出來在 GitHub 上(4500 多顆星! 最近也才知道原來 HackMD 在中國及歐洲也有許多死忠用戶!),算是很回饋台灣資訊社群的一個廠商!

平心而論,HackMD 整體程式碼品質不低,所以並沒有甚麼太嚴重的弱點,不過你也知道 XSS 不是那種想防就防得了的問題,綜觀 HackMD 歷年來關於安全相關的問題,發現都是一些老手法如 javascript:alert(1) 或 onclick , onload 等,所以相較之下這個漏洞算是比較有趣的一個 XSS,視攻擊方式甚至可以達到像是 Samy Worm 等 XSS 蠕蟲的感染效果!


P.S. 其實本來沒有要找 XSS 的,但看到寫法就覺得一定有問題,跳下去看後漏洞就自己跑出來了 ╮(╯_╰)╭ 

漏洞成因


(以下皆以 CodiMD 版本 1.2.1 來進行解說)

最初是看到 HackMD 在前端渲染 Markdown 時的 XSS 防禦所引起我的興趣,由於 HackMD 允許嵌入客製化的網頁標籤,為了防止 XSS 的問題勢必得對 HTML 進行過濾,這裡 HackMD 使用了一個 XSS 防禦函示庫 - npm/xss 來防禦! 從相關的文檔及 GitHub 上的 Issue 及星星數觀察看起來是一個很成熟的 XSS 防禦函示庫,找到問題的話也是 0day 等級,不過只是隨手看看而已沒必要還幫幫第三方函示庫找 0day 吧?

因此把焦點放到函示庫的使用上,再安全的函示庫碰到不安全的用法也會無用武之地,這也是為什麼要找專業駭客的緣故!(置入性行銷XD) 整個 HackMD 使用到 npm/xss 的位置位於 public/js/render.js 的 preventXSS 中,第一眼看到這段程式碼就直覺一定會有問題!

var filterXSSOptions = {
  allowCommentTag: true,
  whiteList: whiteList,
  escapeHtml: function (html) {
    // allow html comment in multiple lines
    return html.replace(/<(?!!--)/g, '&lt;').replace(/-->/g, '-->').replace(/>/g, '&gt;').replace(/-->/g, '-->')
  },
  onIgnoreTag: function (tag, html, options) {
    // allow comment tag
    if (tag === '!--') {
            // do not filter its attributes
      return html
    }
  },
  onTagAttr: function (tag, name, value, isWhiteAttr) {
    // allow href and src that match linkRegex
    if (isWhiteAttr && (name === 'href' || name === 'src') && linkRegex.test(value)) {
      return name + '="' + filterXSS.escapeAttrValue(value) + '"'
    }
    // allow data uri in img src
    if (isWhiteAttr && (tag === 'img' && name === 'src') && dataUriRegex.test(value)) {
      return name + '="' + filterXSS.escapeAttrValue(value) + '"'
    }
  },
  onIgnoreTagAttr: function (tag, name, value, isWhiteAttr) {
    // allow attr start with 'data-' or in the whiteListAttr
    if (name.substr(0, 5) === 'data-' || window.whiteListAttr.indexOf(name) !== -1) {
      // escape its value using built-in escapeAttrValue function
      return name + '="' + filterXSS.escapeAttrValue(value) + '"'
    }
  }
}

function preventXSS (html) {
  return filterXSS(html, filterXSSOptions)
}

為了提供開發者可以自由的客製化過濾的處理,npm/xss 提供了多個不同的選項給開發者,而其中在 onIgnoreTag 這個 callback 中,開發者判斷了如果是註解的標籤便直接回傳原始的 HTML 內容,在 JavaScript 上的註解也寫得很直白!

do not filter its attributes

可以想像開發者原本的用意應該是希望保留註解原本的內容! 既然它這麼相信註解中的內容,那我們來看一下是否可以從註解標籤中去汙染 DOM 的渲染! 我們構造如下的 HTML 內容:

<!-- foo="bar--> <s>Hi</s>" -->

把 bar--> ... 當成一個屬性的值,並在這個值中使用 --> 去閉合前方的註解標籤,如此一來便輕鬆地繞過只允許信任的 HTML 標籤及屬性,去插入惡意的 HTML 代碼!

繞過 CSP 政策


到這裡,你可能以為已經結束了,閉合前方的 <!-- 標籤後再插入 script 標籤去執行任意 JavaScript 代碼! 但事情不是憨人想的那麼簡單,為了防止未知的 XSS 攻擊,HackMD 使用了 CSP(Content Security Policy) 去阻擋未授權的 JavaScript 代碼執行! 相關的 CSP 政策如下:

content-security-policy: script-src 'self' vimeo.com https://gist.github.com www.slideshare.net https://query.yahooapis.com 'unsafe-eval' https://cdnjs.cloudflare.com https://cdn.mathjax.org https://www.google.com https://apis.google.com https://docs.google.com https://www.dropbox.com https://*.disqus.com https://*.disquscdn.com https://www.google-analytics.com https://stats.g.doubleclick.net https://secure.quantserve.com https://rules.quantcount.com https://pixel.quantserve.com https://js.driftt.com https://embed.small.chat https://static.small.chat https://www.googletagmanager.com https://cdn.ravenjs.com 'nonce-38703614-d766-4dff-954b-57372aafe8bd' 'sha256-EtvSSxRwce5cLeFBZbvZvDrTiRoyoXbWWwvEVciM5Ag=' 'sha256-NZb7w9GYJNUrMEidK01d3/DEtYztrtnXC/dQw7agdY4=' 'sha256-L0TsyAQLAc0koby5DCbFAwFfRs9ZxesA+4xg0QDSrdI='; img-src * data:; style-src 'self' 'unsafe-inline' https://assets-cdn.github.com https://cdnjs.cloudflare.com https://fonts.googleapis.com https://www.google.com https://fonts.gstatic.com https://*.disquscdn.com https://static.small.chat; font-src 'self' data: https://public.slidesharecdn.com https://cdnjs.cloudflare.com https://fonts.gstatic.com https://*.disquscdn.com; object-src *; media-src *; frame-src *; child-src *; connect-src *; base-uri 'none'; form-action 'self' https://www.paypal.com; upgrade-insecure-requests

仔細分析這個 CSP 政策,看到 unsafe-eval 這個關鍵字,第一個想到的是在 2017 å¹´ Black Hat USA 由幾個 Google Security 成員所發表的 Breaking XSS mitigations via Script Gadgets æ‰‹æ³•! 不過其實不用這麼麻煩,CSP 政策還允許了 https://cdnjs.cloudflare.com/ 這個 JavaScript hosting 服務,上方提供了許多第三方函示庫以供引入! 由於這個 CDN 提供商,繞過 CSP 就變成很簡單的一件事情了! 我們可以直接使用 AngularJS 函示庫,配合 Client-Side Template Injection 的方式輕鬆繞過!


P.S. 如果你對於 CSP 的政策不甚熟悉但還是想檢查自己的網站是否設置正確的話,可以使用 Google 所提供的 CSP Evaluator 來檢測!

最終攻擊代碼


透過註解標籤屬性的跳脫及 CSP 的繞過,最後組出來的攻擊代碼如下:

<!-- foo="-->
<script src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.min.js>
</script>
<div ng-app>
    {{constructor.constructor('alert(document.cookie)')()}}
</div>
//sssss" -->

這裡也展示了當與駭客同時編輯一份共筆時,對當前線上文件的所有人發動攻擊:





P.S. 這個漏洞已經在最新版 CodiMD 中修復了,詳情可以參考 pull request

50 則留言:

  1. I have read some just right stuff here. Definitely worth bookmarking for revisiting. I surprise how so much attempt you put to create this kind of wonderful informative site.

    사설토토
    카지노사이트
    파워볼

    回覆刪除
  2. Your article is very interesting. I think this article has a lot of information needed, looking forward to your new posts.
    바카라사이트

    回覆刪除
  3. Thanks for such a valuable post. I am waiting for your next post, I have enjoyed a lot reading this post keep it up.
    온라인카지노

    回覆刪除
  4. What a post I've been looking for! I'm very happy to finally read this post. 토토사이트 Thank you very much. Can I refer to your post on my website? Your post touched me a lot and helped me a lot. If you have any questions, please visit my site and read what kind of posts I am posting. I am sure it will be interesting.

    回覆刪除
  5. htI blog often and I truly appreciate your content.
    야설
    Feel free to visit my blog :
    야설

    回覆刪除
  6. I’m going to bookmark your site and keep checking for new details about once per week.
    국산야동
    Feel free to visit my blog : 국산야동

    回覆刪除
  7. Hi there! This article could not be written much better!
    야설
    Feel free to visit my blog : 야설

    回覆刪除
  8. I like the helpful info you provide in your articles. I’ll bookmark your blog and check again here frequently. I’m quite sure I’ll learn plenty of new stuff right here! Good luck for the next. 스포츠토토

    回覆刪除
  9. That's a great article! The neatly organized content is good to see. Can I quote a blog and write it on my blog? My blog has a variety of communities including these articles. Would you like to visit me later? 메이저안전놀이터

    回覆刪除
  10. I've been using WordPress on a number of websites for about a year and am worried about switching to another platform. I have heard good things about keonhacai. Is there a way I can transfer all my wordpress content into it? Any help would be really appreciated!

    回覆刪除
  11. Actually Magnificent. I am also a specialist in this topic so I can understand your effort.

    텍사스홀덤

    回覆刪除
  12. I’m trying to get my blog to rank for some targeted keywords but I’m not seeing very good results. If you know of any please share.

    오피헌터

    回覆刪除
  13. "First of all I would like to say awesome blog! I had a
    quick question that I'd like to ask if you do not mind. I was interested to find out how you center yourself and clear your thoughts before writing.

    I have had a tough time clearing my mind in getting my thoughts out.
    I do enjoy writing but it just seems like the first 10 to 15 minutes are wasted just trying to figure out how to begin. Any recommendations or tips?
    Kudos!"

    마사지블루

    回覆刪除
  14. Hey there! Someone in my Myspace group shared this site with us so I came to look it over.

    건마탑

    回覆刪除
  15. It’s truly a nice and helpful piece of information. I’m happy that you simply shared this helpful information with us. 파칭코

    回覆刪除
  16. I am someone who works on the web. Sometimes I like to visit overseas sites sòng bạc when I have time. Among them, I like the site related to , but your site seems to be optimized for too!! Very good

    回覆刪除
  17. What a nice post! I'm so happy to read this. baccarat What you wrote was very helpful to me. Thank you. Actually, I run a site similar to you. If you have time, could you visit my site? Please leave your comments after reading what I wrote. If you do so, I will actively reflect your opinion. I think it will be a great help to run my site. Have a good day.


    回覆刪除
  18. Why couldn't I have the same or similar opinions as you? T^T I hope you also visit my blog and give us a good opinion. 안전놀이터

    回覆刪除
  19. Do you like the kind of articles related to 메이저놀이터 If someone asks, they'll say they like related articles like yours. I think the same thing. Related articles are you the best.

    回覆刪除
  20. Extremely decent blog and articles. I am realy extremely glad to visit your blog. Presently I am discovered which I really need. I check your blog regular and attempt to take in something from your blog. Much obliged to you and sitting tight for your new post.메이저사이트모음

    回覆刪除
  21. Your article is very interesting. I think this article has a lot of information needed, looking forward to your new posts. Get permission to share. 바카라사이트

    回覆刪除
  22. I no uncertainty esteeming each and every bit of it. It is an amazing site and superior to anything normal give. I need to grateful. Marvelous work! Every one of you complete an unfathomable blog, and have some extraordinary substance. Keep doing stunning 메이저사이트순위

    回覆刪除
  23. "
    Extraordinarily new! Some extraordinarily sensible center interests! I'm especially appreciative that
    you made this article, different pieces of the site are all things considered extraordinary. 토토사이트
    "

    回覆刪除
  24. I think your website has a lot of useful knowledge. I'm so thankful for this website.
    I hope that you continue to share a lot of knowledge.
    This is my website.
    머니상

    回覆刪除
  25. make small amounts of money. This game pg 888th
    comes in an ancient war theme with 15 lines to win each day. Players can bet from £1.50 to £150 even starting with the lowest bet amount. But there is a chance to win

    回覆刪除
  26. I think your website has a lot of useful knowledge. I'm so thankful for this website.
    I hope that you continue to share a lot of knowledge.
    This is my website.
    넷마블머니상

    回覆刪除
  27. I think your website has a lot of useful knowledge. I'm so thankful for this website.
    I hope that you continue to share a lot of knowledge.
    This is my website.
    한게임머니상

    回覆刪除
  28. Thanks for such a fantastic blog. Where else could anyone get that kind of info written in such a perfect way? I have a presentation that I am presently writhing on, and I have been on the look out for such great information. 먹튀검증사이트

    回覆刪除
  29. ambpoke เว็บพนันออนไลน์ คาสิโนออนไลน์ ที่ยอดเยี่ยม MEGASLOTGAME รวมพนันทุกแบบอย่าง ทดสอบเล่นสล็อตทุกค่ายไม่ต้องสมัคร เกมยิงปลา สล็อต รวมทั้งเกมไพ่ทุกแระเภท เล่นง่ายกำไรงาม คาสิโนที่ครบถ้วน สล็อต

    回覆刪除
  30. It's a really interesting topic and it has helped me a lot. In fact, I also run a website with similar content to your posting. Please visit once 바카라검증사이트

    回覆刪除