COMMAND
Novell Netware
SYSTEMS AFFECTED
Novell Netware 5.0, 5.1 including the latest patches
PROBLEM
Following is based on Razor BindView Advisory. 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.
RAZOR has received reports of distributed port scans looking for
port 524 on the Internet, so this technique is probably being used
by potential attackers to gain information from potential targets.
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.
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 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:
http://razor.bindview.com/tools/files/ncpquery-1.2.tgz
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;
Now we have a connection to the Netware server.
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.
SOLUTION
Novell feels that the following recommendations section is fine
the way it is. No patch, just configuration issues. The
seriousness can probably best be assessed by running the NCPQuery
tool against your Netware servers that are running IP. Probably
the most interesting thing is the tool runs on plain old Unix, so
probes from the Internet are possible if port 524 is open.
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 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.