LDAP注入

  • 0x00 前言
  • 0x01 LDAP出现背景
  • 0x02 LDAP的特性
    • 0x02.1 LDAP协议
    • 0x02.2 LDAP存储
    • 0x02.3 LDAP入口 & 对象类 & 属性
    • 0x02.4 LDAP基本语法
    • 0x02.5 LDAP查询语法
  • 0x03 LDAP注入攻击剖析
    • 1、引言
    • 2、概览
    • 3、常见的LDAP环境
    • 4、Web应用中的LDAP注入
      • 4.1、AND注入
        • 4.1.1、案例1:绕过访问控制
        • 4.1.2、案例2:权限提升
      • 4.2、OR注入
        • 4.2.1 案例1:信息泄露
    • 5、LDAP盲注入
      • 5.1 AND盲注
      • 5.2 OR盲注
      • 5.3 利用案例
        • 5.3.1 发现属性
        • 5.3.2 Booleanization
        • 5.3.3 字符集削减
  • 0x04 防御LDAP注入
  • 0x05 补充
  • 0x06 参考资料

0x00 前言

想学习LDAP注入,在网上找了一圈资料后,发现还是乌云上的资料比较全面,故做下学习记录。

0x01 LDAP出现背景

LDAP(Lightweight Directory Access Protocol):轻量级目录访问协议,是一种在线目录访问协议,主要用于目录中资源的搜索和查询,是x.500的一种简便实现。是运行在TCP/IP之上的协议,端口号:389,加密:636(SSL)

x.500申明了目录客户端和目录服务器使用的是目录访问协议(DAP),然而作为应用层协议,DAP要求完整的7层OSI协议栈操作,会要求比小环境(配置、资源有限的环境)所能提供更多的资源,因此需要一种轻量级的协议来代替x.500,LDAP正是因此而生。

随着互联网的广泛使用,web应用的数量呈爆炸式增长,而这些应用的资源和数据呈分布式存储于目录中。通常不同的应用会有专属于自己相关数据的目录,即专有目录。专有目录数量的增长导致了信息孤岛(一种不能与其他相关信息系统之间进行互操作或者协调工作的信息系统)的出现,系统和资源的共享及管理变得日益困难。

以查找联系人和加密证书为例,太多的目录明显会给计算机搜索带来巨大的压力,当然随之出现了相应的解决方案,如x.500,不过在介绍x.500之前先讨论一下目录和关系型数据库之间的一些关系,因为前面提到了Web应用的数据是存储在目录中,而不是数据库中。的确,目录和数据库有很多共同之处,都能存储数据,并在一定程度上进行搜索和查询。

不同之处在于目录适合于存放静态数据,而且不同于数据库,目录中存储的数据无论在类型和种类较之数据库中的数据都要更为繁多,包括音频、视频、可执行文件、文本等文件,另外目录中还存在目录的递归。相比之下,数据库中存储的数据在格式和类型都有较严格的约束,数据库有索引、视图、能处理事务(通常包含了一个序列的对数据库的读、写操作)。简单来说,数据库更多见于处理专有类型的数据,而目录则具有通用用途。目录中的内容发生变化后会给搜索操作带来不便,因而目录服务在进行优化后更适宜于读访问,而非写、修改等操作。

0x02 LDAP的特性

0x02.1 LDAP协议

简单了解一下LDAP:LDAP不定义客户端和服务端的工作方式,但会定义客户端和服务端的通信方式。另外,LDAP还会定义LDAP数据库的访问权限及服务端数据的格式和属性。LDAP有三种基本通信机制:没有处理的匿名访问;基本的用户名、密码形式的认证;使用SASL、SSL的安全认证方式。LDAP和很多其他协议一样,基于TCP/IP协议通信,注重服务的可用性、信息的保密性等。部署了LDAP的应用不会直接访问目录中的内容,一般通过函数调用或者API,应用可以通过定义的C、Java的API进行访问,Java应用的访问方式为JNDI。

0x02.2 LDAP存储

数据库主要是三个DB,TABLE,ROW数据都是按记录一条条记录存在表中。而LDAP数据库,是树结构的,数据存储在叶子节点上。

LDAP目录中的信息是按照树形结构组织的:

dn:一条记录的位置
dc:一条记录所属的区域
ou:一条记录所属的组织
cn/uid:一条记录的名字/ID

