0x01 code analysisPath of the file where the php encryption function is located: % wwwRoot % \ Deepthroat \ inc \ class. shlencryption. php code (with a note added): <? Phpclass shlEncryption {var $ enstr = null; function shlEncryption ($ str) {$ this-> enstr = $ str;} function get_shal () {return sha1 ($ this-> enstr); // sha1 encryption, 40-bit output} function get_md5 () {return md5 ($ this-> enstr); // md5 encryption, 32-bit output} function get_jxqy3 () {$ tmpMS = $ this-> get_shal (). $ this-> get_md5 (); // The sha1 encryption value of the input value (40) + md5 value (32) // 40 + 8 + [a0 + a1 +... + a15] + 8 $ tmpNewStr = substr ($ tmpMS, 0, 9 ). 'S '. substr ($ tmpMS, 10, 9 ). 'H '. Substr ($ tmpMS, 20, 9 ). 'l '. substr ($ tmpMS, 30, 9 ). 'S '. substr ($ tmpMS, 40, 9 ). 'U '. substr ($ tmpMS, 50, 9 ). 'N '. substr ($ tmpMS, 60, 9 ). 'y '. substr ($ tmpMS, 70, 2); // Replace the 10 integers with the characters s, h, l, s, u, n, y $ tmpNewStr = substr ($ tmpNewStr, -36 ). substr ($ tmpNewStr,); // the first 36 digits and the last 36 digits reversed 12 + 16 + 8 $ tmpNewStr = substr ($ tmpNewStr ); // obtain the first 70 digits $ tmpNewStr = substr ($ tmpNewStr ). 'J '. substr ($ tmpNewStr, 14,14 ). 'X '. substr ($ tmpNewStr, 28, 14 ). 'q '. sub Str ($ tmpNewStr, 32, 14 ). 'y '. substr ($ tmpNewStr, 56,14 ). '3'; // Add the characters j, x, q, y, 3 return $ tmpNewStr on the multiples of 15th; // return} function to_string () {$ tmpstr = $ this-> get_jxqy3 (); $ tmpstr = substr ($ tmpstr,-35 ). substr ($ tmpstr,); // return $ tmpstr ;}}?>0x02 algorithm analysisIn this encryption process, the md5 and sha1 values of the plaintext (the string to be encrypted) are spliced, combined, intercepted, and transposed to obtain the ciphertext. In this way, we have a basic understanding of the entire process during encryption. From this, we can see that, when we know the algorithm, if we only adopt the transposition operation, we can decrypt the plaintext (no loss of all information, the professional statement is that information entropy has not changed). However, if a replacement operation is performed, the situation is different. Because once there is a replacement, the amount of ciphertext information will change. For example, if ABC is used for transposition, there are only 6 possibilities. If C is replaced with D, the ciphertext is changed to ABD, where C does not exist, during decryption, this D can only be found in enumeration or other rules. Back to our cms, we noticed that md5 encryption is used and it is 32-bit. Can we track the 32-bit data and check whether the data is encrypted, what changes have occurred to these 32-bit instances? Here we think of 32-bit data, and the 32-bit md5 can actually be converted into 16 bits (in fact, 16 bits are the substrings of 32 bits, it's 9th to 25). Well, here, our goal is clear. We track the 16 strings and see what changes have taken place throughout the string encryption process. Www.2cto.com, change 0x01 to the following code for analysis: <? Phpvar $ enstr = 'admin'; var sha1str = sha1 ($ enstr); // sha1 encryption, 40-bit output var md5str = md5 ($ enstr); $ tmpMS = sha1str. md5str; // The sha1 encryption value of the input value (40) + md5 value (32) echo "Step 1, merge :". $ tmpMS. "\ r \ n"; $ tmpNewStr = substr ($ tmpMS, 0, 9 ). 'S '. substr ($ tmpMS, 10, 9 ). 'H '. substr ($ tmpMS, 20, 9 ). 'l '. substr ($ tmpMS, 30, 9 ). 'S '. substr ($ tmpMS, 40, 9 ). 'U '. substr ($ tmpMS, 50, 9 ). 'N '. substr ($ tmpMS, 60, 9 ). 'y '. substr ($ tmpMS,); // Replace 10 integers with the characters s, h, l, s, u, n, yecho" Step 2, replace :". $ tmpNewStr. "\ r \ n"; $ tmpNewStr = substr ($ tmpNewStr,-36 ). substr ($ tmpNewStr,); // the first 36 digits and the last 36 digits reverse echo "step 3, transposition :". $ tmpNewStr. "\ r \ n"; $ tmpNewStr = substr ($ tmpNewStr,); // obtain the first 70 echo "step 3, capture :". $ tmpNewStr. "\ r \ n"; $ tmpNewStr = substr ($ tmpNewStr, 0, 14 ). 'J '. substr ($ tmpNewStr, 14,14 ). 'X '. substr ($ tmpNewStr, 28, 14 ). 'q '. substr ($ tmpNewStr, 32, 14 ). 'y '. substr ($ tmpNewStr, 56,14 ). '3'; echo "Step 4: add :". $ tmpNewStr. "\ r \ n"; $ t Mpstr = $ tmpNewStr; $ tmpstr = substr ($ tmpstr,-35 ). substr ($ tmpstr,); // the last 35-bit + the Start 40-bit echo "final result ". $ tmpstr. "\ r \ n";?> Execute: Step 1, merge: Merge step 2, replace: Rotate step 3, change: Rotate step 3, intercept: Merge Step 4, add: Merge final result: Merge We can see: in step 1, in merging, the string is not affected. In Step 2, the second character string is replaced with "u ", character string 12th bits are replaced with "n". In Step 2, the position of the character string changes. in step 3, the position is truncated, which has no effect on the character string. In Step 4, add, it does not affect the character string. The position of the character string changes. In Step 5, the position of the character string changes before the output. In essence, the 16-bit character string changes two digits: 2nd digits, 12th bits and know that 16 BITs exist in the ciphertext values of 48, 49 (u), 50-59,60 (n), 61, 62.63.64. Then, if you know the 75-bit ciphertext after the password is encrypted, you can determine the 14-bit ciphertext, then there are only two possibilities left, and 36*36 known possibilities left.0x03 VerificationNow, in cms, change the password to 'wooyun, and view the database. After the password is encrypted, retrieve the 48, 49 (u), 50-59,60 (n), 61, 62.63.64-bit 0u1ffbd4128na84cx and the md of the string 'wooyun '(The 16-bit value is 061ffbd41284a84cx, which exactly matches the analysis in 0x02)0x04 SummaryBecause I can only notice the md5 string changes in the encryption process in this algorithm, and finally decrypt the encrypted string of the cms password, the 48, 49 (u ), 50-59,60 (n), 61, 62.63.64 bits, replace the u and n bits with other 0-9 or a-z, respectively, to form a valid md5 value, perform md5 cracking. Of course, the encrypted string contains other information that the author cannot use. If you have other ideas, I hope you will give me some advice.