从面试题中学安全

渗透测试 2017-11-22

本文作者:温酒送诗人

根据 Github 上的面经总结的一些安全岗面试的基础知识,这些基础知识不仅要牢记,而且要熟练操作,分享给大家,共勉。

如果有漏掉的大家可以留言或是联系作者补充,谢谢。

1.对Web安全的理解

我觉得 Web 安全首先得懂 Web、第三方内容、Web 前端框架、Web 服务器语言、Web 开发框架、Web 应用、Web容器、存储、操作系统等这些都要了解,然后较为常见且危害较大的,SQL 注入,XSS 跨站、CSRF 跨站请求伪造等漏洞要熟练掌握。

第三方内容: 广告统计、mockup 实体模型

Web前端框架: jQuery 库、BootStrap

Web服务端语言: aps.net、php

Web开发框架: Diango/Rails/Thinkphp

Web应用: BBS ( discuz、xiuno ) / CMS ( 帝国、织梦、动易、Joomla ) / BLOG ( WordPress、Z-Blog、emlog )

Web 容器: Apache ( php )、IIS ( asp )、Tomcat ( java ) -- 处理从客户端发出的请求

存储:数据库存储 / 内存存储 / 文件存储

操作系统: linux / Windows

2.http协议

安装火狐浏览器常用插件方便HTTP抓包调试:

firebug:抓包与各种调试

Tamper Data:拦截修改

Live Http Header:重放功能

Hackbar:编码解码 / POST 提交

Modify Headers:修改头部

http常见状态码:

1xx:信息提示,表示请求已被成功接收,继续处理。

2xx:成功,服务器成功处理了请求

3xx:重定向,告知客户端所请求的资源已经移动

4xx:客户端错误状态码,请求了一些服务器无法处理的东西。

5xx:服务端错误,描述服务器内部错误


200 请求成功,一般用于 GET 和 POST 请求

301 URL 重定向,永久移动

302 URL 重定向,临时移动

404 请求资源不存在

400 客户端请求有语法错误,不能被服务器理解

401 请求未经授权

403 服务器收到请求,但是拒绝服务

500 服务器内部错误

503 服务器当前不能处理客户端请求,一段时间后可能恢复正常

GET 和 POST:

GET方法用于获取请求页面的指定信息,如点击链接

POST方法是有请求内容的,由于向服务器发送大量数据,如提交表单

http 请求:

http 请求包括三个部分,请求行 ( 请求方法 )、请求头 ( 消息报头 ) 和请求正文

1.png

http响应:

http 响应也由三部分组成,响应行,响应头 ( 消息报头 ) 和响应正文 ( 消息主题 )

2.png

3.数据库

基本 SQL 语句

增:INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)

删:DELETE FROM 表名称 WHERE 列名称 = 值

查:SELECT 列名称 FROM 表名称

改:UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值

mysql 有哪些表

mysql 自带的数据库有 information_schema、performance_schema、sys、mysql,information_schema 数据库是 mysql 自带的,它提供了访问元数据库的方式。

在 mysql 数据库中,有 mysql_install_db 脚本初始化权限表,存储权限的表有:

1、user表: 用户列、权限列、安全列、资源控制列

2、db表 : 用户列、权限列

3、host表

4、table_priv表

5、columns_priv表

6、proc_priv表

sys 数据库表说明 sys_config ,这是在这个系统库上存在的唯一一个表了:

详见这两篇文章:

http://blog.csdn.net/xlxxcc/article/details/51754524

http://blog.csdn.net/huwei0518/article/details/43563583

mysql 提权方式 ( 搭建环境使用 mysql5.1 或以前的版本)

mof 提权:

拿到 Webshell 后:

1.找一个可写目录上传mof文件,例如上传到 C:/Windows/nullevt.mof 代码如下:

3.png

2.执行load_file及into dumpfile把文件导出到正确的位置即可:

Select load_file('C:/Windows/nullevt.mof') into dumpfile 'c:/windows/system32/wbem/mof/nullevt.mof'

执行成功后,即可添加一个普通用户,然后你可以更改命令,再上传导出执行把用户提升到管理员权限,然后3389连接即可

反弹端口提权