这种树结构非常有利于数据的查询。首先要说明是哪一棵树(dc),然后是从树根到目标所经过的所有分叉(ou),最后就是目标的名字(cn/uid),借用一张图来表明结构如下:

具体到如何定义,如下:

dn:cn=stan,ou=linux,ou=computer,dc=ourschool,dc=org
objectClass:organizationalPerson
cn:stan
cn:小刀
sn:小刀
description:a good boy//保存为LDIF文件,可以导入到LDAP数据库中

LDAP目录以入口(entry,目录中存储的基本信息单元)的形式存储和组织数据结构,每个入口有一个唯一标识自己的专属名称(distnguished name),DN由一系列RDNs(relative distinguished names)组成。另外还有两个常见的结构,对象类和属性。对象类会定义独一的OID,每个属性(attribute)也会分配唯一的OID号码。

0x02.3 LDAP入口 & 对象类 & 属性

  • 入口(entry):是目录中存储的基本信息单元,上图中每一个方框代表一个entry。一个entry有若干个属性和若干个值,有些entry还能包含子entry。
  • 对象类(objectClass):对象类封装了可选 / 必选的属性,同时对象类也是支持继承的。一个entry必须包含一个objectClass,且需要赋予至少一个值。而且objectClass有着严格的等级之分,最顶层是top和alias。例如,organizationalPerson这个objectClass就隶属于person,而person又隶属于top。

  • 属性(Attribute):用来存储字段值。被封装在objectClass里的,每个属性也会分配唯一的OID号码。

入口点和属性之间的关系为:

0x02.4 LDAP基本语法

一个圆括号内的判断语句又称为一个过滤器filter。

("&"or"|"(filter1)(filter2))
  • =(等于)
    查找“ 名 ”属性为“ John ”的所有对象,可以使用:
(givenName=John)
//这会返回“名”属性为“John”的所有对象。圆括号是必须的,以便强调LDAP语句的开始和结束。
  • &(逻辑与)
    如果具有多个条件并且希望全部条件都得到满足,则可使用此语法。例如,如果希望查找居住在Dallas并且" 名 "为 " John "的所有人员,可以使用:
(&(givenName=John)(l=Dallas))
//请注意,每个参数都被属于其自己的圆括号括起来。
整个LDAP语句必须包括在一对主圆括号中。
操作符&表明,只有每个参数都为真,才会将此筛选条件应用到要查询的对象。
  • |(逻辑或)

满足一个条件即可。显示居住在Dallas或者“ 名 ”为“ John ”的所有人员。可以使用:

(|(givenName=John)(l=Dallas))
  • !(逻辑非)
    此操作符用来排除具有特定属性的对象。假定您需要查找“ 名 ”为“ John ”的对象以外的所有对象。则应使用如下语句:
(!givenName=John)
//此语句将查找“名”不为“John”的所有对象。
请注意:!操作符紧邻参数的前面,并且位于参数的圆括号内。
由于本语句只有一个参数,因此使用圆括号将其括起以示说明。
  • *(通配符)
    可使用通配符表示值可以等于任何值。使用它的情况可能是:您希望查找具有职务头衔的所有对象。为此,可以使用:
(title=*)
//这会返回“title”属性包含内容的所有对象。
另一个例子是:
您知道某个对象的“名”属性的开头两个字母是“Jo”。那么可以使用如下语法进行查找:
(givenName=Jo*)
//这会返回“名”为“Jo”开头的所有对象。

特殊说明:

  1. 除了使用逻辑操作符外,还允许使用下面单独符号作为两个特殊常量:(&)表示True;(|) 表示False。
  2. 默认情况下,LDAP的DN和所有属性都不区分大小写。

0x02.5 LDAP查询语法

LDAP主要用于搜索查询,那它是怎么查询的呢?

search语法:

attribute operator value search filter options:("&" or "|" (filter1)(filter2)...)

主要根据属性和值进行搜索,就如浏览网页时我们通常并不会直接浏览某个目录,而是其下存在的某个文件。

LDAP的URL形式为:

ldap://<host>:<port>/<path>
<path>:<dn>[?<attribute>[?<scope>?<filter>]]

例如:

ldap://austin.ibm.com/ou=Austin,o=IBM
ldap:///ou=Austin,o=IBM??sub?(cn=Joe Q. Public)

看得出来在URL中这里使用逗号分隔查询,而数据库查询则使用‘ & ’ 号,这是LDAP特有的,另外这里o表示组织(organization),u表示单元(unit),cn表示country name。

