Python中的Scapy初探之六--找出非法的DHCP Server

记得以前在公司时,经常碰到未经授权的DHCP服务器接入网络,可能是做实验,没有把虚拟机的网络与真实网络屏蔽,这样就很难搞。而且还遇到一特邪门的事情,VOIP的DHCPServer蹿入了用户网络,导致用户拿到的是IP电话的IP,通过DHCP获取IP,就有这个麻烦,谁快就拿谁的。那么,如何通过Scapy找到DHCP李鬼呢?可以自己写,也可以使用内置的函数dhcp_request()

这个工具非常简单,就是创建一个DHCP请求包,在网络中发送广播,如果接受到DHCPACK,就会返回这个ACK包,这样就可以分析到底是哪个DHCP发送的IP地址

Python中的Scapy初探之六--找出非法的DHCP <wbr>Server

dhcp_request()需要两个参数,iface表示使用哪个网卡接口,如果没有赋值,那么使用conf.iface所指定的网卡,这种情况对多个网卡好用,还有一个参数是conf.checkIPaddr,如果为1,那么会有提示,可能会检查IP地址,还没仔细看这个参数是干嘛用的。设置好之后,就可以直接使用了

conf.iface=0

dhcp_request(iface='wlan0')

如果留空,那么就是conf.iface指定的网口,一般留空就好了

 >>>dhcp_request()
Begin emission:
.Finished to send 1 packets.
*
Received 2 packets, got 1 answers, remaining 0 packets
<Ether  dst=00:0c:29:3e:0f:dasrc=5c:63:bf:76:90:20 type=0x800|<IP  version=4L ihl=5L tos=0x0len=576 id=57084 flags= frag=0L ttl=64 proto=udp chksum=0x15f7src=192.168.1.1 dst=192.168.1.104 options=[]|<UDP  sport=bootps dport=bootpclen=556 chksum=0x5266 |<BOOTP op=BOOTREPLY htype=1 hlen=6 hops=0 xid=0 secs=0 flags=ciaddr=0.0.0.0 yiaddr=192.168.1.104 siaddr=0.0.0.0 giaddr=0.0.0.0chaddr='\x00\x0c)>\x0f\xda\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'sname='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'file='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'options='c\x82Sc' |<DHCP options=[message-type=offer server_id=192.168.1.1 lease_time=7200subnet_mask=255.255.255.0 router=192.168.1.1name_server=192.168.1.1 end pad ... pad]|>>>>>

>>> a=_

>>>a.summary()
'Ether / IP / UDP 192.168.1.1:bootps >192.168.1.104:bootpc / BOOTP / DHCP'

>>>a.sprintf('%Ether.src%:%IP.src%')
'5c:63:bf:76:90:20:192.168.1.1'

这样就可以看出DHCP服务器的IP地址与MAC地址了,可以看看DHCP应答的包结构

>>>a[BOOTP].show()
###[ BOOTP ]###
  op= BOOTREPLY
  htype= 1
  hlen= 6
  hops= 0
  xid= 0
  secs= 0
  flags=
  ciaddr= 0.0.0.0
  yiaddr= 192.168.1.104
  siaddr= 0.0.0.0
  giaddr= 0.0.0.0
  chaddr='\x00\x0c)>\x0f\xda\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  sname='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  file='\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
  options= 'c\x82Sc'
###[ DHCP options ]###
    options= [message-type=offer server_id=192.168.1.1 lease_time=7200subnet_mask=255.255.255.0 router=192.168.1.1name_server=192.168.1.1 end pad ...pad]

这个工具有一定的局限性,就是太模拟客户端了,如果有一个最快的DHCP返回了DHCPRequest,那么就显示这个最快的数据包

如何能找到所有的DHCP服务器呢?这个需要添加srp()的参数multi=True

等到接收到所有的DHCP应答,才返回接收到的结果

这个就不能用方便的dhcp_request()了

改写一下脚本

>>>conf.checkIPaddr = False
>>> fam,hw =get_if_raw_hwaddr(conf.iface)
>>> dhcp_discover =Ether(dst="ff:ff:ff:ff:ff:ff")/IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67)/BOOTP(chaddr=hw)/DHCP(options=[("message-type","discover"),"end"])
>>> ans, unans =srp(dhcp_discover,multi=True)     # Press CTRL-C after several seconds
Begin emission:
Finished to send 1 packets.
.*...*..
Received 8 packets, got 2 answers, remaining 0 packets
>>>ans.summary()
Ether / IP / UDP 0.0.0.0:bootpc >255.255.255.255:bootps / BOOTP / DHCP ==> Ether / IP/ UDP 192.168.1.1:bootps > 255.255.255.255:bootpc /BOOTP / DHCP
Ether / IP / UDP 0.0.0.0:bootpc >255.255.255.255:bootps / BOOTP / DHCP ==> Ether / IP/ UDP 192.168.1.11:bootps > 255.255.255.255:bootpc /BOOTP / DHCP
>>> for p in ans:print p[1][Ether].src, p[1][IP].src
...
00:de:ad:be:ef:00 192.168.1.1
00:11:11:22:22:33 192.168.1.11

第二步参考

http://trac.secdev.org/scapy/wiki/IdentifyingRogueDHCPServers
其实,可以看dhcp_request()源代码的,源代码是这么写的

def dhcp_request(iface=None,**kargs):
    ifconf.checkIPaddr != 0:
       warning("conf.checkIPaddr is not 0, I may not be able to match theanswer")
    if iface isNone:
       iface = conf.iface
    fam,hw =get_if_raw_hwaddr(iface)
    returnsrp1(Ether(dst="ff:ff:ff:ff:ff:ff")/IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67)
                /BOOTP(chaddr=hw)/DHCP(options=[("message-type","discover"),"end"]),iface=iface,**kargs)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值