1、拿到 mysql root 权限,无法通过网站 Getshell,利用 mysql 客户端工具连接 mysql 服务器,然后执行下面的操作:

4.png

2、本地监听你反弹的端口

nc.exe -vv -l -p 2010

成功后,你将获得一个 system 权限的 cmdshell

Mysql udf 提权

目录位置:

c:\windows\system32

1、最常见的是直接使用 udf.php ( http://pan.baidu.com/s/1jIEIQbk ) 此类的工具来执行 udf 提权

具体如下:

连接到 mysql 以后,先导出 udf.dll 到 c:\\windows\\system32 目录下。

2、创建相应的函数并执行命令,具体如下:

5.png

某些情况下,我们会遇到 Can't open shared library 的情况,

这时就需要我们把 udf.dll 导出到 lib\plugin 目录下才可以,利用 NTFS ADS 流来创建文件夹

select @@basedir; //查找到mysql的目录

select 'It is dll' into dumpfile 'C:\Program Files\MySQL\MySQL Server 5.1\lib::$INDEX_ALLOCATION'; //利用NTFS ADS创建lib目录

select 'It is dll' into dumpfile 'C:\Program Files\MySQL\MySQL Server 5.1\lib\plugin::$INDEX_ALLOCATION'; //利用NTFS ADS创建plugin目录

执行成功以后再进行导出即可。

4.操作系统

死锁以及为什么发生死锁,解除死锁

死锁是指一组相互竞争系统资源或进行通信的进程间的"永久"阻塞。

产生死锁的原因:

(1)竞争系统资源

(2)进程的推进顺序不当

产生死锁的四个必要条件:

(1) 互斥条件:一个资源每次只能被一个进程使用。

(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

解除死锁:

当发现有进程死锁后,应立即把它从死锁状态中解脱出来,常采用的方法有:

剥夺资源:从其它进程剥夺足够数量的资源给死锁进程,以解除死锁状态;

撤消进程可以直接撤消死锁进程或撤消代价最小的进程,直至有足够的资源可用,死锁状态消除为止

所谓代价是指优先级、运行代价、进程的重要性和价值等。

进程之间通信方式:

信号,管道,消息队列,共享内存。

启动流程 ( Windows ):

基本上操作系统是从计算机通电自检完成后开始进行的,这一过程可以分为 ( 预引导、引导、载入内核、初始化内核、登录等 5 个阶段 )

1) 预引导

通电自检后,从引导设备中读取并运行主引导记录MBR

2) 引导

引导阶段又可以分为 初始化引导载入程序、操作系统选择、硬件检测、硬件配置文件选择

在这一过程中需要使用的文件包括 ntldr、boot.ini、ntdetect.com、ntoskrnl.exe、ntbootdd.sys、bootsect.dos ( 非必须 )

A 初始化引导载入程序:

程序 ntldr 会自动寻找系统自带的一个微型的文件驱动,读取文件系统驱动并成功找到硬盘上的分区后,引导载入程序的初始化过程就已经完成。

B 操作系统选择:

ntldr 程序完成了初始化工作后就会从硬盘上读取 boot.ini 文件,进行操作系统选择(多系统)

C 硬件检测:

操作系统选择了想要载入的 Windows 系统后,ntdetect.com 首先要将当前计算机中安装的所有硬件信息收集起来并列成一个表,接着将该表发送给 ntldr,这个表的信息稍后会被用来创建注册表中有关硬件的键。这里需要被收集信息的硬件包括总线 / 适配器类型显卡、通讯端口、串口、浮点运算器 ( CPU )、可移动存储器、键盘、指示装置 ( 鼠标 )。

D 配置文件选择:

这个步骤不是必须的。

只有在计算机(常用于笔记本电脑)创建了多个硬件配置文件的时候才需要处理这一步

3) 载入内核阶段

在这一阶段,ntldr 会载入 Windows 的内核文件 ntoskrnl.exe,但这里仅仅是载入,内核此刻还不会被初始化。随后被载入的是硬件抽象层。接下来要被内核载入的是:HKEY_LOCAL_MACHINE\System 注册表键。

ntldr 会根据载入的 Select 键的内容判断接下来需要载入哪个 ControlSet 注册表键,这些键决定随后系统会载入哪些设备驱动或者启动哪些服务。

