Quantcast
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles
Browse latest Browse all 12749

【漏洞分析】Strust2 S2-046 远程代码执行漏洞两个触发点分析

0
0
【漏洞分析】Strust2 S2-046 远程代码执行漏洞两个触发点分析

2017-03-21 14:34:15
来源:安全客 作者:360天眼实验室

阅读:3285次
点赞(0)
收藏





【漏洞分析】Strust2 S2-046 远程代码执行漏洞两个触发点分析

传送门

【重大漏洞预警】Struts 2 远程代码执行漏洞(s2-045\s2-046) (含PoC)


0x00 漏洞介绍

S2-046漏洞和S2-045漏洞非常相似,都是由报错信息带入了buildErrorMessage这个方法造成的。 但是这次存在两个触发点。

Content-Length 的长度值超长

Content-Disposition的filename存在空字节


0x01 漏洞分析

Content-Length 的长度值超长

这个漏洞需要在strust.xml中加入 <constant name="struts.multipart.parser" value="jakarta-stream" />才能触发。

触发漏洞的代码在 JakartaStreamMultiPartRequest类中,processUpload函数处理了content-length长度超长的异常,导致问题触发。

privatevoidprocessUpload(HttpServletRequestrequest,StringsaveDir) throwsException{ //Sanitycheckthattherequestisamulti-part/form-datarequest. if(ServletFileUpload.isMultipartContent(request)){ //Sanitycheckonrequestsize. booleanrequestSizePermitted=isRequestSizePermitted(request); //InterfacewithCommonsFileUploadAPI //UsingtheStreamingAPI ServletFileUploadservletFileUpload=newServletFileUpload(); FileItemIteratori=servletFileUpload.getItemIterator(request); //Iteratethefileitems while(i.hasNext()){ try{ FileItemStreamitemStream=i.next(); //Ifthefileitemstreamisaformfield,delegatetothe //fielditemstreamhandler if(itemStream.isFormField()){ processFileItemStreamAsFormField(itemStream); } //Delegatethefileitemstreamforafilefieldtothe //fileitemstreamhandler,butdelegationisskipped //iftherequestSizePermittedcheckfailedbasedonthe //completecontent-sizeoftherequest. else{ //preventprocessingfilefielditemifrequestsizenotallowed. //alsowarnuserinthelogs. if(!requestSizePermitted){ addFileSkippedError(itemStream.getName(),request); LOG.warn("Skippedstream'#0',requestmaximumsize(#1)exceeded.",itemStream.getName(),maxSize); continue; } processFileItemStreamAsFileField(itemStream,saveDir); } }catch(IOExceptione){ e.printStackTrace(); } } } } 触发点在
LOG.warn("Skippedstream'#0',requestmaximumsize(#1)exceeded.",itemStream.getName(),maxSize);

之后进入了函数addFileSkippedError,我们又见到了熟悉的buildErrorMessage,而这次带入的参数为fileName

privatevoidaddFileSkippedError(StringfileName,HttpServletRequestrequest){ StringexceptionMessage="Skippedfile"+fileName+";requestsizelimitexceeded."; FileSizeLimitExceededExceptionexception=newFileUploadBase.FileSizeLimitExceededException(exceptionMessage,getRequestSize(request),maxSize); Stringmessage=buildErrorMessage(exception,newObject[]{fileName,getRequestSize(request),maxSize}); if(!errors.contains(message)) errors.add(message); }

Content-Disposition的filename存在空字节

第二种触发漏洞的方式,属于直接触发,在streams.class中,会对filename进行检查,如果检查出错,也会记录log。

publicstaticStringcheckFileName(StringfileName){ if(fileName!=null&&fileName.indexOf('\u0000')!=-1){ //pFileName.replace("\u0000","\\0") finalStringBuildersb=newStringBuilder(); for(inti=0;i<fileName.length();i++){ charc=fileName.charAt(i); switch(c){ case0: sb.append("\\0"); break; default: sb.append(c); break; } } thrownewInvalidFileNameException(fileName, "Invalidfilename:"+sb); } returnfileName; }

最终进入的是JakartaStreamMultiPartRequest类的,我们又见到了buildErrorMessage

publicvoidparse(HttpServletRequestrequest,StringsaveDir) throwsIOException{ try{ setLocale(request); processUpload(request,saveDir); }catch(Exceptione){ e.printStackTrace(); StringerrorMessage=buildErrorMessage(e,newObject[]{}); if(!errors.contains(errorMessage)) errors.add(errorMessage); } }

0x02 规则添加注意点

由于存在两种方式,因此规则不是很好添加。且存在一定情况的bypass可能。

由于strust2会对data字段逐字解析,filename后可以跟如下几种情况。

多个空格

多个空格,且里面可以添加\r\n

n个空格


【漏洞分析】Strust2 S2-046 远程代码执行漏洞两个触发点分析

\0b不可当成检测字符,\0b可以被替换成\0000,\0a - \0z 等等。


【漏洞分析】Strust2 S2-046 远程代码执行漏洞两个触发点分析

0x03 漏洞修复

升级版本到 2.3.32 、 2.5.10.1


传送门

【重大漏洞预警】Struts 2 远程代码执行漏洞(s2-045\s2-046) (含PoC)



【漏洞分析】Strust2 S2-046 远程代码执行漏洞两个触发点分析
【漏洞分析】Strust2 S2-046 远程代码执行漏洞两个触发点分析
本文由 安全客 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/3639.html

Viewing all articles
Browse latest Browse all 12749