(Reported to CERT & Oracle on 23 Oct 2000) Synopsis: While playing around with writing my own version of 'tnsping', (http://www.jammed.com/~jwa/hacks/tnscmd) I discovered two interesting bugs in Oracle's tnslsnr. Discovered: 5 Oct 2000 Affected: TNS for Solaris: Version 8.1.6.0.0 - Production Author contact: James W. Abendschan Problem 1: Remote denial-of-service in tnslsnr Description: By sending properly framed but syntatically invalid commands to the tnslsnr, it will crash: 16286: read(14, " C T _ D A T A = ( C O M".., 27) = 27 16286: ioctl(14, FIONBIO, 0xFFBEB3D8) = 0 16286: time() = 971816790 16286: Incurred fault #6, FLTBOUNDS %pc = 0xFEAD0964 16286: siginfo: SIGSEGV SEGV_MAPERR addr=0x00000000 16286: Received signal #11, SIGSEGV [default] 16286: siginfo: SIGSEGV SEGV_MAPERR addr=0x00000000 16286: *** process killed *** gdb indicates it SEGV's while calling strtol() -- #0 0xfead0964 in strtol () from /usr/lib/libc.so.1 Repeat by: Call my 'tsncmd' with one of trc_file trc_level use_plugandplay trc_directory snmp_visible log_file log_status log_directory Workaround: write a simple watchdog to restart the tnslsnr when it dies restrict access to tnslsnr port via packet filter (so only authorized users can crash it!@#) Problem 2: TNS packet leaking Description: By sending TNS packets with incorrect length bytes, it is possible to see the contents of previous TNS packets. This data usually includes oracle usernames. Repeat by: This one requires experimentation. By calling tnscmd with the --cmdsize argument, you can manipulate the "command length" bytes. On two of our oracle boxes, I was able to get additional information by using sizes of 40, 200, and 290, but it doesn't appear to be constant. Start with small values. I was able to get variants of the following: `¢e@(DESCRIPTION=(ERR=1153)(VSNNUM=135290880)(ERROR_STACK=(ERROR=(CODE=1153)(EMFI=4)(ARGS='(CONNECT_DATA=(COMMAND=p))g))OL=TCP)(HOST=oraclesvr)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=pr01)(CID=(PROGRAM=)(HOST=oraclesvr)(USER=oracle)))))(USER=Default))))R=jonathanl))))BIN\ifrun60.EXE)(HOST=MNSTRCSTSVC)(USER=JGuerra))))))))\ifrun60.EXE)(HOST=TEMP01)(USER=temp))))))))))erra))))))))'))(ERROR=(CODE=303)(EMFI=1)))) .. two usernames are leaked. Doing this at different times of the day on a busy server will reveal more usernames, and perhaps other interesting things. Workaround: restrict access to tnslsnr port via packet filter Obviously tnslsnr is brittle. Putting the oracle box behind a firewall isn't the right solution; the listener should not fall over when someone sends it funny packets!