这些注册表键的内容被载入后,系统将进入初始化内核阶段。

这时候ntldr会将系统的控制权交给操作系统内核。

4) 初始化内核阶段

在这一阶段中主要会完成 4 项任务:

创建 Hardware 注册表键、对 Control Set 注册表键进行复制载入和初始化设备驱动、启动服务

A.创建Hardware注册表键:

Windows 内核会使用前面硬件检测阶段收集倒的硬件信息来创建 HKEY_LOCAL_MACHINE/Hardware 键。也就是说注册表中该键的内容不是固定的,会根据系统中的硬件配置情况动态更新。

B.对Control Set注册表键进行复制:

如果上一步成功,系统内核会对 Control Set 键的内容创建一个备份。这个备份会被用在系统的高级启动菜单中 "最后一次正确的配置" 选项。

例如,系统新装了一个显卡驱动,Hardware 还没有创建成功系统就崩溃了,这时就可以使用"最后一次正确的配置"选项,用上一次 Control Set 注册表键的备份内容重新生成 Hardware 键,从而撤销因安装了显卡驱动对系统设置的更改。

C.载入和初始化设备驱动:

操作系统内核首先会初始化之前在载入内核阶段载入的底层设备驱动,然后会在注册表的,HKEY_LOCAL_MACHINE/System/CurrentControlSet/Services 键下查找所有 Strat 键值为 1 的设备驱动,这些设备驱动将会在载入之后立刻进行初始化。

D.启动服务:

系统内核成功载入并且成功初始化所有底层设备驱动后,ntoskrnl.exe 创建会话管理器进程 smss.exe,这是第一个用户态进程 会话管理器会启动其他高层子系统和服务,加载并初始化内核模式中的 Win32 子系统 ( win32k.sys ),启动 csrss.exe ( win32 子系统在用户模式的部分 ),进而启动 Win32 子系统。Win32 子系统的作用是控制所有输入 / 输出设备以及访问显示设备。当这些操作都完成后,Windows 的图形界面就可以显示出来了,同时用户也将可以使用键盘以及其他 I/O 设备。

接下来会话管理器会启动 winlogon 进程。至此,初始化内核阶段已经成功完成,这时候用户就可以开始登陆了。

5)登录阶段

这一阶段,由会话管理器启动的 winlogon.exe 进程将会启动本地安全性授权 lsass.exe 子系统,加载图形化标识和验证 ( Graphical Identfication and Authentication,GINA ) 并等待用户登录。

默认 GINA 是 Msgina.dll,可以自行开发 GINA 实现基于生物信息的用户登录 ( 指纹识别,人脸识别 ),然后启动后台服务管理器 services.exe ,通过它启动所有标识为自动启动的 Win32 服务程序。

在登录过程中,后台可能仍在加载一些非关键的设备驱动。系统会再次扫描 HKEY_LOCAL_MACHINE/System/CurrentControlSet/Services 注册表键,寻找 Start 键的数值是 2 或者更大数字的服务。这些服务就是非关键服务,系统直到成功登录后才开始加载这些服务,至此,Windows 启动过程完成。

线程:

线程有时候又被称为轻量级进程,是程序执行的最小单元。

一个进程可对应多个线程,而一个线程只属于一个进程。进程的执行是以线程为单位进行的,比如说一个简单 “hello world” 程序只有一个线程,就是 main() 函数对应的线程。

保护模式,实模式

保护模式与实模式相对应,在保护模式下, CPU 的寻址模式与实模式不同。

实模式下的寻址方式是 "段基址+段偏移",段的默认大小为 64kb ,所有段都是可读写的,唯有代码段是可执行的,段的特权级为 0。

特权级有 0、1、2、3 四个级别,0 特权级别最高,3 特权级别最低想要控制系统,就必须取得0特权级,比如调试工具 SoftICE 就工作在0特权级上。

详细:

http://blog.csdn.net/rosetta/article/details/8933200

5.https的建立过程

1.客户端发送请求到服务器端 ( 支持的加密协议及版本,SSL,TLS )

2.服务端筛选合适的加密协议,返回 CA 证书和公开秘钥(公开秘钥作为证书的一部分而存在)