0x03 LDAP注入攻击剖析

1、引言

利用LDAP注入技术的关键在于控制用于目录搜索服务的过滤器。使用这些技术,攻击者可能直接访问LDAP目录树下的数据库,及重要的公司信息。情况还可能比这更严重,因为许多应用的安全性依赖于基于LDAP目录的单点登录环境。

2、概览

轻量级目录访问协议是通过TCP/IP查询和修改目录服务的协议,使用最广泛的LDAP服务如微软的ADAM(Active Directory Application Mode)和OpenLDAP。

LDAP目录服务是用于共享某些通用属性的存储和组织信息的软件应用程序,信息基于目录树入口被结构化,而服务器提供方便的浏览和搜索等服务。LDAP是面向对象的,因此LDAP目录服务中的每一个入口都是一个对象实例,并且必须对应对象属性的规则。

由于LDAP目录服务的层次化的性质,基于读取的查询得到了优化,而写查询则受到抑制。

LDAP同样基于客户端/服务器模型,最常见的操作是使用过滤器搜索目录入口。客户端向服务器发送查询,服务器则响应匹配这些过滤器的目录入口。

3、常见的LDAP环境

LDAP服务是许多公司和机构日常操作的关键组成部分,目录服务如微软的Microsoft Active Directory,Nove11 E-Directory和RedHat Directory服务都是基于LDAP协议。不过也有其他的应用和服务会利用LDAP服务。简单来说,Windows下在Server服务器上常用ADAM,在Linux系统常用的服务是OpenLDAP。

这些应用和服务通常需要不同的目录(单独认证)来工作。例如,一个域需要一个目录,邮箱和销售列表也需要一个单独的目录,另外远程访问、数据库和其他Web应用都需要目录。基于LDAP服务的新目录有多种用途,用于作为用户认证的集中化信息容器和使能单点登录环境。这个场景通过减少管理的复杂度、提升安全性和容错能力而提高了生产力。基本上,基于LDAP服务的应用使用目录处于如下用途之一:

  • 访问控制
  • 权限管理
  • 资源管理

由于LDAP服务对于公司网络的重要性,LDAP服务器通常和其他数据库服务器一起放置于后端。如下图所示:

4、Web应用中的LDAP注入

一个安全的Web应用在构造和将查询发送给服务器前应该净化用户传入的参数。在有漏洞的环境中,这些参数没有得到合适的过滤,因而攻击者可以注入任意恶意代码。

使用的最广泛的LDAP:ADAM和LDAP.

(attribute=value)

如果过滤器用于构造查询单缺少逻辑操作符,如value)(injected_filter的注入会导致两个过滤器

(attribute=value)(injected_filter)

在OpenLDAP实施中,第二个过滤器会被忽略,只有第一个会被执行。而在ADAM中,有两个过滤器的查询是不被允许的,因而这个注入毫无用处。

(|(attribute=value)(second_filter)) or (&(attribute)(second_filter))

如果第一个用于构造查询的过滤器有逻辑操作符,形如value)(injected_filter)的注入会变成如下过滤器:

(&(attribute=value)(injected_filter)) (second_filter)

虽然过滤器语法上并不正确,OpenLDAP还是会从左到右进行处理,忽略第一个过滤器闭合后的任何字符。 一些LDAP客户端Web组成会忽略第二个过滤器,将ADAM和OpenLDAP发送给第一个完成的过滤器,因而存在注入。

一些应用框架在将请求发送给服务器之前会检查过滤器是否正确,在这种情况下,过滤器语义上必须是正确的,其注入如:value)(injected_filter))(&(1=0。这会导致出现两个不同的过滤器,第二个会被忽略:

(&(attribute=value)(injected_filter)) (&(1=0)(second_filter))

既然第二个过滤器会被LDAP服务器忽略,有些部分便不允许有两个过滤器的查询。这种情况下,只能构建一个特殊的注入以获得单个过滤器的LDAP查询。value)(injected_filter这样的注入产生的结果是:

(&(attribute=value)(injected_filter)(second_filter))

测试一个应用是否存在代码注入漏洞经典的方法是向服务器发送会生成一个无效输入的请求。因此,如果服务器返回一个错误消息,攻击者就能知道服务器执行了他的查询,他可以利用代码注入技术。

4.1、AND注入

这种情况,应用会构造由“ & ”操作符和用户引入的参数组成的正常查询在LDAP目录中搜索,例如:

(&(parameter1=value1)(parameter2=value2))

这里value1和value2是在LDAP目录中搜索的值,攻击者可以注入代码,维持正确的过滤器结构但能使用查询实现他自己的目标。

payload:admin)(&))
result:(&(username=admin)(&))(password=123))
//LDAP服务器只会处理第一个过滤器,而第一个过滤器永真,因此绕过了登录框。
4.1.1、案例1:绕过访问控制

