Object Enumeration in Novell Environments Issue date: 11/08/00 Contact:Simple Nomad Topic: Default settings allows Novell Netware system information disclosure. Affected Systems: Novell Netware 5.0, 5.1 including the latest patches. Overview: Due to a combination of legacy support and default settings, Novell Netware servers using native IP will leak system information via TCP port 524 when properly queried. In mixed Novell/Microsoft environments, information regarding Microsoft devices is leaked via the Service Advertising Protocol (SAP) table. Third party products, such as those used to synchronize directory services between environments can further the problem. Essentially, a remote attacker can gather the equivalent information provided by the console command "display servers" and the DOS client command "cx /t /a /r" without authentication. Impact: All Novell Netware servers running IP (with port 524 open) can be queried and all objects with Public read access can be enumerated. Information such as account names, server services, and other various objects can be gathered. In mixed environments, such as environments with a mixture of IPX and IP, some IPX objects that are managed and communicate with IP-based servers can be leaked, and in an environment with Microsoft NT some NT objects can be leaked. The information gathered could be used to enumerate user account names and technologies deployed, which could be used for a future attack. The scope of the impact is limited to the internal network unless TCP port 524 access is allowed through a firewall or from dialup technologies deployed internally. This is similar in scope to a Windows NT null session against a Primary or Backup Domain Controller. Details: Novell has pushed to make its Netware environment as connectable as possible. To this end, Novell has deployed a "pure" TCP/IP environment (as opposed to previous implementations that did not fully incorporate Netware into the IP world, such as Netware/IP). The assigned port 524 [1] is for NCP (Netware Core Protocol), and is used in pretty much the same fashion as IPX was previously. This allows normal IPX-based applications running on the client to be able to communicate with an IP-only Netware server, as the client software "wraps" the IPX request in an IP packet and sends it to port 524. Traditionally in Netware environments, IPX was used exclusively for both client-to-server and server-to-server communications. Netware objects, such as printers, would act as clients to a server so when the end user wanted to communicate with a printer, he or she could query the server and receive the information about the printer's location. Additionally, Netware servers could also route IPX communications between multiple network interface cards, and learn about other services available on other servers, all via IPX. To preserve this rich environment, most of the technologies involved were ported to use IP with backwards-compatibility in mind. Basically this means that since IP did not support this "auto-discovery" of available services on its own, Novell used a combination of wrapping NCP commands (the commands that used to be sent client-to-server and server-to-server over IPX) in IP packets over port 524, and using SLP (Service Location Protocol) over port 427. Novell has been very good at trying to ensure it does not lock out older versions of Netware with interoperability with newer versions. However because of this history, older NCP calls used two or three major versions ago can still be used to query the server. Since these calls can now be wrapped in IP, we can make the calls from non-Netware systems. And since many of these calls are not dependent upon the user authenticating first, we can take advantage of default NDS tree settings in enumeration of NDS objects [2]. 1. Build the TCP connection. Send TCP packet with SYN to port 524, receive the SYN/ACK, reply with an ACK. Your basic connection. 2. Now we build the NCP connection. This is done the same way as IPX, except we are putting the data in a TCP packet. We start with an NCP header with no NCP data, using connection type 0x1111. NCP (create_conn) { // begin NCP request header u32 sig; // signature identifies the packet type (0x446d6454) u32 len; // length 0x00000017 (23) u32 reqbuf; // requested buffer size 0x00000000 u16 reqtype; // request type 0x1111 (create connection) u8 seq; // initial sequence number 0x00 u8 connlow; // 0xff (255) wildcard u8 task; // 0x01 u8 connhi; // 0xff (255) wildcard // end NCP request header } create_conn_req; And here is the reply: NCP (create_conn_reply) { // begin NCP reply header u32 sig; // signature u32 len; // length 0x00000010 (16) u16 reqtype; // reply 0x3333 u8 seq; // initial sequence number 0x00 u8 connlow; // 0x0e (14) <--\ u8 task; // 0x01 >-- connection number u8 connhi; // 0x00 (0) <--/ // end NCP reply header // begin data section u8 cc; // completion code 0x00 (OK) u8 cs; // connection status flags 0x00 (OK) // end data section } create_conn_rep; 3. Now we do a Server Info Request call to gather basic information about the server. NCP (server info request) { // begin NCP header u32 sig; // signature (0x446d6454) u32 len; // length = 0x0000001a (26) u32 ver; // version = 0x00000001 u32 bufreply; // reply buffer size = 0x00000080 (128) u16 reqtype; // 0x2222 (request) u8 seq; // 0x01 sequence number is incremented by one u8 connlow; // Conn low 0x0e (14) u8 task; // Task # 0x01 u8 connhi; // Conn hi 0x00 (0) // end NCP header // Request/sub-function code = 23,17 u32 req; // 0x17000111 (23,0,1,17) } server_info_req; Note that we incremented the sequence number by one. This is the old IPX packet sequence numbering scheme, which is to increment by one, unless the number is 255 and then you reset it back to zero. In the reply we get back a bunch of information: NCP (server info reply) { // begin NCP header u32 sig; // 4 byte signature u32 len; // length = 0x00000090 (144) u16 reqtype; // 0x3333 (reply) u8 seq; // 0x01 sequence number u8 connlow; // Conn low 0x0e (14) u8 task; // Task # 0x01 u8 connhi; // Conn hi 0x00 (0) // end NCP header // Reply/sub-function code = 23,17 u8 cc; // completion code = 0x00 (ok) u8 cs; // connection status flags = 0x00 (ok) u8[47] svrname; // object name = 0x50 41 4e (PAN) u8 ser_ver; // file service version = 0x05 u8 ser_subver; // file service sub-version = 0x00 u16 max_conn; // max service connections = 0x000e u16 conn_use; // connections in use = 0x0000 u16 max_vols; // maximum volumes = 0x00ff u8 rev; // revision = 0x00 u8 sft; // sft level = 0x02 u8 tts; // tts level = 0x01 u16 max_used; // max conn ever used = 0x01 u8 acct; // account version = 0x01 u8 vap; // VAP version = 0x01 u8 queue; // Queue version = 0x01 u8 print; // Print version = 0x00 u8 virt_con; // Virtual console version = 0x01 u8 int_brdg; // Internet bridge = 0x01 } server_info_rep; Now we know the server name is PAN, it is Netware 5.0, and a few other items. 4. Do an NDS Ping which will return the NDS Tree name. NDS Ping is used to tell if servers are up. Clients typically send these packets to the first server available. We'll use it because it allows us to determine the tree name without authenticating. NCP (NDS_ping) { // begin NCP header u32 sig; // signature (0x446d6454) u32 len; // length = 0x0000001b (27) u32 ver; // version = 0x00000001 u32 bufreply; // reply buffer size = 0x00000028 (40) u16 reqtype; // 0x2222 (request) u8 seq; // 0x02 sequence number is incremented by one u8 connlow; // Conn low 0x0e (14) u8 task; // Task # 0x01 u8 connhi; // Conn hi 0x00 (0) // end NCP header // Request/sub-function code = 104,0 u32 req; // 0x68010000 (104,1,0,0) } NDS_ping_req; And here's the reply: NCP (NDS_ping_reply) { // begin NCP reply header u32 sig; // signature u32 len; // length 0x00000010 (16) u16 reqtype; // reply 0x3333 u8 seq; // 0x02 sequence number u8 connlow; // 0x0e (14) <--\ u8 task; // 0x01 >-- connection number u8 connhi; // 0x00 (0) <--/ // end NCP reply header // begin data section u8 cc; // completion code 0x00 (OK) u8 cs; // connection status flags 0x00 (OK) u32 u1; // unknown u32 treelen; // length of tree name u8[21] treename;// 0x54 45 53 54 (in this example, TEST) u32 objid; // object ID of tree // end data section } NDS_ping_rep; Now we have the NDS tree name. 5. Finally by sending a Scan Bindery Object request in a loop we can enumerate all objects with at least public read access. NCP (scan bindery object request) { // begin NCP header u32 sig; // signature (0x446d6454) u32 len; // length = 0x00000022 (34) u32 ver; // version = 0x00000001 u32 bufreply; // reply buffer size = 0x00000039 (57) u16 reqtype; // 0x2222 (request) u8 seq; // 0x03 (3) sequence number u8 connlow; // Conn low 0x0e (14) u8 task; // Task # 0x01 u8 connhi; // Conn hi 0x00 (0) // end NCP header // Request/sub-function code = 23,55 u32 req; // 0x17000837 (23,0,8,55) u32 lastobj; // Last object ID seen = 0xffffffff (wild card) // start with ffffffff and simply use the last // object ID that was retrieved u16 objtype; // Object type = 0xffff (wildcard) u16 search; // search string = 0x012a ("*") } scan_bin_obj_req; Here is a sample reply: NCP (scan bindery object reply) { // begin NCP header u32 sig; // signature (0x446d6454) u32 len; // length = 0x00000049 u32 reqtype; // 0x3333 = (reply) u8 seq; // 0x03 (3) sequence number u8 connlow; // Conn low 0x0e (14) u8 task; // Task # 0x01 u8 connhi; // Conn hi 0x00 (0) // end NCP header u8 cc; // completion code = 0x00 u8 cs; // connection status flags = 0x00 u32 obj_id; // object ID found (0xc20000a1) u16 objtype; // object type = 0x0004 (server) u8[48] objname; // object name = 0x50 41 4e (PAN) u8 objflag; // object flag = 0x00 (static) u8 sec; // security status = 0x40 (0100 write access for svr, 0000 read access for all) u8 statflags; // status flags = 0xff (has properties) } scan_bin_obj_rep; The interesting thing is that if the NDS tree object named [Public] has Browse rights, all objects except those restricted by Inherited Rights Filters will have their names enumerated, e.g. user names. The default setting for Novell is to have Browse rights on [Public]. In addition to enumeration of NDS objects, all dynamic listings in the SAP table will be enumerated. This includes not just additional Novell services in the environment, such as non-IP Novell systems that the IP Novell systems are talking to, but other vendor software and hardware products as well. For example, SAP type 0x0640 is for NT RPC services, 0x64e is for NT IIS servers. Using the information in the SAP table and refering to a list of Novell-assigned SAP types, various deployed technologies can be enumerated as well. Microsoft systems that advertise file and print services recognizable by the Novell environment can have their computer Netbios names enumerated via the 0x0640 SAP type. While NDS tree browsing can be limited by adjusting default rights on the NDS tree, this does not limit the information that can be leaked via the SAP table. Recommendations: Due to the amount of information leaked via port 524, it is recommended that access to port 524 be blocked from the Internet. The NDS object [Public] should not have Browse rights, the tree should be restricted to authenticated users only, so remove Browse rights from [Public]. Use the ncpquery [2] tool to check to see what is leaking via port 524. Internal threats may be harder to defend against, particularly the information that leaks via the dynamic SAP table, but removing Browse from [Public] should at least limit user name enumeration. References: [1] ftp://ftp.isi.edu/in-notes/iana/assignments/port-numbers [2] http://razor.bindview.com/tools/files/ncpquery-1.2.tgz [3] http://support.novell.com/, search for Technical Information Document 10050864, "List of Publicly Registered SAP Types" Contact: info@razor.bindview.com| Fax:508-485- 0737|Bindview Home