3.客户端使用浏览器根证书验证证书的合法性

4.如果验证通过,客户端生成对称秘钥,通过证书中的公钥加密,发送到服务端

5.服务端使用私钥解密,获取对称秘钥,使用对称秘钥加密数据

6.客户端使用共享秘钥解密数据,建立 SSL 加密通信...

6.TCP三次握手的过程以及对应的状态转换

6.png

1) 源主机给目标主机发送一个 SYN 标志位为 1 的数据包

2) 目标主机自动应答,SYN 和 ACK 均设置为 1,序号 SEQ 为 Y,并将确认号设置为 Y+1

3) 源主机收到目标主机返回的第二次握手的数据包后,向目的主机发送一个 ACK 标志位为 1 的应答包示意对第二次握手确认要建立连接,第三次握手数据包的序号为 SEQ 为 X+1,确认号为 Y+1。

7.SQL注入漏洞

基本原理和防范

应用程序对用户输入的数据校验处理不严或者根本没有校验,以至用户可以直接执行 SQL 查询

1.对特殊字符进行转义处理(可能被编码绕过)

7.png

2.使用参数化语句 (完全杜绝 SQL 注入) 以 PHP 的 PDO 或 mysqli 为例:

8.png

PDO ( 使用序数参数 ):

9.png

除了数据库数据,利用方式还有哪些?

A 获取系统 shell

B 留数据库后门

8.XSS漏洞

基本原理和分类

当应用程序发送给浏览器的页面中包含用户提交的数据,但没有经过适当验证或转义时,就会导致跨站脚本漏洞。

分类:

反射型:经过后端,不经过数据库

存储型:经过后端,经过数据库

DOM 型:不经过后端,DOM—based XSS 漏洞,是基于文档对象模型 ( Document Objeet Model,DOM ) 的一种漏洞,DOM xss 是通过 url 传入参数去控制触发的。

XSS防范

前端:

对用户输入进行编码转换

10.png

后端(在入口和出口都过滤):

对输入和输出都编码转换

11.png

可以自己编写过滤函数,调用也行。或者查找网上的 XSS 过滤函数。

xssfuzzing

一个基本的流程是:

1.检测输入点

2.潜在注入点检测

3.生成 payload

4.Payload 攻击验证

详细参考下面这篇文章:

https://www.qcloud.com/community/article/172258001490259493

xss还能干什么?

A 重定向网站

B 组建僵尸网络

更多:

http://bobao.360.cn/learning/detail/159.html

9.CSRF

原理与防范

由于浏览器自动发送会话 Cookie 等认证凭证,导致攻击者能够创建恶意的 Web 页面来产生伪造请求

案例:

上面一句话概括了 CSRF 的原理,下面我虚构了一个案例帮助理解:

123456:李白的用户 ID

741741:杜甫的用户 ID

941941:白居易的用户 ID

李白正在某银行网站给白居易转账,则有以下 URL

http://www.abc.com/zhuanzhang?=amount=500&fromAccount=123456&toAccount=941941

杜甫构造一个请求,把李白账户中的钱转到自己账户中(并且修改了金额为 5000 )

杜甫在他控制的多个网站中嵌入这段代码,李白只要登录了银行网站,又恰巧访问了杜甫控制的网站,李白的 5000 块钱就会转给杜甫

防范:

1.给每个 HTTP 请求添加一个不可预测的令牌,并保证该令牌对每个合法用户来说是唯一的,将独有的令牌包含在隐藏字段中,通过 HTTP 请求发送,避免在URL中暴露出来。

2.要求用户重新认证或判断他是一个真实的用户

csrf 如何不带 referer 访问?

那么什么是referer呢?