一个登录页有两个文本框用于输入用户名和密码。Uname和Pwd是用户对应的输入。为了验证客户端提供的user/password对,构造如下LDAP过滤器并发送给LDAP服务器:

(&(USER=Uname)(PASSWORD=Pwd))


如果攻击者输入

Uname=slisberger)(&))

引入任何字符串作为Pwd值,构造如下查询并发送给服务器:

(&(USER=sliberger)(&)(PASSWORD=Pwd))

LDAP服务器只处理第一个过滤器,即仅查询(&(USER=sliberger)(&))得到了处理。这个查询永真,因而攻击者可以绕过认证获取对系统的访问。

4.1.2、案例2:权限提升

现假设下面的查询会向用户列举出所有可见的低安全等级文档:

(&(directory=document)(security_level=low))

这里第一个参数document是用户入口,low是第二个参数的值。如果攻击则想列举出所有可见的高安全等级的文档,他可以利用如下的注入:

document)(security_level=*))(&(directory=document

生成的过滤器为:

(&(directory=document)(security_level=*))
(&(directory=document)(securiyt_level=low))

LDAP服务器仅会处理第一个过滤器而忽略第二个,因而只有下面的查询会被处理:

(&(directory=document)(security_level=*))

结果就是,所有安全等级的可用文档都会列举给攻击者,尽管他没有权限查看。

4.2、OR注入

这种情况,应用会构造由“ | ”操作符和用户引入的参数组成的正常查询在LDAP目录中搜索,例如:

(|(parameter1=value1)(parameter2=value2))

这里value1和value2是在LDAP目录中搜索的值,攻击者可以注入代码,维持正确的过滤器结构但能使用查询实现他自己的目标。

4.2.1 案例1:信息泄露

假设一个资源管理器允许用户了解系统中可用的资源(打印机、扫描器、存储系统等)。这便是一个典型的OR注入案例,因为用于展示可用资源的查询为:

(|(type=Rsc1)(type=Rsc2))

Rsc1和Rsc2表示系统中不同种类的资源,下图Rsc1=printer,Rsc2=scanner用于列出系统中可用的打印机和扫描器。


如果攻击者输入Rsc=printer)(uid=*),则下面的查询被发送给服务器:

(|(type=printer)(uid=*))(type=scanner)

LDAP服务器会响应所有的打印机和用户对象

5、LDAP盲注入

假设攻击者可以从服务器响应中推测出什么,尽管应用没有报出错信息,LDAP过滤器中注入的代码却生成了有效的响应或错误。攻击者可以利用这一行为向服务器问正确的或错误的问题。这种攻击称之为盲注。LDAP盲注攻击比较慢但是容易实施,因为它们基于二进制逻辑,能让攻击者从LDAP目录提取信息。

5.1 AND盲注

假设一个Web应用想从一个LDAP目录列出所有可用的Epson打印机,错误信息不会返回,应用发送如下的过滤器:

(&(objectClass=printer)(type=Epson*))

使用这个查询,如果有可用的Epson打印机,其图标就会显示给客户端,否则没有图标出现。如果攻击者进行LDAP盲注攻击:

*)(objectClass=*))(&(objectClass=void

Web应用会构造如下查询:

(&(objectClass=*)(objectClass=*))
(&(objectClass=void)(type=Epson*))

仅第一个LDAP过滤器会被处理:

(&(objectClass=*)(objectClass=*))

结果是,打印机的图标一定会显示到客户端,因为这个查询总是会获得结果:过滤器objectClass=*总是返回一个对象。当图标被显示时响应为真,否则为假。

从这一点来看,使用盲注技术比较容易,例如构造如下的注入:

(&(objectClass=*)(objectClass=users))(&(objectClass=foo)(type=Epson*))
(&(objectClass=*)(objectClass=resources))(&(objectClass=foo)(type=Epson*))

这种代码注入的设置允许攻击者推测可能存在于LDAP目录服务中不同对象类的值。当响应Web页面至少包含一个打印机图标时,对象类的值就是存在的,另一方面而言,如果对象类的值不存在或没有对它的访问,就不会有图标出现。

LDAP盲注技术让攻击者使用基于TRUE/FALSE的技术访问所有的信息。

5.2 OR盲注

这种情况下,用于推测想要的信息的逻辑与AND是相反的,因为使用的是OR逻辑操作符。接下来使用的是同一个例子,OR环境的注入为:

(|(objectClass=void)(objectClass=void))(&(objectClass=void)(type=Epson*))

这个LDAP查询没有从LDAP目录服务获得任何对象,打印机的图标也不会显示给客户端(FALSE)。如果在响应的Web页面中有任何图标,则响应为TRUE。故攻击者可以注入下列LDAP过滤器来收集信息:

(|(objectClass=void)(objectClass=users))(&(objectClass=void)(type=Epson*))
(|(objectClass=void)(objectClass=resources))(&(objectClass=void)(type=Epson*))
5.3 利用案例

在本例中,printerstatus.php页面接收idprinter参数构造如下的LDAP搜索过滤器:

(&(idprinter=value1)(objectClass=printer))
5.3.1 发现属性

LDAP盲注技术可以通过利用Web应用中内建的搜索过滤器首部的AND操作符,获得LDAP目录服务的敏感信息。这里value1=HPLaserJet2100


一个属性发现攻击可以使用下面的LDAP注入:

(&(idprinter=HPLaserJet2100)(ipaddress=*))(objectClass=printer)
(&(idprinter=HPLaserJet2100)(departments=*))(objectClass=printer)

当属性不存在时的响应如下:


当属性存在时的响应如下:


很显然,攻击者可以根据返回的结果判断属性是否存在。在第一种情况中,应用没有给出打印机的信息,因为属性ipaddress并不存在或不可访问(FALSE)。第二种情况中,响应页面显示了打印机的状态,department属性存在且可以访问。进一步说,可以使用LDAP注入获得一些属性的值。例如,假设攻击者想获得department属性的值:他可以使用booleanization和字符集削减技术。

5.3.2 Booleanization

攻击者可以使用字母、数字搜索提取属性的值,这个想法的关键在于将一个复杂的值转化为TRUE/FALSE列表。这个机制,通常称为booleanization,大意是二值化吧。大致如下图所示:


假设攻击者想知道department属性的值,处理如下:

(&(idprinter=HPLaserJet2100)(department=a*))(object=printer))
(&(idprinter=HPLaserJet2100)(department=f*))(object=printer))
(&(idprinter=HPLaserJet2100)(department=fa*))(object=printer))


