diff --git a/.gitignore b/.gitignore
index cddf5d8..ee547e7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,4 +34,7 @@ build/
### Mac OS ###
.DS_Store
-/logs/
\ No newline at end of file
+/logs/
+/.idea/
+/src/test/
+src/main/resources/application-aliyun.yml
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 13566b8..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
deleted file mode 100644
index cd5bd28..0000000
--- a/.idea/dataSources.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
- mysql.8
- true
- docker-mac-13306
- com.mysql.cj.jdbc.Driver
- jdbc:mysql://localhost:13306
- $ProjectFileDir$
-
-
-
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
deleted file mode 100644
index aa00ffa..0000000
--- a/.idea/encodings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 4b661a5..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/mybatisx/templates.xml b/.idea/mybatisx/templates.xml
deleted file mode 100644
index b022f50..0000000
--- a/.idea/mybatisx/templates.xml
+++ /dev/null
@@ -1,86 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
deleted file mode 100644
index 2b63946..0000000
--- a/.idea/uiDesigner.xml
+++ /dev/null
@@ -1,124 +0,0 @@
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
-
- -
-
-
- -
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 8306744..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 40dcbc3..f345b4c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,13 +3,23 @@ FROM openjdk:8
WORKDIR /work
LABEL maintainer="whgojp@foxmail.com"
-LABEL version="1.0"
+LABEL version="1.4"
LABEL description="I think therefore I am."
COPY target/JavaSecLab.jar /work/JavaSecLab.jar
-EXPOSE 8080
-EXPOSE 9090
+RUN mkdir -p /tmp/upload && mkdir -p /tmp/static \
+ && mkdir -p /tmp/static/api /tmp/static/css /tmp/static/images /tmp/static/js /tmp/static/lib /tmp/static/other /tmp/static/upload \
+ && chmod -R 777 /tmp/upload /tmp/static \
+ && echo "vul test.jsp" > /tmp/upload/test.jsp \
+ && echo "vul test.txt" > /tmp/upload/test.txt \
+ && echo "test readme.md" > /tmp/static/api/readme.md \
+ && echo "test styles.css" > /tmp/static/css/styles.css \
+ && echo "test script.js" > /tmp/static/js/script.js \
+ && echo "test resource.txt" > /tmp/static/other/resource.txt \
+ && echo "test file.txt" > /tmp/static/upload/file.txt
+
+EXPOSE 80
ENV IMAGE_NAME=JavaSecLab
diff --git a/README.md b/README.md
index 746f9cf..42925ce 100644
--- a/README.md
+++ b/README.md
@@ -1,62 +1,84 @@
-[//]: # (# JavaSecLab 一款综合Java漏洞平台)
-# JavaSecLab 一款综合Java漏洞平台
+# JavaSecLab—A comprehensive Java vulnerability platform
-
-
-
-
-
-
+
+
+
+[中文文档😊](./README_ZH.md)
----------------------------------------
-## 项目介绍
- JavaSecLab是一款综合型Java漏洞平台,提供相关漏洞缺陷代码、修复代码、漏洞场景、审计SINK点、安全编码规范,覆盖多种漏洞场景,友好用户交互UI……
+## Project introduction
+ JavaSecLab is **the most comprehensive Java vulnerability platform **, providing related vulnerability defect code, repair code, vulnerability scenarios, audit SINK point, security coding specifications, vulnerability traffic analysis, covering a variety of vulnerability scenarios, user-friendly interaction UI......


-
+## public-facing
+
+- Security services: Help security service personnel understand the principle of vulnerability (generation, repair, audit), and corresponding vulnerability traffic analysis
+
+- Party A's security: It can be used as a development security training demonstration, a friendly interactive way to help R & D students more easily understand the vulnerability
+
+- Security research: Different trigger scenarios for various vulnerabilities can be used for testing security tools such as xAST
+
-## 面向人群
+## Support vulnerability module
-- 安全服务方面:帮助安全服务人员理解漏洞原理(产生、修复、审计)
-- 甲方安全方面:可作为开发安全培训演示,友好的交互方式,帮助研发同学更容易理解漏洞
-- 安全研究方面:各种漏洞的不同触发场景,可用于xAST等安全工具测试
+- Cross-site scripting attacks, cross-site request forgery, CORS, JSONP, URL redirection, XFF forgery, denial of service, XPATH injection
-## 在线环境体验
+- SQL Injection, arbitrary file family, cross-server request forgery, XML entity injection, RCE
+
+- Logic vulnerabilities (IDOR, verification code security, payment security, concurrency security), sensitive information leakage series, login antagonism series
+
+- SPEL injection, SSTI injection, deserialization, component vulnerabilities
+
+
+## Online environment experience
http://whgojp.top/
-账号密码:admin/admin
+Account password: admin/admin
+
+## Project inspiration
+
+ **I have worked in Party A's unit for a period of time, and had access to the complete vulnerability life cycle ** : After completing penetration tests many times, I sent work orders (TAPD, Jira) to notify the R&D students to fix the vulnerability, and I often faced some problems: **1, the R&D did not know why this was a vulnerability? 2, R&D does not know how to fix this vulnerability? **
+ Thus, an idea 💡 arises spontaneously, and I happen to know some development knowledge, wondering whether I can let the R & D students quickly understand the generation and repair of loopholes through the way of code...
-## 项目灵感
+> The platform provides security coding specifications for relevant vulnerabilities, and Party A friends can consider joining the development of security training when doing SDL/DevSecOps construction
- 曾在甲方单位工作过一段时间,有机会可以接触到完整的**漏洞生命周期**:很多次做完渗透测试后,通过(TAPD、Jira)发送工单通知研发朋友修复漏洞,经常面临着一些问题:**1、研发不知道为什么这是个漏洞?2、研发不知道这个漏洞怎么修复?**
- 由此,一个想法💡油然而生,恰巧自己也懂些开发知识,想着可不可以通过代码的方式让研发朋友快速了解漏洞的产生与修复……
+ In addition, I have also done security service projects, I think most of my friends will be with me, just according to the information collection -> network -> Discovery of vulnerabilities -> output report this process test, for how the vulnerability is generated, how to repair, it seems not concerned...
-> 平台提供相关漏洞的安全编码规范,甲方朋友在做SDL/DevSecOps建设的时候,可以考虑加入开发安全培训这一环节
+ In the process of code audit, it is common to locate the SINK point (that is, the key location of code execution or output) and then backtrack to find the corresponding SOURCE point (that is, the location of the input or data source). The code audit is done by concatenating the SOURCE and SINK points
- 此外,自己也做过安全服务类项目,我想大部分朋友会和我一下,只是按照 信息收集->外网打点->发现漏洞->输出报告 这个流程测试,对于漏洞怎么产生、怎么修复,似乎并不关心……
+> For each vulnerability, the platform provides the corresponding defect code and various security repair methods (such as: 1, upgrade repair 2, non-upgrade repair). At the same time, for code audit, the platform also provides the SINK point of related vulnerabilities
- 代码审计过程中,通常是先定位SINK点(即代码执行或输出的关键位置),然后再回溯寻找对应的SOURCE点(即输入或数据来源的位置)。通过将SOURCE点和SINK点串联起来,来完成代码审计工作
+ Later, contact with application security products, SCA, SAST, DAST, RASP, etc., looking at security vulnerabilities seems to be another Angle, for customers, the purchase of security tools, whether it is scanning source code, containers, images... Of course, I also hope to less false positives, the author has more or less access to accessibility analysis and other related technologies, the project has also written different trigger scenarios for each vulnerability, interested friends can test it...
-> 平台针对每种漏洞提供对应缺陷代码、多种安全安全修复方式(例如:1、升级修复 2、非升级修复),同时针对代码审计,平台也提供相关漏洞的SINK点
+> The platform provides multiple trigger scenarios for the same vulnerability
- 再后来,接触了应用安全产品,SCA、SAST、DAST、RASP等,看待安全漏洞似乎又是另一种角度,对于客户来说,采购的安全工具,无论是扫源码、容器、镜像……,都希望尽可能的扫到更多的漏洞,当然也希望少点误报,笔者也或多或少接触到可达性分析等相关技术,项目中也针对每种漏洞编写了不同的触发场景,感兴趣的朋友可以测试一下……
+🆕 update the vulnerability traffic analysis module to facilitate teachers' reference and learning. Take the vulnerability traffic of this project as an example. If you have better vulnerability traffic packets, welcome to submit PR to participate in the project 🌹
-> 平台针对同种漏洞提供多种触发场景
+
-……
+Here, take delayed injection as an example: the traffic characteristic can be clearly seen from the response time: the server responds after 5 seconds
-## 技术架构
+
+
+## Technical architecture
SpringBoot + Spring Security + MyBatis + Thymeleaf + Layui
-## 部署方式
+## Deployment mode
-先clone下项目代码
+clone the project code first
```shell
git clone https://github.com/whgojp/JavaSecLab.git
@@ -64,24 +86,24 @@ git clone https://github.com/whgojp/JavaSecLab.git

-### 原生部署-IDEA
+### Local deployment -IDEA
-> JDK环境 1.8
+> JDK Environment 1.8
-1. 配置数据库(**Mysql 8.0+**)
+1. Configuration Database (**Mysql 8.0+**)
- 执行 sql/JavaSecLab.sql 文件
+ Execute the sql/JavaSecLab.sql file
- 修改配置文件application.yml active为dev(项目默认为docker 如果搭建的过程中出现数据库连接错误 师傅们可以注意下这里)
+ Modify the configuration file application.yml active to dev(the project default is docker if there is a database connection error during the construction process, teachers can pay attention to here)
```yaml
spring:
- # 环境 dev|docker
+ # Environment dev|docker
profiles:
active: dev
```
-2. 修改application-dev.yml配置文件
+2. Modify the application-dev.yml configuration file
```yaml
username: root
@@ -91,11 +113,13 @@ url: jdbc:mysql://localhost:13306/JavaSecLab?characterEncoding=utf8&zeroDateTime
-初始账号密码:admin/admin(后台可修改)
+Initial password: admin/admin(can be changed in the background)
-### Docker部署(推荐)
+### Docker Deployment (**Recommended**)
-> 条件:已安装docker和docker-compose
+> Condition: docker and Docker-Compose are installed
+>
+> If the sql file is not initialized during docker deployment (that is, the database is empty), you need to manually import the sql file
```shell
mvn clean package -DskipTests
@@ -106,30 +130,43 @@ docker-compose -p javaseclab up -d

-## TodoList
-
-- [ ] 跨站脚本模块实现
-- [ ] SQL注入模块实现
-- [ ] 任意文件类模块实现
+For details about deployment solutions and deployment questions, see:[Deployment guide](https://github.com/whgojp/JavaSecLab/wiki/%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97)
-## 开源协议
+## Open source protocol
**When we speak of free software, we are referring to freedom, not price.**
-本项目遵循 [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0) 协议,详细的许可证内容请参见项目中的 [LICENSE](./LICENSE) 文件。
+This project follows [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0) protocol,the detailed content of License please see the [LICENSE](./LICENSE) file。
+
+## Update record
-## 一些Tips🙋
+Project detailed record update, please refer to [update log](https://github.com/whgojp/JavaSecLab/wiki/%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97)
-1. 安全问题:由于是漏洞靶场,因此不建议搭建在公网上使用
-1. 项目中的安全修复代码仅供参考,实际业务中漏洞修复起来可能要复杂的多……
-1. **问题/建议反馈:如果遇到一些项目问题或者更好的建议,欢迎各位师傅可以提Issue或加我微信进行反馈**
-1. **看到这里,师傅觉得项目有用的话,麻烦动动手点个star吧,非常感谢🙏**
+## A few Tips🙋
-## 关于作者
+1. Security issues: Because it is a vulnerability shooting range, it is not recommended to use it on the public network
+1. The security repair code in the project is for reference only, and the actual business vulnerability repair may be much more complex...
+1. **Problem/Suggestion feedback: If you encounter some project problems or better suggestions, you are welcome to raise an Issue or add a communication group for feedback **
+1. **See here, if the master thinks the project is useful, please move and click a star, thank you very much 🙏**
-作者博客:https://blog.csdn.net/weixin_53009585
+## About the author
+
+Author's blog:[今天是几号](https://blog.csdn.net/weixin_53009585)
+
+**If the master is also interested in development security, application security, SDL, vulnerability shooting range, etc., welcome to join the exchange group to discuss... **
-作者微信:
-
\ No newline at end of file
+
+
+
+
+## Sponsor open source
+
+ If you find this tool helpful, consider supporting the author's development efforts. Your sponsorship will be used to maintain the online server and continuously optimize the project function, thank you very much for your encouragement and support!
+
+
+
+
+
+
diff --git a/README_ZH.md b/README_ZH.md
new file mode 100644
index 0000000..96a4f27
--- /dev/null
+++ b/README_ZH.md
@@ -0,0 +1,170 @@
+# JavaSecLab 一款综合Java漏洞平台
+
+
+
+
+----------------------------------------
+
+## 项目介绍
+ JavaSecLab是**一款综合型Java漏洞平台**,提供相关漏洞缺陷代码、修复代码、漏洞场景、审计SINK点、安全编码规范、漏洞流量分析,覆盖多种漏洞场景,友好用户交互UI……
+
+
+
+
+
+## 面向人群
+
+- 安全服务方面:帮助安全服务人员理解漏洞原理(产生、修复、审计),以及对应漏洞流量分析
+
+- 甲方安全方面:可作为开发安全培训演示,友好的交互方式,帮助研发同学更容易理解漏洞
+
+- 安全研究方面:各种漏洞的不同触发场景,可用于xAST等安全工具测试
+
+
+## 支持漏洞模块
+
+- 跨站脚本攻击、跨站请求伪造、CORS、JSONP、URL重定向、XFF伪造、拒绝服务、XPATH注入
+
+- SQL注入、任意文件系列、跨服务端请求伪造、XML实体注入、RCE
+
+- 逻辑漏洞(IDOR、验证码安全、支付安全、并发安全)、敏感信息泄漏系列、登录对抗系列
+
+- SPEL注入、SSTI注入、反序列化、组件漏洞
+
+
+## 在线环境体验
+
+http://whgojp.top/
+
+账号密码:admin/admin
+
+## 项目灵感
+
+ 曾在甲方单位工作过一段时间,有机会接触到完整的**漏洞生命周期**:很多次做完渗透测试后,通过(TAPD、Jira)发送工单通知研发同学修复漏洞,经常面临着一些问题:**1、研发不知道为什么这是个漏洞?2、研发不知道这个漏洞怎么修复?**
+ 由此,一个想法💡油然而生,恰巧自己也懂些开发知识,想着可不可以通过代码的方式让研发同学快速了解漏洞的产生与修复……
+
+> 平台提供相关漏洞的安全编码规范,甲方朋友在做SDL/DevSecOps建设的时候,可以考虑加入开发安全培训这一环节
+
+ 此外,自己也做过安全服务类项目,我想大部分朋友会和我一下,只是按照 信息收集->外网打点->发现漏洞->输出报告 这个流程测试,对于漏洞怎么产生、怎么修复,似乎并不关心……
+
+ 代码审计过程中,通常是先定位SINK点(即代码执行或输出的关键位置),然后再回溯寻找对应的SOURCE点(即输入或数据来源的位置)。通过将SOURCE点和SINK点串联起来,来完成代码审计工作
+
+> 平台针对每种漏洞提供对应缺陷代码、多种安全安全修复方式(例如:1、升级修复 2、非升级修复),同时针对代码审计,平台也提供相关漏洞的SINK点
+
+ 再后来,接触了应用安全产品,SCA、SAST、DAST、RASP等,看待安全漏洞似乎又是另一种角度,对于客户来说,采购的安全工具,无论是扫源码、容器、镜像……,都希望尽可能的扫到更多的漏洞,当然也希望少点误报,笔者也或多或少接触到可达性分析等相关技术,项目中也针对每种漏洞编写了不同的触发场景,感兴趣的朋友可以测试一下……
+
+> 平台针对同种漏洞提供多种触发场景
+
+🆕 更新漏洞流量分析模块,方便师傅们参考学习,以本项目漏洞流量为例,如果您有更好的漏洞流量数据包,欢迎提PR参与项目🌹
+
+
+
+这里以延时注入为例:可以从响应时间明显的看到其流量特征:5秒后服务器响应
+
+
+
+## 技术架构
+
+ SpringBoot + Spring Security + MyBatis + Thymeleaf + Layui
+
+## 部署方式
+
+先clone下项目代码
+
+```shell
+git clone https://github.com/whgojp/JavaSecLab.git
+```
+
+
+
+### 本地部署-IDEA
+
+> JDK环境 1.8
+
+1. 配置数据库(**Mysql 8.0+**)
+
+ 执行 sql/JavaSecLab.sql 文件
+
+ 修改配置文件application.yml active为dev(项目默认为docker 如果搭建的过程中出现数据库连接错误 师傅们可以注意下这里)
+
+ ```yaml
+ spring:
+ # 环境 dev|docker
+ profiles:
+ active: dev
+ ```
+
+2. 修改application-dev.yml配置文件
+
+```yaml
+username: root
+password: QWE123qwe
+url: jdbc:mysql://localhost:13306/JavaSecLab?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true&allowMultiQueries=true
+```
+
+
+
+初始账号密码:admin/admin(后台可修改)
+
+### Docker部署(推荐)
+
+> 条件:已安装docker和docker-compose
+>
+> docker部署过程中 sql文件没有初始化执行的话(即数据库为空) 需要手动导入下sql文件
+
+```shell
+mvn clean package -DskipTests
+docker-compose -p javaseclab up -d
+```
+
+
+
+
+
+更多部署方案、部署问题解答详见:[部署指南](https://github.com/whgojp/JavaSecLab/wiki/%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97)
+
+## 开源协议
+
+ **When we speak of free software, we are referring to freedom, not price.**
+
+本项目遵循 [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0) 协议,详细的许可证内容请参见项目中的 [LICENSE](./LICENSE) 文件。
+
+## 更新记录
+
+项目的详细更新记录请参阅 [更新日志](https://github.com/whgojp/JavaSecLab/wiki/%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97)
+
+## 一些Tips🙋
+
+1. 安全问题:由于是漏洞靶场,因此不建议搭建在公网上使用
+1. 项目中的安全修复代码仅供参考,实际业务中漏洞修复起来可能要复杂的多……
+1. **问题/建议反馈:如果遇到一些项目问题或者更好的建议,欢迎各位师傅可以提Issue或加交流群进行反馈**
+1. **看到这里,师傅觉得项目有用的话,麻烦动动手点个star吧,非常感谢🙏**
+
+## 关于作者
+
+作者博客:[今天是几号](https://blog.csdn.net/weixin_53009585)
+
+**如果师傅同样对开发安全、应用安全、SDL、漏洞靶场等感兴趣的话,欢迎加交流群一起探讨……**
+
+
+
+
+
+
+
+## 赞助开源
+
+ 如果您觉得这个工具对您有帮助,不妨考虑支持一下作者的开发工作。您的赞助将用于维护在线服务器和持续优化项目功能,非常感谢您的鼓励和支持!
+
+
+
+
+
+
diff --git a/deploy.sh b/deploy.sh
deleted file mode 100755
index c906668..0000000
--- a/deploy.sh
+++ /dev/null
@@ -1 +0,0 @@
-docker build -t javasec . && docker run -d -p 80:8888 -v logs:/logs javasec
diff --git a/docker-compose.yml b/docker-compose.yml
index e30506f..00ee434 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -15,26 +15,24 @@ services:
- JavaSecLabNet
JavaSecLab:
- image: javaseclab:1.0
+ image: javaseclab:1.4
container_name: Container-JavaSecLab
restart: always
build: .
ports:
- 80:80
- - 8080:8080
- - 9090:9090
environment:
- - TZ=Asia/Shanghai # 设置时区为上海(GMT+8)
+ - TZ=Asia/Shanghai # 设置时区上海(GMT+8)
depends_on:
- mysql
volumes:
- ./logs:/logs # 记录日志信息
+
networks:
- JavaSecLabNet
- # 密码 admin@portainer.com
portainer:
- image: portainer/portainer-ce
+ image: portainer/portainer-ce:latest
container_name: portainer
restart: always
ports:
diff --git a/pic/donate.jpg b/pic/donate.jpg
new file mode 100644
index 0000000..543f2e1
Binary files /dev/null and b/pic/donate.jpg differ
diff --git a/pic/flow1.png b/pic/flow1.png
new file mode 100644
index 0000000..fc58e5c
Binary files /dev/null and b/pic/flow1.png differ
diff --git a/pic/flow2.png b/pic/flow2.png
new file mode 100644
index 0000000..9482f9c
Binary files /dev/null and b/pic/flow2.png differ
diff --git a/pic/group.png b/pic/group.png
new file mode 100644
index 0000000..a3537d9
Binary files /dev/null and b/pic/group.png differ
diff --git a/pic/home.png b/pic/home.png
index 34ca24b..436a659 100644
Binary files a/pic/home.png and b/pic/home.png differ
diff --git a/pic/show.png b/pic/show.png
index 866223f..d33af53 100644
Binary files a/pic/show.png and b/pic/show.png differ
diff --git a/pom.xml b/pom.xml
index c56f83b..dc216f5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,16 +6,16 @@
top.whgojp
JavaSecLab
- 1.0.0
+ 1.4.0
Java综合漏洞平台
- hello JavaSec!
+ hello JavaSecLab!
org.springframework.boot
spring-boot-starter-parent
-
- 2.4.1
-
+
+ 2.4.1
+
@@ -26,9 +26,10 @@
5.8.21
1.18.4
3.5.1
- 8.0.33
+
+ 8.0.14
2.2.0.0
- 0.10.7
+ 0.11.5
@@ -75,43 +76,13 @@
1.2.16
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- com.mysql
- mysql-connector-j
- ${mysql.version}
+
+ mysql
+ mysql-connector-java
+ 8.0.14
+
com.baomidou
@@ -192,19 +163,6 @@
provided
-
-
-
-
-
-
-
-
-
-
-
-
-
org.codehaus.groovy
groovy-all
@@ -265,6 +223,37 @@
spring-tx
+
+ org.bouncycastle
+ bcprov-jdk15on
+ 1.70
+
+
+
+ ognl
+ ognl
+ 3.3.1
+
+
+
+ commons-collections
+ commons-collections
+ 3.2.1
+
+
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+ 2.4.1
+
+
+
+
+ com.baomidou
+ dynamic-datasource-spring-boot-starter
+ 3.6.1
+
+
JavaSecLab
@@ -288,17 +277,16 @@
+
- acfunnexus
- https://maven.aliyun.com/repository/public/
- default
-
- true
-
-
- true
-
+ aliyun-central
+ https://maven.aliyun.com/repository/central
+
+
+ aliyun-public
+ https://maven.aliyun.com/repository/public
+
diff --git a/sql/JavaSecLab.sql b/sql/JavaSecLab.sql
index 8928816..f5a046b 100644
--- a/sql/JavaSecLab.sql
+++ b/sql/JavaSecLab.sql
@@ -1,5 +1,5 @@
/*
- Navicat Premium Data Transfer
+ Navicat Premium Dump SQL
Source Server : mysql_docker_mac
Source Server Type : MySQL
@@ -11,47 +11,27 @@
Target Server Version : 80200 (8.2.0)
File Encoding : 65001
- Date: 26/08/2024 19:15:41
+ Date: 23/03/2025 17:52:40
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
--- Table structure for hsqli
+-- Table structure for objects
-- ----------------------------
-DROP TABLE IF EXISTS `hsqli`;
-CREATE TABLE `hsqli` (
- `id` bigint NOT NULL AUTO_INCREMENT,
- `password` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
- `username` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,
+DROP TABLE IF EXISTS `objects`;
+CREATE TABLE `objects` (
+ `id` int NOT NULL,
+ `malicious_object` blob,
PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-
--- ----------------------------
--- Records of hsqli
--- ----------------------------
-BEGIN;
-COMMIT;
-
--- ----------------------------
--- Table structure for log
--- ----------------------------
-DROP TABLE IF EXISTS `log`;
-CREATE TABLE `log` (
- `logId` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'log_id',
- `username` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户名',
- `optionName` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户操作',
- `optionTerminal` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '操作终端',
- `optionIp` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'Ip地址',
- `optionTime` date DEFAULT NULL COMMENT '创建时间',
- PRIMARY KEY (`logId`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
--- Records of log
+-- Records of objects
-- ----------------------------
BEGIN;
+INSERT INTO `objects` (`id`, `malicious_object`) VALUES (1, 0xACED000573720034746F702E7768676F6A702E6D6F64756C65732E737072696E67626F6F742E656E746974792E4D616C6963696F75734F626A656374C007A841C29C41060200014C0007636F6D6D616E647400124C6A6176612F6C616E672F537472696E673B78707400126F70656E202D612043616C63756C61746F72);
COMMIT;
-- ----------------------------
@@ -60,35 +40,18 @@ COMMIT;
DROP TABLE IF EXISTS `sqli`;
CREATE TABLE `sqli` (
`id` int NOT NULL AUTO_INCREMENT,
- `username` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',
- `password` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',
+ `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',
+ `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',
PRIMARY KEY (`id`) USING BTREE
-) ENGINE=InnoDB AUTO_INCREMENT=730 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Records of sqli
-- ----------------------------
BEGIN;
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (706, '321', 'qwe');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (707, '2', '1');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (708, '1', '21');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (713, '1', '1');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (714, 'qwe', 'qwe');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (715, '1', '1\' AND GTID_SUBSET(CONCAT(0x71706a7a71,(SELECT (ELT(7170=7170,1))),0x7171717071),7170) AND \'1\'=\'1');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (716, '1', '1\' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1) AND \'1\'=\'1');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (717, '1', '1\' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1) AND \'1\'=\'1');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (718, '1', '1');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (719, 'test', '1\' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1) AND \'1\'=\'1');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (720, 'test', '1\' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1) AND \'1\'=\'1');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (721, 'test', '1\' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1) AND \'1\'=\'1');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (722, 'test', '1\' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1) AND \'1\'=\'1');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (723, 'test', '1\' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1) AND \'1\'=\'1');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (724, 'test', '1\' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1) AND \'1\'=\'1');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (725, 'test', '1\' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1) AND \'1\'=\'1');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (726, '1', '1\' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1) AND \'1\'=\'1');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (727, '1', '1\' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1) AND \'1\'=\'1');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (728, '1', '1\' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1) AND \'1\'=\'1');
-INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (729, '1', '1\' and updatexml(1,concat(0x7e,(SELECT user()),0x7e),1) AND \'1\'=\'1');
+INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (1, 'admin', 'admin');
+INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (2, 'admin123', 'admin123');
+INSERT INTO `sqli` (`id`, `username`, `password`) VALUES (3, 'test', 'test');
COMMIT;
-- ----------------------------
@@ -96,8 +59,8 @@ COMMIT;
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
- `username` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',
- `password` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',
+ `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',
+ `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',
PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
@@ -105,9 +68,9 @@ CREATE TABLE `user` (
-- Records of user
-- ----------------------------
BEGIN;
-INSERT INTO `user` (`username`, `password`) VALUES ('1', '1');
INSERT INTO `user` (`username`, `password`) VALUES ('123', '123');
INSERT INTO `user` (`username`, `password`) VALUES ('admin', 'admin');
+INSERT INTO `user` (`username`, `password`) VALUES ('test', 'test');
COMMIT;
-- ----------------------------
@@ -116,11 +79,11 @@ COMMIT;
DROP TABLE IF EXISTS `xss`;
CREATE TABLE `xss` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
- `content` text COLLATE utf8mb4_general_ci NOT NULL COMMENT '插入内容',
+ `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '插入内容',
`ua` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'User-Agent',
- `date` varchar(255) COLLATE utf8mb4_general_ci NOT NULL COMMENT '插入时间',
+ `date` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '插入时间',
PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=74 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
+) ENGINE=InnoDB AUTO_INCREMENT=85 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
-- ----------------------------
-- Records of xss
diff --git a/src/main/java/top/whgojp/Application.java b/src/main/java/top/whgojp/Application.java
index 5623c51..59e0664 100644
--- a/src/main/java/top/whgojp/Application.java
+++ b/src/main/java/top/whgojp/Application.java
@@ -4,7 +4,6 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
-
import java.io.IOException;
diff --git a/src/main/java/top/whgojp/common/config/DataSourceConfiguration.java b/src/main/java/top/whgojp/common/config/DataSourceConfiguration.java
deleted file mode 100644
index 7b850d7..0000000
--- a/src/main/java/top/whgojp/common/config/DataSourceConfiguration.java
+++ /dev/null
@@ -1,24 +0,0 @@
-//package top.whgojp.common.config;
-//
-//import com.alibaba.druid.pool.DruidDataSource;
-//import org.springframework.boot.context.properties.ConfigurationProperties;
-//import org.springframework.context.annotation.Bean;
-//import org.springframework.context.annotation.Configuration;
-//
-//import javax.activation.DataSource;
-//
-///**
-// * @description <功能描述>
-// * @author: whgojp
-// * @email: whgojp@foxmail.com
-// * @Date: 2024/8/9 13:17
-// */
-//@Configuration
-//public class DataSourceConfiguration {
-//
-// @ConfigurationProperties(prefix = "spring.datasource.druid")
-// @Bean
-// public DataSource dataSource(){
-// return (DataSource) new DruidDataSource();
-// }
-//}
\ No newline at end of file
diff --git a/src/main/java/top/whgojp/common/config/FilterConfig.java b/src/main/java/top/whgojp/common/config/FilterConfig.java
new file mode 100644
index 0000000..4fdaad9
--- /dev/null
+++ b/src/main/java/top/whgojp/common/config/FilterConfig.java
@@ -0,0 +1,19 @@
+package top.whgojp.common.config;
+
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import top.whgojp.modules.mshell.entity.MaliciousFilter;
+
+@Configuration
+public class FilterConfig {
+
+ @Bean
+ public FilterRegistrationBean maliciousFilter() {
+ FilterRegistrationBean registrationBean = new FilterRegistrationBean<>();
+ registrationBean.setFilter(new MaliciousFilter());
+ registrationBean.addUrlPatterns("/mshell/filter/*"); // 拦截所有请求
+ registrationBean.setOrder(1); // 可以设置过滤器的优先级,值越小,优先级越高
+ return registrationBean;
+ }
+}
diff --git a/src/main/java/top/whgojp/common/config/HibernateConfig.java b/src/main/java/top/whgojp/common/config/HibernateConfig.java
deleted file mode 100644
index 71a58d4..0000000
--- a/src/main/java/top/whgojp/common/config/HibernateConfig.java
+++ /dev/null
@@ -1,55 +0,0 @@
-//package top.whgojp.common.config;
-//
-//import org.hibernate.SessionFactory;
-//import org.springframework.context.annotation.Bean;
-//import org.springframework.context.annotation.ComponentScan;
-//import org.springframework.context.annotation.Configuration;
-//import org.springframework.jdbc.datasource.DriverManagerDataSource;
-//import org.springframework.orm.hibernate5.HibernateTransactionManager;
-//import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
-//import org.springframework.transaction.annotation.EnableTransactionManagement;
-//
-//import javax.sql.DataSource;
-//import java.util.Properties;
-//
-//@Configuration
-//@EnableTransactionManagement
-//@ComponentScan(basePackages = "top.whgojp") // 替换为你的包名
-//public class HibernateConfig {
-//
-// @Bean
-// public LocalSessionFactoryBean sessionFactory() {
-// LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
-// sessionFactory.setDataSource(dataSource()); // 设置数据源
-// sessionFactory.setPackagesToScan("top.whgojp"); // 替换为包含实体类的包名
-// sessionFactory.setHibernateProperties(hibernateProperties());
-// return sessionFactory;
-// }
-//
-// @Bean
-// public DataSource dataSource() {
-// DriverManagerDataSource dataSource = new DriverManagerDataSource();
-// dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
-// dataSource.setUrl("jdbc:mysql://localhost:13306/JavaSecLab");
-// dataSource.setUsername("root");
-// dataSource.setPassword("QWE123qwe");
-// return dataSource;
-// }
-//
-// @Bean
-// public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
-// HibernateTransactionManager txManager = new HibernateTransactionManager();
-// txManager.setSessionFactory(sessionFactory);
-// return txManager;
-// }
-//
-// private Properties hibernateProperties() {
-// Properties properties = new Properties();
-// properties.put("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
-// properties.put("hibernate.show_sql", true);
-// properties.put("hibernate.format_sql", true);
-// properties.put("hibernate.hbm2ddl.auto", "update");
-// return properties;
-// }
-//
-//}
diff --git a/src/main/java/top/whgojp/common/config/ViewResolverConfiguration.java b/src/main/java/top/whgojp/common/config/ViewResolverConfiguration.java
deleted file mode 100644
index 0bccf79..0000000
--- a/src/main/java/top/whgojp/common/config/ViewResolverConfiguration.java
+++ /dev/null
@@ -1,80 +0,0 @@
-//package top.whgojp.common.config;
-//
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.context.annotation.Bean;
-//import org.springframework.context.annotation.ComponentScan;
-//import org.springframework.context.annotation.Configuration;
-//import org.springframework.web.servlet.ViewResolver;
-//import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
-//import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-//import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
-//import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-//import org.springframework.web.servlet.view.InternalResourceViewResolver;
-//import org.thymeleaf.spring5.SpringTemplateEngine;
-//import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
-//import org.thymeleaf.spring5.view.ThymeleafViewResolver;
-//import org.thymeleaf.templatemode.TemplateMode;
-//import top.whgojp.common.constant.SysConstant;
-//
-//@Configuration
-//@EnableWebMvc
-//@ComponentScan("top.whgojp.modules") // 扫描控制器组件
-//public class ViewResolverConfiguration implements WebMvcConfigurer {
-//
-// @Autowired
-// private SysConstant sysConstant;
-//
-// @Override
-// public void addResourceHandlers(ResourceHandlerRegistry registry) {
-// String uploadFolderPath = sysConstant.getUploadFolder();
-// registry.addResourceHandler("/file/**")
-// .addResourceLocations("file:" + uploadFolderPath + "/");
-// registry.addResourceHandler("/static/**")
-// .addResourceLocations("classpath:/static/");
-// }
-//
-// // Thymeleaf视图解析器
-// @Bean
-// public ViewResolver thymeleafViewResolver() {
-// ThymeleafViewResolver resolver = new ThymeleafViewResolver();
-// resolver.setTemplateEngine(templateEngine());
-// resolver.setCharacterEncoding("UTF-8");
-// resolver.setOrder(1); // 优先级较高
-// return resolver;
-// }
-//
-// // JSP视图解析器
-// @Bean
-// public ViewResolver jspViewResolver() {
-// InternalResourceViewResolver resolver = new InternalResourceViewResolver();
-// resolver.setPrefix("/WEB-INF/");
-// resolver.setSuffix(".jsp");
-// resolver.setViewNames("jsp/*"); // 只有在视图名称以"jsp/"开头时才使用JSP解析器
-// resolver.setOrder(2); // 优先级较低
-// return resolver;
-// }
-//
-//
-//
-// @Bean
-// public SpringResourceTemplateResolver templateResolver() {
-// SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
-// templateResolver.setPrefix("classpath:/templates/");
-// templateResolver.setSuffix(".html");
-// templateResolver.setTemplateMode(TemplateMode.HTML);
-// templateResolver.setCharacterEncoding("UTF-8");
-// return templateResolver;
-// }
-//
-// @Bean
-// public SpringTemplateEngine templateEngine() {
-// SpringTemplateEngine templateEngine = new SpringTemplateEngine();
-// templateEngine.setTemplateResolver(templateResolver());
-// return templateEngine;
-// }
-//
-// @Override
-// public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
-// configurer.enable("default");
-// }
-//}
diff --git a/src/main/java/top/whgojp/common/config/WebConfig.java b/src/main/java/top/whgojp/common/config/WebConfig.java
index e47b7f4..db4df42 100644
--- a/src/main/java/top/whgojp/common/config/WebConfig.java
+++ b/src/main/java/top/whgojp/common/config/WebConfig.java
@@ -3,13 +3,12 @@
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
import top.whgojp.common.constant.SysConstant;
/**
- * @description <功能描述>
+ * @description 自定义静态资源的访问路径、文件映射
* @author: whgojp
* @email: whgojp@foxmail.com
* @Date: 2024/5/23 18:58
diff --git a/src/main/java/top/whgojp/common/constant/SysConstant.java b/src/main/java/top/whgojp/common/constant/SysConstant.java
index 30225a7..8a3c853 100644
--- a/src/main/java/top/whgojp/common/constant/SysConstant.java
+++ b/src/main/java/top/whgojp/common/constant/SysConstant.java
@@ -1,12 +1,13 @@
package top.whgojp.common.constant;
import lombok.Data;
-import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
+import java.io.File;
import java.io.IOException;
/**
@@ -36,24 +37,36 @@ public class SysConstant {
@Autowired
private ResourceLoader resourceLoader;
+ @Value("${folder.upload:/tmp/upload}")
private String uploadFolder;
+
+ @Value("${folder.static:/tmp/static}")
private String staticFolder;
+ public SysConstant(ResourceLoader resourceLoader) {
+ this.resourceLoader = resourceLoader;
+ }
+
@PostConstruct
public void init() throws IOException {
- // 获取资源对象
- Resource uploadResource = resourceLoader.getResource("classpath:/static/upload/");
- Resource staticResource = resourceLoader.getResource("classpath:/static/");
- if (uploadResource.exists() && staticResource.exists()) {
- try {
- this.uploadFolder = uploadResource.getFile().getPath(); // 仅在资源存在于文件系统中时有效
- this.staticFolder = staticResource.getFile().getPath();
- } catch (IOException e) {
- this.uploadFolder = uploadResource.getURL().toString(); // 获取资源的URL
- this.staticFolder = staticResource.getURL().toString();
- }
- } else {
- throw new IOException("Resource not found!");
+ // 初始化上传目录
+ initializeDirectory(uploadFolder, "upload");
+
+ // 初始化静态资源目录
+ initializeDirectory(staticFolder, "static");
+ }
+
+ /**
+ * 初始化目录,如果不存在则尝试创建
+ *
+ * @param path 目录路径
+ * @param directoryName 目录名称,用于错误提示
+ * @throws IOException 如果目录创建失败
+ */
+ private void initializeDirectory(String path, String directoryName) throws IOException {
+ File dir = new File(path);
+ if (!dir.exists() && !dir.mkdirs()) {
+ throw new IOException("Failed to create " + directoryName + " directory: " + path);
}
}
diff --git a/src/main/java/top/whgojp/common/push/service/DingDingPush.java b/src/main/java/top/whgojp/common/push/service/DingDingPush.java
deleted file mode 100644
index c2e9e30..0000000
--- a/src/main/java/top/whgojp/common/push/service/DingDingPush.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package top.whgojp.common.push.service;
-
-/**
- * @description 钉钉推送
- * @author: whgojp
- * @email: whgojp@foxmail.com
- * @Date: 2024/6/14 16:03
- */
-public interface DingDingPush {
-}
diff --git a/src/main/java/top/whgojp/common/push/service/EmailPush.java b/src/main/java/top/whgojp/common/push/service/EmailPush.java
deleted file mode 100644
index 6021ba9..0000000
--- a/src/main/java/top/whgojp/common/push/service/EmailPush.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package top.whgojp.common.push.service;
-
-/**
- * @description 邮件推送
- * @author: whgojp
- * @email: whgojp@foxmail.com
- * @Date: 2024/6/14 16:05
- */
-public interface EmailPush {
- void send();
-}
diff --git a/src/main/java/top/whgojp/common/push/service/FeiShuPush.java b/src/main/java/top/whgojp/common/push/service/FeiShuPush.java
deleted file mode 100644
index fc99533..0000000
--- a/src/main/java/top/whgojp/common/push/service/FeiShuPush.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package top.whgojp.common.push.service;
-
-/**
- * @description 飞书推送
- * @author: whgojp
- * @email: whgojp@foxmail.com
- * @Date: 2024/6/14 16:03
- */
-public interface FeiShuPush {
-}
diff --git a/src/main/java/top/whgojp/common/push/service/PhonePush.java b/src/main/java/top/whgojp/common/push/service/PhonePush.java
deleted file mode 100644
index 8775de7..0000000
--- a/src/main/java/top/whgojp/common/push/service/PhonePush.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package top.whgojp.common.push.service;
-
-/**
- * @description <功能描述>
- * @author: whgojp
- * @email: whgojp@foxmail.com
- * @Date: 2024/6/14 16:24
- */
-public interface PhonePush {
-}
diff --git a/src/main/java/top/whgojp/common/push/service/SmsPush.java b/src/main/java/top/whgojp/common/push/service/SmsPush.java
deleted file mode 100644
index 8173523..0000000
--- a/src/main/java/top/whgojp/common/push/service/SmsPush.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package top.whgojp.common.push.service;
-
-/**
- * @description 短信推送
- * @author: whgojp
- * @email: whgojp@foxmail.com
- * @Date: 2024/6/14 16:04
- */
-public interface SmsPush {
-}
diff --git a/src/main/java/top/whgojp/common/push/service/WeComPush.java b/src/main/java/top/whgojp/common/push/service/WeComPush.java
deleted file mode 100644
index 9b4217c..0000000
--- a/src/main/java/top/whgojp/common/push/service/WeComPush.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package top.whgojp.common.push.service;
-
-/**
- * @description 企业微信推送
- * @author: whgojp
- * @email: whgojp@foxmail.com
- * @Date: 2024/6/14 16:07
- */
-public interface WeComPush {
-}
diff --git a/src/main/java/top/whgojp/common/push/service/WechatPush.java b/src/main/java/top/whgojp/common/push/service/WechatPush.java
deleted file mode 100644
index 33403dc..0000000
--- a/src/main/java/top/whgojp/common/push/service/WechatPush.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package top.whgojp.common.push.service;
-
-/**
- * @description 微信推送
- * @author: whgojp
- * @email: whgojp@foxmail.com
- * @Date: 2024/6/14 16:04
- */
-public interface WechatPush {
-}
diff --git a/src/main/java/top/whgojp/common/push/service/impl/DingDingPushImpl.java b/src/main/java/top/whgojp/common/push/service/impl/DingDingPushImpl.java
deleted file mode 100644
index 91893b6..0000000
--- a/src/main/java/top/whgojp/common/push/service/impl/DingDingPushImpl.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package top.whgojp.common.push.service.impl;
-
-/**
- * @description <功能描述>
- * @author: whgojp
- * @email: whgojp@foxmail.com
- * @Date: 2024/6/14 16:09
- */
-public class DingDingPushImpl {
-}
diff --git a/src/main/java/top/whgojp/common/push/service/impl/EmailPushImpl.java b/src/main/java/top/whgojp/common/push/service/impl/EmailPushImpl.java
deleted file mode 100644
index 1e80be3..0000000
--- a/src/main/java/top/whgojp/common/push/service/impl/EmailPushImpl.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package top.whgojp.common.push.service.impl;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-import top.whgojp.common.push.service.EmailPush;
-
-/**
- * @description <功能描述>
- * @author: whgojp
- * @email: whgojp@foxmail.com
- * @Date: 2024/6/14 16:09
- */
-@Slf4j
-@Service
-public class EmailPushImpl implements EmailPush {
- @Override
- public void send() {
- log.info("短信发送成功!");
- }
-}
diff --git a/src/main/java/top/whgojp/common/push/service/impl/FeishuPushImpl.java b/src/main/java/top/whgojp/common/push/service/impl/FeishuPushImpl.java
deleted file mode 100644
index 6aaad3d..0000000
--- a/src/main/java/top/whgojp/common/push/service/impl/FeishuPushImpl.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package top.whgojp.common.push.service.impl;
-
-/**
- * @description <功能描述>
- * @author: whgojp
- * @email: whgojp@foxmail.com
- * @Date: 2024/6/14 16:10
- */
-public class FeishuPushImpl {
-}
diff --git a/src/main/java/top/whgojp/common/push/service/impl/PhonePushImpl.java b/src/main/java/top/whgojp/common/push/service/impl/PhonePushImpl.java
deleted file mode 100644
index 00de882..0000000
--- a/src/main/java/top/whgojp/common/push/service/impl/PhonePushImpl.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package top.whgojp.common.push.service.impl;
-
-/**
- * @description <功能描述>
- * @author: whgojp
- * @email: whgojp@foxmail.com
- * @Date: 2024/6/14 16:24
- */
-public class PhonePushImpl {
-}
diff --git a/src/main/java/top/whgojp/common/push/service/impl/SmsPushImpl.java b/src/main/java/top/whgojp/common/push/service/impl/SmsPushImpl.java
deleted file mode 100644
index 391066f..0000000
--- a/src/main/java/top/whgojp/common/push/service/impl/SmsPushImpl.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package top.whgojp.common.push.service.impl;
-
-import top.whgojp.common.push.service.SmsPush;
-
-/**
- * @description <功能描述>
- * @author: whgojp
- * @email: whgojp@foxmail.com
- * @Date: 2024/6/14 16:10
- */
-public class SmsPushImpl implements SmsPush {
-
-}
diff --git a/src/main/java/top/whgojp/common/push/service/impl/WeComPushImpl.java b/src/main/java/top/whgojp/common/push/service/impl/WeComPushImpl.java
deleted file mode 100644
index f5de96d..0000000
--- a/src/main/java/top/whgojp/common/push/service/impl/WeComPushImpl.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package top.whgojp.common.push.service.impl;
-
-/**
- * @description <功能描述>
- * @author: whgojp
- * @email: whgojp@foxmail.com
- * @Date: 2024/6/14 16:10
- */
-public class WeComPushImpl {
-}
diff --git a/src/main/java/top/whgojp/common/push/service/impl/WechatPushImpl.java b/src/main/java/top/whgojp/common/push/service/impl/WechatPushImpl.java
deleted file mode 100644
index c91dfe6..0000000
--- a/src/main/java/top/whgojp/common/push/service/impl/WechatPushImpl.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package top.whgojp.common.push.service.impl;
-
-/**
- * @description <功能描述>
- * @author: whgojp
- * @email: whgojp@foxmail.com
- * @Date: 2024/6/14 16:10
- */
-public class WechatPushImpl {
-}
diff --git a/src/main/java/top/whgojp/common/utils/CheckUserInput.java b/src/main/java/top/whgojp/common/utils/CheckUserInput.java
index 54e381e..8f191d8 100644
--- a/src/main/java/top/whgojp/common/utils/CheckUserInput.java
+++ b/src/main/java/top/whgojp/common/utils/CheckUserInput.java
@@ -1,12 +1,13 @@
package top.whgojp.common.utils;
import org.springframework.stereotype.Component;
-
+import org.springframework.web.util.HtmlUtils;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.regex.Pattern;
/**
* @description 用户输入数据校验
@@ -16,6 +17,30 @@
*/
@Component
public class CheckUserInput {
+ private static final Pattern SCRIPT_PATTERN = Pattern.compile("", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+ private static final Pattern EVENT_PATTERN = Pattern.compile("on\\w+\\s*=", Pattern.CASE_INSENSITIVE);
+ private static final Pattern JAVASCRIPT_PATTERN = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
+
+ public String filter(String input) {
+ if (input == null) {
+ return "";
+ }
+
+ // 基本HTML转义
+ String filtered = HtmlUtils.htmlEscape(input);
+
+ // 移除script标签
+ filtered = SCRIPT_PATTERN.matcher(filtered).replaceAll("");
+
+ // 移除事件处理器
+ filtered = EVENT_PATTERN.matcher(filtered).replaceAll("");
+
+ // 移除javascript:协议
+ filtered = JAVASCRIPT_PATTERN.matcher(filtered).replaceAll("");
+
+ return filtered;
+ }
+
public String checkUser(String username, String password, Integer id) {
String message = "";
if (username == null || username.isEmpty()) {
@@ -81,7 +106,7 @@ public boolean checkSqlBlackList(String content) {
public boolean checkSqlWhiteList(String content) {
String[] white_list = {"id", "username", "password"};
for (String s : white_list) {
- if (content.toLowerCase().contains(s)) {
+ if (content.toLowerCase().equals(s)) {
return true;
}
}
diff --git a/src/main/java/top/whgojp/common/utils/UploadUtil.java b/src/main/java/top/whgojp/common/utils/UploadUtil.java
index 347385a..838e4f1 100644
--- a/src/main/java/top/whgojp/common/utils/UploadUtil.java
+++ b/src/main/java/top/whgojp/common/utils/UploadUtil.java
@@ -1,20 +1,13 @@
package top.whgojp.common.utils;
-import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
-import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import top.whgojp.common.constant.SysConstant;
import java.io.File;
import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Objects;
@Slf4j
@Component
@@ -23,26 +16,26 @@ public class UploadUtil {
@Autowired
private SysConstant sysConstant;
-
- private static final String UPLOAD_DIR = "uploads"; // 可以改成配置文件中的路径
-
- public String uploadFile(MultipartFile file, String suffix,String path) throws IOException {
-
+ public String uploadFile(MultipartFile file, String suffix, String path) throws IOException {
+ // 从配置中获取上传目录
String uploadFolderPath = sysConstant.getUploadFolder();
-
try {
-
- String fileName = +DateUtil.current() + "."+suffix;
- String newFilePath = uploadFolderPath + "/" + fileName;
-
- file.transferTo(new File(newFilePath)); // 将文件保存到指定路径
+ // 确保目录存在
+ File uploadDir = new File(uploadFolderPath);
+ if (!uploadDir.exists() && !uploadDir.mkdirs()) {
+ throw new IOException("Failed to create upload directory: " + uploadFolderPath);
+ }
+ // 构建文件路径
+ String fileName = System.currentTimeMillis() + "." + suffix;
+ String newFilePath = uploadFolderPath + File.separator + fileName;
+ // 保存文件
+ file.transferTo(new File(newFilePath));
log.info("上传文件成功,文件路径:" + newFilePath);
return "上传文件成功,文件路径:" + path + fileName;
} catch (IOException e) {
- e.printStackTrace(); // 打印异常堆栈信息
- log.info("文件上传失败" + e.getMessage());
- return "文件上传失败" + e.getMessage();
+ log.error("文件上传失败:{}", e.getMessage(), e);
+ throw e; // 重新抛出异常供上层处理
}
-
}
+
}
\ No newline at end of file
diff --git a/src/main/java/top/whgojp/modules/components/fastjson/controller/FastjsonController.java b/src/main/java/top/whgojp/modules/components/fastjson/controller/FastjsonController.java
index bcd5598..03de345 100644
--- a/src/main/java/top/whgojp/modules/components/fastjson/controller/FastjsonController.java
+++ b/src/main/java/top/whgojp/modules/components/fastjson/controller/FastjsonController.java
@@ -29,7 +29,7 @@ public String fastjson() {
@PostMapping("/vul")
@ResponseBody
- public String vulFastjson(@RequestBody String content) {
+ public String vul(@RequestBody String content) {
try {
JSONObject jsonObject = JSON.parseObject(content);
return jsonObject.toString();
@@ -38,16 +38,21 @@ public String vulFastjson(@RequestBody String content) {
}
}
+ public String vul2(){
+
+ return "";
+ }
+
@PostMapping("/safe")
@ResponseBody
- public String safeFastjson(@RequestBody String content) {
+ public String safe(@RequestBody String content) {
try {
// 1、禁用 AutoType
ParserConfig.getGlobalInstance().setAutoTypeSupport(false);
// 2、使用AutoType白名单机制
// ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
// ParserConfig.getGlobalInstance().addAccept("top.whgojp.WhiteListClass");
- // 3、1.2.68之后的版本,Fastjson真家里safeMode的支持
+ // 3、1.2.68之后的版本,Fastjson增加了safeMode的支持
// ParserConfig.getGlobalInstance().setSafeMode(true);
// JSONObject jsonObject = JSON.parseObject(content, Feature.DisableSpecialKeyDetect);
JSONObject jsonObject = JSON.parseObject(content);
diff --git a/src/main/java/top/whgojp/modules/components/jackson/controller/JacksonController.java b/src/main/java/top/whgojp/modules/components/jackson/controller/JacksonController.java
index 257f754..20febaa 100644
--- a/src/main/java/top/whgojp/modules/components/jackson/controller/JacksonController.java
+++ b/src/main/java/top/whgojp/modules/components/jackson/controller/JacksonController.java
@@ -28,39 +28,37 @@ public String jackson() {
return "vul/components/jackson";
}
- @PostMapping("/vul")
- @ResponseBody
- public String vulJackson(@RequestBody String content) {
+ @RequestMapping("/vul")
+ public String vul(@RequestBody String content) {
try {
- return new ObjectMapper()
- .enableDefaultTyping()
- .writeValueAsString(
- new ObjectMapper().enableDefaultTyping().readValue(content, Object.class)
- );
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.enableDefaultTyping(); // 启用多态类型处理
+
+ // 反序列化接收的JSON数据,触发漏洞
+ Object obj = mapper.readValue(content, Object.class);
+ return "[+]Jackson 反序列化: " + obj.toString();
} catch (Exception e) {
- return "Jackson RCE Error";
+ e.printStackTrace();
+ return "[-]Jackson反序列化失败";
}
}
@PostMapping("/safe")
@ResponseBody
- public String safeJackson(@RequestBody String content) {
+ public String safeJackson(@RequestBody String payload) {
try {
- // 使用安全的 ObjectMapper 配置
ObjectMapper mapper = new ObjectMapper();
- // 禁用潜在的危险功能
- mapper.disableDefaultTyping();
- // 安全配置:只允许反序列化指定类型(如自定义的类或简单数据类型)
+
+ // 启用安全的类型验证
mapper.activateDefaultTyping(
LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL
);
- // 示例:仅允许特定的受信任类反序列化(可以根据需求自定义)
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
- // 将 JSON 字符串安全地反序列化为指定的 POJO 类型
- Map safePayload = mapper.readValue(content, new TypeReference>() {});
+ // 反序列化传入的JSON数据
+ Map safePayload = mapper.readValue(payload, Map.class);
return mapper.writeValueAsString(safePayload);
} catch (Exception e) {
e.printStackTrace();
@@ -69,7 +67,6 @@ public String safeJackson(@RequestBody String content) {
}
-
/**
* CVE-2020-35728
* com.oracle.wls.shaded.org.apache.xalan.lib.sql.JNDIConnectionPool组件库存在不安全的反序列化
diff --git a/src/main/java/top/whgojp/modules/components/log4j2/controller/Log4j2Controller.java b/src/main/java/top/whgojp/modules/components/log4j2/controller/Log4j2Controller.java
index d6e6219..3c8e4fb 100644
--- a/src/main/java/top/whgojp/modules/components/log4j2/controller/Log4j2Controller.java
+++ b/src/main/java/top/whgojp/modules/components/log4j2/controller/Log4j2Controller.java
@@ -28,7 +28,7 @@ public String log4j2() {
@PostMapping("/vul")
@ResponseBody
- public String vulLog4j2(@RequestParam("payload") String payload) {
+ public String vul(@RequestParam("payload") String payload) {
System.out.println("[+]Log4j2反序列化:"+payload);
logger.error(payload);
return "[+]Log4j2反序列化:"+payload;
@@ -36,7 +36,7 @@ public String vulLog4j2(@RequestParam("payload") String payload) {
@PostMapping("/safe")
@ResponseBody
- public String safeLog4j2(@RequestParam("payload") String payload) {
+ public String safe(@RequestParam("payload") String payload) {
payload = StringEscapeUtils.escapeHtml4(payload);
System.out.println("[+]Log4j2反序列化:"+payload);
diff --git a/src/main/java/top/whgojp/modules/components/xstream/controller/XstreamController.java b/src/main/java/top/whgojp/modules/components/xstream/controller/XstreamController.java
index e2ef639..3d3a1e2 100644
--- a/src/main/java/top/whgojp/modules/components/xstream/controller/XstreamController.java
+++ b/src/main/java/top/whgojp/modules/components/xstream/controller/XstreamController.java
@@ -41,7 +41,7 @@ public String xstream() {
@RequestMapping("/vul")
@ResponseBody
- public String vulXstream(@RequestBody String content) {
+ public String vul(@RequestBody String content) {
log.info("组件漏洞-Xstream\n" + "Payload:" + content);
XStream xs = new XStream();
Object result = xs.fromXML(content); // 反序列化得到的对象
@@ -50,8 +50,8 @@ public String vulXstream(@RequestBody String content) {
return "组件漏洞-Xstream Vul, 反序列化结果: \n" + result.toString();
}
- @RequestMapping("/safe-BlackList")
- public String safeXstreamBlackList(@RequestBody String content) {
+ @RequestMapping("/safe1")
+ public String safe1(@RequestBody String content) {
XStream xstream = new XStream();
// 首先清除默认设置,然后进行自定义设置
xstream.addPermission(NoTypePermission.NONE);
@@ -60,8 +60,8 @@ public String safeXstreamBlackList(@RequestBody String content) {
xstream.fromXML(content);
return "组件漏洞-Xstream Safe-BlackList";
}
- @RequestMapping("/safe-WhiteList")
- public String safeXstreamWhiteList(@RequestBody String content) {
+ @RequestMapping("/safe2")
+ public String safe2(@RequestBody String content) {
XStream xstream = new XStream();
// 首先清除默认设置,然后进行自定义设置
xstream.addPermission(NoTypePermission.NONE);
diff --git a/src/main/java/top/whgojp/modules/other/controller/CrossOriginController.java b/src/main/java/top/whgojp/modules/crossorigin/controller/CrossOriginController.java
similarity index 93%
rename from src/main/java/top/whgojp/modules/other/controller/CrossOriginController.java
rename to src/main/java/top/whgojp/modules/crossorigin/controller/CrossOriginController.java
index a8b857d..5a628e4 100644
--- a/src/main/java/top/whgojp/modules/other/controller/CrossOriginController.java
+++ b/src/main/java/top/whgojp/modules/crossorigin/controller/CrossOriginController.java
@@ -1,4 +1,4 @@
-package top.whgojp.modules.other.controller;
+package top.whgojp.modules.crossorigin.controller;
import io.jsonwebtoken.io.IOException;
import io.swagger.annotations.Api;
@@ -18,19 +18,19 @@
* @Date: 2024/6/6 20:46
*/
@Slf4j
-@Api(value = "CrossOriginController", tags = "其他漏洞-CORS")
+@Api(value = "CrossOriginController", tags = "跨域安全问题")
@Controller
//@CrossOrigin(origins = "*")
-@RequestMapping("/other/CrossOrigin")
+@RequestMapping("/crossorigin")
public class CrossOriginController {
@RequestMapping("/cors")
public String cors() {
- return "vul/other/cors";
+ return "vul/crossorigin/cors";
}
@RequestMapping("/jsonp")
public String jsonp() {
- return "vul/other/jsonp";
+ return "vul/crossorigin/jsonp";
}
@GetMapping("/corsVul")
diff --git a/src/main/java/top/whgojp/modules/other/controller/CsrfController.java b/src/main/java/top/whgojp/modules/csrf/controller/CsrfController.java
similarity index 81%
rename from src/main/java/top/whgojp/modules/other/controller/CsrfController.java
rename to src/main/java/top/whgojp/modules/csrf/controller/CsrfController.java
index e3af4a9..dea2a5f 100644
--- a/src/main/java/top/whgojp/modules/other/controller/CsrfController.java
+++ b/src/main/java/top/whgojp/modules/csrf/controller/CsrfController.java
@@ -1,9 +1,8 @@
-package top.whgojp.modules.other.controller;
+package top.whgojp.modules.csrf.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.HttpRequest;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
@@ -14,31 +13,30 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
-import java.security.Principal;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
- * @description 其他漏洞-跨站请求伪造
+ * @description 跨站请求伪造
* @author: whgojp
* @email: whgojp@foxmail.com
* @Date: 2024/7/12 22:12
*/
@Slf4j
-@Api(value = "CsrfController", tags = "其他漏洞-跨站请求伪造")
+@Api(value = "CsrfController", tags = "跨站请求伪造")
@Controller
@CrossOrigin(origins = "*")
-@RequestMapping("/other/csrf")
+@RequestMapping("/csrf")
public class CsrfController {
@ApiOperation("")
@RequestMapping("")
public String csrf() {
- return "vul/other/csrf";
+ return "vul/csrf/csrf";
}
@RequestMapping("/vul")
@ResponseBody
- public R vulCsrf(String receiver, String amount, @AuthenticationPrincipal UserDetails userDetails){
+ public R vul(String receiver, String amount, @AuthenticationPrincipal UserDetails userDetails){
String currentUser = userDetails.getUsername();
Map result = new HashMap<>();
result.put("currentUser", currentUser);
@@ -80,9 +78,9 @@ public Map getCsrfToken(HttpSession session, Model model) {
return result;
}
- @GetMapping("/safe")
+ @GetMapping("/safe1")
@ResponseBody
- public Map safeCsrf(@RequestParam("receiver") String receiver,@RequestParam("amount") String amount,@AuthenticationPrincipal UserDetails userDetails,@RequestParam("csrfToken") String csrfToken,HttpSession session) {
+ public Map safe1(@RequestParam("receiver") String receiver,@RequestParam("amount") String amount,@AuthenticationPrincipal UserDetails userDetails,@RequestParam("csrfToken") String csrfToken,HttpSession session) {
String currentUser = userDetails.getUsername();
String sessionToken = (String) session.getAttribute("csrfToken");
@@ -101,7 +99,7 @@ public Map safeCsrf(@RequestParam("receiver") String receiver,@R
@GetMapping("/safe2")
@ResponseBody
- public Map safeCsrf(HttpServletRequest request, @RequestParam("receiver") String receiver, @RequestParam("amount") String amount, @AuthenticationPrincipal UserDetails userDetails, HttpSession session) {
+ public Map safe2(HttpServletRequest request, @RequestParam("receiver") String receiver, @RequestParam("amount") String amount, @AuthenticationPrincipal UserDetails userDetails, HttpSession session) {
String currentUser = userDetails.getUsername();
Map result = new HashMap<>();
String referer = request.getHeader("referer");
diff --git a/src/main/java/top/whgojp/modules/deserialize/readobject/controller/ReadObjectController.java b/src/main/java/top/whgojp/modules/deserialize/readobject/controller/ReadObjectController.java
index d3fd972..e014f8e 100644
--- a/src/main/java/top/whgojp/modules/deserialize/readobject/controller/ReadObjectController.java
+++ b/src/main/java/top/whgojp/modules/deserialize/readobject/controller/ReadObjectController.java
@@ -8,6 +8,9 @@
import org.springframework.web.bind.annotation.*;
import top.whgojp.common.utils.R;
import top.whgojp.modules.sqli.entity.Sqli;
+import java.io.ByteArrayInputStream;
+import java.io.ObjectInputStream;
+
import java.io.ByteArrayInputStream;
import java.util.Base64;
@@ -30,26 +33,49 @@ public String readObject(){
return "vul/deserialize/readObject";
}
- @RequestMapping("/vulReadObject")
+// @RequestMapping("/vul")
+// @ResponseBody
+// public R vul(String payload) {
+// System.setProperty("org.apache.commons.collections.enableUnsafeSerialization", "true");
+// log.info("Java反序列化:"+payload);
+// try {
+// payload = payload.replace(" ", "+");
+// byte[] bytes = Base64.getDecoder().decode(payload);
+// ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
+// java.io.ObjectInputStream in = new java.io.ObjectInputStream(stream);
+// in.readObject();
+// in.close();
+// return R.ok("[+]Java反序列化:ObjectInputStream.readObject()");
+// } catch (Exception e) {
+// return R.error("[-]请输入正确的Payload!\n"+e.getMessage());
+// }
+// }
+ @RequestMapping("/vul")
@ResponseBody
- public R vulReadObject(String payload) {
+ public R vul(String payload) {
System.setProperty("org.apache.commons.collections.enableUnsafeSerialization", "true");
- log.info("Java反序列化:"+payload);
+ log.info("Java反序列化:" + payload);
try {
payload = payload.replace(" ", "+");
byte[] bytes = Base64.getDecoder().decode(payload);
ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
- java.io.ObjectInputStream in = new java.io.ObjectInputStream(stream);
- in.readObject();
+ ObjectInputStream in = new ObjectInputStream(stream);
+
+ Object obj = in.readObject();
+ log.info("反序列化对象:" + obj.toString());
+
in.close();
- return R.ok("[+]Java反序列化:ObjectInputStream.readObject()");
+ return R.ok("[+]Java反序列化:"+obj);
} catch (Exception e) {
- return R.error("[-]请输入正确的Payload!\n"+e.getMessage());
+ return R.error("[-] 请输入正确的 Payload!\n" + e.getMessage());
}
}
- @RequestMapping("/safeReadObject1")
+
+
+
+ @RequestMapping("/safe1")
@ResponseBody
- public R safeReadObject1(String payload) {
+ public R safe1(String payload) {
// 安全措施:禁用不安全的反序列化
System.setProperty("org.apache.commons.collections.enableUnsafeSerialization", "false");
log.info("Java反序列化:"+payload);
@@ -65,9 +91,9 @@ public R safeReadObject1(String payload) {
return R.error("[-]请输入正确的Payload!\n"+e.getMessage());
}
}
- @RequestMapping("/safeReadObject2")
+ @RequestMapping("/safe2")
@ResponseBody
- public R safeReadObject2(String payload) {
+ public R safe2(String payload) {
log.info("Java反序列化:"+payload);
try {
payload = payload.replace(" ", "+");
diff --git a/src/main/java/top/whgojp/modules/deserialize/snakeyaml/controller/controller/SnakeYamlController.java b/src/main/java/top/whgojp/modules/deserialize/snakeyaml/controller/controller/SnakeYamlController.java
index 0f4d01d..25c3792 100644
--- a/src/main/java/top/whgojp/modules/deserialize/snakeyaml/controller/controller/SnakeYamlController.java
+++ b/src/main/java/top/whgojp/modules/deserialize/snakeyaml/controller/controller/SnakeYamlController.java
@@ -29,20 +29,22 @@ public String snakeYaml(){
return "vul/deserialize/snakeYaml";
}
- @RequestMapping("/vulSnakeYaml")
+ @RequestMapping("/vul")
@ResponseBody
- public R vulSnakeYaml(String payload) {
+ public R vul(String payload) {
+ log.info("payload:"+payload);
Yaml y = new Yaml();
y.load(payload);
return R.ok("[+]Java反序列化:SnakeYaml原生漏洞");
}
- @PostMapping("/safeSnakeYaml")
- public R safeSnakeYaml(String payload) {
+ @PostMapping("/safe")
+ @ResponseBody
+ public R safe(String payload) {
try {
Yaml y = new Yaml(new SafeConstructor());
y.load(payload);
- return R.ok("[-]Java反序列化:SnakeYaml安全构造");
+ return R.ok("[+]Java反序列化:SnakeYaml安全构造");
} catch (Exception e) {
return R.error("[-]Java反序列化:SnakeYaml反序列化失败");
}
diff --git a/src/main/java/top/whgojp/modules/deserialize/xmldecoder/controller/XMLDecoderController.java b/src/main/java/top/whgojp/modules/deserialize/xmldecoder/controller/XMLDecoderController.java
index 2b14af1..11e948c 100644
--- a/src/main/java/top/whgojp/modules/deserialize/xmldecoder/controller/XMLDecoderController.java
+++ b/src/main/java/top/whgojp/modules/deserialize/xmldecoder/controller/XMLDecoderController.java
@@ -1,21 +1,22 @@
package top.whgojp.modules.deserialize.xmldecoder.controller;
import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
+
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
-import org.springframework.web.bind.annotation.CrossOrigin;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.*;
import top.whgojp.common.utils.R;
-import java.beans.XMLDecoder;
-import java.beans.XMLEncoder;
-import java.io.*;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
+import java.util.ArrayList;
+import java.util.List;
+import org.xml.sax.InputSource;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
/**
* @description 反序列化 - XMLDecoder
@@ -34,9 +35,9 @@ public String xmlDecoder() {
return "vul/deserialize/xmlDecoder";
}
- @RequestMapping("/vulXmlDecoder")
+ @RequestMapping("/vul")
@ResponseBody
- public R vulXmlDecoder(String payload) {
+ public R vul(String payload) {
String[] strCmd = payload.split(" ");
StringBuilder xml = new StringBuilder()
.append("")
@@ -51,11 +52,80 @@ public R vulXmlDecoder(String payload) {
try {
new java.beans.XMLDecoder(new ByteArrayInputStream(xml.toString().getBytes(StandardCharsets.UTF_8)))
.readObject().toString();
- return R.ok("命令执行成功");
+ return R.ok("[+]命令执行成功");
} catch (Exception e) {
- return R.error("命令执行失败: " + e.getMessage());
+ return R.error("[-]命令执行失败: " + e.getMessage());
}
}
+ @RequestMapping("/safe")
+ @ResponseBody
+ public R safe(@RequestParam String payload) {
+ try {
+ // 构建 XML 字符串
+ StringBuilder xml = new StringBuilder()
+ .append("")
+ .append("")
+ .append("")
+ .append("");
+
+ for (int i = 0; i < payload.split(" ").length; i++) {
+ xml.append("")
+ .append(payload.split(" ")[i]).append(" ");
+ }
+
+ xml.append(" ");
+
+ // 使用 SAX 解析器解析 XML
+ SAXParserFactory factory = SAXParserFactory.newInstance();
+ SAXParser saxParser = factory.newSAXParser();
+ CommandHandler handler = new CommandHandler();
+
+ // 将 ByteArrayInputStream 包装成 InputSource
+ InputSource inputSource = new InputSource(new ByteArrayInputStream(xml.toString().getBytes(StandardCharsets.UTF_8)));
+ saxParser.parse(inputSource, handler);
+
+ // 获取解析后的命令参数
+ List args = handler.getArgs();
+
+ // 处理解析后的命令参数
+ System.out.println("Parsed command: " + String.join(" ", args));
+
+ return R.ok("[+]命令解析成功:"+String.join(" ", args));
+ } catch (Exception e) {
+ return R.error("[-]命令解析失败: " + e.getMessage());
+ }
+ }
+
+ // SAX 处理器
+ static class CommandHandler extends DefaultHandler {
+ private List args = new ArrayList<>();
+ private boolean inString = false;
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ if ("string".equals(qName)) {
+ inString = true;
+ }
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ if (inString) {
+ args.add(new String(ch, start, length));
+ }
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ if ("string".equals(qName)) {
+ inString = false;
+ }
+ }
+
+ public List getArgs() {
+ return args;
+ }
+ }
}
diff --git a/src/main/java/top/whgojp/modules/file/controller/DeleteController.java b/src/main/java/top/whgojp/modules/file/controller/DeleteController.java
index c9ea204..098ecb5 100644
--- a/src/main/java/top/whgojp/modules/file/controller/DeleteController.java
+++ b/src/main/java/top/whgojp/modules/file/controller/DeleteController.java
@@ -33,11 +33,11 @@ public String fileDelete() {
return "vul/file/delete";
}
- @ApiOperation(value = "漏洞环境:任意文件删除", notes = "原生漏洞环境,未做任何限制")
- @RequestMapping("/deleteFile")
+ @ApiOperation(value = "漏洞场景:任意文件删除", notes = "原生漏洞场景,未做任何限制")
+ @RequestMapping("/vul")
@ResponseBody
@SneakyThrows
- public String vulArbitraryFileDeletion(@RequestParam("filePath") String filePath) {
+ public String vul(@RequestParam("filePath") String filePath) {
String currentPath = System.getProperty("user.dir");
log.info("当前路径:"+currentPath);
File file = new File(filePath);
@@ -54,11 +54,11 @@ public String vulArbitraryFileDeletion(@RequestParam("filePath") String filePath
@Autowired
private SysConstant sysConstant;
- @ApiOperation(value = "安全环境:限制文件删除", notes = "仅允许删除特定目录中的文件")
- @RequestMapping("/safeDeleteFile")
+ @ApiOperation(value = "安全场景:限制文件删除", notes = "仅允许删除特定目录中的文件")
+ @RequestMapping("/safe")
@ResponseBody
@SneakyThrows
- public String safeFileDelete(@RequestParam("fileName") String fileName) {
+ public String safe(@RequestParam("fileName") String fileName) {
String baseDir = sysConstant.getUploadFolder(); // 限制删除文件所在目录为 /static/upload/下
File file = new File(baseDir, fileName);
boolean deleted = false;
diff --git a/src/main/java/top/whgojp/modules/file/controller/DownloadController.java b/src/main/java/top/whgojp/modules/file/controller/DownloadController.java
index a0bc07f..099d9b1 100644
--- a/src/main/java/top/whgojp/modules/file/controller/DownloadController.java
+++ b/src/main/java/top/whgojp/modules/file/controller/DownloadController.java
@@ -4,12 +4,16 @@
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.log4j.lf5.util.StreamUtils;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
+import top.whgojp.common.constant.SysConstant;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
+import java.nio.file.Path;
+import java.nio.file.Paths;
/**
* @description 任意文件类-文件下载
@@ -29,8 +33,8 @@ public String fileDownload() {
}
@ApiOperation(value = "下载文件", notes = "下载指定文件")
- @RequestMapping("/downloadFile")
- public void downloadFile(@RequestParam("fileName") String fileName, HttpServletResponse response) throws IOException {
+ @RequestMapping("/vul")
+ public void vul(@RequestParam("fileName") String fileName, HttpServletResponse response) throws IOException {
File file = new File(fileName);
if (file.exists() && file.isFile()) {
@@ -50,23 +54,16 @@ public void downloadFile(@RequestParam("fileName") String fileName, HttpServletR
}
}
- @ApiOperation(value = "下载文件", notes = "下载指定文件")
- @RequestMapping("/safeDownloadFile")
- public void safeDownloadFile(@RequestParam("fileName") String fileName, HttpServletResponse response) throws IOException {
- // Define a safe directory to limit file access
- String baseDir = "/path/to/safe/directory/";
-
- // Validate the file name to prevent directory traversal attacks
+ @Autowired
+ private SysConstant sysConstant;
+ @RequestMapping("/safe")
+ public void safe(@RequestParam("fileName") String fileName, HttpServletResponse response) throws IOException {
+ String baseDir = sysConstant.getUploadFolder();
if (!isValidFileName(fileName)) {
- log.warn("Invalid file name: {}", fileName);
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "非法文件名:" + fileName);
return;
}
-
- // Construct the full file path
File file = new File(baseDir, fileName);
-
- // Ensure the file is within the allowed directory
if (file.exists() && file.isFile() && file.getCanonicalPath().startsWith(new File(baseDir).getCanonicalPath())) {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
@@ -75,19 +72,15 @@ public void safeDownloadFile(@RequestParam("fileName") String fileName, HttpServ
StreamUtils.copy(fis, os);
os.flush();
} catch (FileNotFoundException e) {
- log.error("File not found: {}", fileName, e);
- response.sendError(HttpServletResponse.SC_NOT_FOUND, "文件未找到:" + fileName);
+ throw new RuntimeException(e);
} catch (IOException e) {
- log.error("Error reading file: {}", fileName, e);
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "文件读取错误:" + fileName);
+ throw new RuntimeException(e);
}
} else {
- log.warn("File does not exist or is not accessible: {}", fileName);
response.sendError(HttpServletResponse.SC_NOT_FOUND, "文件不存在或不可访问:" + fileName);
}
}
- // Helper method to validate file names
private boolean isValidFileName(String fileName) {
return fileName != null && fileName.matches("^[\\w,\\s-]+\\.[A-Za-z]{3,4}$");
}
diff --git a/src/main/java/top/whgojp/modules/file/controller/ReadController.java b/src/main/java/top/whgojp/modules/file/controller/ReadController.java
index 7397dce..8008e64 100644
--- a/src/main/java/top/whgojp/modules/file/controller/ReadController.java
+++ b/src/main/java/top/whgojp/modules/file/controller/ReadController.java
@@ -41,9 +41,9 @@ public String fileRead() {
@ApiOperation(value = "读取文件内容", notes = "读取指定文件的内容")
- @RequestMapping("/readFile")
+ @RequestMapping("/vul")
@ResponseBody
- public String readFile(@RequestParam("fileName") String fileName) throws IOException {
+ public String vul(@RequestParam("fileName") String fileName) throws IOException {
String currentPath = System.getProperty("user.dir");
log.info(currentPath);
File file = new File(fileName);
@@ -64,11 +64,11 @@ public String readFile(@RequestParam("fileName") String fileName) throws IOExcep
private SysConstant sysConstant;
@ApiOperation(value = "安全读取文件内容", notes = "仅允许读取特定目录中的文件内容")
- @RequestMapping("/safeReadFile")
+ @RequestMapping("/safe")
@ResponseBody
- public String safeReadFile(@RequestParam("fileName") String fileName) throws IOException {
- String baseDir = sysConstant.getUploadFolder(); // 限制删除文件所在目录为 /static/upload/下
- Path filePath = Paths.get(baseDir, fileName).normalize(); // 规范化路径
+ public String safe(@RequestParam("fileName") String fileName) throws IOException {
+ String baseDir = sysConstant.getUploadFolder();
+ Path filePath = Paths.get(baseDir, fileName).normalize();
// 确保文件路径在允许的目录中
if (!filePath.startsWith(Paths.get(baseDir))) {
return "访问被拒绝:文件路径不合法";
diff --git a/src/main/java/top/whgojp/modules/file/controller/UploadController.java b/src/main/java/top/whgojp/modules/file/controller/UploadController.java
index 6570938..8a05821 100644
--- a/src/main/java/top/whgojp/modules/file/controller/UploadController.java
+++ b/src/main/java/top/whgojp/modules/file/controller/UploadController.java
@@ -38,11 +38,11 @@ public String fileUpload() {
return "vul/file/upload";
}
- @ApiOperation(value = "漏洞环境:任意文件上传", notes = "原生漏洞环境,未做任何限制")
- @RequestMapping("/anyFIleUpload")
+ @ApiOperation(value = "漏洞场景:任意文件上传", notes = "原生漏洞场景,未做任何限制")
+ @RequestMapping("/vul")
@ResponseBody
@SneakyThrows
- public R vul1AnyFIleUpload(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
+ public R vul(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
String res;
String suffix = FilenameUtils.getExtension(file.getOriginalFilename());
String path = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/file/";
@@ -50,10 +50,10 @@ public R vul1AnyFIleUpload(@RequestParam("file") MultipartFile file, HttpServlet
return R.ok(res);
}
@ApiOperation(value = "安全代码:文件上传白名单", notes = "检测文件后缀,做白名单过滤")
- @RequestMapping("/anyFIleUploadWhiteList")
+ @RequestMapping("/safe")
@ResponseBody
@SneakyThrows
- public R safe1AnyFIleUploadWhiteList(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
+ public R safe(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
String res;
String suffix = FilenameUtils.getExtension(file.getOriginalFilename());
// 后缀白名单检查
diff --git a/src/main/java/top/whgojp/modules/loginconfront/LoginConfrontController.java b/src/main/java/top/whgojp/modules/funny/controller/HijackController.java
similarity index 50%
rename from src/main/java/top/whgojp/modules/loginconfront/LoginConfrontController.java
rename to src/main/java/top/whgojp/modules/funny/controller/HijackController.java
index 1d1b0db..ff3e9a9 100644
--- a/src/main/java/top/whgojp/modules/loginconfront/LoginConfrontController.java
+++ b/src/main/java/top/whgojp/modules/funny/controller/HijackController.java
@@ -1,4 +1,4 @@
-package top.whgojp.modules.loginconfront;
+package top.whgojp.modules.funny.controller;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
@@ -7,19 +7,20 @@
import org.springframework.web.bind.annotation.RequestMapping;
/**
- * @description 登录框对抗
+ * @description <功能描述>
* @author: whgojp
* @email: whgojp@foxmail.com
- * @Date: 2024/8/8 23:16
+ * @Date: 2025/1/17 16:31
*/
@Slf4j
-@Api(value = "LoginConfrontController", tags = "敏感信息泄漏-测试页面")
+@Api(value = "HijackController", tags = "劫持模块")
@Controller
@CrossOrigin(origins = "*")
-@RequestMapping("/loginConfront")
-public class LoginConfrontController {
- @RequestMapping("")
- public String CeShi() {
- return "vul/loginconfront/loginConfront";
+@RequestMapping("/funny/hijack")
+public class HijackController {
+ @RequestMapping()
+ public String hijack(){
+ return "vul/funny/hijack";
}
+
}
diff --git a/src/main/java/top/whgojp/modules/infoleak/controller/DirTraversalController.java b/src/main/java/top/whgojp/modules/infoleak/controller/DirTraversalController.java
index f47e940..d8afe06 100644
--- a/src/main/java/top/whgojp/modules/infoleak/controller/DirTraversalController.java
+++ b/src/main/java/top/whgojp/modules/infoleak/controller/DirTraversalController.java
@@ -35,9 +35,9 @@ public String DirTraversal() {
return "vul/infoleak/dirTraversal";
}
- @GetMapping("/listdir")
+ @GetMapping("/vul")
@ResponseBody
- public String listDirectory(@RequestParam String dir) {
+ public String vul(@RequestParam String dir) {
String staticFolderPath = sysConstant.getStaticFolder();
File baseDir = new File(staticFolderPath);
File requestedDir = new File(baseDir, dir);
@@ -91,10 +91,10 @@ public String listDirectory(@RequestParam String dir) {
return response.toString();
}
- @GetMapping("/safe1listdir")
+ @GetMapping("/safe1")
@ResponseBody
@SneakyThrows
- public String safe1ListDirectory(@RequestParam String dir) {
+ public String safe1(@RequestParam String dir) {
String staticFolderPath = sysConstant.getStaticFolder();
File baseDir = new File(staticFolderPath);
@@ -155,9 +155,9 @@ public String safe1ListDirectory(@RequestParam String dir) {
response.append("