DHCP 协议原理与攻防简介

1. 协议原理

1.1 简介

DHCP( Dynamic Host Configuration Protocol, 动态主机配置协议),是一个局域网的网络协议,使用 UDP 协议工作, 主要有两个用途:给内部网络或网络服务供应商自动分配 IP 地址,给用户或者内部网络管理员作为对所有计算机作中央管理的手段,在 RFC 2131 中有详细的描述。DHCP 有3个端口,其中 UDP67 和 UDP68 为正常的 DHCP 服务端口,分别作为 DHCP Server 和 DHCP Client 的服务端口;546 号端口用于 DHCPv6 Client ,而不用于 DHCPv4,是为 DHCP Failover 服务,这是需要特别开启的服务,DHCP Failover 是用来做“双机热备”的。

在 IP 网络中,每个连接 Internet 的设备都需要分配唯一的 IP 地址。DHCP 使网络管理员能从中心结点监控和分配 IP 地址。当某台计算机移到网络中的其它位置时,能自动收到新的 IP 地址,而不用在每台计算机上单独配置固定的 IP 地址。

DHCP 使用了 租约 的概念,或称为计算机 IP 地址的有效期。租用时间是不定的,主要取决于用户在某地联接 Internet 需要多久,这对于教育行业和其它用户频繁改变的环境是很实用的。通过较短的租期,DHCP 能够在一个计算机比可用 IP 地址多的环境中动态地重新配置网络。DHCP 支持为计算机分配静态地址,如需要永久性 IP 地址的 Web 服务器。

DHCP 和另一个网络 IP 管理协议 BOOTP 类似(BOOTP 是 DHCP 的前身)。目前两种配置管理协议都得到了普遍使用,其中 DHCP 更为先进。某些操作系统,如 Windows NT/2000,都带有 DHCP 服务器。DHCP 或 BOOTP 客户端是装在计算机中的一个程序,这样就可以对其进行配置操作。

1.2 详解

1.2.1 报文格式

DHCP 报文格式

各字段解释如下:

字段 长度(byte) 说明
op 1 报文类型,1表示请求报文,2表示响应报文
htype 1 硬件地址类型,1 表示 10Mb/s 以太网 地址
hlen 1 硬件地址长度,以太网中该值为 `6
hops 1 跳数。客户端设置为 0,也能被一个 DHCP 代理服务器设置
xid 4 事务ID,由客户端选择的一个随机数,被服务器和客户端用来在它们之间交流请求和响应,客户端用它对请求和应答进行匹配。该ID由客户端设置并由服务器返回,为 32 位整数
secs 2 由客户端填充,表示从客户端开始获得 IP 地址或 IP 地址续借后所使用了的秒数
flags 2 标志字段。这个 16 比特的字段,目前只有最左边的一个比特有用,该位为 0 ,表示单播,为 1 表示广播
ciaddr 4 客户端 IP,只有客户端处于 BoundRenewRebinding 状态,并且能响应 ARP 请求时,才能被填充
yiaddr 4 “你自己的” 或客户端的 IP 地址
siaddr 4 DHCP 协议流程的下一个阶段要使用的服务器的IP地址,由服务端在 DHCPOFFERDHCPACK 报文中返回
giaddr 4 DHCP 中继器的 IP 地址
chaddr 16 客户端硬件地址,客户端必须设置它的 chaddr 字段。UDP 数据包中的以太网帧首部也有该字段,但通常通过查看 UDP 数据包来确定以太网帧首部中的该字段获取该值比较困难或者说不可能,而在 UDP 协议承载的 DHCP 报文中设置该字段,用户进程就可以很容易地获取该值
sname 64 可选的服务器主机名,该字段是空结尾的字符串,由服务器填写
file 128 启动文件名,是一个空结尾的字符串。DHCP Discover 报文中是 generic 名字或空字符,DHCP OFFER 报文中提供有效的目录路径全名
options 可选 可选参数域,格式为 代码+长度+数据

关于 options 字段的具体说明,可以参考: http://tools.ietf.org/html/rfc2132

1.2.2 报文类型

DHCP 报文共有 8 种,分别用于不同的功能,详解如下:

报文类型 说明
DHCPDISCOVER DHCP 客户端请求地址时,并不知道 DHCP 服务器的位置,因此 DHCP 客户端会在本地网络内以广播方式发送请求报文,这个报文成为 Discover 报文,目的是发现网络中的 DHCP 服务器,所有收到 Discover 报文的 DHCP 服务器都会发送回应报文,DHCP 客户端据此可以知道网络中存在的 DHCP 服务器的位置。
DHCPOFFER DHCP 服务器收到 Discover 报文后,就会在所配置的地址池中查找一个合适的 IP 地址,加上相应的租约期限和其他配置信息(如网关、DNS 服务器等),构造一个 Offer 报文,发送给用户,告知用户本服务器可以为其提供 IP 地址。( 只是告诉 Client可以提供,是预分配,还需要 Client 通过 ARP 协议检测该 IP 是否重复)
DHCPREQUEST 客户端发给服务端,用来(1)从众多服务器的 DHCPOFFER 报文中选取一个最先接收到的,摒弃其他的 DHCP 服务器;(2)系统重启后确认之前分配的 IP 是否可用;(3)租期续约(在地址使用租期过去1/2时,会向DHCP服务器发送单播Request报文续延租期,如果没有收到DHCP ACK报文,在租期过去3/4时,发送广播Request报文续延租期。)
DHCPACK 服务端发给客户端,服务端根据收到的 Request 报文中携带的用户 MAC 地址来查找有没有相应的租约记录,如果有则发送 DHCPACK 报文作为回应,通知用户可以使用分配的 IP 地址
DHCPNAK DHCP 服务器收到 Request 报文后,没有发现有相应的租约记录或者由于某些原因(租约到期、客户端移动到别的字网)法正常分配 IP 地址,则发送 NAK 报文作为回应,通知用户无法分配合适的 IP 地址
DHCPDECLINE DHCP 客户端收到 DHCP 服务器回应的 DHCPACK 报文后,通过地址冲突检测发现服务器分配的地址冲突或者由于其他原因导致不能使用,则发送 Decline 报文,通知服务器所分配的 IP 地址不可用
DHCPRELEASE 当用户不再需要使用已分配的 IP 地址时,就会主动向 DHCP 服务器发送 Release 报文,告知服务器用户不再需要分配 IP 地址,DHCP 服务器会释放被绑定的租约
DHCPINFORM DHCP 客户端如果需要从 DHCP 服务器端获取更为详细的配置信息,则发送 Inform 报文向服务器进行请求,服务器收到该报文后,将根据租约进行查找,找到相应的配置信息后,发送 DHCPACK 报文回应 DHCP 客户端

1.2.3 DHCP报文交换过程

主要有两种流程:

  1. 客户端请求新分配一个 IP 地址;
  2. 客户端请求续租当前已有的 IP 地址。

客户端请求分配一个新的 IP 地址:

Alt text

客户端请求续租当前已有的 IP 地址:

Alt text

NOTE:
要看懂上面的数据包时序图,需要先理解前面表格中介绍过的 DHCP 8 种报文类型里的关键几种。
客户端在发送 DHCPDISCOVERDHCPREQUEST 报文时,可以指定发给某个 DHCP 服务器,也可以不指定 DHCP 服务器而进行广播,这两种情况下客户端与服务端数据交互的细节不完全相同。
更多细节可参考 RFC2131。

2. 协议缺陷

上面两个时序图,是比较复杂的完整情况,而通常的 DHCP 交互过程可以简化成以下几个关键步骤(也是最容易出问题的几个步骤):

  1. 客户端发出一个 DHCPDISCOVER 报文(广播),表明想从一个 DHCP 服务器那里分配到一个 IP 地址;客户端可能会指定想租用一个以前被分配过的 IP 地址,此时会有遭受 “中间人攻击” 的危险(后文详解);
  2. 接收到客户端 DHCPDISCOVER报文的 DHCP 服务器,会发送一个 DHCPOFEER 报文,告诉客户端一个成功分配的 IP 地址,但这个地址不一定是客户端指定想要的那个 IP 地址,这取决于 DHCP 服务器的 IP 地址池中的已分配情况;如果服务端 IP 地址池中有客户端指定想要的 IP 地址,那么 DHCP 服务器就会把这个 IP 地址分配给客户端;如果 DHCP 服务器的 IP 地址池中没有客户端指定想要的 IP 地址,但有其他可用的 IP 地址,则会把其他的 IP 地址分配给客户端;如果 DHCP 服务器的 IP 地址池中已经没有可用的IP 地址,则会返回一个 DHCPNAK 报文;
  3. 客户端接收到 DHCP 服务端发送的 DHCPOFEER 报文以后,会发送一个 DHCPREQUEST 报文给服务端,告知服务端即将租用这个分配来的 IP 地址;
  4. DHCP 服务端接收到 客户端的 DHCPREQUEST 报文后,会发送一个 DHCPACK 报文给客户端,告知客户端可以使用了,并在服务端将客户端的 MAC 地址 和 IP 地址绑定,在 IP 地址池中做标记该 IP 地址已分配出去。

2.1 拒绝服务

伪造一批 DHCP 客户端(手动构造 MAC 地址),通过上面的 DHCP 客户端<—->DHCP服务端之间的数据包交互流程,向当前网络中的 DHCP 服务器申请大量 IP 地址,耗尽 DHCP 服务器中的可用 IP 地址池。这样会造成以下 拒绝服务 的效果:

  • DHCP 服务器中 IP 池已耗尽,所有的 IP 地址都分配给攻击发生之前已上线正常主机、和攻击所伪造的虚假主机
  • 由于 DHCP 服务器已经没能力再分配新的 IP 地址,所以该网络中的其他 刚上线正常主机无法获得可用 IP 地址;
  • 此攻击发生 之前已经上线正常主机 无法觉察 到攻击已发生;

这种方式实现的 拒绝服务攻击 有个小问题:某些 DHCP 服务器会通过 ARP 请求 数据包或 ICMP Ping 数据包探测那些已分配的 IP 地址存活情况,如果探测到某个 IP 地址无响应,则会自动回收该 IP(通常情况 DHCP 客户端那一方,如果机器不关机,不会自动释放当前的 IP 地址)。而我们也有应对方式:加大伪造 DHCP 客户端申请新的 IP 地址的频率,这个频率远高于 DHCP 服务器探测未存活 IP 并将其回收的频率,从而保证只要 DHCP 服务器可以分配 IP 地址,就通过伪造的DHCP 数据包交互将可用的 IP 地址占用。(已有 POC 能应对 DHCP 服务器 ARP 请求 形式的探测, ICMP Ping 方式未测试)。

2.2 伪造恶意的 DHCP 服务

黑客可以通过伪造一个 DHCP 服务器在当前网络下进行一些对 DHCP 客户端的欺骗攻击。DHCP 报文中的 options 字段可以由 DHCP Server 向 DHCP Client 指定可用的 网关DNS 服务器地址 ,这样一来,黑客伪造的 DHCP Server 就可以通过构造的 DHCP 数据包向客户端指定恶意的网关或 DNS 服务器地址,从而进一步实施中间人攻击

2.3 中间人攻击

2.3.1 原理

上面 伪造恶意的 DHCP 服务中间人攻击 的关键步骤,中间人攻击 最常用的方式是伪造一个 恶意网关,将受害者的网络流量都劫持到恶意网关那里,然后可以对流量进行嗅探、修改,从而使操控受害者——当然,前提是伪造的恶意网关必须有数据包转发功能。

按照 DHCP 协议规范,在 DHCP 客户端发出 DHCPDISCOVER 的广播数据包之后,如果本地网络存在多个 DHCP 服务器并且收到客户端的数据包之后各自都回应了 DHCPOFFER 数据包,DHCP 客户端会收到多个 DHCPOFFER 数据包,通常只会选择收到的第一个 DHCPOFFER 数据包。这样一来,其实多个 DHCP 服务器之间存在一个 竞争关系,哪一台DHCP服务器响应客户端的速度快、频率高,那么成功接管 DHCP 客户端的可能性就会越大。

在 DHCP 中间人攻击的过程中,恶意的 DHCP 服务器可以专门针对一个 DHCP 客户端进行攻击,一旦收到一个 DHCP 客户端发来的 DHCPDISCOVER 广播包,恶意 DHCP 服务器和真实 DHCP 服务器都会同时响应一个 DHCPOFFER包,只要 恶意 DHCP 服务器的数据包先于真实 DHCP 服务器的数据包到达客户端,恶意 DHCP 服务器就会被客户端选用,中间人攻击的第一步就会成功,否则整个中间人攻击就会失败。

2.3.2 问题

关于 DHCP 中间人攻击 一个明显的问题是,这种攻击在一个小型网络里面很难实施。

  • 如果客户端的网卡填充了以前曾用过但当前被回收了的IP,那么中间人攻击将很可能无法实施;
  • 如果客户端的网卡填充了指定想要的某个 IP 地址(上面的曾经用过的旧 IP),而真实的 DHCP 服务器恰好分配了这个指定的 IP 地址给客户端,那么客户端将采用这个指定想要的 IP 地址,而忽略恶意 DHCP 服务器的响应;
  • 唯一可能成功的,是客户端指定想要的这个 IP 地址,真实的 DHCP 服务器无法分配——可能已经分配跟网内的正常主机,也可能被恶意的 DHCP 服务主机用前面说过的 拒绝服务 攻击给恶意占用,而恶意 DHCP 服务器的 IP 池则是这些被自己恶意占用的 IP地址(恶意DHCP服务器不能随便伪造一个 IP 地址分配给受害 DHCP 客户端,那样可能造成网段内的 IP 地址冲突)——这时,恶意 DHCP 服务器才有机会成功接管受害主机的 DHCP 服务。

DHCP 中间人攻击 的另一个问题出在攻击的第二阶段——流量劫持。一旦第一阶段成功将受害主机的流量骗到恶意网关,下一步就是具体的流量劫持。流量劫持的完美实施,不仅需要欺骗受害主机、让受害主机把恶意网关误以为真实网关,还要欺骗真实网关、让真实网关把恶意网关误以为受害主机,这样才能完全接管受害主机出、入的双向流量。所以,一个完整的 DHCP 中间人攻击,还需要借助 ARP欺骗

2.4 伪造 DNS 服务

前面说过,DHCP 服务器可以通过数据包向 DHCP 客户端指定一个 DNS 服务器地址。如果上面的 DHCP 服务欺骗成功,则恶意 DHCP 服务器可以通过这种方式,来对 受害主机进行 钓鱼攻击:将某个或某些受害主机用户经常上的网站的域名解析到黑客自己的服务器 IP 上去,在那里用伪造的网站页面,骗取用户登录,便可轻松得到账号、密码、联系方式、身份信息等等。

3. 攻击实践

前面一小节列出了 DHCP 协议相关的多种缺陷,即可能导致用户网络被攻击的一些点,本小节做一个简单的实践来演示一下。当然不会掩饰所有的攻击方式,只演示最基础的、简单的 DHCP 服务器欺骗攻击。原理是去年爆出的 Bash-Shellshock 漏洞在 DHCP 客户端中的利用。Linux 自带 DHCP 客户端的实现中,有通过系统调用执行 Shell 命令的代码,而除了标准字段,DHCP 还提供了可选字段(识别号码),在这种情况下,一些恶意的服务器通过可选字段 114 发送包含恶意指令的命令,DHCP 服务端响应的数据包中包含的恶意指令如果被客户端接收,且 Bash 版本存在漏洞,那么恶意指令就会被执行。

这里用到的中间人攻击攻击,还是做 ARP 中间人攻击 实验时用到的中间人攻击平台 MITMF,只需在攻击机上开启 DHCP 服务欺骗的指令,等待一个 DHCP 客户端来申请 IP 地址即可:

  1. 攻击机 Kali 上启动攻击平台
    Alt text
  1. 受害主机(带有 Shellshock 漏洞的 Ubuntu1204)重启 DHCP 客户端,申请 IP 地址
    Alt text

即发现受害主机的 DHCP 客户端启动时,倒数第二行打出了 123 这一串异常字符,即是恶意 DHCP 服务器的 echo 123 指令得到了执行。

4. 参考资料

  1. http://zh.wikipedia.org/zh/%E5%8A%A8%E6%80%81%E4%B8%BB%E6%9C%BA%E8%AE%BE%E7%BD%AE%E5%8D%8F%E8%AE%AE
  2. http://seclists.org/vuln-dev/2002/Sep/99
  3. http://tools.ietf.org/html/rfc2131
  4. http://tools.ietf.org/html/rfc2132
  5. http://tools.ietf.org/html/rfc951
  6. https://isc.sans.edu//forums/diary/Cyber+Security+Awareness+Month+Day+6+ports+6768+udp+bootp+and+dhcp/7279/
  7. http://howdoesinternetwork.com/2011/spoofing-attack
  8. http://www.freebuf.com/tools/45796.html
  9. http://sign0f4.blogspot.it/2014/07/introducing-mitmf-framework-for-man-in.html
  10. http://sign0f4.blogspot.it/2014/07/mitmf-update-spoof-plugin_23.html
  11. http://sign0f4.blogspot.it/2014/10/mitmf-update-dhcp-pwnage.html
  12. http://www.trustedsec.com/september-2014/shellshock-dhcp-rce-proof-concept/