根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该HTTP请求的来源地址。在通常情况下,访问一个安全受限页面的请求必须来自于同一个网站。比如某银行的转账是通过用户访问 http://bank.test/test?page=10&userID=101&money=10000 页面完成,用户必须先登录 bank.test,然后通过点击页面上的按钮来触发转账事件。当用户提交请求时,该转账请求的 Referer 值就会是转账按钮所在页面的 URL(本例中,通常是以 bank. test 域名开头的地址)。而如果攻击者要对银行网站实施 CSRF 攻击,他只能在自己的网站构造请求,当用户通过攻击者的网站发送请求到银行时,该请求的 Referer 是指向攻击者的网站。因此,要防御 CSRF 攻击,银行网站只需要对于每一个转账请求验证其 Referer 值,如果是以 bank.test 开头的域名,则说明该请求是来自银行网站自己的请求,是合法的。如果 Referer 是其他网站的话,就有可能是 CSRF 攻击,则拒绝该请求。

测试发现:

测试发现 302 跳转不会带 referer,可以直接请求配置写 php 代码实现不带 referer 访问

302 跳转 php 代码实现

12.png

还有更简单的方式,使用 html 中 a 标签的一个属性

<a href="http://www.51xkx.cn" rel="noreferrer">test

10.SSRF 漏洞

原理介绍

SSRF ( Server-Side Request Forgery: 服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF 攻击的目标是从外网无法访问的内部系统。正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统 SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。

比如从指定 URL 地址获取网页文本内容,加载指定地址的图片,下载等等.

如何寻找?

一、从 Web 功能上寻找

​ 1)分享:通过URL地址分享网页内容

​ 2)图片加载与下载:通过URL地址加载或下载图片

​ 3)图片、文章收藏功能

二、从 URL 关键字寻找

大致有以下关键字:

share、wap、url、link、src、source、target、u、3g、display、sourceURl、imageURL、domain

如果利用 google 语法加上这些关键字去寻找 SSRF 漏洞,耐心的验证,现在还是可以找到存在的 SSRF 漏洞

如何深入利用?如何探测非 HTTP 协议?如何防范?

这两篇文章写的不错,搭建环境什么的都有:

http://www.91ri.org/17111.html

https://www.t00ls.net/articles-41070.html

11.如何渗透一个网站/思路(渗透测试流程)

1.信息收集

whois 查询 //站长工具

DNS 信息 //站长工具

子域名查询 //站长工具

旁站、C 段查询:http://www.webscan.cc/

开放协议、操作系统、中间件、使用的开源 Web 应用(如 WordPress,凭借经验判断)

用 nmap 进行端口扫描:

nmap-sP 192.168.1.100 //查看一个主机是否在线

nmap 192.168.1.100 //查看一个主机上开放的端口

nmap-p 1-1000 192.168.1.100 //扫描指定端口范围

nmap-p 80 192.168.1.* //扫描特定端口

nmap-O 192.168.1.100 //判断目标操作系统类型

nmap-sV 192.168.1.100 //查看目标开放端口对应的协议及版本信息

获取 WAF、IDS、防火墙信息 ( 使用 hping3、wafw00f 等工具)

网站目录 ( 使用工具 DirBuster )

数据库类型:

我通常是通过中间件信息和开放端口来判断,这些只是判断思路并不是 100% 正确

MySQL:Apache+PHP:3306

MSSQL:asp+IIS:1433

Oracle:Java+Tomcat:1521

PostgreSQL:5432

2.漏洞扫描

使用 w3af、AWVS、Nessus、APPscan 等专业的漏洞扫描器自动化扫描,或者,用自己收集的EXP编写漏洞扫描器

3.漏洞利用

SQLmap:SQL 注入利用

BeFF:XSS 漏洞利用

Metasploit:漏洞利用模块

总而言之,根据扫描到的漏洞选择合适的方法或工具来利用

4.权限获取

后台编辑器提权、Webshell 提权、数据库提权、内网渗透提权

5.分析报告

渗透测试范围和内容 ( 包不包括社工··· )

脆弱性分析:

有哪些漏洞哪些风险等等、漏洞信息以图示出。

检测过程

使用的方法和工具

改善建议和修复方案

如何获得一个域名的邮箱列表

工具:

如何社工一个企业的员工信息:

嗯,不太擅长,简单说一下吧~

先线上搜索他的公开信息,社交账号,社交圈子等等

可以先从他身边的人间接了解他本人

然后以顾客的身份接近,套取所需信息

再者时间充裕的可以跟踪一下(违法危险,被抓住容易被揍成猪头)

然后就是投其所好获取信任了

12.需要认识的常见端口

13.jpg

