標籤:

深入分析 CVE-2018-1045 MSA-18-0004

漏洞信息分析

漏洞信息的原話是這樣的

「可以在日曆塊中的事件名稱中注入JavaScript。但通常情況下,創建活動的能力只提供給信任的用戶(如教師),所以不會被標記為具有XSS風險,而被視為安全問題。」

Xss注入點在』日曆塊中的事件名稱中』

於是註冊了一個賬號,根據描述找了一下,並沒有找到』event name』,但是找到了一些較為相近的,單單根據上面的漏洞描述信息,感覺xss注入點可能是在類似下面的鏈接的頁面里。

可能一:

learn.moodle.net/calend

可能二:

learn.moodle.net/calend

繼續查看信息,找到一個diff

很明顯,這裡的修復方法是對$name這個參數使用了clean_text()函數進行了過濾,也就是原來的$name變數是存在xss注入的。

代碼審計分析

下面下載3.3.4版本的源碼進行代碼審計分析一下

(為什麼下載修復後的3.3.4版本 不下載存在漏洞的3.3.3版本呢?因為3.3.3版本我沒找到,而且3.3.4版本和3.3.3版本在這個漏洞上的不同只在於一句代碼,所以我們完全可以拿3.3.4版本來分析。)

分析目標有兩個

  • 找出$name變數具體是在哪裡傳過來的(找到可控的點)
  • 分析$name變數在沒有進行clean_text()函數過濾時最後是在哪裡輸出,是如何導致xss注入的,如何構造payload
  • 分析修補方案是否存在繞過(由於時間關係,這次暫不分析這一點)

漏洞修復點在/calendar/lib.php的1460行

這一行未修復前的代碼為

跟進html_writer::link方法,class html_writer 類在/lib/outputcomponents.php第1590行,link方法在1732行,這裡我整理了一下相關的代碼,讓邏輯更加清晰一點,貼出整理後的關鍵代碼,可以得到如下邏輯

通過閱讀這個邏輯可以知道,$name變數的變化過程是$name–$text–$contents,

,變數$popupcontent返回的內容的最後的格式肯定是類似這個樣子的 <a ………>$name</………….a>

然後後面的變數的傳遞過程就是$popupcontent–$popupdata–$data–$cell然後最後實際上就是把$popupcontent輸出到html頁面,實際上就是把

<a ………>$name</………….a> 這樣的內容輸出到頁面,並且在這個過程中(從返回$popupcontent到輸出的過程中)沒有對$name做任何的過濾。

下面我們可以驗證一下輸出的內容是不是像分析的 <a ………>$name</………….a> 這樣的格式的

Ps:這裡要說明一下,因為我搭建了很久都沒有把那個moodle.的網站搭建起來,按照官方文檔去搭建總是會顯示安裝出錯,谷歌了好久也沒搞定,所以最後很無奈,只能直接在這個頁面做測試了(需要先登錄)

learn.moodle.net/calend

我們審查一下元素,可以看到

確實是符合<a ………>$name</………….a> 這樣的格式的在這裡$name=test

說明我們上面的分析是正確的。(這個頁面的版本什麼的可能會有發生一定的變化,發生的變化應該也是對$name變數進行了過濾而已,並不會影響$name輸出的位置,而且我們這裡使用的是 字元串『test』進行的驗證,目的是驗證」我們上面的分析返回的$popupcontent值的格式是<a ………>$name</………….a>這樣的」 ,這裡雖然版本會不一樣,但實際上應該是不會影響這一個的驗證的。)

既然上面我們已經分析和驗證了,輸入的$name,最後會以<a ………>$name</………….a>的格式輸出,而且在這個過程中沒有對$name進行過濾,那麼在$event->name傳遞到$name的過程中,如果也沒有對其進行過濾的話,這就可能造成xss注入了。

下面先分析$name的來源,有四處 分別在1444、1452、1454、1457行(實際上都是傳入的$event-name)

先跟進一下format_string方法,在/lib/weblib.php 1409行,此部分代碼有點多就不貼出了,但是可以發現這裡也是沒有對$event-name變數進行過濾的。

結合上面的分析,可以知道從1452、1454、1457行得到的$name是會存在xss注入的。

下面分析$name = get_string(『namewithsource』, 『calendar』, $a);

跟進get_string方法,在/lib/moodlelib.php 7031行,內容如下

我們繼續跟進class lang_string這個類,在/lib/moodlelib.php 9827行

貼出部分關鍵代碼

這部分的代碼有點多,具體邏輯細節也稍微有點複雜,但是根據最初的這幾句代碼

我們可以知道,但其實我們的重點是要分析$name有沒有被過濾,也就是分析$a->name有沒有被過濾(因為可控變數是$event->name,傳給了$a->name)所以我們只要關注在$a->name變數的傳遞過程中是否被過濾了就可以了。

經過跟蹤$a的傳遞過程,並沒有發現對$a->name有做過什麼過濾,所以從第1444行進來的$name變數也是存在xss的

$name = get_string(namewithsource, calendar, $a);

並且根據代碼的注釋

以及初始漏洞的描述

以及我們上面的分析過程,我們可以知道$name變數是the event name in the calendar block,而且這個是我們完全可控的。也就是在類似這樣的頁面中

learn.moodle.net/calend

這裡我們只要輸入<script>alert(0)</script>或者<img data-original=0 onerror=alert(0)>即可驗證此漏洞。

(但是網頁learn.moodle.net/calend已經修復了這個漏洞,我沒有辦法在該網頁上驗證~然後moodle這個網站我又嘗試了很久也沒有搭建起來,總是會安裝報錯,谷歌也暫時沒有找到有用的解決辦法)

總結:

本漏洞存在的原因是存在可控輸入點 Event title而且傳遞到$name中並且未經任何過濾就按以下格式直接輸出<a….>$name</…a> 由此導致了xss注入 (此格式是簡化格式)

(較完整格式類似下圖)

關於漏洞利用:

但是這裡利用這個漏洞需要用戶先進行登錄,我們才能打開日程管理模塊,才能進行xss注入,所以利用起來可能會顯得非常的雞肋。

因為這裡是屬於存儲型的xss,目前想到的一種利用方法就是 攻擊者註冊賬戶A,並在自己的日程管理模塊中注入盲打cookie的xss代碼,這樣如果其他用戶B訪問查看了A的日程事件安排event的話,這時候就會執行A注入進去的xss代碼,可能能夠盲打到訪問的用戶B的cookie。

很遺憾的是沒能夠把環境搭建起來進行實際的測試。

漏洞修復

只需要更改/calendar/lib.php的1460行代碼,把原來的

$popupcontent .= html_writer::link($dayhref, $name);

改為

$popupcontent .= html_writer::link($dayhref, clean_text($name));

即可

推薦閱讀:

【阿里聚安全·安全周刊】Intel晶元級安全漏洞事件|macOS存在漏洞
火絨安全周報:iOS源碼遭泄露 谷歌火狐擴展程序存漏洞或致用戶數據遭泄露
【阿里聚安全技術公開課】移動APP漏洞風險與解決方案
招行網銀曝漏洞:客戶信息泄露可被修改,回應稱系伺服器緩存

TAG:漏洞 |