/** * Wraps an exception thrown by an implementation * method. It returns the corresponding client-side exception. * @param orig the exception to wrap. * @return the wrapped exception. */ public RemoteException wrapException(Throwable orig) { if (orig instanceof SystemException) { return mapSystemException((SystemException)orig); } if (orig instanceof Error) { return new ServerError("Error occurred in server thread",(Error)orig); } else if (orig instanceof RemoteException) { return new ServerException("RemoteException occurred in server thread", (Exception)orig); } else if (orig instanceof RuntimeException) { throw (RuntimeException) orig; } if (orig instanceof Exception) return new UnexpectedException( orig.toString(), (Exception)orig ); else return new UnexpectedException( orig.toString()); }
private static Object invokeRemote(@NotNull Method localMethod, @NotNull Method remoteMethod, @NotNull Object remoteObj, @Nullable Object[] args, @Nullable ClassLoader loader, boolean substituteClassLoader) throws Exception { boolean canThrowError = false; try { Object result = remoteMethod.invoke(remoteObj, args); canThrowError = true; return handleRemoteResult(result, localMethod.getReturnType(), loader, substituteClassLoader); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); // root cause may go deeper than we need, so leave it like this if (cause instanceof ServerError) cause = ObjectUtils.chooseNotNull(cause.getCause(), cause); if (cause instanceof RuntimeException) throw (RuntimeException)cause; else if (canThrowError && cause instanceof Error || cause instanceof LinkageError) throw (Error)cause; else if (canThrow(cause, localMethod)) throw (Exception)cause; throw new RuntimeException(cause); } }
private Object[] readParams(Method m, RMIObjectInputStream oin) throws RemoteException { Class[] paramTypes = m.getParameterTypes(); Object[] params = new Object[paramTypes.length]; try { for (int i = 0; i < paramTypes.length; ++i) { params[i] = oin.readRMIObject(paramTypes[i]); } } catch (RemoteException re) { // rmi.69=RemoteException occurred while unmarshalling arguments throw new ServerException(Messages.getString("rmi.69"), re); //$NON-NLS-1$ } catch (IOException ioe) { // rmi.6A=IOException occurred while unmarshalling arguments throw new UnmarshalException(Messages.getString("rmi.6A"), ioe); //$NON-NLS-1$ } catch (ClassNotFoundException cnfe) { // rmi.6B=ClassNotFoundException occurred while unmarshalling arguments throw new UnmarshalException(Messages.getString("rmi.6B"), cnfe); //$NON-NLS-1$ } catch (Error er) { // rmi.6C=Error occurred while unmarshalling arguments throw new ServerError(Messages.getString("rmi.6C"), er); //$NON-NLS-1$ } return params; }
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getDeclaringClass() == Object.class) { return method.invoke(myRemote, args); } else { Method m = ourRemoteToLocalMap.get(Pair.<Class<?>, Class<?>>create(myRemote.getClass(), myClazz)).get(method); if (m == null) throw new NoSuchMethodError(method.getName() + " in " + myRemote.getClass()); try { return handleRemoteResult(m.invoke(myRemote, args), method.getReturnType(), myLoader, false); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); // root cause may go deeper than we need, so leave it like this if (cause instanceof ServerError) cause = ObjectUtils.chooseNotNull(cause.getCause(), cause); if (cause instanceof RuntimeException) throw cause; if (cause instanceof Error) throw cause; if (canThrow(cause, method)) throw cause; throw new RuntimeException(cause); } } }
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getDeclaringClass() == Object.class) { return method.invoke(myRemote, args); } else { Method m = ourRemoteToLocalMap.get(Pair.<Class<?>, Class<?>>create(myRemote.getClass(), myClazz)).get(method); if (m == null) throw new NoSuchMethodError(method.getName() + " in " + myRemote.getClass()); try { return handleRemoteResult(m.invoke(myRemote, args), method.getReturnType(), myLoader, false); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); // root cause may go deeper than we need, so leave it like this if (cause instanceof ServerError) cause = ObjectUtil.chooseNotNull(cause.getCause(), cause); if (cause instanceof RuntimeException) throw cause; if (cause instanceof Error) throw cause; if (canThrow(cause, method)) throw cause; throw new RuntimeException(cause); } } }
/******************* * Helper method which checks exceptions triggered by a deserialization * attacks and attempts to provide additional output to guide the user. * * If a ServerException was caused by a ClassNotFoundException then we can * safely assume that the chosen gadget chain is not available on the * server. * * If a ServerError was caused by an IOException which has "Cannot run * program" in the message then we can safely assume that the chosen gadget * chain is present, but the command wasn't available. * * @param ex ******************/ protected final void checkDeserException(Throwable t) { boolean responded = false; //Check for server-side ClassNotFoundException, indicating that the payload is no use if(t instanceof ServerException) { while(t.getCause() != null) { t = t.getCause(); if(t instanceof ClassNotFoundException) { System.out.println("\n[-] The chosen deserialization payload is not available at the server side."); responded = true; break; } } } //Check for server-side IOException saying that the program could not be run, indicating a successful attack but unavailable target program if(t instanceof ServerError) { while(t.getCause() != null) { t = t.getCause(); if(t instanceof IOException && t.getMessage().contains("Cannot run program")) { System.out.println("\n[+] The attack was successful, however the chosen command was not available."); responded = true; break; } } } //Print generic response if we can't work anything out from the exception if(responded == false) { System.out.println("\n[~] Attack completed but success could not be verified."); } }
/** * {@link java.rmi.ServerError#ServerError(java.lang.String, java.lang.Error)}. */ public void testServerError() { Error t = new Error(); ServerError e = new ServerError("fixture", t); assertTrue(e.getMessage().indexOf("fixture") > -1); assertSame(t, e.getCause()); assertSame(t, e.detail); }
/** * Converts the exception that was thrown by the implementation method on a * server side into RemoteException that can be transferred and re-thrown on a * client side. The method converts exceptions as defined in the following * table: <table border = "1"> * <tr> * <th>Exception to map (or subclass)</th> * <th>Maps into</th> * </tr> * <tr> * <td>{@link Error}</td> * <td>{@link ServerError}</td> * </tr> * <tr> * <td>{@link RemoteException}</td> * <td>{@link ServerException}</td> * </tr> * <tr> * <td>{@link SystemException}</td> * <td>wrapException({@link #mapSystemException})</td> * </tr> * <tr> * <td>{@link RuntimeException}</td> * <td><b>rethrows</b></td> * </tr> * <tr> * <td>Any other exception</td> * <td>{@link UnexpectedException}</td> * </tr> * </table> * * @param ex an exception that was thrown on a server side implementation. * * @return the corresponding RemoteException unless it is a RuntimeException. * * @throws RuntimeException the passed exception if it is an instance of * RuntimeException. * * @specnote It is the same behavior, as in Suns implementations 1.4.0-1.5.0. */ public RemoteException wrapException(Throwable ex) throws RuntimeException { if (ex instanceof RuntimeException) throw (RuntimeException) ex; else if (ex instanceof Error) return new ServerError(ex.getMessage(), (Error) ex); else if (ex instanceof RemoteException) return new ServerException(ex.getMessage(), (Exception) ex); else if (ex instanceof SystemException) return wrapException(mapSystemException((SystemException) ex)); else return new UnexpectedException("Unexpected", (Exception) ex); }