很多人很容易忽略的是DDE注入:導(dǎo)出格式為csv,xls時(shí),或許你可以嘗試構(gòu)造這個(gè)漏洞,它不會(huì)對(duì)網(wǎng)站本身產(chǎn)生危害,但會(huì)對(duì)終端用戶造成任意OS命令執(zhí)行等危害。
Excel解析機(jī)制
在Excel任何以
'='字符開(kāi)頭的單元格都將被電子表格軟件解釋為公式,如果我們輸入=1+2,則表格會(huì)顯示為:3
等于'='加'+'減號(hào)' - '在'@'符號(hào)都可用于在Microsoft Excel中觸發(fā)公式解釋,這個(gè)可以幫助我們?cè)诘忍?hào)=被過(guò)濾時(shí),使用其他運(yùn)算符繞過(guò)

用戶準(zhǔn)備導(dǎo)出的Excel表格內(nèi)容

導(dǎo)出后以'='字符開(kāi)頭的單元格被解析為3
漏洞危害
可以使用
= cmd | '/ C calc' !A0彈計(jì)算器,或者使用=cmd|'/k ipconfig'!A0彈出ipconfig命令。如果系統(tǒng)可以實(shí)現(xiàn)彈框效果,說(shuō)明我們可以執(zhí)行任意的js代碼,比如:
添加用戶
開(kāi)啟任意應(yīng)用程序:IE
操作注冊(cè)表
信息泄露,超鏈接功能 Hyperlink創(chuàng)建快捷方式并進(jìn)行跳轉(zhuǎn) 等
防御手段
- 一般的防御手段為,在生成電子表格時(shí),以任何危險(xiǎn)符號(hào)開(kāi)頭的字段應(yīng)該以單引號(hào)、撇號(hào)(')或空格作為前綴,確保單元格不被解釋為公式,但存在可能被繞過(guò)的風(fēng)險(xiǎn)
// tableExport.js 部分源碼
function preventInjection (str) {
if (str.length > 0 && defaults.preventInjection === true) {
var chars = '=+-@';
if (chars.indexOf(str.charAt(0)) >= 0)
return ('\'' + str); // 若查找到以=+-@開(kāi)頭的字符,添加單引號(hào)'作為前綴
}
return str;
}

單元格前加單引號(hào)'防止解析
- 更好的防御手段為,根據(jù)業(yè)務(wù)需求控制用戶輸入為字母數(shù)字字符;或黑名單過(guò)濾
=或-號(hào)開(kāi)頭的單元格數(shù)據(jù),過(guò)濾=(-)cmd或=(-)HYPERLINK或concat等
- 通過(guò)給導(dǎo)出的td添加
style="mso-number-format:'\@'; vnd.ms-excel.numberformat:'\@'",設(shè)置單元格為文本格式,可以完美解決代碼被解析
<!-- 我是用這種方法解決的 -->
<!-- 首先需要處理的td標(biāo)簽上加上 data-tableexport-msonumberformat="\@" -->
<td data-tableexport-msonumberformat="\@">=1+2</td>
// tableExport.js 部分源碼
// 獲取td標(biāo)簽上data-tableexport-msonumberformat屬性值,并設(shè)置style
var tdcss = $(cell).attr('data-tableexport-msonumberformat');
if (typeof tdcss === 'undefined' && typeof defaults.mso.onMsoNumberFormat === 'function')
tdcss = defaults.mso.onMsoNumberFormat(cell, row, col);
if (typeof tdcss !== 'undefined' && tdcss !== '')
tdstyle = 'style="mso-number-format:\'' + tdcss + '\';vnd.ms-excel.numberformat:\''+ tdcss + '\'';

此方法將單元格設(shè)置為文本格式,完美解決