kk Blog —— 通用基础


date [-d @int|str] [+%s|"+%F %T"]
netstat -ltunp
sar -n DEV 1

DNSSEC学习笔记

1
2
3
4
dig @192.58.128.30 +dnssec . A
dig @192.58.128.30 +dnssec . NS

dig @192.58.128.30 +dnssec . DNSKEY

https://blog.csdn.net/huangzx3/article/details/86526068

1 、什么是DNSSEC

DNSSEC(DNS Security Extension)—-DNS安全扩展,主要是为了解决DNS欺骗和缓存污染问题而设计的一种安全机制。

1.1 DNS欺骗&缓存污染

客户端(pc)发起域名(例如:www.baidu.com)请求的时候,如果在本地缓存没有的情况下,会往递归服务器发送域名查询请求(我们也称之为localdns),递归服务器再一层层递归从.到com.再到baidu.com.(即到.的权威服务器–>com.的权威服务器–>baidu.com.的权威服务器),最终取到www.baidu.com.对应的解析A记录返回给客户端。在整个查询过程中,攻击者可以假冒任何一个应答方:递归服务器–>.的权威服务器–>com.的权威服务器–>baidu.com.的权威服务器,给请求方发送一个伪造的响应(UDP包极其容易伪造),其中响应的解析记录给了一个错误的IP地址或者其他类型的解析记录(比如NXDomain、ServFail或者cname到错误的域名地址去等)。客户端或者是解析服务器在没有经过数据来源正确性校验的情况下接受了伪造的应答,直接将导致客户端无法正常访问网站或者其他资源或者客户端请求重定向到了伪造的网站上去。另外由于DNS当中存在着缓存,这种错误的记录将随着攻击者设定的TTL进行存活缓存,如果是递归服务器受到DNS欺骗那将会导致自身以及大面积的客户端缓存了错误的解析记录(可以通过清除缓存解决)。

2、DNSSEC原理

DNSSEC依靠数字签名来保证DNS应答报文的真实性和完整性。简单来说,权威服务器使用私钥对资源记录进行签名,递归服务器利用权威服务器的公钥对应答报文进行验证。如果验证失败,则说明这一报文可能是有问题的。

例子:

一台支持dnssec的递归服务器向支持dnssec的权威服务器发起paypal.com.的A记录请求,它除了得到A记录以外还得到了同名的RRSIG记录,其中包含了paypal.com.这个ZONE的权威数字签名,它使用paypal.com.的私钥来签名。为了验证这一签名是否正确,递归服务器再次向paypal.com.权威查询其公钥,即请求paypal.com.的dnskey类型的记录。递归服务器就可以使用公钥来验证收到的A记录是否是真实且完整的。但是注意:这种状态下,这台权威服务器可能是假冒的,递归服务器请求这台假冒的权威服务器,那么对于解析结果的正确性和完整性的验证上认为是正确的,但其实这个解析结果是假冒的,怎么发现?DNSSEC需要一条信任链,即必须要有一个或者多个相信的公钥,这些公钥被称为信任锚。理想情况下,假设dnssec已经实现了全部署,那每个递归服务器只需要保留根域名服务器的dnskey。

如下:

3、DNSSEC的资源记录

为了实现资源记录的签名和验证,DNSSEC增加了四种类型的资源记录:RRSIG(Resource Record Signature)、DNSKEY(DNS Public Key)、DS(Delegation Signer)、NSEC(Next Secure)

3.1 RRSIG记录

RRSIG资源记录存储的是对资源记录集合(RRSets)的数字签名。如下:

3.2 DNSKEY记录

DNSKEY资源记录存储的是公开密钥,下面是一个DNSKEY的资源记录的例子:

在实践中,权威域的管理员通常用两个密钥配合完成对区数据的签名。一个是Zone-Signing Key(ZSK),另一个是Key-Signing Key(KSK)。ZSK用于签名区数据,而KSK用于对ZSK进行签名。这样做的好处有二:

(1)用KSK密钥签名的数据量很少,被破解(即找出对应的私钥)概率很小,因此可以设置很长的生存期。这个密钥的散列值作为DS记录存储在上一级域名服务器中而且需要上级的数字签名,较长的生命周期可以减少密钥更新的工作量。

(2)ZSK签名的数据量比较大,因而破解的概率较大,生存期应该小一些。因为有了KSK的存在,ZSK可以不必放到上一级的域名服务中,更新ZSK不会带来太大的管理开销(不涉及和上级域名服务器打交道)。

如下:

3.3 DS记录

DS(Delegation Signer)记录存储DNSKEY的散列值,用于验证DNSKEY的真实性,从而建立一个信任链。DNSKEY存储在资源记录所有者所在的权威域的区文件中,但是DS记录存储在上级权威域名服务器中,比如paypal.com的DS RR存储在.com的区中。如下:

3.4 NSEC记录

NSEC记录是为了响应那些不存在的资源记录而设计的。为了保证私有密钥的安全性和服务器的性能,所有的签名记录都是事先生成的。服务器显然不能为所有不存在的记录事先生成一个公共的“不存在”的签名记录,因为这一记录可以被重放(Replay);更不可能为每一个不存在的记录生成独立的签名,因为它不知道用户将会请求怎样的记录。

4、DNSSEC请求过程

下面是针对paypal.com.的一个解析过程,抓包过程有丢包,但是不影响对于dnssec解析过程的大致理解

解析过程中关于DNSSEC的请求过程大致如下:

过程图如下所示:

5、DNSSEC中的DLV

DLV–DNSSECLookasideValidation

1、localdns在其上层zone权威服务器查找被验证ZONE的DS记录

2、如果不存在,向DLV注册机构发出一个对DLV记录的请求

3、如果成功,DLV资源记录被当做这个ZONE的DS记录

4、localdns进行真实性可完整性验证

DLV是一个DNS服务器,提供DNSSEC签名认证的信任链一个解决方案,递归服务器配置的信任锚点是DLV,就可以认证域,进而认证权威域授权的信任的权威域。

递归服务器的配置:当设置了dnssec-lookaside,它为验证器提供另外一个能在网络区域的顶层验证DNSKEY的方法

1
2
3
4
dnssec-lookaside "." trust-anchor dlv.cnnic.cn
trusted-keys {
	dlv.cnnic.cn 256 3 5 "qWmA7OpfdqvqMtLCzZTm982aTaeC6tTRiPUOFDVMXEkIuM14T8Tw6jg2qmX7JUtriYHAGwIQ+9jzYyRziSFdijaO2elgh90NMW0jIcjZ+3cHehpETCEUar813SHN38biRu4UL0EQ/X5C5LJyh1djaw8eZFXxaLyT8fcJedBZtYE=";
}

6、DNSSEC的一些设想

6.1 DNSSEC与防域名劫持

dnssec并没有办法在域名劫持上起到很好的作用,如果发生域名劫持则无法得到真正的解析结果,因为数字签名校验是没有校验通过的。实际上较多localdns在各个yys手上,各个yys可以对localdns进行相应的改造,则域名劫持会依然存在。

6.2 DNSSEC可能导致解析失败

响应中也有RRSIG记录,会直接导致UDP包的大小超过512字节,那么可能造成部分localdns解析失败,因为根据之前对于线上的观察,部分localdns并不支持超过512字节大小的UDP包,从而可能直接导致响应失败。

RRSIG、DNSKEY、信任炼和NSEC

1
2
3
4
dig @192.58.128.30 +dnssec . A
dig @192.58.128.30 +dnssec . NS

dig @192.58.128.30 +dnssec . DNSKEY

https://www.dazhuanlan.com/xwuxin/topics/1848106

DNSSEC 验证流程

第一步:RRSIG

前述提到,DNSSEC 的状况下,每一个纪录都应该要经过数字签章做签署的动作。所以 DNSSEC 里面有提到一种 DNS 纪录,这个纪录叫做 RRSIG,会附在 DNS 请求的回复当中。

内容大概像这样:

