【博文推薦】OA高危漏洞的修復(fù)過(guò)程
21日信息安全部副總監(jiān)轉(zhuǎn)來(lái)一封郵件,關(guān)于OA的重大安全隱患,一是越權(quán)訪問(wèn)的問(wèn)題;二是struts版本問(wèn)題,經(jīng)過(guò)一段時(shí)間的整改,現(xiàn)將問(wèn)題描述和解決方案及實(shí)施過(guò)程總結(jié)如下:
越權(quán)訪問(wèn)漏洞
風(fēng)險(xiǎn)等級(jí):高危
問(wèn)題類型:程序漏洞
問(wèn)題描述:
由于OA系統(tǒng)檔案查詢模塊沒(méi)有對(duì)查詢者的權(quán)限進(jìn)行完整驗(yàn)證,導(dǎo)致攻擊者可以利用該漏洞在查詢模塊通過(guò)修改工號(hào)的方式遍歷公司所有員工的個(gè)人信息。(注:editStaffInfoByCode參數(shù)值即工號(hào))
漏洞地址:
curl 'https://oa.*******.com/dependence/queryStaffinfoByStaffId.action' -H 'Cookie: Hm_lvt_0f350e5390b92578122a09670da4e18a=1444457881;JSESSIONID=17F532AA5A02473F18BFC2251D9EB4CD.s39;Hm_lvt_f5127c6793d40d199f68042b8a63e725=1444382434,1444640491,1445232940;Hm_lpvt_f5127c6793d40d199f68042b8a63e725=1445234011' -H 'Origin: https://oa.*******.com' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: zh-CN,zh;q=0.8' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36' -H 'Content-Type: application/json;charset=UTF-8' -H 'Accept: application/json, text/javascript, */*; q=0.01' -H 'Referer:https://oa.*******.com/dependence/staffInfoAdd.action?editStaffInfoByCode=FX006635&command=detail&selfstaffinfo=showFiled' -H 'X-Requested-With: XMLHttpRequest' -H 'Connection: keep-alive' --data-binary '{"staffinfoVo":{"staffinfoEntity":{"staffId":"FX006635"}}}' --compressed
解決方案:
1.修改網(wǎng)站代碼,添加權(quán)限驗(yàn)證功能,可以劃分用戶組,根據(jù)用戶組進(jìn)行權(quán)限劃分并嚴(yán)格限制用戶的訪問(wèn);
2.復(fù)用管理范圍和數(shù)據(jù)權(quán)限功能(mybatis攔截器對(duì)查詢進(jìn)行攔截并處理),使數(shù)據(jù)查詢控制在管理范圍的范疇內(nèi);
3.前端不向后端傳遞參數(shù),用于查詢的工號(hào)在后端從redis服務(wù)器上直接拉取當(dāng)前用戶的工號(hào);
4.前端傳遞的參數(shù)不使用工號(hào),而使用檔案的uuid代理主鍵,防止攻擊者使用偽造數(shù)據(jù)遍歷;
Struts2命令執(zhí)行漏洞
風(fēng)險(xiǎn)等級(jí):高危
問(wèn)題類型:程序漏洞
問(wèn)題描述:
OA系統(tǒng)使用的struts2框架版本較低,存在遠(yuǎn)程代碼執(zhí)行漏洞,攻擊者可利用該漏洞遠(yuǎn)程進(jìn)行執(zhí)行命令、上傳腳本后門文件等操作,進(jìn)而直接獲取服務(wù)器權(quán)限。
漏洞地址:
https://oa.*******.com/main/index.action?redirect:${%23a%3d(new%20java.lang.ProcessBuilder(new%20java.lang.String[]{%27cat%27,%27/etc/passwd%27})).start(),%23b%3d%23a.getInputStream(),%23c%3dnew%20java.io.InputStreamReader(%23b),%23d%3dnew%20java.io.BufferedReader(%23c),%23e%3dnew%20char[50000],%23d.read(%23e),%23matt%3d%23context.get(%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27),%23matt.getWriter().println(%23e),%23matt.getWriter().flush(),%23matt.getWriter().close()}
解決方案:
1.升級(jí)struts2框架到最新版本,將struts2升級(jí)到2.3.15.1
2.在升級(jí)的過(guò)程中導(dǎo)致 StrutsModuleConfigProvider 類在加載classpath 下的struts配置文件出錯(cuò);
3.通過(guò)以下方法解決該錯(cuò)誤
1.在pom.xml中更新版本號(hào)
- <struts-version>2.3.15.1</struts-version>
2.將struts2的自動(dòng)裝載配置文件方法重寫如下
- public class StrutsModuleConfigProvider extends XmlConfigurationProvider {
- //需要解析加載的文件路徑
- private static final String FILE_PATTERN = "classpath*:com/fx/**/server/META-INF/struts.xml";
- public StrutsModuleConfigProvider() {
- Map<String, String> mappings = new HashMap<String, String>();
- mappings.put("-//OpenSymphony Group//XWork 2.1.3//EN",
- "xwork-2.1.3.dtd");
- mappings.put("-//OpenSymphony Group//XWork 2.1//EN", "xwork-2.1.dtd");
- mappings.put("-//OpenSymphony Group//XWork 2.0//EN", "xwork-2.0.dtd");
- mappings.put("-//OpenSymphony Group//XWork 1.1.1//EN",
- "xwork-1.1.1.dtd");
- mappings.put("-//OpenSymphony Group//XWork 1.1//EN", "xwork-1.1.dtd");
- mappings.put("-//OpenSymphony Group//XWork 1.0//EN", "xwork-1.0.dtd");
- mappings
- .put(
- "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN",
- "struts-2.0.dtd");
- mappings
- .put(
- "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN",
- "struts-2.1.dtd");
- mappings
- .put(
- "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN",
- "struts-2.1.7.dtd");
- setDtdMappings(mappings);
- }
- /**
- * (non-Javadoc)
- *
- * @see com.opensymphony.xwork2.config.ContainerProvider#needsReload()
- */
- @Override
- public boolean needsReload() {
- return true;
- }
- /*
- * (non-Javadoc)
- *
- * @see com.opensymphony.xwork2.config.ContainerProvider#register(com.opensymphony.xwork2.inject.ContainerBuilder,
- * com.opensymphony.xwork2.util.location.LocatableProperties)
- */
- @Override
- public void register(ContainerBuilder containerBuilder,
- LocatableProperties props) throws ConfigurationException {
- super.register(containerBuilder, props);
- }
- /*
- * (non-Javadoc)
- *
- * @see com.opensymphony.xwork2.config.PackageProvider#loadPackages()
- */
- @Override
- public void loadPackages() throws ConfigurationException {
- super.loadPackages();
- }
- @Override
- protected Iterator<URL> getConfigurationUrls(String fileName)
- throws IOException {
- List<URL> urls = new ArrayList<URL>();
- Resource[] resources = getAllResourcesUrl();
- for (Resource resource : resources) {
- urls.add(resource.getURL());
- }
- return urls.iterator();
- }
- /**
- * 獲取系統(tǒng)中需要搜尋的struts的配置
- *
- * @return
- * @throws IOException
- */
- private Resource[] getAllResourcesUrl() {
- ResourcePatternResolver resoler = new PathMatchingResourcePatternResolver();
- try {
- return resoler.getResources(FILE_PATTERN);
- } catch (IOException e) {
- e.printStackTrace();
- }
- return new Resource[0];
- }
在大的項(xiàng)目的開(kāi)發(fā)中,如果采用了struts2,就有可能有很多的struts2的配置文件,雖然struts2提供通配符和action的自動(dòng)加載,但我們一般還是很難將所有的配置文件采用一個(gè)單一的action配置文件來(lái)解決,因此就產(chǎn)生了很多的action配置文件。如果我們將所有的配置文件存放在一個(gè)配置文件中,這樣在項(xiàng)目間的協(xié)同開(kāi)發(fā)和測(cè)試就會(huì)出現(xiàn)混亂,而最好的開(kāi)發(fā)模式就是每個(gè)模塊都有自己的action配置文件,而系統(tǒng)會(huì)自動(dòng)搜索到所有的配置文件,采用自動(dòng)加載的方式來(lái)完成struts2的初始化。
雖然在struts2中提供在web.xml文件中配置config參數(shù),將說(shuō)有需要加載的配置文件的路徑寫在其中,以逗號(hào)分隔,這樣對(duì)于大的項(xiàng)目來(lái)說(shuō)還是很難實(shí)施的,最好的辦法還是采用自動(dòng)掃描的方法,我們可以擴(kuò)展struts2的ConfigurationProvider接口,在web.xml中配置自定義的加載類即可,這樣就解決了struts2配置文件自動(dòng)加載的問(wèn)題。
另外,struts2的漏洞時(shí)升級(jí)到2.3.15.1時(shí)報(bào)下面錯(cuò)誤
java.lang.NoSuchMethodError: ognl.SimpleNode.isEvalChain(Lognl/OgnlContext;)Z
原因是因?yàn)閛gnl的版本也需要跟著升級(jí)需要升級(jí)到3.0.6