DMI是desktop Management接口,是SUN公司搭带的管理应用程序,每个通过DMI管理的应用程序有一个MIF记录能通过 dmisp(DMI SERVICE PROVIDOR)守护程序插入到MIF数据库(/var/dmi/db)。但没有对谁发布了新的MIF没有进行身份验证,即意思是任何人可以做这件事情。有两个可能引起拒绝服务的情况,第一是耗尽/var下面的磁盘空间,其对DMI 能使用多少空间没有进行限制。第二是在dmispd产生缓冲溢出。
1. 本地和远程的用户可以用尽/var下的所有磁盘空间
通过使用"dmi_cmd",任意用户在任何其他的Solaris机器上可以用"dmi_cmd -CI sp.mif"命令向/var/dmi/db的数据库里添加sp.mif文件。用户可以重复这一操作直至/var(或者其他任何存放该配置文件的地方)的空间用尽。sp.mif是默认安装的并且没有用户的认证。这类攻击可以作为其他更为严重攻击的前奏,因为Solaris系统把日志文件都放在/var的目录下面。而dmispd的活动没有任何纪录。(本站提示:也就是说,攻击者可以先行把/var的资源用尽,然后再进行入侵,这样使得系统的syslogd行同虚设。)
2. 本地和远程的用户可以使dmispd守护进程崩溃
同样通过使用"dmi_cmd -CI"命令,用户可以指定加入他们自己的文件。如果这个文件在第一行有足够的比特数,那么会导致这个守护进程的段溢出和崩溃。我们可以用如下的程序来实现:
# any more than 1024 characters in here and dmispd reports an error
# and exit()''s without segfaulting.
echo `perl -e "print ''A'' x 1000"` > /usr/home/btellier/my.mif
dmi_cmd -CI ../../../usr/home/btellier/my.mif
然后客户端就挂起了,并报告错误信息(实际上是守护进程段溢出和崩溃了)。这个仅仅改写了%o4寄存器。此外,这个守护进程之接受常规的字母/数字/符号,而忽略了其他的字符。这样就使得攻击者除了进行拒绝服务攻击以外,很难实现别的攻击。
Solution
Apply a patch from Sun when it is available
Sun has been notified of this issue and is actively working on patches to address the problem. This advisory will be updated when patches are available.
Disable snmpXdmi
Until patches are available, sites that do not use both SNMP and DMI are stongly encouraged to disable snmpXdmid.
One way to accomplish this is to issue the following commands (as root):
Prevent the daemon from starting up upon reboot
mv /etc/rc3.d/SXXdmi /etc/rc3.d/KXXdmi
Killing the currently running daemon
/etc/init.d/init.dmi stop
Verify that the daemon is no longer active
ps -ef | grep dmi
As an additional measure, you may wish to make the daemon non-executable
chmod 000 /usr/lib/dmi/snmpXdmid
Restrict access to snmpXdmi and other RPC services
For sites that require the functionality of snmpXdmi or other RPC services, local IP filtering rules that prevent hosts other than localhost from connecting to the daemon may mitigate the risks associated with running the daemon. Sun RPC services are advertised on port 111/{tcp,udp}. The snmpXdmid RPC service id is 100249; use 'rpcinfo -p' to list local site port bindings:
# rpcinfo -p | grep 100249
100249 1 udp 32785
100249 1 tcp 32786
Note that site-specific port binding will vary.
# man dmispd
Reformatting page. Please Wait... done
Maintenance Commands dmispd(1M)
NAME
dmispd - Sun Solstice Enterprise DMI Service Provider
SYNOPSIS
/usr/lib/dmi/dmispd [ -h ] [ -c config-dir ] [ -d debug-
level ]
DESCRIPTION
The DMI Service Provider, dmispd, is the core of the DMI
solution. Management applications and Component instrumenta-
tions communicate with each other through the Service Pro-
vider. The Service Provider coordinates and arbitrates
requests from the management application to the specified
component instrumentations. The Service Provider handles
runtime management of the Component Interface (CI) and the
Management Interface (MI), including component installation,
registration at the MI and CI level, request serialization
and synchronization, event handling for CI, and general flow
control and housekeeping.
OPTIONS
The following options are supported:
-c config-dir
Specify the full path of the directory containing the
dmispd.conf configuration file. The default directory
is /etc/dmi/conf.
-d debug-level
Debug. Levels from 0 to 5 are supported, giving vari-
ous levels of debug information. The default is 0,
meaning no debug information is given.
If this option is omitted, then dmispd is run as a
daemon process.
-h Help. Print the command line usage.
EXIT STATUS
The following error values are returned:
0 Successful completion.
1 An error occurred.
FILES
/etc/dmi/conf/dmispd.conf
DMI Service Provider configuration file
ATTRIBUTES
See attributes(5) for descriptions of the following attri-
butes:
SunOS 5.8 Last change: 17 Dec 1996 1
Maintenance Commands dmispd(1M)
____________________________________________________________
| ATTRIBUTE TYPE | ATTRIBUTE VALUE |
|_____________________________|_____________________________|
| Availability | SUNWsadmi |
|_____________________________|_____________________________|
SEE ALSO
snmpXdmid(1M), attributes(5)
SunOS 5.8 Last change: 17 Dec 1996 2
# man snmpXdmid
Reformatting page. Please Wait... done
Maintenance Commands snmpXdmid(1M)
NAME
snmpXdmid - Sun Solstice Enterprise SNMP-DMI mapper subagent
SYNOPSIS
/usr/lib/dmi/snmpXdmid -s hostname [ -h ] [ -c config-dir
] [ -d debug-level ]
DESCRIPTION
The snmpXdmid utility is a subagent in the Solstice Enter-
prise Agent Desktop Management Interface package. It maps
the SNMP requests forwarded by the Master Agent (
snmpdx(1M)) into one or more equivalent DMI requests.
Further, it remaps the DMI response into SNMP response back
to snmpdx. By default, snmpXdmid also forwards the DMI indi-
cations as SNMP traps to snmpdx. The feature is configur-
able and can be disabled by setting
TRAP_FORWARD_TO_MAGENT=0 in the snmpXdmid configuration
file, snmpXdmid.conf.
This subagent runs as a daemon in the system. The subagent
uses a set of .MAP files located in /var/dmi/map to map the
SNMP Object Identifier (OID) into a corresponding DMI com-
ponent. The map files are generated using the MIF-to-MIB
utility, miftomib. They are read by snmpXdmid when a
corresponding MIF file gets registered with the DMI Service
Provider ( dmispd(1M)).
The snmpXdmid.conf file is used for configuration informa-
tion. Each entry in the file consists of a keyword followed
by an equal sign (=), followed by a parameter string. The
keyword must begin in the first position. A line beginning
with a pound sign (#) is treated as a comment and the subse-
quent characters on that line are ignored. The keywords
currently supported are:
WARNING_TIMESTAMP
Indication subscription expiration, warning time.
EXPIRATION_TIMESTAMP
Indication subscription expiration timestamp.
FAILURE_THRESHOLD
DMISP retries before dropping indication due to comm
errors.
TRAP_FORWARD_TO_MAGENT
0 Drop indication at the subagent level.
non-zero
Forward indications as SNMP traps to snmpdx.
SunOS 5.8 Last change: 17 Dec 1996 1
Maintenance Commands snmpXdmid(1M)
By default, the configuration file snmpXdmid.conf is located
in the /etc/dmi/conf directory. You can specify an alterna-
tive directory with the -c option.
OPTIONS
The following options are supported:
-c config-dir
Specify the directory where snmpXdmid.conf file is
located.
-d debug-level
Debug. Levels from 1 to 5 are supported, giving vari-
ous levels of debug information.
-h Help. Print the command line usage.
-s hostname
Specify the host on which dmispd is running.
FILES
/etc/dmi/conf/snmpXdmid.conf
DMI mapper configuration file
ATTRIBUTES
See attributes(5) for descriptions of the following attri-
butes:
____________________________________________________________
| ATTRIBUTE TYPE | ATTRIBUTE VALUE |
|_____________________________|_____________________________|
| Availability | SUNWsadmi |
|_____________________________|_____________________________|
SEE ALSO
dmispd(1M), snmpdx(1M), attributes(5)
SunOS 5.8 Last change: 17 Dec 1996 2
# more /etc/init.d/init.dmi
#!/sbin/sh
#
# Copyright (c) 1996-1997 by Sun Microsystems, Inc.
# All rights reserved.
#
#ident "@(#)init.dmi 1.15 97/12/08 SMI"
case "$1" in
'start')
if [ -f /etc/dmi/conf/dmispd.conf -a -x /usr/lib/dmi/dmispd ]; then
/usr/lib/dmi/dmispd
fi
if [ -f /etc/dmi/conf/snmpXdmid.conf -a \
-x /usr/lib/dmi/snmpXdmid ]; then
if /usr/bin/pgrep -x -u 0 snmpdx >/dev/null 2>&1; then
[ -z "$_INIT_UTS_NODENAME" ] && \
_INIT_UTS_NODENAME=`/usr/bin/uname -n`
`/usr/lib/dmi/snmpXdmid -s $_INIT_UTS_NODENAME`
fi
fi
if [ -x /etc/dmi/ciagent/ciinvoke ]; then
dirents=`echo /etc/dmi/ciagent/*`
if [ "$dirents" != /etc/dmi/ciagent/ciinvoke ]; then
/etc/dmi/ciagent/ciinvoke
fi
fi
;;
'stop')
/usr/bin/pkill -9 -x -u 0 '(snmpXdmid|dmispd)'
;;
*)
echo "Usage: $0 { start | stop }"
exit 1
;;
esac
exit 0
Security Review: Securing SNMP on Solaris Information Systems and Technology University of Waterloo
What we Learned
This section documents our efforts to answer the questions noted above and secure the SNMP service on a Solaris 8 system. If you're interested in quick answers you can safely skip to the Recommendations that follow. If you're interested in how we came to those recommendations this section may be worth reading.
My baseline: I know very little about SNMP. I do know that's it's often used to monitor systems and sometimes used to control them. Typically, network operations use tools (like the InterMapper noted above) that rely on SNMP to detect and resolve networking problems like router outages. People who know these things talk about SNMP traps, MIB's, OID's and other three letter acronyms. I'm not one of them.
A quick peek at our system with ps(1) and lsof(1) to find snmp services reveals a couple of candidates to investigate:
# ps -ef | grep snmp
root 808 1 0 Oct 03 ? 0:00 /usr/lib/snmp/snmpdx -y -c /etc/snmp/conf
root 815 1 0 Oct 03 ? 0:00 /usr/lib/dmi/snmpXdmid -s wally
reggers 12675 9473 0 14:09:24 pts/2 0:00 grep snmp
# lsof -i | grep snmp
snmpdx 808 root 4u inet 0xf61c8418 0t0 UDP *:snmp (Idle)
snmpdx 808 root 5u inet 0xf61c8568 0t0 UDP *:33037 (Idle)
snmpdx 808 root 6u inet 0xf6459c70 0t0 UDP *:33038 (Idle)
snmpXdmid 815 root 0u inet 0xf61c84f8 0t0 UDP *:33031 (Idle)
snmpXdmid 815 root 1u inet 0xf6459f80 0t0 TCP *:32792 (LISTEN)
snmpXdmid 815 root 6u inet 0xf6459d50 0t0 UDP *:33033 (Idle)
snmpXdmid 815 root 7u inet 0xf6459ce0 0t0 UDP *:6500 (Idle)
We were expecting a simple daemon listening on one port for SNMP requests and we've found two daemons listening on seven different service ports. The manual pages tell us that snmpdx(1M) is the Sun Solstice Enterprise Master Agent while snmpXdmid(1M) is the Sun Solstice Enterprise SNMP-DMI mapper subagent. It turns out that there is an incredibly complicated web of service dependencies. Here's what we understand:
The snmpdx process that's listening at the "snmp" port is a master that spawns off "sub agents" (ie. processes) to do the work -- an important one is mibiisa(1M).
The snmpdx process starts the mibiisa(1M) process and instructs it to listen on a particular port (by default it would listen to the "snmp" port but that's busy with the snmpdx process!).
SNMP requests received by the snmpdx process (received at the "snmp" port) are sent to mibiisa(1M) and the answers returned to the snmpdx process are then returned to the client who made the request. That's a simple relaying operation.
The snmpdx process also relays SNMP traps the subagents generate but nothing had been configured -- our manager ratbert only polls wally. Traps are event driven interrupts like "Hey ratbert, I just ran out of memory!" We weren't using any of them.
These processes are started at boot time from /etc/rc3.d/S76snmpdx.
Likewise the snmpXdmid is a subagent that processes "snmp" requests (received on some other port) and spawns off a sub-process dmispd(1M).
The snmpXdmid process accepts SNMP requests from snmpdx (and anyone else I suppose) and translates them into DMI requests serviced by the dmispd process. That's a translate and relay.
The snmpXdmid process also relays certain DMI events as SNMP traps. But again nothing had been configured.
These processes are started at boot time from /etc/rc3.d/S77dmi.
So now our simple problem has become even more complicated:
# ps -ef | egrep 'dmi|mib|snmp'
root 814 1 0 Oct 03 ? 0:01 /usr/lib/dmi/dmispd
root 808 1 0 Oct 03 ? 0:00 /usr/lib/snmp/snmpdx -y -c /etc/snmp/conf
root 838 808 0 Oct 03 ? 1:38 mibiisa -r -p 33036
root 815 1 0 Oct 03 ? 0:00 /usr/lib/dmi/snmpXdmid -s wally
root 12340 12307 1 13:32:41 pts/2 0:00 egrep dmi|mib|snmp
# lsof -i | egrep 'dmi|mib|snmp'
snmpdx 808 root 4u inet 0xf61c8418 0t0 UDP *:snmp (Idle)
snmpdx 808 root 5u inet 0xf61c8568 0t0 UDP *:33037 (Idle)
snmpdx 808 root 6u inet 0xf6459c70 0t0 UDP *:33038 (Idle)
dmispd 814 root 3u inet 0xf61c85d8 0t0 UDP *:33030 (Idle)
dmispd 814 root 4u inet 0xf6459e30 0t0 TCP *:32793 (LISTEN)
snmpXdmid 815 root 0u inet 0xf61c84f8 0t0 UDP *:33031 (Idle)
snmpXdmid 815 root 1u inet 0xf6459f80 0t0 TCP *:32792 (LISTEN)
snmpXdmid 815 root 6u inet 0xf6459d50 0t0 UDP *:33033 (Idle)
snmpXdmid 815 root 7u inet 0xf6459ce0 0t0 UDP *:6500 (Idle)
mibiisa 838 root 0u inet 0xf6459c00 0t0 UDP *:33036 (Idle)
We assumed one process listening at the "snmp" port and find instead four processes listening at ten ports! That's a lot of baggage and considerable exposure. How can we manage this?
Our first success was to determine that we could safely disable all DMI services with no loss of functionality for the InterMapper at ratbert. That eliminates two processes listening at six different ports. We assume there are some SNMP requests that can only be answered by the dmispd(1M) daemon. But we're not using them!
An observation: At least some of those DMI services are delivered as RPC services -- you'll find them using rpcinfo. With a little digging you'll discover that both daemons are offering RPC services. By contrast SNMP services are not layered on RPC. We suppose, but cannot confirm, that you cannot run DMI services without also running rpcbind -- that's the rendezvous point to translate RPC service numbers into TCP/UDP port numbers.
We turned our attention to the snmpdx(1M) and mibiisa(1M) processes. Both are configured from files found in /etc/snmp/conf. The file names are a little confusing --- snmpd.conf configures mibiisa(1M) while snmpdx.acl configures snmpdx(1M). There are other configuration files there and elsewhere but we only looked at these.
The manual page for snmpdx(1M) is pretty minimal but it points to an access control file snmpdx.acl that looked promising. Unfortunately there's no manual page for that and the commentary in the access control file provided does not correspond at all to the Solaris Answerbook (which you will find at Sun Product Documentation). Nevertheless we spent several hours working with the configuration trying variations:
Uncommenting this stanza, killing and restarting the daemons, results in syslog gripes:
# The list of hosts that can send SNMP queries.
# If this list is empty, all the hosts are allowed to
# send SNMP queries.
#managers = {
#}
The "managers =" fragment is not recognized at all -- it's a syntax error. There are several top level stanzas in the vendor provided configuration -- the only allowed stanzas according to the Answerbook and our tests are "acl=" and "traps=".
We tried changing the "managers" list on this stanza (again killing and restarting the daemons after each change):
# The list of community names needed for read/write access
# to the entire MIB.
# If the list is empty, the only valid community name is "public"
# and its access type is read-only
acl = {
{
communities = public, private
access = read-write
managers = *
}
}
But no matter what we did the server always responded to ratbert. We were also a little distressed by what looks like "read-write" access to both the public and the private data -- very scary.
Finally we gave up on configuring the snmpdx process and turned our attention to the mibiisa daemon. The manual page for mibiisa(1M) is very good and even has a section on security. The default configuration, when stripped of commentary, looks something like this:
sysdescr Sun SNMP Agent, SPARCstation-10
syscontact System administrator
sysLocation System administrators office
system-group-read-community public
read-community public
trap localhost
trap-community SNMP-trap
managers localhost
We determined that the vendor configuration restricted the daemon to provide responses only to the localhost (ie. to the same system). That's the "managers" line. Since we had learned to not trust the vendor documentation we ran the daemon in a debug mode to verify that, as configured, it would not respond to anyone other than the "managers" listed in the configuration file. Changing the "managers" to include ratbert meant the InterMapper got the information it needed.
Summary: after considerable effort we've determined that there's a great wack of services we don't need and we can safely configure one daemon to restrict it's attention to a list of authorized managers.