1
2
3
4
5
6
7
8
9
   网域名称       TTL  类型   内容
   a.z.w.example. 3600 IN MX  1 ai.example.
   a.z.w.example. 3600 RRSIG  MX 5 2 3600 20040509183619 (
                              20040409183619 38519 example.
                              OMK8rAZlepfzLWW75Dxd63jy2wswESzxDKG2
                              f9AMN1CytCd10cYISAxfAdvXSZ7xujKAtPbc
                              tvOQ2ofO7AZJ+d01EeeQTVBPq4/6KCWhqe2X
                              TjnkVLNvvhnc0u28aoSsG0+4InvkkOHknKxw
                              4kX18MMR34i8lC36SR5xBni8vHI= )

第一行是 ai.example 这个网域的 MX 纪录。

第二行是给第一笔记录使用的 RRSIG 纪录。

RRSIG 的格式是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[对应格式] [算法编号] [涵盖数量]  [有效时间长短] [签章期限] 
|            |         |              |           |
|   ---------/         |              |           |
|  /  -----------------/              |           |
|  | /  /-----------------------------/           |
|  | |  |   /-------------------------------------/
|  | |  |   |
|  | |  |   |
MX 5 2 3600 20040509183619 ( 20040409183619 38519 example. OM.....HI= ) 
                             |               |     |         |
  /--------------------------/               |     |         |
  |          /-------------------------------/     |         |
  |          |      /------------------------------/         |
  |          |      |            /---------------------------/
[签署日期] [Tag] [签署者名称] [内容,base64]

DNSKEY

随着 RRSIG 的出现,我们拿到凭证的内容了。不过我们需要验证这个签章是不是伪造的,然后是谁签的。这个信息,会在 DNSKEY 纪录当中。

1
2
3
4
5
6
7
   example.com. 86400 IN DNSKEY 256 3 5 ( AQPSKmynfzW4kyBv015MUG2DeIQ3
                                          Cbl+BBZH4b/0PY1kxkmvHjcZc8no
                                          kfzj31GajIQKY+5CptLr3buXA10h
                                          WqTkF7H6RfoRqXQeogmMHfpftf6z
                                          Mv1LyBUgia7za6ZEzOJBOztyvhjL
                                          742iU/TpPSEDhm2SNKLijfUppn1U
                                          aNvv4w==  )

DNSKEY 里面会包含拿去签署 RRSIG 的公钥。

不过,即使我们能够确认「这个 RRSIG 和 DNSKEY 对得起来」,也还不能够确认「这个 DNSKEY 真的属于这个网域」。

所以我们会需要一个能够信任方式,来验证这个 DNSKEY。

就像前面提到的 HTTPS 凭证信任链的状况,我们可能有几种做法,可以验证这个东西:

  1. 用其他的方式去获得「这个网域真正的公钥」,例如 PGP、中华邮政寄 U 盘、用纸抄、用 scp 先下载一份

  2. 叫别人证明你是合法的(参考 HTTPS 中介凭证机制)

信任链机制

前述提到,只拿到 DNSKEY 没什么用。然后若要将上述第一种取得真正公钥的方式,放到 DNS 这种许多人用的协定之上,是不可行的。想像一下,你要联网之前,必须要插 U 盘。这是一个多荒诞的事情?

所以,我们可以依赖上一级网域的 DNS 纪录,把上一级凭证的公钥放在那边。在 DNSSEC 中,这个叫做 DS (Delegation Signer) 纪录。由于你可以指定非常多的子网域,所以 DS 纪录中,只会记载「这个凭证的指纹 (hash)」。

真的很短,他长得像这样:

1
2
 dskey.example.com. 86400 IN DS 60485 5 1 ( 2BB183AF5F22588179A53B0A
                                            98631FAD1A292118 )

然后假设一笔 DNSKEY 是被上一级签署过的话,他会看起来像这样:

