📄 dcetest.nasl
字号:
# Extract UUID from buffer#function load_uuid_le(b, t){ __ret = ""; for (__i = 0; __i < 16; __i = __i + 1) { # ouch, would drop zero bytes without raw_string __ret = string(__ret, raw_string(ord(b[t + __i]))); } return (__ret);}function load_uuid(b, t){ __ret = ""; if (little_endian) { __ret = load_uuid_le(b:b, t:t); } else { __ret = string(__ret, raw_string(ord(b[t + 3])), raw_string(ord(b[t + 2])), raw_string(ord(b[t + 1])), raw_string(ord(b[t])), raw_string(ord(b[t + 5])), raw_string(ord(b[t + 4])), raw_string(ord(b[t + 7])), raw_string(ord(b[t + 6]))); for (__i = 8; __i < 16; __i = __i + 1) { __ret = string(__ret, raw_string(ord(b[t + __i]))); } } return (__ret);}## Extract string from buffer# Unprintable characters are replaced with ?#function load_string(b, t, l){ __ret = ""; for (__i = 0; __i < l; __i = __i + 1) { __c = ord(b[t + __i]); if (__c == 0) return (__ret); if ((__c < 32) || (__c > 127)) { __ret = string(__ret, "?"); } else { __ret = string(__ret, raw_string(__c)); } } return (__ret);}## Parse a response to an enumeration request#function dce_parse(result){ # Check whether we got RESPONSEPACKET if (ord(result[2]) != 0x02) { return (-1); } # Update the context handle hndatr = load_long(b:result, t:24); handle = load_uuid(b:result, t:28); # Skip: # common DCE header (16 bytes) # alloc_hint, p_cont_id, cancel_count, padding (8 bytes) # context_handle.attributes (4 bytes) # context_handle.uuid (16 bytes) # num_elts (4 bytes) (should check != 0?) # "something" (36 bytes) p = 84; # Annotation tint = load_long(b:result, t:p); p = p + 4; if (tint > 64) { return (-1); } annotation = load_string(b:result, t:p, l:tint); p = p + tint; while (p % 4 != 0) p = p + 1; # Skip tower lengths p = p + 8; # Number of floors floors = load_short_le(b:result, t:p); p = p + 2; guid = ""; majver = "???"; proto = "???"; ncaproto = "???"; ncahost = "???"; ncaport = "???"; ncaunk = ""; # for undecoded floors # Analyze floors for (floor = 1; floor <= floors; floor = floor + 1) { # Sanity check if (p >= strlen(result) - 4) { return (-1); } # Floor part #1 (protocol identifier) tint = load_short_le(b:result, t:p); p = p + 2; addr_type = ord(result[p]); addr_data = string_from_buffer(b:result, start:p+1, end:p+tint-2); if (floor == 1) { # expecting addr_type == 0x0d (UUID_type_identifier), tint == 19 guid = load_uuid_le(b:result, t:p + 1); guid = struuid(uuid:guid); majver = load_short_le(b:result, t:p + 17); } p = p + tint; # Floor part #2 (related information) tint = load_short_le(b:result, t:p); p = p + 2; # skip floors 1-3, expected contents: # floor #1: interface UUID (see above) # floor #2: transfer syntax UUID # floor #3: RPC connection-oriented/connectionless if (floor > 3) { decoded = 0; if (addr_type == 0x01) { # nonstandard NetBIOS name (string) ncahost = "{0x01}" + load_string(b:result, t:p, l:tint); decoded = 1; } if (addr_type == 0x07) { # TCP port (2 bytes) proto = "tcp"; ncaproto = "ncacn_ip_tcp:"; ncaport = load_short_be(b:result, t:p); decoded = 1; } if (addr_type == 0x08) { # UDP port (2 bytes) proto = "udp"; ncaproto = "ncadg_ip_udp:"; ncaport = load_short_be(b:result, t:p); decoded = 1; } if (addr_type == 0x09) { # IP address (4 bytes) ncahost = string( ord(result[p]), ".", ord(result[p+1]), ".", ord(result[p+2]), ".", ord(result[p+3])); decoded = 1; } if (addr_type == 0x0f) { # named pipe path (string) proto = "PIPE"; ncaproto = "ncacn_np:"; ncaport = load_string(b:result, t:p, l:tint); decoded = 1; } if (addr_type == 0x10) { # LRPC port (string) proto = "LRPC"; ncaproto = "ncalrpc"; ncahost = ""; ncaport = load_string(b:result, t:p, l:tint); decoded = 1; } if (addr_type == 0x11) { # NetBIOS name (string) ncahost = load_string(b:result, t:p, l:tint); decoded = 1; } if (addr_type == 0x16) { # Appletalk DSP port (string) proto = "APPLE-DSP"; ncaproto = "ncacn_at_dsp"; ncaport = load_string(b:result, t:p, l:tint); decoded = 1; } if (addr_type == 0x17) { # Appletalk DDP port (string?) proto = "APPLE-DDP"; ncaproto = "ncadg_at_ddp"; ncaport = load_string(b:result, t:p, l:tint); decoded = 1; } if (addr_type == 0x18) { # Appletalk name (string) ncahost = load_string(b:result, t:p, l:tint); decoded = 1; } if (addr_type == 0x1f) { # HTTP port (2 bytes) proto = "tcp"; ncaproto = "ncacn_http:"; ncaport = load_short_be(b:result, t:p); decoded = 1; } # seen in the wild, to be identified: # - 0x0c (2 bytes) broken IPX? # - 0x0d (10 bytes) broken IPX? (collision with UUID) if (!decoded) { ncaunk = string( ncaunk, "{", hex(addr_type), "}", addr_data, ":", string_from_buffer(b:result, start:p, end:p+tint-1)); } } p = p + tint; } # Found a service if (guid) { report = report + string( " UUID: ", guid, ", version ", majver, "\n"); if (proto != "???") report = report + string( " Endpoint: ", ncaproto, ncahost, "[", ncaport, "]\n"); if (ncaunk) report = report + string( " Undecoded endpoint data: ", ncaunk, "\n"); if (annotation) report = report + string( " Annotation: ", annotation, "\n"); if ( rpc_svc_pipes[guid] ) report += string(" Named pipe : ", rpc_svc_pipes[guid], "\n"); if ( rpc_svc_processes[guid] ) report += string(" Win32 service or process : ", rpc_svc_processes[guid], "\n"); if ( rpc_svc_name[guid] ) report += string(" Description : ", rpc_svc_name[guid], "\n"); if ((proto == "udp") || (proto == "tcp")) { if(proto == "tcp") { register_service(port:ncaport, proto:string("DCE/", guid)); all_report_tcp[ncaport] += report + '\n'; } else all_report_udp[ncaport] += report + '\n'; } else all_report_135 += report + '\n'; return (1); } return (0);}## Receive a DCE message# this is much faster than recv(..., length:4096)#function read_dce_pdu(sock){ # Read response header __r0 = recv(socket:sock, length:16); # Check length if (strlen(__r0) != 16) { return (""); } # Check endianness if (ord(__r0[4]) & 0xF0 == 0x10) little_endian = 1; else little_endian = 0; # Extract fragment length and read the rest __r1len = load_short(b:__r0, t:8) - 16; __r1 = recv(socket:sock, length:__r1len); # Check length if (strlen(__r1) != __r1len) { return (""); } # Concatenate the results...the safe way __r = ""; for (__i = 0; __i < 16; __i = __i + 1) __r = string(__r, raw_string(ord(__r0[__i]))); for (__i = 0; __i < __r1len; __i = __i + 1) __r = string(__r, raw_string(ord(__r1[__i]))); return (__r);}#---------------------------------------------------------------------### The main program#zero_handle = raw_string (0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);handle = zero_handle; if (get_port_state(135)){ all_report_tcp = make_list(); all_report_udp = make_list(); soc = open_sock_tcp(135); if (!soc) exit(0); enum = 0; send(socket:soc, data:dce_bind()); r = read_dce_pdu(sock:soc); if (strlen(r) < 60) exit(0); # bad reply length for (x = 0; x < 4096; x = x + 1) { send(socket:soc, data:dce_enum_get_next(callid:x, handle:handle)); r = read_dce_pdu(sock:soc); if (strlen(r) <= 65) { # finished x = 4096; } else { dce_parse(result:r); enum = enum + 1; if (handle == zero_handle) { # finished x = 4096; } } } close(soc); if (enum) security_warning(135); myprereport = string("Distributed Computing Environment (DCE) services running on the remote hostcan be enumerated by connecting on port 135 and doing the appropriate queries.An attacker may use this fact to gain more knowledgeabout the remote host.Here is the list of DCE services running on this port:\n\n");mypostreport = string("Solution : filter incoming traffic to this port.Risk factor : Low"); if(!isnull(all_report_tcp)) { foreach port (keys(all_report_tcp)) security_note(port:port, data:myprereport + all_report_tcp[port] + mypostreport); } if(!isnull(all_report_udp)) { foreach port (keys(all_report_udp)) security_note(port:port, data:myprereport + all_report_udp[port] + mypostreport, proto:"udp"); } if(all_report_135 != NULL) security_note(port:135, data:myprereport + all_report_135 + mypostreport);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -