利用在一個流行的wordpress插件上發(fā)現(xiàn)的漏洞進(jìn)行攻擊可以很輕而易舉的攻陷全球成千上萬的網(wǎng)站,比如最近的WP GDPR Compliance。一個插件出現(xiàn)漏洞則代表著所有使用這個插件的網(wǎng)站都存在巨大風(fēng)險。但是能不能在wordpress圈子內(nèi)找到一個比一個流行插件漏洞更具有攻擊性的漏洞呢?這就是這篇文章的主要內(nèi)容。本文將介紹研究人員今年五月份在wordpress上發(fā)現(xiàn)的一個具有蠕蟲特性的存儲XSS漏洞的過程
事件簡介
WordPress.org掌管著wordpress cms所使用的所有插件和主題倉庫。此外,它還管理著主題/插件開發(fā)者用于修改代碼的賬號。在今年的五月份,研究人員在wordpress.org上發(fā)現(xiàn)了一個具有蠕蟲特性的存儲XSS漏洞。漏洞點(diǎn)出現(xiàn)在上文所提到的倉庫中的插件版本編號處。因此任何一個插件開發(fā)者都擁有實(shí)現(xiàn)本次XSS攻擊的條件。
研究人員在開發(fā)coderisk.com網(wǎng)站時檢測到該漏洞(他們的工作是為wordpress每一個插件的版本進(jìn)行排序,因此注意到這個漏洞)。他們通過自己的一個插件對該漏洞進(jìn)行了驗(yàn)證。在下文當(dāng)中,將會講述漏洞成因以及它是如何影響其他插件的用戶。
技術(shù)細(xì)節(jié)
因?yàn)閣ordpress.org的開源性,我們得以通過代碼審計來判斷該漏洞存在的可能性。
WordPress.org使用wordpress CMS構(gòu)建。在官網(wǎng)上展示的插件內(nèi)容只是一個模板文件所生成的,插件開發(fā)者無法通過操作來通過展示的內(nèi)容影響官網(wǎng)的安全性。
插件開發(fā)者不與官網(wǎng)直接交互,而是通過SVN來完成修改插件文件,更新插件等等操作。當(dāng)一個插件開發(fā)者通過了wordpress的審核后,他就擁有了與SVN交互的能力,可以通過獲得的SVN地址來對他的插件進(jìn)行修改等。這里所獲得的權(quán)限相當(dāng)于他獲得了wordpress.org開發(fā)者用戶賬號一樣。wordpress官網(wǎng)上的插件信息(比如插件名,插件描述,插件版本等)通過插件的readme.txt和插件php主文件獲取。官網(wǎng)將會時刻關(guān)注插件倉庫的變化以便于及時更新插件的數(shù)據(jù)。
我們發(fā)現(xiàn)這個漏洞的原因是在版本號輸出到倉庫的插件頁面前并沒有做任何的過濾處理。
下面的代碼展示了版本號是如何輸出的
wordpress.org/public_html/wp-content/plugins/plugin-directory/widgets/class-meta.php
第43行 <li><?php printf( __( 'Version: %s', 'wporg-plugins' ),
第44行 '<strong>' . get_post_meta( $post->ID, 'version', true ) . '</strong>' ); ?></li>
如同上文所說,在倉庫里,插件通過特定的模板展示它的信息。插件的其他信息,比如版本號,會作為meta data插入到模板中展示。
下面的代碼則展示了版本號從數(shù)據(jù)庫中取出并沒有經(jīng)過任何的過濾和清洗就輸出了。那么現(xiàn)在,如果版本號在存儲到數(shù)據(jù)庫前也沒有進(jìn)行任何的過濾的話,則存儲型XSS存在。而版本號是從插件的php主文件的一個特別的header中讀出。
wordpress.org/public_html/wp-content/plugins/plugin-directory/cli/class-import.php
第56行 namespace WordPressdotorgPlugin_DirectoryCLI;
第57行 ?
第58行 class Import {
第59行 ?
第60行 public function import_from_svn( $plugin_slug ) {
第61行 ?
第62行 $data = $this->export_and_parse_plugin( $plugin_slug );
第63行 ?
第64行 $headers = $data['plugin_headers'];
第65行 ?
第66行 update_post_meta( $plugin->ID, 'version', wp_slash( $headers->Version ) );
正如我們從代碼中看到的一樣,方法WordPressdotorgPlugin_DirectoryCLIImport:import_from_svn()
(第60行)負(fù)責(zé)將SVN中的更改與存儲在插件倉庫中的數(shù)據(jù)同步。而方法export_and_parse_plugin()
(第62行)負(fù)責(zé)將插件的信息提取出來(從上文提到過的readme.txt和php主文件),并保存重要的更改。版本號作為元數(shù)據(jù)插入到變更中,最終被更新到官網(wǎng)上的插件介紹中。而在變更和保存的過程中,對于版本號只應(yīng)用了wp_slash()方法,而這個方法沒有對XSS作任何保護(hù)。至此利用鏈完整
漏洞的危害
利用這個漏洞,需要一個開發(fā)者賬號。因?yàn)樵趙ordpress上傳一個插件就可以獲取到開發(fā)者賬號了,因此該漏洞利用難度低。
攻擊者可以將payload插入到它的插件版本號中,每一個在官網(wǎng)的插件倉庫中瀏覽到該惡意插件的用戶都會被攻擊。那么這個漏洞的危害到底有多大呢?
我們來想象一下,一個有開發(fā)者權(quán)限的用戶可以在WordPress.org上添加其他賬號作為插件的貢獻(xiàn)者。這樣一來被添加的賬號會獲得對該插件SVN的完全控制權(quán),從而可以修改插件的代碼。不僅如此,被添加的賬號還具有插件的訪問控制權(quán)限,可以刪除和添加其他賬號作為插件的貢獻(xiàn)者,比如可以不需要經(jīng)過任何認(rèn)證刪除插件的作者。
我們可以在payload中添加一些簡單的ajax來進(jìn)行這樣的操作。攻擊者可以設(shè)計一個payload,使得當(dāng)擁有開發(fā)者權(quán)限的用戶訪問受此XSS感染的插件頁面時,向被感染的用戶的插件添加一個賬號作為貢獻(xiàn)者。之后,攻擊者再利用這個秘密添加的貢獻(xiàn)者賬號,繼續(xù)將payload插入到本次被感染的插件的版本號中,從而進(jìn)行下一輪的傳播。對于payload的首輪傳播可以在論壇上發(fā)布新插件(含payload的惡意插件)宣傳帖子進(jìn)行。
另一個在admin儀表盤上的反射性XSS
在找到第一個漏洞后,我們使用RIPS 對WordPress.org代碼庫進(jìn)行了掃描。發(fā)現(xiàn)了另一個在admin儀表盤上的反射性XSS漏洞。
wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/tools/class-stats-report.php
第1行 public function show_stats() {
第2行 ?
第3行 if ( isset( $_POST['date'] ) && preg_match( '/[0-9]{4}-[0-9]{2}-[0-9]{2}$/', $_POST['date'] ) ) {
第4行 $args['date'] = $_POST['date'];
第5行 } else {
第6行 $args['date'] = '';
第7行 }
第8行 ?
第9行 $stats = $this->get_stats( $args );
第10行 ?
第11行 printf(
第12行 __( 'Displaying stats for the %1$d days preceding %2$s (and other stats for the %3$d most recent days).', 'wporg-plugins' ),
第13行 $stats['num_days'],
第14行 $stats['date'],
第15行 $stats['recentdays']
第16行 );
在上面代碼的第3行中,從$ _POST [‘date’]收到的用戶輸入用preg_match進(jìn)行正則匹配。然后沒有經(jīng)過其他轉(zhuǎn)移,直接輸出了這個從用戶接受的值(第14行)。而這里的正則匹配模式顯然缺了個^
使得可繞過構(gòu)造payload,比如<script>alert(1)</script> 0000-00-00
總結(jié)
在本文中,我們介紹了在WordPress.org網(wǎng)站上發(fā)現(xiàn)的兩個漏洞。第一個是插件庫中一個嚴(yán)重的存儲型XSS,任何在插件庫中擁有插件的用戶都可以利用它。如果惡意攻擊者利用它,會造成嚴(yán)重的后果。第二個是wordpress.org/plugins admin儀表盤中反射型的XSS,它展示了正則表達(dá)式中的一個小疏忽也會導(dǎo)致一個大漏洞。
原文地址:https://blog.ripstech.com/2018/wordpress-org-stored-xss/