13.如何获取 Web 指纹

1:网页中发现关键字

2:特定文件的 MD5(主要是静态文件、不一定要是 MD5 )

3:指定 URL 的关键字

4:指定 URL 的 TAG 模式

whatweb ( Ruby 写的 ) 是一个 web 应用程序指纹识别工具,可以鉴别出内容管理系统 ( CMS ),博客平台、统计分析软件、javascript 库、服务器和其他更多Web程序。

whatweb 拥有超过 900 个插件,插件是用来鉴别 Web 应用系统的。

可以说 whatweb 是目前网络上比较强大的一款应用识别程序了。

它支持正则表达式、md5 hash 匹配、url 识别、HTML 标记模式、蜘蛛爬行等等

下载地址:

https://github.com/urbanadventurer/whatweb/

plecost 是基于 python 架构,利用了 Beautiful Soup 来解析 html、xml 文件,识别网站使用的插件及版本。kali 系统上集成了这个工具。(感兴趣的可以试着读读它的代码,自己开发一个指纹识别工具)

14.如何代码审计

自己找到过的代码审计问题

15.如何做扫描器-思路-为什么要这么设计

端口扫描器:

通过连接测试服务端口可以判断端口是否开放

(1) TCP 全连接扫描

尝试与目标主机建立正常的TCP三次握手,如果能建立三次握手,说明目标端口开放,但是扫描过程容易被检测到。

(2) TCP SYN 扫描 ( TCP 的半连接扫描)

利用 TCP 前两次握手,如第二次握手回复了,则证明端口开放,因为没有第三次握手建立连接,降低了被发现的可能,同时提高了扫描性能

(3) TCP FIN 扫描

向目标主机发送 FIN 标志位为 1 的数据包进行探测。

如果目标端口开放,则丢弃此包,不进行回应

若未开放,则返回一个 RST 标志位为 1 的数据包

这种扫描更隐秘又叫秘密扫描通常用于 UNIX 操作系统主机

有的 Windows 主机 ( Windows NT ),不论端口是否开放都回复 RST。

(4) UDP 的 ICMP 端口不可达扫描

用 UDP 协议向目标主机 UDP 端口发送探测数据包。

如果目标端口未打开,会返回一个 ICMP_PORTUNREACHABLE 错误。

根据是否收到这个消息,可以发现关闭的 UDP 端口

(5) ICMP 扫描

用 ICMP 协议向目标主机发送一个协议存在错误的 IP 数据包

根据反馈的 ICMP 信息判断目标主机使用的网络服务和端口

(6) 乱序扫描和慢速扫描

将扫描端口的顺序打乱,降低扫描速度,躲避防火墙和入侵检测系统的检查

漏洞扫描器

用模拟攻击扫描出具体的漏洞类型

比如 SQL 漏洞扫描器用 payload 字符去试、使页面报错

一个 SQL 漏洞扫描器实例:

http://blog.csdn.net/oxuzhenyi/article/details/72763486?locationNum=13&fps=1

防范扫描可以在目标主机和网络的外围边界部署防火墙和入侵检测系统

16.黑客兵器谱(渗透常用工具)

信息收集: Maltego

Web 程序 ( 拦截、重放 ):Burp suite

端口扫描: nmap (其实不仅仅是端口扫描它的脚本也很有用)

漏洞扫描:w3af、AWVS、Nessus、AppScan

SQL 注入神器: SQLmap

sqlmap 给出类型对安全研究有什么帮助(区别有、无),tamper 脚本使用:信安之路的一篇总结挺好,地址:

http://mp.weixin.qq.com/s/vEEoMacmETUA4yZODY8xMQ

XSS利用框架:BeEF

漏洞利用框架:metasploit

爆破利器:Hydra

17.python

基础类库

常用第三方类库、爬虫的基本流程

18.挖过哪些有趣的漏洞讲述过程

没有拿得出手的?

分享一个域名劫持钓鱼获取管理权限的思路文章吧:

http://mp.weixin.qq.com/s/iteYPCNPq0Sly1nf8QJWhg

19.还有就是 HR 面的时候,记住一定要准备一份自己的职业规划。


本文由 信安之路 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

楼主残忍的关闭了评论