1
2
3
4
5
6
7
8
9
dskey.example.com. 86400 IN DNSKEY 256 3 5 ( AQOeiiR0GOMYkDshWoSKz9Xz
                                         fwJr1AYtsmx3TGkJaNXVbfi/
                                         2pHm822aJ5iI9BMzNXxeYCmZ
                                         DRD99WYwYqUSdjMmmAphXdvx
                                         egXd/M5+X7OrzKBaMbCVdFLU
                                         Uh6DhweJBjEVv5f2wwjM9Xzc
                                         nOf+EPbtG9DMBmADjFDc2w/r
                                         ljwvFw==
                                         ) ;  key id = 60485

其中,我们会发现 key id 和上面的 DS 纪录是一样的。另外,是可以通过 DNSKEY 去计算出 DS 的数值,所以我们可以通过证明这两个之间的关系,来保证 DNSKEY 纪录的可靠性。 特殊状况: 找不到纪录怎么办? (NSEC)

在 DNS 的状况下,基本上,若找不到东西,只要回复 NXDOMAIN 就好了。不过在 DNSSEC 的状况下,由于回复的数据内容内也要证明这消息不是伪造的,但这东西根本查不到,所以我们要想办法告诉对方「我真的找不到」。

DNSSEC 想到了这个问题,所以又有一种纪录叫做 NSEC (Next Secure)。这个纪录里面会记载说「下一笔纪录是什么」。

所以,假设今天有 A、B、D。有人问了 C,你找不到,但是你可以用 NSEC 和他说:「下一笔真的是 D,我知道他还有 A、RRSIG 和 NSEC,你可以看看 D 是不是真的有这些东西」来确保你没有说谎。

由于 DNS 纪录是以字母来做排序的,所以你可以确定「真的没有那笔东西」。

另外,若某一个网域的纪录是存在的,只是问错类别(例如你有 A 但对方问 MX)的话,这时候的回复里面会告诉对方这个网域所有的纪录

不过,不管是不是这个状况,NSEC 都有可能引起安全疑虑,之后会提到。

邮件MIME格式分析

base64 解码

1
2
3
4
5
6
7
From: "=?gb2312?B?26zQocHB?=" <gaoxl@legendsec.com>

26zQocHB 是 base64 编码, 解码方法:

echo 26zQocHB | base64 -d > /tmp/dd

iconv -fgbk -tutf8 /tmp/dd

https://www.cnblogs.com/crystalray/atricles/3302427.html

总体来说,MIME消息由消息头和消息体两大部分组成。这里,分别称为为邮件头、邮件体。

邮件头

邮件头包含了发件人、收件人、主题、时 间、MIME版本、邮件内容的类型等重要信息。每条信息称为一个域,由域名后加“: ”和信息内容构成,可以是一行,较长的也可以占用多行。域的首行必须“顶头”写,即左边不能有空白字符(空格和制表符);续行则必须以空白字符打头,且第 一个空白字符不是信息本身固有的,解码时要过滤掉。

邮件头中不允许出现空行。有一些邮件不能被邮件客户端软件识别,显示的是原始码,就是因为首行是空行。

例如:

1
2
3
4
5
6
7
8
9
Date: Mon, 29 Jun 2009 18:39:03 +0800
From: "=?gb2312?B?26zQocHB?=" <gaoxl@legendsec.com>
To: "moreorless" <moreorless@live.cn>
Cc: "gxl0620" <gxl0620@163.com>
BCC: "=?gb2312?B?26zQocHB?=" <venus.oso@gmail.com>
Subject: attach
Message-ID: <200906291839032504254@legendsec.com>
X-mailer: Foxmail 6, 15, 201, 21 [cn]
Mime-Version: 1.0

邮件体

在邮件体中,大致有如下一些域:

有的域除了值之外,还带有参数。值与参数、参数与参数之间以“;”分隔。参数名与参数值之间以“=”分隔。

邮件体包含邮件的内容,它的类型由邮件头的“Content-Type”域指出。常见的简单类型有text/plain(纯文本)和text/html(超文本)。

multipart类型,是MIME邮件的精髓。邮件体被分为多个段,每个段又包含段头和段体两部分,这两部分之间也以空行分隔。常见的multipart类型有三种:multipart/mixed, multipart/related和multipart/alternative。从它们的名称,不难推知这些类型各自的含义和用处。它们之间的层次关系可归纳为下图所示:

可以看出,如果在邮件中要添加附件,必须定义multipart/mixed段;如果存在内嵌资源,至少要定义multipart/related段;如果纯文本与超文本共存,至少要定义multipart/alternative段。

示例:

 

MIME编码

参考rfc2047,MIME Part Three:Message Header Extensions for Non-ASCII Text

http://tools.ietf.org/html/rfc2047

MIME编码的两种方法:

对邮件进行编码最初的原因是因为Internet上的很多网关不能正确传输8bit内码的字符,比如汉字等。编码的原理就是把8bit的内容转换成7bit的形式以能正确传输,在接收方收到之后,再将其还原成8bit的内容。   

MIME是“多用途网际邮件扩充协议”的缩写,在MIME协议之前,邮件的编码曾经有过UUENCODE等编码方式,但是由于MIME协议算法简单,并且易于扩展,现在已经成为邮件编码方式的主流,不仅是用来传输8 bit的字符,也可以用来传送二进制的文件,如邮件附件中的图像、音频等信息,而且扩展了很多基于MIME的应用。

从编码方式来说,MIME 定义了两种编码方法Base64与QP(Quote-Printable):

Base64

Base64是一种通用的方法,其原理很简单,就是把三个Byte的数据用4个Byte表示,这样,这四个Byte中,实际用到的都只有前面6 bit,这样就不存在只能传输7bit的字符的问题了。Base64的缩写一般是“B”。

Base64将输入的字符串或一段数据编码成只含有{‘A’-‘Z’, ‘a’-‘z’, ‘0’-‘9’, ‘+’, ‘/’}这64个字符的串,'=‘用于填充。其编码的方法是,将输入数据流每次取6bit,用此6bit的值(0-63)作为索引去查表,输出相应字符。这样,每3个字节将编码为4个字符(3×8 → 4×6);不满4个字符的以’=‘填充。 Base64的算法很简单,它将字符流顺序放入一个24位的缓冲区,缺字符的地方补零。 然后将缓冲区截断成为4个部分,高位在先,每个部分6位,用64个字符重新表示。如果输入只有一个或两个字节,那么输出将用等号“=”补足。这可以隔断附加的信息造成编码的混乱。

QP

另一种方法是QP(Quote-Printable)方法,通常缩写为“Q”方法,其原理是把一个8 bit 的字符用两个16进制数值表示,然后在前面加“=”。所以我们看到经过QP编码后的文件通常是这个样子:=B3=C2=BF=A1=C7=E5=A3=AC=C4=FA=BA=C3=A3=A1。

QP编码要求编码后每行不能超过76个字符。当超过这个限制时,将使用软换行,用”=”表示编码行的断行,后接CRLF。(76的限制包括”=”)。

“=” 等号被编码为”=3D”。

tab和空格出现在行尾时,需要被编码为”=09”(tab) “=20”(space)

编码格式:encoded-word = “=?” charset “?” encoding “?” encoded-text “?=”

编码信息有"=?“和”?=“括起来,”=?“后是字符集名称,再一个”?“后是编码方式,再一个”?“后是编码后的字符串。字符集和编码方式都不区分大小写。

字符集可以是任意系统支持的字符集(iso-8859-1、utf-8、gb2312、gbk、gb18030….)

编码方式有两种:"B"或"b"代表base64编码;"Q"或"q"代表QP编码。

Generally, an “encoded-word” is a sequence of printable ASCII characters that begins with “=?”, ends with “?=”, and has two “?"s in between. It specifies a character set and an encoding method, and also includes the original text encoded as graphic ASCII characters, according to the rules for that encoding method.

 

SMTP与MIME的关系

从上图可以看出发件人、收件人地址都出现了两次,一次在smtp命令中(SMTP email address),一次在邮件正文中(MIME email address)。需要注意的是:

邮件正文中可以包含发件人、收件人的别名,smtp命令中不可以

密送人的地址不一定会出现在邮件正文中。不同客户端实现不同。

参考:

rfc4021,Registration of Mail and MIME Header Fields,

http://www.apps.ietf.org/rfc/rfc4021.html,