Project Honeynet - Scan of the Month - June 2001 Analysis and Answers Submitted by: Joris Bontje ----------------------------------------------------- The Challenge: -------------- The past several Scan of the Month challenges have been oriented towards beginners, our goal has been to introduce newer security members to the world of incident response and forensic analysis. We decided to change things this month and make a more difficult challenge for advance members. In March, 2001 a Solaris system was compromised. A collection of tools, utilities and files were uploaded onto the system by the blackhat. One of the files was encrypted. For this challenge, we have changed the name of the encrypted file to "somefile". You can download this file as somefile.zip, MD5 Checksum=eb7ed869ffcfe72d4b48caf57e648910, or somefile.tgz, MD5 Checksum=f7964d9860cbf8135ef64bcf5b96facb. Analysis & Answers: ------------------- Sounds like a nice challenge, I have just been reading papers about cryptoanalysis so this can be a good start. $ wget http://project.honeynet.org/scans/scan16/somefile.tgz $ md5sum somefile.tgz f7964d9860cbf8135ef64bcf5b96facb somefile.tgz $ tar zxvf somefile.tgz somefile Its only a short file so I think that big dictionary attacks won't be needed. $ wc -l somefile 532 1.Identify the encryption algorithim used to encrypt the file. ______________________________________________________________ Okay, first I have taken a look with hexdump. All high ASCII values, a hint that it isnt a very difficult encryption. $ hexdump somefile 0000000 99a4 9396 a29a 99f5 9196 c29b 9bd0 899a 0000010 8fd0 8c8b cfd0 d0ce 969d d091 9699 9b91 0000020 9bf5 c28a 9bd0 899a 8fd0 8c8b cfd0 d0ce 0000030 969d d091 8a9b 93f5 c28c 9bd0 899a 8fd0 0000040 8c8b cfd0 d0ce 969d d091 8c93 99f5 9396 0000050 a09a 9699 8b93 8d9a c28c cecf 93d3 939d 0000060 9d96 8c8f 8cd1 d390 918c 93d1 8fd3 908d 0000070 d392 939c 9e9a 9a91 d38d 909b d38c 9c8a 0000080 9190 d199 9196 d389 8c8f 919d d39c 8f93 0000090 9c9e 8b9c aad3 baac f5ad a4f5 8c8f f5a2 00000a0 8c8f d0c2 9a9b d089 8b8f d08c cecf 9dd0 00000b0 9196 8fd0 8d8c 8ff5 a08c 9699 8b93 8d9a 00000c0 c28c 8f93 d38e 8f93 9c8c 9a97 d39b 978c 00000d0 8bce 8fd3 8d8c 8cd3 978c cd9b 93d3 8c8f 00000e0 8b9a 93d3 9e8f 9c9c d38b 919d 939c d38f 00000f0 8f93 868c f58c 8c93 9990 99a0 9396 9a8b 0000100 8c8d 93c2 d38f 9c8a 9190 d199 9196 d389 0000110 8c8f 9691 9999 8fd3 8d8c c5d3 ccce cfcf 0000120 d3cf cdc5 cfca cfcf c5d3 c9c9 c7c9 c5d3 0000130 c9c9 c8c9 d0d3 9a9b d089 8b8f d08c cecf 0000140 8cd3 d191 d393 8d8f 9290 93d3 908c d399 0000150 8c8f 919d f59c a4f5 9a91 8c8b 9e8b a28b 0000160 91f5 8b9a 8b8c 8b9e d0c2 9a9b d089 8b8f 0000170 d08c cecf 9dd0 9196 91d0 8b9a 8b8c 8b9e 0000180 91f5 8b9a 99a0 9396 9a8b 8c8d cbc2 cfc8 0000190 c7ce c9d3 c9c9 f5c7 a4f5 9093 9698 a291 00001a0 8cf5 a08a 9093 c29c 9bd0 899a 8fd0 8c8b 00001b0 cfd0 d0ce 969d d091 8a8c 8ff5 9196 c298 00001c0 9bd0 899a 8fd0 8c8b cfd0 d0ce 969d d091 00001d0 968f 9891 8ff5 8c9e 888c c29b 9bd0 899a 00001e0 8fd0 8c8b cfd0 d0ce 969d d091 9e8f 8c8c 00001f0 9b88 8cf5 9a97 9393 d0c2 969d d091 978c 0000200 f5f5 8a8c 8fa0 8c9e c28c cc93 8bcc cb97 0000210 cf87 f58d 0000214 How would these characters be distributed? I wrote a little Perl program that draws a nice ASCII art graph of the distribution. $ ./stats somefile 0: ( 0) [cut] 134: ( 1) * 135: ( 1) * 136: ( 2) ** 137: ( 11) *********** 138: ( 7) ******* 139: ( 28) **************************** 140: ( 52) **************************************************** 141: ( 11) *********** 142: ( 1) * 143: ( 34) ********************************** 144: ( 10) ********** 145: ( 29) ***************************** 146: ( 2) ** 147: ( 28) **************************** 148: ( 0) 149: ( 0) 150: ( 24) ************************ 151: ( 6) ****** 152: ( 3) *** 153: ( 14) ************** 154: ( 24) ************************ 155: ( 18) ****************** 156: ( 12) ************ 157: ( 14) ************** 158: ( 9) ********* 159: ( 0) 160: ( 6) ****** 161: ( 0) 162: ( 4) **** 163: ( 0) 164: ( 4) **** 165: ( 0) 166: ( 0) 167: ( 0) 168: ( 0) 169: ( 0) 170: ( 1) * 171: ( 0) 172: ( 1) * 173: ( 1) * 174: ( 0) 175: ( 0) 176: ( 0) 177: ( 0) 178: ( 0) 179: ( 0) 180: ( 0) 181: ( 0) 182: ( 0) 183: ( 0) 184: ( 0) 185: ( 0) 186: ( 1) * 187: ( 0) 188: ( 0) 189: ( 0) 190: ( 0) 191: ( 0) 192: ( 0) 193: ( 0) 194: ( 14) ************** 195: ( 0) 196: ( 0) 197: ( 4) **** 198: ( 0) 199: ( 3) *** 200: ( 2) ** 201: ( 9) ********* 202: ( 1) * 203: ( 2) ** 204: ( 3) *** 205: ( 2) ** 206: ( 13) ************* 207: ( 18) ****************** 208: ( 45) ********************************************* 209: ( 5) ***** 210: ( 0) 211: ( 30) ****************************** [cut] 245: ( 22) ********************** [cut] 255: ( 0) Well that looks like some kind of character shifting, or maybe XOR, because there is an easy to recognize grouping. Best thing would be to compare character frequenties against that of the english language, but since I am lazy I will take another approach. 2.How did you determine the encryption method? ---------------------------------------------- Just brute force character shifting of 0-255 and XOR of 0-255. Wrote another Perl program. $ ./shift.pl |less [try for yourself to see the output] Fullspeed Pagedown: Okay, its no shifting but a simple XOR 255 encryption. 3.Decrypt the file, be sure to explain how you decrypted the file. ------------------------------------------------------------------ Yet another Perl program that does the decryption process (XOR 255). $ ./xor255.pl somefile [file] find=/dev/pts/01/bin/find du=/dev/pts/01/bin/du ls=/dev/pts/01/bin/ls file_filters=01,lblibps.so,sn.l,prom,cleaner,dos,uconf.inv,psbnc,lpacct,USER [ps] ps=/dev/pts/01/bin/psr ps_filters=lpq,lpsched,sh1t,psr,sshd2,lpset,lpacct,bnclp,lpsys lsof_filters=lp,uconf.inv,psniff,psr,:13000,:25000,:6668,:6667,/dev/pts/01,sn.l,prom,lsof,psbnc [netstat] netstat=/dev/pts/01/bin/netstat net_filters=47018,6668 [login] su_loc=/dev/pts/01/bin/su ping=/dev/pts/01/bin/ping passwd=/dev/pts/01/bin/passwd shell=/bin/sh su_pass=l33th4x0r So "somefile" is a encoded configuration file for some rootkit trojans. 4.Once decrypted, explain the purpose/function of the file and why it was encrypted ----------------------------------------------------------------------------------- The [file] section gives the paths to the 'good' find, du and ls programs, so the real ones are trojaned. file_filters tells what files and directories shouldnt be displayed. The [ps] section gives the path to the 'good' ps program. ps_filters tells the trojaned ps not to display some 'evil' daemons. lsof_filters tells what files and ports to hide. Same idea for [netstat], the path to the original program and what ports to hide. Defined in [login], the original su, ping and passwd, what shell the trojans can use. Probably it captures passwords and/or allows to get a root shell. su_pass defines the password to become root as l33th4x0r This file was encrypted to hide the names of the trojaned programs, used TCP ports, daemons and blackhat password. Now someone might think that binary files in /dev/pts/01/bin are normal :) 5.What lesson did you learn from this challenge? ------------------------------------------------ After this I searched the web with my favorite searchengine Google, maybe others have seen such a file. Searching for "su_pas" and "su_loc" leads to http://archives.neohapsis.com/archives/sf/sun/2001-q2/0088.html Seems like the file is called "/dev/pts/01/uconf.inv" here. Another search for "uconf.inv" gives this great report: http://www.sans.org/y2k/the_compromise.htm On this site is also a hexdump of a file named uconf.inv, decode it back with xxd and then do an endian conversion. $ xxd -r uconf.inv.victim1.hex > uconf.inv.victim1.big $ ./big2little.pl uconf.inv.victim1.big >uconf.inv.victim1.little $ ./xor255.pl uconf.inv.victim1.little [file] find=/lib/security/.config/bin/find du=/lib/security/.config/bin/du ls=/lib/security/.config/bin/ls file_filters=uconf.inv,tcp.log,xlogin,.config,.config,ssh2d [ps] ps=/lib/security/.config/bin/psr ps_filters=lpq,lpsched,sh1t,psr,ssh2d,lpset,lpsched,xlogin,/lib/sec lsof_filters=/lib/security/.config,uconf.inv,psniff,psr,:13000,:25000,/dev/pts/01,sn.l,prom,lsof,tcp.log,ssh2d,lpsched,xlogin,.config [netstat] netstat=/lib/security/.config/bin/netstat net_filters=13000,25000,6667,8000,9000 [login] su_loc=/lib/security/.config/bin/su ping=/lib/security/.config/bin/ping passwd=/lib/security/.config/bin/passwd shell=/bin/sh su_pass=r6f02txn That looks quite simular, more people got this on different systems. 6.How long did this challenge take you? --------------------------------------- The total process took me 2 hours, 1.5 hours of analysis of somefile and programming the Perl programs. 0.5 hours of searching the web for other clues. Bonus Question: This encryption method and file are part of a security toolkit. Can you identify this toolkit? ---------------------------------------------------------------------------------------------- Okay, 30 minutes of searching isnt enough... Lets try Usenet: (Google helps here too) http://groups.google.com/groups?q=uconf.inv&hl=en&lr=&safe=off&rnum=1&ic=1&selm=tPLT6.31%244Y4.88875%40news.uswest.net (From: Bruce Ediger (eballen1@qwest.net) Subject: Notes on a Solaris Rootkit Newsgroups: comp.security.unix Date: 2001-06-07 07:02:02 PST ) Bruce even gives a little c program to decode somefile :) He tells us that the rootkit is a combination of two common kits: -- quote -- 1. "SunOS Rootkit" by tragedy/dor . I got hold of v1.8 and the distribution contained a file nearly identical to the /usr/lib/lpstart shell script I found on my machine. I found a reference to a v2.5 "SunOS Rootkit" by the same "tragedy/dor" fellow on another web page. This contains a trojan "ps" different than in the installed rootkit I found. The "setup" script from this rootkit explains why I found a zero-length in.fingerd, and why /usr/lib/nfs/statd disappeared. 2. "Universal Root Kit". This is the trojaned "ls", "ps", "netstat" and "find". It contains a file "inv.c" that demonstrates how the rootkit file /dev/pts/01/uconf.inv gets decoded (invert all bits, basically). -- end of quote --