用‘a’开头的没有获取任何打印机信息,因而第一个字母不是‘a’。测试过其他字母之后,唯一能正常返回的只有’f’,接下来测试第二个字母,当为‘i’时才正常返回,以此类推可以获得department的值。

5.3.3 字符集削减

攻击者可以使用字符集削减技术减少获得信息所需的请求数,为完成这一点,使用通配符测试给定的字符值是否为* anywhere * :

(&(idprinter=HPLaserJet2100)(department=*b*))(object=printer))
(&(idprinter=HPLaserJet2100)(department=*n*))(object=printer))



通过这样处理,构成department值的字母是哪些就可以知道了,一旦字符集削减完成,只有发现的那些字母会用于booleanization处理,因此减少了请求的数量。

0x04 防御LDAP注入

在应用层过滤掉圆括号、星号、逻辑操作符、关系运算符等。无论什么时候,只要可能,构造LDAP搜索过滤器的值在发送给LDAP服务器查询之前都要用应用层有效的值列表来核对。(包括转义字符、编码字符都需要过滤)

0x05 补充

  1. 实战中能遇到的主要是大厂内网
  2. 针对LDAP的软件有ldapbroswer、ldap blind explorer;

0x06 参考资料

Web渗透(九)LDAP注入相关推荐

  1. WEB渗透之SQL 注入

    SQL 注入 文章目录 SQL 注入 前言 1. SQL 注入分类 2. 按照数据库类型 1. 数据库相关知识 1. MYSQL 1. information_schema 2. 常用的函数 2. 判 ...

  2. web渗透之sql注入

    博主姓名:摆烂阳 博主主页面链接:传送门 新人入圈,希望博主的内容可以给大家带来帮助,有任何问题可以私信本人 摆烂阳从不摆烂滴 目录 一.前言 二.实验准备 三.sql注入检测方法 1.数字型检测 2 ...

  3. 【web渗透】专栏文章汇总

    一.基础部分 web渗透–1–写在开始 web渗透–2–web安全原则(上) web渗透–3–web安全原则(下) web渗透–4–web渗透测试清单 web渗透–5–自动化漏洞扫描 web渗透–6– ...

  4. Kali Linux Web 渗透测试视频教程—第十一课-扫描、sql注入、上传绕过

    Kali Linux Web 渗透测试视频教程-第十一课-扫描.sql注入.上传绕过 文/玄魂 原文链接:http://www.xuanhun521.com/Blog/2014/10/25/kali- ...

  5. 从小白到web渗透工程师——零基础指南(2)sql注入漏洞

    hello,各位小伙伴,在看过上一篇文章之后,想必大家伙对于web渗透工程师有了一定的了解,那么,作为一名渗透工程师,挖洞,就是我们的日常工作中必不可少的一部分了.在安全圈中,如果你挖的洞危险系数够高 ...

  6. Web渗透测试对靶机注入shell(phpMyAdmin)

    Web渗透测试对靶机注入shell 文章目录 Web渗透测试对靶机注入shell 1.寻找目标信息 netdiscover扫描 nmap扫描 利用御剑后台进行扫描 2.对登录页面进行暴力破解 启动bu ...

  7. Web渗透-SQL注入

    渗透测试基础 一.渗透攻击流程 二.渗透测试主流工具 域名注册信息查询: Whois在线查询目标网络信息DNS和IP,nslookup 在线漏洞搜索引擎: fofa.info,shodan.io,zo ...

  8. 2017-2018-2 20155303『网络对抗技术』Final:Web渗透获取WebShell权限

    2017-2018-2 『网络对抗技术』Final:Web渗透获取WebShell权限 --------CONTENTS-------- 一.Webshell原理 1.什么是WebShell 2.We ...

  9. web中各种命令注入的检测和利用二

    0x00 前言 我们都知道在web 中有着各种数据注入攻击,其中有SQL注入.命令注入.XML注入等等.在平时我们渗透测试的任务中,如何快速检测和利用这些注入的漏洞,以下是一些注入命令总结 0x01 ...

