From goober@ksp.sk Sun Jun 24 11:26:49 2001 Date: Fri, 22 Jun 2001 16:33:14 +0200 (CEST) From: Peter Kosinar To: project@honeynet.org Subject: Scan of the Month 16 -= [ Scan of the Month 16 ] =- According to the description of this Scan of the Month ("... and make a more difficult challenge for advance members."), this SotM should have been more difficult than the previous ones. From my point of view, it was exactly the opposite :-). But, read on... (NB. Through the text, I'll use cryptograpic terms like `plaintext' (the original file), `ciphertext' (the encrypted file), `cipher' (the encryption method), etc.) -= [ How would I solve it ? ] =- When analyzing a file encrypted with unknown cipher, we have to make several assumptions about the original file and the encryption method (otherwise the problem would be unsolvable, see note [1]). I've summarized my assumptions in the following table ('+' denotes arguments supporting the particular assumption): * The encryption works on blocks, where one block = 1 byte (ie, every byte is encrypted indepentently, not depending on the previous/following bytes). * The used encryption is a substitution cipher based on a simple generator + If the encryption was more sophisticated than a simple substitution, it would be practically impossible to `crack' it having only one ciphertext. * The plaintext contains only characters in ASCII 32-126 range + CR + LF + The file is a part of a security toolkit (bonus question). According to its length, it is not an executable, so it might be a configuration file or a part of the documentation. In both cases, it is likely that the file contains printable characters from the lower part of the ASCII table. Having enough assumptions, one can identify the encryption method and decrypt the file (heuristical/empirical methods usually help). Of course, it is possible that we wouldn't be able to decrypt the file with these assumptions. In that case, one could widen/remove some of them and try it once again. -= [ How did I solve it ? ] =- After decrypting a dozen of files using the approach similar to the one described above, I decided to write a little program which would save me part of the work. Its source is, of course, attached (however, it was written for internal use only, thus it looks pretty messy). In this case, the program gives us the result immediately: main~/scan:$ ./analyzer decrypt somefile -a chars.in [Decrypt] Activated [Decrypt] Opening somefile [Decrypt] Reading + generation of statistics. [Decrypt] Reading AllowedChars [Decrypt] Unknown argument (chars.in), ignored [Decrypt] Decrypting... [Decrypt] Using threshold=50%, maxerr=50% [Decrypt] Trying ADD Minimal error found: 54.14% [Decrypt] Trying XOR Minimal error found: 0.00% (FullShot) Key: 0xff, rerror=0.00%, writing... It is highly probable that the file was encrypted using simple XOR encryption with constant 0xff (or -1, if you prefer it written this way). The decrypted file was saved as somefile-xor-ff, so we can have a look at it (some of the lines got split, because their length exceeded the width of my screen): main~/scan:$ cat somefile-xor-ff [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 This answers the first four questions: Q1: Identify the encryption algorithim used to encrypt the file. A1: XORing each byte by 0xff Q2: How did you determine the encryption method? A2: Using the attached program. Q3: Decrypt the file, be sure to explain how you decrypted the file. A3: It was decrypted by the used program. On the other hand, once we knew the encryption method was just XOR by 0xff, we could use something similar to xxd somefile | awk '{print $1;system("echo "$2$3$4$5$6$7$8$9" | \ tr 0123456789abcdef fedcba9876543210")}' | xxd -r to decrypt the file :-) Q4: Once decrypted, explain the purpose/function of the file and why it was encrypted A4: The file was a configuration file for a security toolkit (or better, rootkit). First section, (labeled [file]) contains configuration of `find', `du' and `ls' trojans - the locations of the trojans and the list of filenames which should be invisible. Second section ([ps]) contains configuration of `ps' and possibly `lsof' trojans. The same goes for third section ([netstat]). The last section is probably the most important one - it shows the backdoors that can be used by the attacker to get higher priviledge. Finally, the last line shows the universal password for `su' utility. As the configuration file contains vital information for the rootkit, it was encrypted to prevent the legitimate administrator from reading it. The remaining questions: Q5: What lesson did you learn from this challenge? A5: `Don't forget where you have your programs' (I spent most of the time looking for the program I used :-) ) Q6: How long did this challenge take you? A6: 1 minute - first look at the file. 4 minutes - finding the exact method of encryption, actual decryption of the file (= searching for the source of the used program and running it) cca. 25 minutes - looking for the rootkit and writing this text ---------------- about 30 minutes = total QB: This encryption method and file are part of a security toolkit. Can you identify this toolkit? AB: I wasn't able to identify this rootkit by name. Nevertheless, I recalled seeing something similar on a compromised machine. The file was stored in /dev/pts/01 (in the case of Solaris) and in /lib/security/.config/ (in case of RedHat). In both cases, the name of the file was uconf.inv. Searching the Internet (google, altavista) shows some interesting information, but as far as I've been able to see, no-one has given this rootkit a name :-) ------------- Peter Kosinar Notes: [1] - For any pair of (plaintext P, ciphertext C), there is an encryption method E, such that E(P)=C. Thus, if we only have C, there are infinitely many plaintexts that could be encrypted into the ciphertext we have. In order to narrow the infinity to something reasonable, we have to make the mentioned assumptions. [ Part 2, "" Text/PLAIN (Name: "somefile-xor-ff") 12 lines. ] [ Unable to print this part. ] [ Part 3, "" Text/PLAIN (Name: "chars.in") 2 lines. ] [ Unable to print this part. ] [ Part 4, "" Text/X-CSRC (Name: "analyzer.c") 170 lines. ] [ Unable to print this part. ]