最新文章

  1. Bio+IT 生信科技爱好者知识库
  2. 怎样下载python模块sublime text3中_Python3.7.3安装教程并集成Sublime Text3
  3. VC++格式化输出单个字符和格式化输出十六进制的不同形式
  4. 福大软工1816:项目测评
  5. 人工智能:一种现代方法汇总
  6. nginx从入门、搭建到理解
  7. 2.18-2.20 特殊权限和软硬链接
  8. HDU 6186 CS Course
  9. java继承方法规则或规律
  10. mysql show 语句大全
  11. 3月数据库排行:前10整体下行,出新技术了?
  12. Codeforces Round #631 (Div. 2) D. Dreamoon Likes Sequences 思维 + 组合数学
  13. mysql 占用的解决_解决 MySQL 突然占用全部内存的问题
  14. Linux服务器环境搭建《Redis、Nginx、mysql8安装》
  15. LG已停止手机生产 手机生产线向家电制造转变
  16. PHP中普通类、抽象类、接口之间的关联
  17. Android应用案例开发大全 吴亚峰 苏亚光
  18. MDM-WIFI(QCA9377,QCA6174)
  19. [CTF] 攻防世界MISC高手区部分题目WriteUp
  20. Layui Select四级联动效果触发

热门文章

  1. 全闪存存储的服务器虚拟化场景应用
  2. MySQL- cluster集群----实现高可用
  3. Beanshell解析json-解析简单复杂json数据
  4. tplinkwr710n改无线打印服务器,TP-Link TL-WR710N V1无线路由器AP模式怎么设置
  5. js + jquery 两栏Tab鼠标移入显示/隐藏的效果(详)
  6. git基础教程(11) git checkout命令,掌握这些足以
  7. DSP F28335时钟及控制系统
  8. springboot 整合mybatis plus
  9. T细胞培养方法进展及方法学对比
  10. Centos7+Elasticsearch7.4.2+Kibana+IK分词+ElasticHD 安装配置以及集群搭建